Vize

Shortcut

Headless Shortcut; covers VS Code keybindings, React Aria useKeyboard, GitHub Hotkey.

Package @vizejs/ui/shortcut
Maturity stable
Own the source vize lib pull shortcut
Requires —
Aliases keyboard shortcuts, hotkeys, keybindings, kbd formatting
Covers VS Code keybindings, React Aria useKeyboard, GitHub Hotkey

API

createShortcutRegistry

Create an SSR-safe, scope-aware keyboard shortcut registry. The registry resolves Mod for one platform, routes chords and multi-chord sequences to the winning binding, and never touches the DOM on the server: with no ambient document it stays detached until a target appears or events are fed through ShortcutRegistry.input. Call ShortcutRegistry.dispose when using this factory outside a Vue effect scope.

function createShortcutRegistry(options: ShortcutRegistryOptions = {}): ShortcutRegistry

useShortcutRegistry

Create a shortcut registry disposed with the current Vue effect scope.

function useShortcutRegistry(options: ShortcutRegistryOptions = {}): ShortcutRegistry

getShortcutKeycaps

Break a shortcut into display keycaps for <kbd> rendering. The result carries one array per sequence step; each step lists modifier keycaps in platform order followed by the key keycap. Formatting is deterministic for a given platform, so pass an explicit platform when the output is server-rendered.

function getShortcutKeycaps( shortcut: string | ShortcutSequence, options: ShortcutFormatOptions = {}, ): readonly (readonly string[])[]

formatShortcut

Format a shortcut as one display string, e.g. ⇧⌘K or Ctrl+Shift+K. Apple symbol keycaps join without separators; every other combination joins with +. Sequence steps are joined with a single space.

function formatShortcut( shortcut: string | ShortcutSequence, options: ShortcutFormatOptions = {}, ): string

detectShortcutPlatform

Detect the modifier layout of the current environment. Server rendering has no ambient keyboard, so the detector deterministically reports standard there; pass an explicit platform when formatting keycaps into server-rendered markup.

function detectShortcutPlatform(): ShortcutPlatform

readPlatform

function readPlatform(platform: ShortcutPlatform | undefined): ShortcutPlatform

isCharacterKeyValue

True when the key value is a single character rather than a named key.

function isCharacterKeyValue(value: string): boolean

parseShortcut

Parse a shortcut pattern into a normalized chord sequence. Chord steps are separated by whitespace and each step joins modifiers and one key with +, e.g. "Mod+K", "Ctrl+Shift+P", or "G D". Mod resolves to Meta on Apple layouts and Control elsewhere.

function parseShortcut( pattern: string, options: ShortcutParseOptions = {}, ): ShortcutSequence

toShortcutSequence

Validate and freeze a caller-supplied sequence without re-parsing.

function toShortcutSequence( value: string | ShortcutSequence, platform: ShortcutPlatform, ): ShortcutSequence

serializeShortcut

Stable identity string used for routing and conflict detection.

function serializeShortcut(sequence: ShortcutSequence): string

isModifierOnlyEvent

True when the event is a lone modifier press that can never end a chord.

function isModifierOnlyEvent(event: KeyboardEvent): boolean

matchesShortcutChord

True when the event satisfies the chord's key and exact modifier state.

function matchesShortcutChord(event: KeyboardEvent, chord: ShortcutChord): boolean

chordFromEvent

Build the normalized chord described by one keyboard event.

function chordFromEvent(event: KeyboardEvent): ShortcutChord

readOptionalBoolean

function readOptionalBoolean(value: boolean | undefined, name: string): boolean

validateBindingStatics

function validateBindingStatics(options: ShortcutBindingOptions): void

readWhen

function readWhen(binding: InternalShortcutBinding): boolean

chordEquals

function chordEquals(left: ShortcutChord, right: ShortcutChord): boolean

isEditableEventTarget

Detect text-editing targets across light and shadow DOM retargeting.

