Skip to main content

Option groups, separators and disabled options

The choice widgets - select and search, single-choice or with ->multiple() - accept more than a flat list. Alongside the ->options(['value' => 'Label']) map shorthand, you can declare options one at a time, mark them disabled, and add non-selectable structure.

$p->select('item', 'Item')
->heading('Fruit') // A non-selectable group heading.
->option('apple', 'Apple') // value => label
->option('banana', 'Banana')
->separator() // A non-selectable divider row.
->heading('Vegetable')
->option('carrot', 'Carrot')
->option('rhubarb', 'Rhubarb', disabled: TRUE, disabled_reason: 'out of season');

Runnable scripts: playground/02-widgets/select-groups.php and select-multiple-groups.php.

Builder methods

NameDescription
option($value, $label = '', ...)Add one selectable row. The label defaults to the value; re-declaring a value replaces it in place. Pass disabled: TRUE (with an optional disabled_reason) to show it but block selection.
options([$value => $label])Add many selectable rows from a map - shorthand for repeated option().
heading($label)Add a non-selectable group-heading row.
separator()Add a non-selectable divider row.

Behaviour

Headings, separators and disabled options are visual only: navigation skips them, so the cursor lands only on selectable options, and they can never be highlighted or selected. A disabled option shows its reason beside the label, dimmed. Every kind is theme-driven - override heading(), divider() or disabled() on a theme to restyle it.

Non-selectable rows never leak into the answer: a disabled value is dropped from a multiple-choice default, absent from the collected value, and excluded from the JSON schema (Tui::schema() lists selectable options only). Supplying a disabled

  • or otherwise unknown - option value headlessly (via --prompts JSON or an environment override) fails collection with a clear error naming the value.

Examples

A single-choice select with a group heading, a separator and a disabled option (its reason shown beside the dimmed label):

ANSINo ANSI
UnicodeSelect with groups: Unicode + ANSISelect with groups: Unicode + ANSISelect with groups: Unicode + No ANSISelect with groups: Unicode + No ANSI
ASCIISelect with groups: ASCII + ANSISelect with groups: ASCII + ANSISelect with groups: ASCII + No ANSISelect with groups: ASCII + No ANSI

A multiple select where the cursor and Space skip the separator and the disabled option, which can never be checked:

ANSINo ANSI
UnicodeSelect (multiple) with groups: Unicode + ANSISelect (multiple) with groups: Unicode + ANSISelect (multiple) with groups: Unicode + No ANSISelect (multiple) with groups: Unicode + No ANSI
ASCIISelect (multiple) with groups: ASCII + ANSISelect (multiple) with groups: ASCII + ANSISelect (multiple) with groups: ASCII + No ANSISelect (multiple) with groups: ASCII + No ANSI