A wider screen, please

This page features interactive demos and side-by-side code samples that need at least 340 pixels of horizontal space. Please widen your browser window, or rotate your device, to continue.

Morpheus v0.3.0
v0.3.0

Keys#

Component <neo-keys> is a behavioural utility that binds keyboard shortcuts. While connected it installs a key listener on a target element (its parent by default) and removes it on disconnect. A matched chord dispatches a bubbling neo-keys event. Renders as display: contents and shows nothing.

It depends on no framework. Configuration arrives through attributes (keys, disabled, target) and activation leaves through the dispatched event. That is the signals-down-to-attributes, events-up-to-expressions shape. A Datastar data-attr:disabled arms or disarms a binding and data-on:neo-keys runs an expression on a match, with no Datastar code inside the element.

Reference#

Attributes #

NameTypeDefaultDescription
keysstring observednoneChord spec. + joins a chord, , sequences steps, | lists alternatives. Required.
targetstring observedparentListener host, one of parent, window, document, or a CSS selector resolved with querySelector.
forstringnoneID of an element to activate with click() when the shortcut matches. The neo-keys event is still dispatched.
upboolean observedfalseMatch on keyup instead of keydown.
repeatbooleanfalseAllow auto-repeat (held key) to fire.
preventtrue | falsetrueCall preventDefault() on a match. Set prevent="false" to keep the default action.
stopbooleanfalseCall stopPropagation() on a match.
in-inputbooleanfalseAlso fire when focus is in a text-entry context. By default bare-key chords are suppressed there; modifier chords fire regardless.
disabledbooleanfalseBinding is inert while set. The reactive enable/disable hook.
sequence-timeoutnumber1000Milliseconds allowed between sequence steps.

Events #

NameDetailBubblesDescription
neo-keys{ combo, key, sequence, originalEvent }yesA chord matched. combo is the matched alternative, key the KeyboardEvent.key, sequence the matched steps, originalEvent the source KeyboardEvent.

Expression syntax#

A chord is 0 or more modifiers plus 1 key, joined with + (mod+k, shift+?, alt+ArrowDown). The 3 separators do not overlap.

SeparatorMeaningExample
+Joins a modifier to a key within one chord.mod+k
,Sequences chords, pressed in order within sequence-timeout.g, i
|Lists alternatives; any one fires.mod+k | ctrl+k

mod resolves to ⌘ on Apple platforms and Ctrl elsewhere. A literal comma key is the comma alias, which keeps the separator from colliding with a key.

Examples#

Scoped shortcut#

Because the listener lives on the panel (the element's parent), mod+s only fires while focus is inside it. Default prevent blocks the browser's own save dialog. Click away and the shortcut stops firing.

Focus this panel, then press ⌘ S (Ctrl S elsewhere). Move focus away and the shortcut stops firing.

Saved times.

Sequence#

A comma-separated chord list fires only after the steps arrive in order. 2 <neo-keys> elements share the panel, one per destination, each emitting on its own g-prefixed sequence.

Focus the panel, then type in sequence g i to open inbox or g s to open settings.

Route:

Reactive disable#

A signal is bound through data-attr:disabled; toggling it arms or disarms both bindings without re-rendering anything. Each binding lists an arrow and a vim-style alternative (up | k, down | j).

Focus the panel and press ↑/k or ↓/j. Toggle the binding to watch a signal drive the disabled attribute.

Counter:

Global shortcuts#

A target of window (or a CSS selector) lifts the binding out of the parent scope so it fires page-wide, even when nothing in the demo is focused.

Press anywhere on the page, no focus needed.

Fired times.

Trigger an element#

for names an element id; on a match the shortcut calls click() on it. A keyboard trigger then needs no event handler. Here mod+i opens a popover and mod+o a select.

Focus this panel, then press ⌘ I to open the popover or ⌘ O to open the select (Ctrl elsewhere). Each shortcut clicks a trigger, so the widget opens with nothing listening for the event.

Shortcuts

Opened by keyboard, no handler wired.

LightDarkSystem

Settings

Theme

DefaultSunshineOceanMatrixRose☀ ◐ ☾

Accessibility

Playgrounds

Server Simulator