Contextual Pointer Guidance
Every click teaches the keyboard path for the clicked control instead of failing silently. Clicks are not blocked: text selection, copy buttons, and native buttons keep working. Acceptance coverage lives in Shortcuts.
How it works
- Interactive targets opt in with
data-pointer-action(anddata-pointer-event-idfor a specific event). Working controls that have a shortcut carrydata-pointer-shortcut, usually stamped byTooltipWrapper'sshortcutprop. usePointerHintTracker(mounted inRootShell) listens forpointerdownat window capture without callingpreventDefault. It resolves the nearest annotated ancestor incomposedPath()and pulses the pointer-hint store. Native buttons and links are markedperformed: true; a working control with nothing to teach stays silent, as does whitespace.PointerHintrenders copy for the attempt. A performed click saysNext time, press <key>. Sidebar open/close teach]. Event open teaches the current jump token plus Enter, orHif no token is available. An empty timed-grid click teaches the matching HHMM digits (1200,1830) so the same create can be typed. An empty all-day-row click teachesShift+C. The sidebar month picker (calendar.date-pick) teachesI, then the arrow keys and Enter. The X turns tips off for that browser (compass.pointer-hint.dismissed-permanently).- A primary event click also dispatches
compass:pointer-event-jumpso the mounted grid's event-jump owner can assign tokens and focus the event. Right-clicks teach nothing soMstill opens the context menu. An empty-grid click parks that HHMM as a short-lived teaching target so typing the shown digits creates at the clicked instant. Both keep working after tips are turned off. pointer_hint_shownandpointer_hint_dismissedare captured so adoption can be read as a funnel intoshortcut_invoked.
Unannotated controls that look clickable (role="button") get the generic
fallback. A subtree can opt out with data-pointer-pass (MobileGate, the
welcome modal, copy buttons) so those clicks stay silent.
/life is a public lead magnet: the tracker is disabled and PointerHint
is not mounted there.
Adding a target
- For a dead target, add a
POINTER_ACTIONSid and teach it inPointerHint. For a working control, passshortcuttoTooltipWrapperor spreadpointerShortcutAttributes. - Annotate the interactive element, not an inner icon.
- Keep the shown shortcut executable from the current view and lock state.