Select

New

Overview

A native select with customizable picker styling, option groups, visual sizes, and validation states.

It renders a native select element.

Supporting browsers use customizable select styles for the picker and options. Other browsers retain their native picker.

This controls the member's workspace permissions.

HEEx
<.form for={@form}>
  <Select.select
    field={@form[:role]}
    label="Role"
    sublabel="Workspace access"
    prompt="Select a role"
    description="This controls the member's workspace permissions."
    options={[{"Administrator", "admin"}, {"Member", "member"}, {"Viewer", "viewer"}]}
  />
</.form>

Native picker

Set custom_style=false to retain the styled control with the platform’s native opened menu.

The opened menu uses the browser and operating system appearance.

HEEx
<.form for={@form}>
  <Select.select
    field={@form[:time_zone]}
    label="Time zone"
    description="The opened menu uses the browser and operating system appearance."
    custom_style={false}
    options={[
      {"Eastern Time", "America/Detroit"},
      {"Central Time", "America/Chicago"},
      {"Mountain Time", "America/Denver"},
      {"Pacific Time", "America/Los_Angeles"}
    ]}
  />
</.form>

Sizes

Use control_size for visual sizing. The native size attribute remains available for controlling visible option rows.

HEEx
<.form for={@form} class="grid gap-4 sm:grid-cols-3">
  <Select.select
    field={@form[:role_small]}
    label="Small"
    control_size={:sm}
    options={[{"Administrator", "admin"}, {"Member", "member"}, {"Viewer", "viewer"}]}
  />
  <Select.select
    field={@form[:role_medium]}
    label="Medium"
    options={[{"Administrator", "admin"}, {"Member", "member"}, {"Viewer", "viewer"}]}
  />
  <Select.select
    field={@form[:role_large]}
    label="Large"
    control_size={:lg}
    options={[{"Administrator", "admin"}, {"Member", "member"}, {"Viewer", "viewer"}]}
  />
</.form>

Grouped and disabled options

Phoenix option formats can create native groups and disable individual choices.

HEEx
<.form for={@form}>
  <Select.select
    field={@form[:deployment_region]}
    label="Deployment region"
    options={[
      {"Americas", [
        {"US East", "us-east"},
        {"US West", "us-west"},
        [key: "South America (coming soon)", value: "south-america", disabled: true]
      ]},
      {"Europe", [{"Frankfurt", "eu-central"}, {"London", "eu-west"}]},
      {"Asia Pacific", [{"Singapore", "ap-southeast"}, {"Tokyo", "ap-northeast"}]}
    ]}
  />
</.form>

Multiple

While you can use the multiple attribute with the native select to do multiple selections, I don't recommend it. I would instead use the Dizzy Combobox component for this purpose, which works much better for a multiple-selection situation but is less native.

Required and disabled

HEEx
<.form for={@form} class="grid gap-4 sm:grid-cols-2">
  <Select.select
    field={@form[:required_role]}
    label="Role"
    prompt="Select a role"
    required
    options={[{"Administrator", "admin"}, {"Member", "member"}, {"Viewer", "viewer"}]}
  />
  <Select.select
    field={@form[:disabled_role]}
    label="Current role"
    disabled
    options={[{"Administrator", "admin"}, {"Member", "member"}, {"Viewer", "viewer"}]}
  />
</.form>

Errors

When bound with field, validation errors render beneath the select .

can't be blank

HEEx
<.form for={@form}>
  <Select.select
    field={@form[:role]}
    label="Role"
    prompt="Select a role"
    options={[{"Administrator", "admin"}, {"Member", "member"}, {"Viewer", "viewer"}]}
  />
</.form>

Add this module

terminal
mix dizzy.add select

Component API

Select.select

Attributes

Attributes for Select.select
NameTypeDefault Values
class :any nilβ€”
control_size :atom :md:sm, :md, :lg
custom_style :boolean trueβ€”
description :string nilβ€”
disabled :boolean falseβ€”
errors :list []β€”
field {:struct, Phoenix.HTML.FormField} nilβ€”
id :string nilβ€”
label :string nilβ€”
multiple :boolean falseβ€”
name :string nilβ€”
options :list Requiredβ€”
prompt :string nilβ€”
required :boolean falseβ€”
rest :global nilβ€”
sublabel :string nilβ€”
value :any nilβ€”

Explore Dizzy