lantern

Forms & inputs

Select & autocomplete

Client and server-driven option pickers.

Select

FormField-aware select (Fluxon API): rich listbox with keyboard nav + type-ahead over a hidden input, or a native fallback.

Basic

Rich listbox with label, options, and placeholder.

With value

Controlled value selects the matching option.

Multiple

multiple keeps the panel open and submits name[] for each selection.

Searchable

searchable adds a filter box in the listbox (or set search_threshold).

Multi + search

Combine multiple and searchable for large option sets.

Native

native renders a plain <select> — useful for dense tool UIs.

Error state

Same FormField / errors list pattern as input.

can't be blank

Client mode (default)

Zag owns the value from data-default-value; picks sync the hidden input and fire input/change, so an existing phx-change keeps working with no server round trip.

Server-driven (controlled)

controlled makes the server value truth: client picks flow out through on_change, and server patches flow back into the machine. Pick in the listbox, or drive it from the server buttons.

Server value: active

API reference

Props and slots, introspected from the component.

Prop Type Default Description
class any nil Extra classes merged onto the root element.
clearable boolean false show a clear (×) button that resets the selection (Fluxon parity).
controlled boolean false server-driven mode: the server `value` is truth and patches flow into the Zag machine (non-searchable rich path only).
description string nil Helper text under the label stack.
disabled boolean false Render disabled and non-interactive.
errors list [] Validation messages; derived from field when used.
field {:struct, Phoenix.HTML.FormField} nil Form field; derives id, name, value, and errors.
help_text string nil Trailing help line under the field when no errors.
id any nil Element id. Derived from `field` when omitted. With a bare `name` and no `field`, the rich path falls back to `name` (the id feeds a hook, so it must stay stable) while `native` auto-generates a unique `lui-select-<n>`, mirroring Fluxon. Pass an explicit id to get a stable, predictable id on the native path.
include_hidden boolean true Emit a blank hidden input so empty submits.
label string nil Primary label above the control.
max integer nil max selections when multiple
multiple boolean false multi-select; submits name[] hidden inputs
name any nil Form input name; derived from field when omitted.
native boolean false Use a native <select> instead of the rich listbox.
on_change string nil server event pushed with `%{id, value}` when the Zag select value changes (non-searchable rich path only).
on_change_client string nil bubbling DOM CustomEvent dispatched with `%{id, value}` on Zag value changes (non-searchable rich path only).
options list [] Choices as values or {label, value} tuples.
placeholder string "Select…" Toggle text when nothing is selected.
prompt string nil blank first option (native path)
search_input_placeholder string "Search…" Placeholder for the listbox search input.
search_no_results_text string "No results" Empty-state copy when search matches nothing.
search_threshold integer nil auto-enable search at N+ options
searchable boolean false search box inside the listbox
size xs | sm | md | lg | xl "md" Control density / type scale.
sublabel string nil Secondary label line under the primary label.
value any nil Selected value(s); list when multiple.

Autocomplete

Accessible static or LiveView-backed search. Lantern owns the combobox, keyboard selection, and presentation; your LiveView owns remote querying, authorization, and result order. The public API mirrors Fluxon 2.3.1.

Static filtering

Static options filter in the browser; selection fills the hidden form input.

Server-backed search

Type at least two characters (try “zel”). The LiveView filters server-owned data and patches grouped, rich results back into the same focused combobox.

Server-backed, grouped results with rich option rows.

API reference

Props and slots, introspected from the component.

Prop Type Default Description
animation string "transition duration-150 ease-in-out" Accepted for Fluxon compatibility; currently a CSS/token-driven no-op.
animation_enter string "opacity-100 scale-100" Accepted for Fluxon compatibility; currently a no-op.
animation_leave string "opacity-0 scale-95" Accepted for Fluxon compatibility; currently a no-op.
autofocus boolean false Focus the search input on page load.
class any nil Extra classes merged onto the field wrapper.
clearable boolean false Show a button that clears the selection.
debounce integer 200 Server-search debounce in milliseconds.
description string nil Description between label and control.
disabled boolean false Disable searching and selection.
errors list [] Validation messages; derived from field when used.
field {:struct, Phoenix.HTML.FormField} nil Form field; derives id, name, value, and errors.
help_text string nil Help line shown when there are no errors.
id any nil Element id; derived from field when omitted.
label string nil Primary label above the control.
name any nil Form input name; derived from field when omitted.
no_results_text string "No results" Empty copy; an optional `%{query}` placeholder is replaced in the browser.
on_search string nil LiveView search event receiving `%{"query" => query}`.
open_on_focus boolean false Open the suggestions when focused.
options list [] Choices as values, tuples, tuple-child groups, or `{:group, label, children}`.
placeholder string "Search…" Placeholder shown in the search input.
search_mode contains | starts-with | exact "contains" Static matching mode.
search_threshold integer 0 Characters required before searching.
size xs | sm | md | lg | xl "md" Control density and type scale.
sublabel string nil Secondary label beside the primary label.
value any nil Current selected value.
Slots
:empty_state Custom content displayed when no result matches.
:footer Content at the bottom of the suggestions panel.
:header Content at the top of the suggestions panel.
:inner_prefix Content inside the control before the input.
:inner_suffix Content inside the control after the input.
:option Rich option content; receives `{label, value}`.
:outer_prefix Content outside the control before it.
:outer_suffix Content outside the control after it.