Corex.Select (Corex v0.1.0-alpha.13)
View SourcePhoenix 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
idfrom the form field - Setting the
namefor form submission - Mapping the form value to the
selectvalue - 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")}
endStyling
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
Attributes
id(:string)collection(:list) - Defaults to[].controlled(:boolean) - Whether the select is controlled. Defaults tofalse.placeholder(:string) - The placeholder of the select. Defaults tonil.value(:list) - The value of the select. Defaults to[].disabled(:boolean) - Whether the select is disabled. Defaults tofalse.close_on_select(:boolean) - Whether to close the select on select. Defaults totrue.dir(:string) - The direction of the select. Defaults to"ltr".loop_focus(:boolean) - Whether to loop focus the select. Defaults tofalse.multiple(:boolean) - Whether to allow multiple selection. Defaults tofalse.invalid(:boolean) - Whether the select is invalid. Defaults tofalse.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 tofalse.required(:boolean) - Whether the select is required. Defaults tofalse.prompt(:string) - the prompt for select inputs. Defaults tonil.on_value_change(:string) - The server event name to trigger on value change. Defaults tonil.on_value_change_client(:string) - The client event name to trigger on value change. Defaults tonil.bubble(:boolean) - Whether the client events are bubbled. Defaults tofalse.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.