function isEditableEventTarget(event: KeyboardEvent): boolean

routeChord

Route one accepted chord against the registered bindings. Exact matches win over pending extensions. Among exact matches the binding in the most recently activated scope wins, and within one scope the most recently registered binding wins.

function routeChord( bindings: Iterable<InternalShortcutBinding>, activeScopes: readonly string[], next: readonly ShortcutChord[], context: { readonly isEditable: boolean; readonly isRepeat: boolean }, ): ShortcutRouteDecision

toBindingInfo

function toBindingInfo(binding: InternalShortcutBinding): ShortcutBindingInfo

collectConflicts

Group same-scope bindings that claim one identical normalized sequence.

function collectConflicts( bindings: Iterable<InternalShortcutBinding>, ): readonly ShortcutConflict[]

Behavior

Normative state × input → outcome table for @vizejs/ui/shortcut. Every row is exercised by src/families/interaction/shortcut/shortcut*.test.ts; compile-only assertions live in src/families/interaction/shortcut/shortcut.types.test-d.ts.

# State Input Outcome Proven by
S1 registered chord matching keydown with exact modifiers handler receives an immutable match and the native action is canceled chord test
S2 registered chord keydown with extra or missing modifiers nothing dispatches and the event keeps its native action chord test
S3 Mod pattern parsed on apple and standard platforms Meta and Control resolve respectively and match accordingly platform test
S4 registered sequence first chord of the sequence pending state records the step and later chords complete the handler sequence test
S5 pending sequence timeout elapses or a non-continuing key pending clears; the key is retried as a fresh sequence start sequence-reset test
S6 shadowed shortcut scope activated above global the deepest active scope wins; release restores the earlier routing scope test
S7 scoped binding, scope inactive matching keydown nothing dispatches scope test
S8 conflicting registrations identical normalized sequence in one scope getConflicts groups them; the latest registration wins routing conflict test
S9 binding with when gate gate resolves false binding is skipped without consuming the event enablement test
S10 text-editing target printable shortcut without allowInEditable binding is skipped so typing is preserved, opted-in bindings dispatch editable-target test
S11 held key auto-repeated keydown only allowRepeat chords re-dispatch repeat test
S12 modifier-only or IME input lone modifier keydown or composing event pending state is preserved and nothing dispatches filter test
S13 reactive target target ref resolves or changes native listeners move to the new target, including shadow roots target test
S14 reactive disabled disabled becomes true pending clears synchronously and later input is ignored disabled test
S15 invalid pattern or options malformed pattern, chord, or option value stable runtime diagnostics reject the misuse diagnostics test
S16 any pattern formatted for display keycaps follow platform order and style deterministically format test
S17 active registry dispose or Vue scope stop listeners and timers release and imperative calls become terminal lifecycle test
S18 concurrent SSR requests identical consumers byte-identical markup contains no listeners or scheduled timers SSR test
S19 SSR followed by hydration matching keydown host identity remains and the shortcut dispatches without warnings hydration test
S20 DOM, SSR, and Vapor lanes authored consumer compiles every renderer accepts the same registry props and formatted keycaps renderer gate
S21 root and subpath consumer only shortcut is retained equal CSS-free bundles exclude unrelated component families tree-shaking gate
S22 public TypeScript API mutation or invalid options compile-only assertions reject misuse type declaration test

Accessibility obligation

Shortcuts are accelerators, never the only path: every action reachable through a shortcut must stay reachable through visible, focusable controls. Bindings skip text-editing targets by default so shortcuts cannot steal typing, single-character shortcuts should stay opt-in per WCAG 2.2 §2.1.4 (Character Key Shortcuts), and consumers should surface formatShortcut output near the control (for example in <kbd> or aria-keyshortcuts) so users can discover the accelerator. Platform detection is deterministic on the server; pass an explicit platform when rendering keycaps into SSR markup.