Plushie.Widget.ComboBox (Plushie v0.7.1)

Copy Markdown View Source

Combo box, searchable dropdown with free-form text input.

The renderer manages an internal combo_box::State cache keyed by node ID. Options changes trigger a state rebuild.

Props

NameTypeDefaultDescription
options[String.t() | atom()]requiredAvailable choices.
selectedString.t() | atom()nilCurrently selected value. Also accepts :value as alias.
placeholderString.t() | atom()nilPlaceholder text.
width:fill | :shrink | {:fill_portion, pos_integer()} | number()nilWidget width. Default: fill.
paddingnumber() | {number(), number()} | %Plushie.Type.Padding{}nilInternal padding.
sizenumber()nilText size in pixels.
font:default | :monospace | String.t() | %Plushie.Type.Font{}nilFont specification.
line_heightnumber() | %{relative: number()} | %{absolute: number()}nilText line height.
menu_heightnumber()nilMaximum dropdown menu height in pixels.
iconmap()nilIcon inside the text input.
on_option_hoveredboolean()nilEmit hover events over dropdown options.
on_openboolean()nilEmit open event when the dropdown opens.
on_closeboolean()nilEmit close event when the dropdown closes.
shaping:basic | :advanced | :autonilText shaping strategy.
ellipsis:none | :start | :middle | :endnilText ellipsis: :none, :start, :middle, or :end.
menu_stylemap()nilInline style for the dropdown menu.

| style | :default \| :primary \| :secondary \| :success \| :danger \| :warning \| :dark \| :weak \| :rounded_box \| term() | nil | Named preset or custom StyleMap. | | required | boolean() | nil | Marks the field as required. Flows into a11y.required automatically. | | validation | term() | nil | Form validation state. Accepts :valid, :pending, or {:invalid, message}. Flows into a11y.invalid and a11y.error_message automatically. | | event_rate | integer() | nil | Max events per second for coalescable events. | | a11y | %Plushie.Type.A11y{} \| map() \| keyword() | %{role: :combo_box, label_from: :placeholder, has_popup: "listbox"} | Accessibility annotations. |

Events

EventTypeDescription
:selectvalue: String.t() | atom()Emitted when an option is selected.
:inputvalue: String.t() | atom()Emitted on every text input change (for filtering).
:option_hoveredvalue: String.t() | atom()Emitted on hover (requires on_option_hovered).
:opennoneEmitted when dropdown opens (requires on_open: true).
:closenoneEmitted when dropdown closes (requires on_close: true).

Constructor

ComboBox.new(id, options)
ComboBox.new(id, options, opts)

Summary

Functions

Accessibility annotations.

Converts this widget struct to a ui_node() map.

Creates a :combo_box widget.

Text ellipsis: :none, :start, :middle, or :end.

Max events per second for coalescable events.

Font specification.

Icon inside the text input.

Maximum dropdown menu height in pixels.

Inline style for the dropdown menu.

Creates a new widget struct with the given positional args and keyword options.

Emit close event when the dropdown closes.

Emit open event when the dropdown opens.

Emit hover events over dropdown options.

Available choices.

Internal padding.

Marks the field as required. Flows into a11y.required automatically.

Currently selected value. Also accepts :value as alias.

Text shaping strategy.

Text size in pixels.

Named preset or custom StyleMap.

Form validation state. Accepts :valid, :pending, or {:invalid, message}. Flows into a11y.invalid and a11y.error_message automatically.

Widget width. Default: fill.

Applies keyword options to an existing widget struct.

Types

option()

