Flicker.Keyboard (Flicker v0.1.0)

Copy Markdown View Source

Server-side chord parsing/validation for activate_with_keyboard (Spec 006).

A chord string is +-separated modifiers (meta, ctrl, alt, shift, or the portable alias mod) followed by exactly one key, e.g. "mod+k" or "ctrl+shift+a". Validation happens once, at Flicker.select/1 render time, so a misconfigured attr fails loudly at the call site rather than silently doing nothing in the browser.

mod is deliberately left unresolved here — it becomes meta on macOS and ctrl elsewhere, a decision the colocated hook makes client-side (ADR-007) because the server can't reliably know the requesting platform. aria_keyshortcuts/1 sidesteps the same problem by emitting both alternatives.

Summary

Types

t()

A validated chord: its modifier list (as given, mod unresolved) and trailing key.

Functions

Formats a validated chord as an aria-keyshortcuts value.

A platform-neutral display string for the kbd hint, e.g. "Mod+K".

Parses and validates a chord string.

Like parse/1, raising ArgumentError with a clear message on an invalid chord.

Types

t()

@type t() :: %{modifiers: [String.t()], key: String.t()}

A validated chord: its modifier list (as given, mod unresolved) and trailing key.

Functions

aria_keyshortcuts(map)

@spec aria_keyshortcuts(t()) :: String.t()

Formats a validated chord as an aria-keyshortcuts value.

Emits space-separated alternatives so "mod+k" yields both platform forms — "Meta+K Control+K" — per the WAI-ARIA spec, since the server can't know which one the visiting browser will resolve mod to.

display(map)

@spec display(t()) :: String.t()

A platform-neutral display string for the kbd hint, e.g. "Mod+K".

Shown until the colocated hook's mounted callback replaces it with platform-formatted text (⌘K on macOS, Ctrl+K elsewhere) — this function never itself guesses the platform.

parse(chord)

@spec parse(String.t()) :: {:ok, t()} | {:error, String.t()}

Parses and validates a chord string.

Returns {:ok, chord} for a syntactically valid chord — at least one recognised modifier, followed by exactly one key that isn't itself a modifier name — or {:error, reason} describing what's wrong. Bare-key chords (no modifier, e.g. "k") are always rejected: activating on a plain keypress anywhere in the document would hijack ordinary typing.

validate!(chord)

@spec validate!(String.t()) :: t()

Like parse/1, raising ArgumentError with a clear message on an invalid chord.