@keyboard-hub/keycode-preview
v0.0.1
Published
`@keyboard-hub/keycode-preview` is a small dependency-free TypeScript library for rendering and searching HID keycodes. Companion packages add icon labels, localized layouts, and firmware notation.
Readme
@keyboard-hub/keycode-preview
@keyboard-hub/keycode-preview is a small dependency-free TypeScript library
for rendering and searching HID keycodes. Companion packages add icon labels,
localized layouts, and firmware notation.
Design
The package keeps the HID catalog neutral and separates catalog selection from per-view display selection:
- Usage definitions: stable USB HID Keyboard/Keypad usages, common Consumer usages used by Keyboard Abyss adapters, and Generic Desktop system controls used by keyboard firmware/tooling.
- Catalog instances:
KeycodeCatalogis configured with exactly one active layout and one active locale. If the user changes layout or locale, create or swap to another catalog instance. - Display formats:
short,normal, and external formats such as icon, ZMK, or QMK can coexist inside one catalog. Views choose a display format at render time, for example for compact keycaps or larger detail panels. - Custom usage pages: callers can add HID usage definitions on custom usage
pages. KeyboardHub JSON's predefined parameterized bindings, such as
MO(1)andLT(2, A), are registered this way and use the sameformat,resolve, andsearchmethods as ordinary HID usages. - Layouts:
usLayoutor a caller-defined layout profile. A catalog receives exactly one active layout profile. - Locales:
enLocaleor a caller-defined locale profile. A catalog receives exactly one active locale profile. - Platforms:
default,macos,ios,windows,linux,android, or a caller-defined platform id. Display formats, layouts, and locales can each define platform-specific overrides for any preview field. - Extensions: reusable bundles of keycodes, display formats, lookup aliases, and search providers.
The core package ships the standard extension with short and normal display
formats, plus predefined usLayout and enLocale profiles. Firmware/tool
notation and optional localized/icon profiles are intentionally not built in;
register them from companion packages or app-owned extensions.
The core API returns serializable data. @keyboard-hub/keycode-preview-icon
provides iconDisplayFormat and icon symbol maps.
@keyboard-hub/keycode-preview-ja provides jisLayout, jaLocale, and
jaKanaLocale.
@keyboard-hub/keycode-preview-qmk and @keyboard-hub/keycode-preview-zmk
provide firmware notation.
Keyboard layouts can also attach shifted legends through
preview.shiftedLabel. This lets keycap renderers show both the unmodified key
and the Shift-modified key without knowing layout-specific symbol rules.
Locale profiles can attach up to two additional keycap legends through
preview.locales. Renderers should place one locale legend at the lower right,
or two locale legends at the lower right and upper right.
Usage
import {
KeycodeCatalog,
type KeycodeCodeMap,
type KeycodePreviewExtension,
} from "@keyboard-hub/keycode-preview";
const catalog = new KeycodeCatalog();
catalog.format({ usage: 0x28 });
// { label: "Enter", code: "ENTER", displayFormat: "normal", ... }
catalog.format("N1", { displayFormat: "short" });
// { label: "1", shiftedLabel: "!", ... }
catalog.withPlatform("macos").format("LGUI")?.label;
// "Left Command"
catalog.search("Backspace")[0]?.definition.code;
// "BSPC"
catalog.format("MO(1)")?.label;
// "MO(1)"
catalog.resolve("LT(2, A)")?.code;
// "LT"Companion Packages
import { KeycodeCatalog } from "@keyboard-hub/keycode-preview";
import { iconDisplayFormat } from "@keyboard-hub/keycode-preview-icon";
import {
jaKanaLocale,
jaLocale,
jisLayout,
} from "@keyboard-hub/keycode-preview-ja";
import { qmkKeycodePreviewExtension } from "@keyboard-hub/keycode-preview-qmk";
import { zmkKeycodePreviewExtension } from "@keyboard-hub/keycode-preview-zmk";
const jisJaCatalog = new KeycodeCatalog({
displayFormats: [iconDisplayFormat],
extensions: [qmkKeycodePreviewExtension, zmkKeycodePreviewExtension],
layout: jisLayout,
locale: jaLocale,
});
jisJaCatalog.format("GRAVE", { displayFormat: "short" })?.label;
// "半/全"
jisJaCatalog.format("BSPC", { displayFormat: "icon" })?.icon;
// "delete"
jisJaCatalog.format("ESC", { displayFormat: "qmk" })?.label;
// "KC_ESC"
const jisKanaCatalog = jisJaCatalog.withLocale(jaKanaLocale);
jisKanaCatalog.format("N3", { displayFormat: "short" })?.locales;
// ["あ", "ぁ"]
jisJaCatalog.format("LT(2, A)", { displayFormat: "zmk" })?.label;
// "<\n2\nA"Firmware companion packages return newline-separated labels for parameterized custom codes so keycap previews can place the behavior name and each parameter on separate lines.
Extension Example
ZMK/QMK-like notation should be registered by the caller as a display format and alias extension:
const zmkSymbols: KeycodeCodeMap = {
BSPC: "BACKSPACE",
ENTER: "RETURN",
ESC: "ESCAPE",
};
const zmkExample = {
id: "example-zmk",
displayFormats: [
{
id: "zmk",
format({ definition }) {
const symbol = zmkSymbols[definition.code] ?? definition.code;
return {
label: `&kp ${symbol}`,
title: definition.names.normal,
};
},
searchTerms({ definition }) {
const symbol = zmkSymbols[definition.code] ?? definition.code;
return [`&kp ${symbol}`];
},
},
],
lookupAliases: [
{
id: "example-zmk-lookup",
aliases(definition) {
const symbol = zmkSymbols[definition.code] ?? definition.code;
return [`&kp ${symbol}`];
},
},
],
} satisfies KeycodePreviewExtension;
const zmkCatalog = new KeycodeCatalog({
extensions: [zmkExample],
});
zmkCatalog.format("&kp A", { displayFormat: "zmk" })?.label;
// "&kp A"
zmkCatalog.search("&kp A", { displayFormat: "zmk" })[0]?.definition.code;
// "A"Layouts, locales, and platforms are selected by creating catalog instances.
platforms overrides are resolved inside each display format, layout, or locale
before the next layer runs:
const compactFormat = {
id: "compact",
format({ definition }) {
return { label: definition.code, title: definition.names.normal };
},
platforms: {
macos: {
format({ definition }) {
return definition.code === "LGUI" ? { label: "⌘" } : {};
},
},
},
};
const symbolicLayout = {
id: "symbolic",
transform({ definition }) {
return definition.code === "SPACE"
? { label: "Spacebar", shiftedLabel: "Spacebar" }
: {};
},
platforms: {
macos: {
transform({ definition }) {
return definition.code === "N2" ? { shiftedLabel: "@" } : {};
},
},
},
};
const friendlyLocale = {
id: "friendly",
searchTerms({ definition }) {
return definition.code === "SPACE" ? ["big thumb key"] : [];
},
transform({ definition }) {
return definition.code === "N1" ? { shiftedLabel: "!" } : {};
},
platforms: {
macos: {
transform({ definition }) {
return definition.code === "LGUI" ? { title: "Command" } : {};
},
},
},
};
const catalog = new KeycodeCatalog({
defaultDisplayFormat: "compact",
displayFormats: [compactFormat],
layout: symbolicLayout,
locale: friendlyLocale,
defaultPlatform: "macos",
});Catalog Configuration
layout: active layout profile for this catalog instance.locale: active locale profile for this catalog instance.defaultPlatform: platform used when a format/search call does not specify one. Defaults todefault.defaultDisplayFormat: display format used when a format call does not specify one.extensions: reusable bundles of keycodes, display formats, lookup aliases, and search providers.displayFormats: additional one-off display format implementations.keycodes: replacement keycode definitions. Defaults to the built-in HID definitions when omitted.lookupAliases: extra strings that should resolve directly to a keycode, such as a firmware token.searchTerms: extra searchable readings that do not need to resolve directly.
withLayout, withLocale, withPlatform, withDisplayFormat, and extend
return new catalog instances:
const base = new KeycodeCatalog();
const mac = base.withPlatform("macos");
const withFirmwareNotation = mac.extend(zmkExample);Coverage
The built-in keyboardKeycodes table covers USB HID Keyboard/Keypad page usages
0x00 through 0xA4, extended keypad usages 0xB0 through 0xDD, and
modifiers 0xE0 through 0xE7. Reserved ranges are not emitted as keycodes.
consumerKeycodes covers common media, display, application launch, browser,
and application control usages used by keyboard tooling. genericDesktopKeycodes
covers System Power, System Sleep, and System Wake on the Generic Desktop page.
The generated mapping table lists the built-in KeyboardHub keycodes, base display labels, platform-specific labels, and KeyboardHub custom codes.