@type option() ::
  (((((((((((((((((({:selected, String.t() | atom()}
                    | {:placeholder, String.t() | atom()})
                   | {:width,
                      :fill
                      | :shrink
                      | {:fill_portion, pos_integer()}
                      | number()})
                  | {:padding,
                     number()
                     | {number(), number()}
                     | %Plushie.Type.Padding{
                         bottom: term(),
                         left: term(),
                         right: term(),
                         top: term()
                       }})
                 | {:size, number()})
                | {:font,
                   :default
                   | :monospace
                   | String.t()
                   | %Plushie.Type.Font{
                       family: term(),
                       stretch: term(),
                       style: term(),
                       weight: term()
                     }})
               | {:line_height,
                  number() | %{relative: number()} | %{absolute: number()}})
              | {:menu_height, number()})
             | {:icon, map()})
            | {:on_option_hovered, boolean()})
           | {:on_open, boolean()})
          | {:on_close, boolean()})
         | {:shaping, :basic | :advanced | :auto})
        | {:ellipsis, :none | :start | :middle | :end})
       | {:menu_style, map()})
      | {:style,
         :default
         | :primary
         | :secondary
         | :success
         | :danger
         | :warning
         | :dark
         | :weak
         | :rounded_box
         | term()})
     | {:required, boolean()})
    | {:validation, term()})
   | {:event_rate, integer()})
  | {:a11y,
     %Plushie.Type.A11y{
       active_descendant: term(),
       busy: term(),
       described_by: term(),
       description: term(),
       disabled: term(),
       error_message: term(),
       expanded: term(),
       has_popup: term(),
       hidden: term(),
       invalid: term(),
       label: term(),
       label_from: term(),
       labelled_by: term(),
       level: term(),
       live: term(),
       mnemonic: term(),
       modal: term(),
       orientation: term(),
       position_in_set: term(),
       radio_group: term(),
       read_only: term(),
       required: term(),
       role: term(),
       selected: term(),
       size_of_set: term(),
       toggled: term(),
       value: term()
     }
     | map()
     | keyword()}

t()

@type t() :: %Plushie.Widget.ComboBox{
  a11y:
    (%Plushie.Type.A11y{
       active_descendant: term(),
       busy: term(),
       described_by: term(),
       description: term(),
       disabled: term(),
       error_message: term(),
       expanded: term(),
       has_popup: term(),
       hidden: term(),
       invalid: term(),
       label: term(),
       label_from: term(),
       labelled_by: term(),
       level: term(),
       live: term(),
       mnemonic: term(),
       modal: term(),
       orientation: term(),
       position_in_set: term(),
       radio_group: term(),
       read_only: term(),
       required: term(),
       role: term(),
       selected: term(),
       size_of_set: term(),
       toggled: term(),
       value: term()
     }
     | map()
     | keyword())
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  ellipsis:
    (:none | :start | :middle | :end)
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  event_rate:
    integer()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  font:
    (:default
     | :monospace
     | String.t()
     | %Plushie.Type.Font{
         family: term(),
         stretch: term(),
         style: term(),
         weight: term()
       })
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  icon:
    map()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  id: String.t(),
  line_height:
    (number() | %{relative: number()} | %{absolute: number()})
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  menu_height:
    number()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  menu_style:
    map()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  on_close:
    boolean()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  on_open:
    boolean()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  on_option_hovered:
    boolean()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  options:
    [String.t() | atom()]
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  padding:
    (number()
     | {number(), number()}
     | %Plushie.Type.Padding{
         bottom: term(),
         left: term(),
         right: term(),
         top: term()
       })
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  placeholder:
    (String.t() | atom())
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  required:
    boolean()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  selected:
    (String.t() | atom())
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  shaping:
    (:basic | :advanced | :auto)
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  size:
    number()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  style:
    (:default
     | :primary
     | :secondary
     | :success
     | :danger
     | :warning
     | :dark
     | :weak
     | :rounded_box
     | term())
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  validation:
    term()
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil,
  width:
    (:fill | :shrink | {:fill_portion, pos_integer()} | number())
    | Plushie.Animation.Transition.t()
    | Plushie.Animation.Spring.t()
    | Plushie.Animation.Sequence.t()
    | nil
}

Functions

a11y(widget, descriptor)

@spec a11y(
  widget :: t(),
  value ::
    (%Plushie.Type.A11y{
       active_descendant: term(),
       busy: term(),
       described_by: term(),
       description: term(),
       disabled: term(),
       error_message: term(),
       expanded: term(),
       has_popup: term(),
       hidden: term(),
       invalid: term(),
       label: term(),
       label_from: term(),
       labelled_by: term(),
       level: term(),
       live: term(),
       mnemonic: term(),
       modal: term(),
       orientation: term(),
       position_in_set: term(),
       radio_group: term(),
       read_only: term(),
       required: term(),
       role: term(),
       selected: term(),
       size_of_set: term(),
       toggled: term(),
       value: term()
     }
     | map()
     | keyword())
    | nil
) :: t()

Accessibility annotations.

Accepts %Plushie.Type.A11y{} | map() | keyword().

build(widget)

@spec build(widget :: t()) :: Plushie.Widget.ui_node()

Converts this widget struct to a ui_node() map.

combo_box(id, opts \\ [])

(macro)

Creates a :combo_box widget.

Shorthand for new/2. Import this macro to use the widget name directly in view functions:

