# `PhiaUi.Components.MultiSelect`
[🔗](https://github.com/charlenopires/PhiaUI/blob/v0.1.17/lib/phia_ui/components/inputs/multi_select.ex#L1)

Multi-select form component for Phoenix LiveView.

`multi_select/1` renders a native `<select multiple>` element with PhiaUI
styling, selected-value chip display, and remove-chip buttons. It is suited
for selecting **predefined options** from a fixed list (unlike `tags_input/1`
which accepts freeform text typed by the user).

`form_multi_select/1` wraps the bare component with `Phoenix.HTML.FormField`
integration: label, error messages, and automatic id/name/value extraction.

## When to use

- The user picks one or more values from a known, finite list of options.
- You want zero JavaScript with native browser multi-select semantics.
- An accessible chip row showing current selections is required.

For freeform tag entry, use `phia_tags_input/1` instead.

## Basic usage

    <.multi_select
      id="framework-select"
      name="frameworks"
      options={[{"Elixir", "elixir"}, {"Phoenix", "phoenix"}, {"LiveView", "liveview"}]}
      selected={@selected_frameworks}
      placeholder="Select frameworks..."
      on_change="update_frameworks"
    />

## Form integration

    <.form_multi_select
      field={@form[:categories]}
      options={@category_options}
      label="Categories"
      on_change="update_categories"
    />

## Handling events

The chip remove buttons emit `phx-click={@on_change}` with
`phx-value-deselect={val}`, so the LiveView can pattern-match:

    def handle_event("update_frameworks", %{"deselect" => val}, socket) do
      updated = List.delete(socket.assigns.selected_frameworks, val)
      {:noreply, assign(socket, selected_frameworks: updated)}
    end

The native `<select multiple>` submission sends all selected values as
`name[]` parameters to the server automatically via form submit.

## Accessibility

- `<select multiple>` uses `aria-label={@placeholder}` for screen readers.
- Chip remove buttons carry `aria-label="Remove {value}"`.
- The `disabled` attribute is forwarded to the `<select>` element.

# `form_multi_select`

`Phoenix.HTML.FormField`-integrated multi-select with label and error display.

Extracts `id`, `name`, and `value` from the `field` struct and delegates to
`multi_select/1`. Renders changeset errors below the select in
`text-destructive` colour.

## Example

    <.form_multi_select
      field={@form[:categories]}
      options={@category_options}
      label="Categories"
      on_change="update_categories"
    />

## Attributes

* `field` (`Phoenix.HTML.FormField`) (required) - A `Phoenix.HTML.FormField` struct from `@form[:field_name]`. Provides the
  element `id`, `name`, current `value` (used as selected list), and `errors`
  for changeset error display.

* `label` (`:string`) - Text rendered in a `<label>` above the select. Omitted when `nil`. Defaults to `nil`.
* `options` (`:list`) - List of `{label, value}` tuples — forwarded to `multi_select/1`. Defaults to `[]`.
* `on_change` (`:string`) - LiveView event name for chip removal — forwarded to `multi_select/1`. Defaults to `nil`.
* `class` (`:string`) - Additional Tailwind CSS classes merged into the root `<div>` wrapper. Defaults to `nil`.
* `disabled` (`:boolean`) - Forwarded to the underlying `multi_select/1` to disable the select. Defaults to `false`.

# `multi_select`

Renders a native `<select multiple>` with chip display for selected values.

Selected values appear as removable chips above the native select. Each chip
shows the human-readable label (resolved via `find_label/2`) and a `×` button
that fires the `on_change` event with `phx-value-deselect`.

The native `<select multiple>` follows below and marks the matching options
as `selected`. This dual representation lets the component work both with
standard form submission and LiveView event-driven updates.

## Examples

    <%!-- Basic usage --%>
    <.multi_select
      id="roles"
      name="roles"
      options={[{"Admin", "admin"}, {"Member", "member"}, {"Viewer", "viewer"}]}
      selected={@roles}
      placeholder="Assign roles..."
      on_change="update_roles"
    />

    <%!-- Disabled --%>
    <.multi_select
      id="locked"
      name="locked"
      options={[{"A", "a"}, {"B", "b"}]}
      selected={["a"]}
      disabled={true}
      on_change="noop"
    />

## Attributes

* `id` (`:string`) (required) - HTML `id` attribute for the underlying `<select>` element.
* `name` (`:string`) (required) - Base `name` attribute. The component automatically appends `[]` to produce
  `name[]`, so all selected values are submitted as an array.

* `options` (`:list`) - List of `{label, value}` tuples to render as `<option>` elements.
  `label` is the human-readable text; `value` is the submitted form value.

  Defaults to `[]`.
* `selected` (`:list`) - List of currently selected values (strings). Options whose value appears
  in this list are rendered with the `selected` attribute and displayed as
  removable chips above the select.

  Defaults to `[]`.
* `placeholder` (`:string`) - Placeholder text used as the `aria-label` of the `<select>` element.
  Helps screen-reader users understand what to select.

  Defaults to `"Select..."`.
* `on_change` (`:string`) - LiveView event name fired when the user clicks a chip's remove button.
  The event receives `phx-value-deselect` with the value being removed.

  Defaults to `nil`.
* `class` (`:string`) - Additional Tailwind CSS classes merged into the root `<div>` wrapper via `cn/1`. Defaults to `nil`.
* `disabled` (`:boolean`) - When `true`, the `<select>` element is rendered with the `disabled` attribute. Defaults to `false`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
