@@ -10,10 +10,11 @@ dropdowns, checkboxes), collect results via an `on_submit` callback.
1010
1111- Bordered floating window with optional title
1212- Keyboard-navigable: ` <Tab> ` / ` <S-Tab> ` to move between inputs
13- - Input types: ` text ` , ` multiline ` , ` select ` , ` checkbox ` , plus ` spacer ` (visual-only gap between
14- fields)
13+ - Input types: ` text ` , ` multiline ` , ` select ` , ` checkbox ` , ` button ` , plus ` spacer ` (visual-only gap
14+ between fields)
1515- Select dropdowns open with ` <CR> ` ; arrows navigate; ` <CR> ` confirms
1616- Checkbox toggles with ` <Space> ` or ` <CR> `
17+ - Buttons activate with ` <CR> ` or ` <Space> ` and invoke a user-supplied callback
1718- Submit with ` <C-s> ` — results delivered as a ` { [name] = value } ` table
1819- Cancel with ` <Esc> ` or ` q `
1920- Built-in toggleable help popup (` ? ` ) listing every active keymap — updates automatically when you
@@ -164,6 +165,41 @@ glyph sits immediately next to the label, and any validation error is appended o
164165 bordered inputs. Tune via ` style.checkbox.padding ` (default ` 1 ` , set to ` 0 ` to pack tight).
165166- Pair with ` validators.checked() ` to require the box to be ticked (see [ Validation] ( #validation ) ).
166167
168+ #### ` button `
169+
170+ ``` lua
171+ {
172+ type = " button" ,
173+ label = " Submit" ,
174+ on_activate = function (form )
175+ form :submit ()
176+ end ,
177+ }
178+ ```
179+
180+ A focusable control that carries no value (skipped in ` form:results() ` ) and invokes
181+ ` on_activate(form) ` when activated. The form passes itself as the first argument so handlers can
182+ call ` form:submit() ` / ` form:cancel() ` / inspect ` form:results() ` without a closure.
183+
184+ - ` label ` (required) — text rendered inside the button.
185+ - ` on_activate ` (optional) — ` fun(form): nil ` callback fired on activation.
186+ - ` name ` (optional) — buttons don't appear in ` results() ` , but a name can still be set for
187+ identification.
188+ - Activated with the configured ` keymaps.activate ` keys (default ` <CR> ` and ` <Space> ` ).
189+ - Per-button style overrides — any of ` bordered ` , ` prefix ` , ` suffix ` , ` align ` can be set directly on
190+ the spec to override the global ` style.button ` defaults (see [ Button styling] ( #button-styling ) ).
191+
192+ ``` lua
193+ {
194+ type = " button" ,
195+ label = " Save" ,
196+ prefix = " [ " ,
197+ suffix = " ]" ,
198+ bordered = false ,
199+ on_activate = function (form ) form :submit () end ,
200+ }
201+ ```
202+
167203#### ` spacer `
168204
169205``` lua
@@ -284,6 +320,42 @@ require("input-form").setup({
284320Alternatives that render well in most fonts: ` [x] ` / ` [ ] ` , ` ✔ ` / ` · ` , ` ● ` / ` ○ ` . Set ` padding = 0 `
285321to pack checkboxes flush against adjacent bordered inputs.
286322
323+ ### Button styling
324+
325+ ` button ` inputs read their visual defaults from ` style.button ` , and any key can be overridden on the
326+ per-button spec:
327+
328+ ``` lua
329+ require (" input-form" ).setup ({
330+ style = {
331+ button = {
332+ bordered = true , -- wrap the button in a floating-window border
333+ prefix = " " , -- e.g. "[ " for `[ Save ]`
334+ suffix = " " , -- e.g. " ]" for `[ Save ]`
335+ align = " center" , -- "left" | "center" | "right"
336+ },
337+ },
338+ })
339+ ```
340+
341+ Focus state swaps ` NormalFloat ` / ` FloatBorder ` for ` InputFormButtonFocus ` /
342+ ` InputFormButtonFocusBorder ` , both of which default to ` reverse = true ` — the focused button renders
343+ with its foreground and background colors swapped. Override the highlight groups to use explicit
344+ colors instead:
345+
346+ ``` lua
347+ require (" input-form" ).setup ({
348+ style = {
349+ highlights = {
350+ InputFormButton = { fg = " #cdd6f4" , bg = " #1e1e2e" },
351+ InputFormButtonBorder = { fg = " #585b70" },
352+ InputFormButtonFocus = { fg = " #1e1e2e" , bg = " #cdd6f4" , bold = true },
353+ InputFormButtonFocusBorder = { fg = " #cdd6f4" },
354+ },
355+ },
356+ })
357+ ```
358+
287359### Help popup
288360
289361The form's bottom border shows a compact ` ? help ` hint on the right. Press ` ? ` (configurable via
@@ -358,6 +430,10 @@ Available groups:
358430| ` InputFormFieldErrorTitle ` | Invalid field label |
359431| ` InputFormDropdown ` | Select dropdown background |
360432| ` InputFormDropdownActive ` | Highlighted dropdown row |
433+ | ` InputFormButton ` | Unfocused button background |
434+ | ` InputFormButtonBorder ` | Unfocused button border |
435+ | ` InputFormButtonFocus ` | Focused button background (default reversed) |
436+ | ` InputFormButtonFocusBorder ` | Focused button border (default reversed) |
361437
362438User overrides fully ** replace** the default spec per group (they are not deep-merged at the field
363439level), so you don't need to re-specify ` default = true ` . Highlights are re-applied on every
@@ -388,6 +464,7 @@ require("input-form").setup({
388464 cancel = { " <Esc>" , " q" }, -- list form: both keys cancel the form
389465 open_select = " <CR>" ,
390466 toggle = " <Space>" ,
467+ activate = { " <CR>" , " <Space>" }, -- activate a focused `button` input
391468 help = " ?" , -- toggle the help popup (set `false` to hide)
392469 },
393470 select = {
@@ -402,6 +479,12 @@ require("input-form").setup({
402479 unchecked = " ☐" ,
403480 padding = 1 , -- blank rows above/below each checkbox
404481 },
482+ button = {
483+ bordered = true ,
484+ prefix = " " ,
485+ suffix = " " ,
486+ align = " center" ,
487+ },
405488 -- ...chevron, highlights, etc. — see sections above.
406489 },
407490})
0 commit comments