import Plushie.Widget.ComboBox, only: [combo_box: 2]

combo_box("my-id", prop: value)

ellipsis(widget, descriptor)

@spec ellipsis(widget :: t(), value :: (:none | :start | :middle | :end) | nil) :: t()

Text ellipsis: :none, :start, :middle, or :end.

Accepts :none | :start | :middle | :end.

event_rate(widget, descriptor)

@spec event_rate(widget :: t(), value :: integer() | nil) :: t()

Max events per second for coalescable events.

Accepts integer().

font(widget, descriptor)

@spec font(
  widget :: t(),
  value ::
    (:default
     | :monospace
     | String.t()
     | %Plushie.Type.Font{
         family: term(),
         stretch: term(),
         style: term(),
         weight: term()
       })
    | nil
) :: t()

Font specification.

Accepts :default | :monospace | String.t() | %Plushie.Type.Font{}.

icon(widget, descriptor)

@spec icon(widget :: t(), value :: map() | nil) :: t()

Icon inside the text input.

Accepts map().

line_height(widget, descriptor)

@spec line_height(
  widget :: t(),
  value :: (number() | %{relative: number()} | %{absolute: number()}) | nil
) :: t()

Text line height.

Accepts number() | %{relative: number()} | %{absolute: number()}.

new(id, options, opts \\ [])

Creates a new widget struct with the given positional args and keyword options.

Arguments

  • id - unique widget identifier
  • options - Available choices.
  • opts - keyword list of optional props

on_close(widget, descriptor)

@spec on_close(widget :: t(), value :: boolean() | nil) :: t()

Emit close event when the dropdown closes.

Accepts boolean().

on_open(widget, descriptor)

@spec on_open(widget :: t(), value :: boolean() | nil) :: t()

Emit open event when the dropdown opens.

Accepts boolean().

on_option_hovered(widget, descriptor)

@spec on_option_hovered(widget :: t(), value :: boolean() | nil) :: t()

Emit hover events over dropdown options.

Accepts boolean().

options(widget, descriptor)

@spec options(widget :: t(), value :: [String.t() | atom()]) :: t()

Available choices.

Accepts [String.t() | atom()].

padding(widget, descriptor)

@spec padding(
  widget :: t(),
  value ::
    (number()
     | {number(), number()}
     | %Plushie.Type.Padding{
         bottom: term(),
         left: term(),
         right: term(),
         top: term()
       })
    | nil
) :: t()

Internal padding.

Accepts number() | {number(), number()} | %Plushie.Type.Padding{}.

placeholder(widget, descriptor)

@spec placeholder(widget :: t(), value :: (String.t() | atom()) | nil) :: t()

Placeholder text.

Accepts String.t() | atom().

required(widget, descriptor)

@spec required(widget :: t(), value :: boolean() | nil) :: t()

Marks the field as required. Flows into a11y.required automatically.

Accepts boolean().

selected(widget, descriptor)

@spec selected(widget :: t(), value :: (String.t() | atom()) | nil) :: t()

Currently selected value. Also accepts :value as alias.

Accepts String.t() | atom().

shaping(widget, descriptor)

@spec shaping(widget :: t(), value :: (:basic | :advanced | :auto) | nil) :: t()

Text shaping strategy.

Accepts :basic | :advanced | :auto.

size(widget, descriptor)

@spec size(widget :: t(), value :: number() | nil) :: t()

Text size in pixels.

Accepts number().

style(widget, descriptor)

@spec style(
  widget :: t(),
  value ::
    (:default
     | :primary
     | :secondary
     | :success
     | :danger
     | :warning
     | :dark
     | :weak
     | :rounded_box
     | term())
    | nil
) :: t()

Named preset or custom StyleMap.

Accepts :default | :primary | :secondary | :success | :danger | :warning | :dark | :weak | :rounded_box | term().

validation(widget, descriptor)

@spec validation(widget :: t(), value :: term() | nil) :: t()

Form validation state. Accepts :valid, :pending, or {:invalid, message}. Flows into a11y.invalid and a11y.error_message automatically.

Accepts term().

width(widget, descriptor)

@spec width(
  widget :: t(),
  value :: (:fill | :shrink | {:fill_portion, pos_integer()} | number()) | nil
) ::
  t()

Widget width. Default: fill.

Accepts :fill | :shrink | {:fill_portion, pos_integer()} | number().

with_options(widget, opts)

@spec with_options(widget :: t(), opts :: [option()]) :: t()

Applies keyword options to an existing widget struct.