Corex.Select (Corex v0.1.0-alpha.13)

View Source

Phoenix implementation of Zag.js Select.

Examples

Minimal

This example assumes the import of .icon from Core Components, you are free to replace it

<.select
  id="my-select"
  class="select"
  placeholder="Select a country"
  collection={[
    %{label: "France", id: "fra", disabled: true},
    %{label: "Belgium", id: "bel"},
    %{label: "Germany", id: "deu"},
    %{label: "Netherlands", id: "nld"},
    %{label: "Switzerland", id: "che"},
    %{label: "Austria", id: "aut"}
  ]}
>
  <:trigger>
    <.icon name="hero-chevron-down" />
  </:trigger>
</.select>

Grouped

This example assumes the import of .icon from Core Components, you are free to replace it

<.select
  class="select"
  placeholder="Select a country"
  collection={[
    %{label: "France", id: "fra", group: "Europe"},
    %{label: "Belgium", id: "bel", group: "Europe"},
    %{label: "Germany", id: "deu", group: "Europe"},
    %{label: "Netherlands", id: "nld", group: "Europe"},
    %{label: "Switzerland", id: "che", group: "Europe"},
    %{label: "Austria", id: "aut", group: "Europe"},
    %{label: "Japan", id: "jpn", group: "Asia"},
    %{label: "China", id: "chn", group: "Asia"},
    %{label: "South Korea", id: "kor", group: "Asia"},
    %{label: "Thailand", id: "tha", group: "Asia"},
    %{label: "USA", id: "usa", group: "North America"},
    %{label: "Canada", id: "can", group: "North America"},
    %{label: "Mexico", id: "mex", group: "North America"}
  ]}
>
  <:trigger>
    <.icon name="hero-chevron-down" />
  </:trigger>
</.select>

### Custom

This example requires the installation of Flagpack to display the use of custom item rendering. This example assumes the import of .icon from Core Components, you are free to replace it

<.select
  class="select"
  placeholder="Select a country"
  collection={[
    %{label: "France", id: "fra"},
    %{label: "Belgium", id: "bel"},
    %{label: "Germany", id: "deu"},
    %{label: "Netherlands", id: "nld"},
    %{label: "Switzerland", id: "che"},
    %{label: "Austria", id: "aut"}
  ]}
>
  <:label>
    Country of residence
  </:label>
  <:item :let={item}>
    <Flagpack.flag name={String.to_atom(item.id)} />
    {item.label}
  </:item>
  <:trigger>
    <.icon name="hero-chevron-down" />
  </:trigger>
  <:item_indicator>
    <.icon name="hero-check" />
  </:item_indicator>
</.select>

Custom Grouped

This example requires the installation of Flagpack to display the use of custom item rendering. This example assumes the import of .icon from Core Components, you are free to replace it

<.select
  class="select"
  placeholder="Select a country"
  collection={[
    %{label: "France", id: "fra", group: "Europe"},
    %{label: "Belgium", id: "bel", group: "Europe"},
    %{label: "Germany", id: "deu", group: "Europe"},
    %{label: "Japan", id: "jpn", group: "Asia"},
    %{label: "China", id: "chn", group: "Asia"},
    %{label: "South Korea", id: "kor", group: "Asia"}
  ]}
>
  <:item :let={item}>
    <Flagpack.flag name={String.to_atom(item.id)} />
    {item.label}
  </:item>
  <:trigger>
    <.icon name="hero-chevron-down" />
  </:trigger>
  <:item_indicator>
    <.icon name="hero-check" />
  </:item_indicator>
</.select>

Phoenix Form Integration

When using with Phoenix forms, you must add an id to the form using the Corex.Form.get_form_id/1 function.

Controller

<.form :let={f} for={@changeset} id={get_form_id(@changeset)}>
   <.select
  class="select"
  field={f[:country]}
  placeholder="Select a country"
  collection={[
    %{label: "France", id: "fra", disabled: true},
    %{label: "Belgium", id: "bel"},
    %{label: "Germany", id: "deu"},
    %{label: "Netherlands", id: "nld"},
    %{label: "Switzerland", id: "che"},
    %{label: "Austria", id: "aut"}
  ]}
>
  <:label>
    Your country of residence
  </:label>
  <:trigger>
    <.icon name="hero-chevron-down" />
  </:trigger>
  <:error :let={msg}>
    <.icon name="hero-exclamation-circle" class="icon" />
    {msg}
  </:error>
