Builtin Library
README.md
kbd
Keybind widget — a Luau builder over hbox + button (or a
focusable canvas while capturing). Uses canvas onKey and
ui.focus(id) to capture the next pressed key from primitives. Has
two call shapes that produce the same widget kind: a display-only
form for showing a key combo, and an interactive capture form for
rebinding.
Exports
kbd(keysOrOpts: string | KbdOpts, opts: table?) -> WidgetNode— module returns the builder function directly. The first arg is polymorphic.
Display-only call: kbd("Ctrl+S") or kbd("Ctrl+S", { style = {...} }).
Interactive call (table form):
id: string— required; identifies the widget for state + handlers.label: string?— left-side label. Default"Key".key: string?— current binding text. Default"None".onChange: string?— callback id; fires on commit with{ value = "F1" }.app: App?— explicit app; falls back toApp.current().buttonWidth,buttonHeight,gap,labelStyle,buttonStyle,canvasStyle,style,classes— layout/style overrides.
Usage
local Z = require("@builtin::modules.zui")
-- Display only:
Z.kbd("Ctrl+S")
-- Interactive:
Z.kbd({
id = "settings:bind:jump",
label = "Jump",
key = state.jumpKey,
onChange = "ui:bind:jump", -- fires with { value = "F1" }
})
Notes
- Behaviour while capturing: clicking the
[<key>]button transitions to capturing and focuses the per-instance hidden canvas. Any key press commits and leaves capturing.Escapecancels (capturing flips off, key unchanged). - Captured state lives in
ui.widgetState(id, "capturing"|"key")so the wrapper survives screen rerenders without the caller threading it through. onChangefires only on commit, not on cancel.- Per-id handler registration is deduped via
app._keybindHandlers(mirrors theradioGrouppattern);onChangeswaps land on each render without re-registering. - Calling the table form without an
idfalls back to display-only.