Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

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 to App.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. Escape cancels (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.
  • onChange fires only on commit, not on cancel.
  • Per-id handler registration is deduped via app._keybindHandlers (mirrors the radioGroup pattern); onChange swaps land on each render without re-registering.
  • Calling the table form without an id falls back to display-only.