DevactionUI.Listbox (devaction_ui v0.7.0)

Copy Markdown View Source

A select with a panel of our own, for when the native DevactionUI.Select is not enough: options with a marker (an icon, an avatar, a swatch) and a line of description, groups, a search at the top of the panel, several choices at once, a button that empties the choice and a row that creates what the search did not find. For a short list with none of that, the native select is still the right one.

<Listbox.listbox
  field={@form[:category_id]}
  label="Category"
  placeholder="Choose a category"
  options={[
    {"Work", [%{value: "dev", label: "Development", description: "Code, review and deploy"}]},
    %{value: "fin", label: "Finance", keywords: "money invoice"}
  ]}
/>

Options are maps %{value, label} with the optional description (a quiet line under the label), keywords (more words the search finds it by, not shown) and disabled; a {label, options} tuple is a group with a heading. The option_marker slot draws something before each label and gets the option as it was given, so it may carry anything else (an icon, an avatar).

searchable puts a field at the top of the panel that filters while you type, ignoring case and accents, by the label and the keywords; empty is what shows when nothing is left, with %{term} for the text typed. With create ("Create “%{term}”") the last row offers to create the text typed when no option is called exactly that; choosing it sends on_create to the LiveView (phx-target points it at a component) with %{"id" => id, "term" => text}, and the LiveView adds the option and sets the value; create_hint is a small text at the end of that row (the key that chooses it). search_clear_label names a button in the search field that empties what was typed.

multiple keeps the panel open while choosing and sends a list (name[], an empty list when nothing is chosen). The button says count_text ("%{count} chosen") or, without it, the labels joined by commas, so it never changes height. indicator is :check (a mark at the end of the row, the default) or :checkbox (a box at the start). prefix is a fixed text before the choice on the button (Compare to).

The panel is position: fixed, put by the hook under the button (position={:top} for above, align for the side), so an ancestor with overflow: hidden does not cut it; it opens on the other side when the wanted one has no room and shortens its list when neither has.

The keyboard is the ARIA pattern: ↓ ↑ on the button open it, ↑ ↓ Home End move, Enter (and Space without a search) chooses, Esc closes and returns to the button, Tab leaves; without a search, typing letters jumps to the option that starts with them. The value is in hidden inputs and the hook fires input on them, so the form's phx-change hears every choice. The chosen value is the caller's, as in any LiveView field: a form that re-renders should hold value (with phx-change).

field={@form[:category_id]} fills the id, the name, the value and the error (see DevactionUI.FormField). The library knows no language: every word is an attribute.

Summary

Functions

A select whose panel the library draws: groups, descriptions, search, several choices, create.

Functions

listbox(assigns)

@spec listbox(map()) :: Phoenix.LiveView.Rendered.t()

A select whose panel the library draws: groups, descriptions, search, several choices, create.

Attributes

  • id (:string) - required unless a field gives it. Defaults to nil.
  • name (:string) - required unless a field gives it; [] is added when multiple. Defaults to nil.
  • field (Phoenix.HTML.FormField) - a form field (@form[:category_id]): gives the id, the name, the value and the error. Defaults to nil.
  • options (:list) (required) - %{value, label} maps (with description, keywords and disabled optional) and {label, options} groups.
  • value (:any) - the chosen value, or a list of them when multiple. Defaults to nil.
  • label (:string) (required) - what is being chosen, for assistive technology.
  • placeholder (:string) (required) - shown on the button when nothing is chosen.
  • multiple (:boolean) - several choices; the panel stays open while choosing. Defaults to false.
  • indicator (:atom) - how a chosen option is marked: a check at the end or a box at the start. Defaults to :check. Must be one of :check, or :checkbox.
  • count_text (:string) - the button text of a multiple choice, with %{count}; the labels joined when nil. Defaults to nil.
  • prefix (:string) - a fixed text on the button before the choice. Defaults to nil.
  • searchable (:boolean) - a search field at the top of the panel. Defaults to false.
  • search_placeholder (:string) - Defaults to nil.
  • empty (:string) - shown when the search finds nothing; %{term} is the text typed. Defaults to nil.
  • create (:string) - the text of the row that creates what was typed, with %{term}; needs on_create. Defaults to nil.
  • on_create (:string) - the event sent with %{"id" => id, "term" => text} when the create row is chosen. Defaults to nil.
  • create_hint (:string) - a small text at the end of the create row, such as the key that chooses it (Enter). Defaults to nil.
  • clear_label (:string) - the name of the button that empties the choice; none when nil. Defaults to nil.
  • search_clear_label (:string) - the name of the button in the search field that empties what was typed; none when nil, drawn with clear_icon. Defaults to nil.
  • size (:atom) - Defaults to :md. Must be one of :sm, :md, or :lg.
  • position (:atom) - where the panel opens. Defaults to :bottom. Must be one of :bottom, or :top.
  • align (:atom) - the side the panel lines up with. Defaults to :start. Must be one of :start, or :end.
  • panel_class (:any) - classes of the panel, such as a width (w-72). Defaults to nil.
  • disabled (:boolean) - Defaults to false.
  • required (:boolean) - Defaults to false.
  • show_label (:boolean) - draws label above the field instead of leaving it for assistive technology only. Defaults to false.
  • help (:string) - a line of explanation under the field. Defaults to nil.
  • error (:string) - the message under the field; also marks it invalid. Defaults to nil.
  • class (:any) - Defaults to nil.
  • Global attributes are accepted. Supports all globals plus: ["phx-target"].

Slots

  • icon - an icon at the start of the button.
  • chevron_icon - the arrow at the end of the button; turns over when open.
  • search_icon - the magnifier in the search field.
  • clear_icon - the icon of the clear button.
  • check_icon - the mark of a chosen option (indicator={:check}) and in its box.
  • create_icon - drawn before the text of the create row.
  • option_marker - drawn before the label of each option; gets the option as given.