Skip to content

ui-select

Purpose

Single-selection dropdown input. Binds to a scalar field; emits selection changes via on_change event.

When to use / when NOT

Use for finite, mutually-exclusive choices (status, priority, category). NOT for multi-select (use multi_select), free text (use text_input), or large dynamic lists without filtering.

YAML shape

component: select
config:
  field: status                  # Dot-path to bind; reads/writes via shared DataRef
  label: Status                  # Display label
  placeholder: Choose status     # Hint text when empty (optional)
  options:                       # Static option list (required) — no dynamic sourcing
    - { value: active,   label: Active }
    - { value: inactive, label: Inactive }
  disabled: false                # Grey out / block editing (optional, default false)
  required: false                # Mark as mandatory (optional, default false)

Config keys

Key Type Meaning
field string Dot-path to the scalar field to bind (e.g. status, data.tier)
label string Display label for the dropdown
placeholder string Hint text when value is empty (optional)
options array List of { value, label } pairs. Only static options supported — no options_from
disabled boolean When true, the dropdown is greyed out and non-editable (default false)
required boolean When true, empty state is invalid (default false)
hint string Optional help text shown via ? info icon beside the label.

Data & events

Data binding: Reads and writes the current selection via the shared DataRef, keying off field.

Event: on_change (fired when selection changes)

  • Bare dispatcher — does NOT auto-attach row snapshot
  • Receives only the new value; existing row data is preserved (state-only path)
  • Useful for pure state transitions without data mutation
on_change:
  action: save_data_item
  collection: tickets
  key: "$: ticket_id"
  data_field: status             # Optional: patch only the `status` field
  # Without data_field, state flips but the row's existing value is unchanged

Example

- component: select
  config:
    field: priority
    label: Priority
    placeholder: Set priority
    options:
      - { value: high,   label: High }
      - { value: medium, label: Medium }
      - { value: low,    label: Low }
  on_change:
    action: save_data_item
    collection: tasks
    key: "$: task_id"
    data_field: priority

Gotchas

  • Static options only (vs multi_select): select does NOT support options_from — author every option in options:. multi_select is the asymmetric one: it adds dynamic sourcing via options_from: states | agents | volumes (+ exclude_self_field). Reach for multi_select when the option list must track factory config.
  • disabled, not read_only: select (and multi_select) honour disabled to block editing — they have no read_only display-only mode. The read_only key (a formatted, chrome-free display) exists on text_input / textarea / code_editor, not on the dropdowns; writing read_only: on a select is silently ignored.
  • Bare dispatcher: on_change on select is a bare dispatcher — it does NOT carry a full row snapshot. Use data_field to slice a specific field, or use an explicit data: { ... } map to patch multiple fields.
  • Required validation: The required:false default allows empty selections; toggling to true adds client-side validation but does not block invalid payloads server-side.