Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 8x 8x 8x 1554x 6x 8x 231x 8x 8x 8x 8x 1510x 1276x 1275x 1510x 1274x | import type { KeyAction, KeyDefinition } from "./types";
/** Default accessible label for the keyboard container. */
export const DEFAULT_ARIA_LABEL = "On-screen keyboard";
/** Names of the built-in layouts. */
export const LAYOUT_NAMES = {
qwerty: "qwerty",
numeric: "numeric",
phone: "phone",
email: "email",
azerty: "azerty",
qwertz: "qwertz",
dvorak: "dvorak",
colemak: "colemak",
} as const;
/** Actions that toggle a modifier (and therefore expose `aria-pressed`). */
const MODIFIER_ACTIONS: ReadonlySet<KeyAction> = new Set<KeyAction>([
"shift",
"capslock",
"layer",
]);
/**
* Whether a key action toggles a modifier (Shift / Caps Lock / symbol layer).
* Modifier keys expose `aria-pressed` in the rendered UI.
*/
export function isModifierAction(action: KeyAction | undefined): boolean {
return action !== undefined && MODIFIER_ACTIONS.has(action);
}
/** Whether a key action is a text-editing / value-affecting action. */
export function isTextAction(action: KeyAction | undefined): boolean {
return (
action === "backspace" ||
action === "enter" ||
action === "space" ||
action === "tab" ||
action === "clear"
);
}
/**
* Actions eligible for auto-repeat while held (with `enableKeyRepeat`). Only
* `backspace` today — it is the sole destructive / caret-motion action in the
* built-in layouts. Character keys never auto-repeat (holding a letter opens the
* accent-variants popup instead).
*/
const REPEATABLE_ACTIONS: ReadonlySet<KeyAction> = new Set<KeyAction>([
"backspace",
]);
/** Whether an action auto-repeats when held (and `enableKeyRepeat` is on). */
export function isRepeatableAction(action: KeyAction | undefined): boolean {
return action !== undefined && REPEATABLE_ACTIONS.has(action);
}
/** Long-press threshold (ms) before the accent-variants popup opens. */
export const LONG_PRESS_MS = 400;
/** Delay (ms) before auto-repeat begins while a repeatable key is held. */
export const KEY_REPEAT_DELAY_MS = 400;
/** Interval (ms) between auto-repeat fires once repeating. */
export const KEY_REPEAT_INTERVAL_MS = 50;
/** Human-readable names for action keys, used as an ARIA fallback. */
const ACTION_LABELS: Record<KeyAction, string> = {
backspace: "Backspace",
enter: "Enter",
space: "Space",
tab: "Tab",
clear: "Clear",
shift: "Shift",
capslock: "Caps Lock",
layer: "Symbols",
"layout-switch": "Switch layout",
hide: "Hide keyboard",
};
/**
* Compute an accessible name for a key. Prefers an explicit `ariaLabel`, then a
* humanized action label, then the emitted value (space is spelled out).
*/
export function keyAccessibleName(
key: KeyDefinition,
effectiveValue?: string
): string {
if (key.ariaLabel) return key.ariaLabel;
if (key.action) return ACTION_LABELS[key.action];
const value = effectiveValue ?? key.key;
if (value === " ") return "Space";
return value;
}
|