</.select>
  <button type="submit">Submit</button>
</.form>

Live View

When using Phoenix form in a Live view you must also add controlled mode. This allows the Live view to be the source of truth and the component to be in sync accordingly

<.form for={@form} id={get_form_id(@form)} phx-change="validate" phx-submit="save">
   <.select
        class="select"
        field={@form[:country]}
        controlled
        placeholder="Select a country"
        collection={[
          %{label: "France", id: "fra", disabled: true},
          %{label: "Belgium", id: "bel"},
          %{label: "Germany", id: "deu"},
          %{label: "Netherlands", id: "nld"},
          %{label: "Switzerland", id: "che"},
          %{label: "Austria", id: "aut"}
        ]}
      >
        <:label>
          Your country of residence
        </:label>
        <:trigger>
          <.icon name="hero-chevron-down" />
        </:trigger>
        <:error :let={msg}>
          <.icon name="hero-exclamation-circle" class="icon" />
          {msg}
        </:error>
      </.select>
</.form>

The field attribute automatically handles:

  • Setting the id from the form field
  • Setting the name for form submission
  • Mapping the form value to the select value
  • Displaying validation errors
  • Integration with Phoenix changesets

API Control

# Client-side
<button phx-click={Corex.Select.set_value("my-select", "fra")}>
  Check
</button>

<button phx-click={Corex.Select.toggle_value("my-select")}>
  Toggle
</button>

# Server-side
def handle_event("set_value", _, socket) do
  {:noreply, Corex.Select.set_value(socket, "my-select", "fra")}
end

Styling

Use data attributes to target elements:

  • [data-scope="select"][data-part="root"] - Label wrapper
  • [data-scope="select"][data-part="control"] - Select control
  • [data-scope="select"][data-part="label"] - Label text
  • [data-scope="select"][data-part="input"] - Hidden input
  • [data-scope="select"][data-part="error"] - Error message

State-specific styling:

  • [data-state="open"] - When select is open
  • [data-state="closed"] - When select is closed
  • [data-disabled] - When select is disabled
  • [data-readonly] - When select is read-only
  • [data-invalid] - When select has validation errors

Summary

Functions

select(assigns)

Attributes

  • id (:string)
  • collection (:list) - Defaults to [].
  • controlled (:boolean) - Whether the select is controlled. Defaults to false.
  • placeholder (:string) - The placeholder of the select. Defaults to nil.
  • value (:list) - The value of the select. Defaults to [].
  • disabled (:boolean) - Whether the select is disabled. Defaults to false.
  • close_on_select (:boolean) - Whether to close the select on select. Defaults to true.
  • dir (:string) - The direction of the select. Defaults to "ltr".
  • loop_focus (:boolean) - Whether to loop focus the select. Defaults to false.
  • multiple (:boolean) - Whether to allow multiple selection. Defaults to false.
  • invalid (:boolean) - Whether the select is invalid. Defaults to false.
  • name (:string) - The name of the select.
  • form (:string) - The id of the form of the select.
  • read_only (:boolean) - Whether the select is read only. Defaults to false.
  • required (:boolean) - Whether the select is required. Defaults to false.
  • prompt (:string) - the prompt for select inputs. Defaults to nil.
  • on_value_change (:string) - The server event name to trigger on value change. Defaults to nil.
  • on_value_change_client (:string) - The client event name to trigger on value change. Defaults to nil.
  • bubble (:boolean) - Whether the client events are bubbled. Defaults to false.
  • positioning (Corex.Positioning) - Positioning options for the dropdown. Defaults to %Corex.Positioning{hide_when_detached: true, strategy: "fixed", placement: "bottom", gutter: 0, shift: 0, overflow_padding: 0, arrow_padding: 4, flip: true, slide: true, overlap: false, same_width: true, fit_viewport: false}.
  • field (Phoenix.HTML.FormField) - A form field struct retrieved from the form, for example: @form[:country]. Automatically sets id, name, value, and errors from the form field.
  • errors (:list) - List of error messages to display. Defaults to [].
  • Global attributes are accepted.

Slots

  • label - The label content.
  • trigger (required) - The trigger button content.
  • item_indicator - Optional indicator for selected items.
  • error - Accepts attributes:
    • class (:string)
  • item - Custom content for each item. Receives the item as :let binding.