Provides core UI components.
At first glance, this module may seem daunting, but its goal is to provide core building blocks for your application, such as modals, tables, and forms. The components consist mostly of markup and are well-documented with doc strings and declarative assigns. You may customize and style them in any way you want, based on your application growth and needs.
The default components use Tailwind CSS, a utility-first CSS framework. See the Tailwind CSS documentation to learn how to customize them or feel free to swap in another framework altogether.
Summary
Functions
Renders a back navigation link.
Renders a button.
Renders the container around one group of form elements.
Generates a generic error message.
Renders flash notices.
Shows the flash group with standard titles and content.
Renders a header with title.
Renders a Heroicon.
Renders an input with label and error messages.
Renders a labeled group of checkboxes bound to an array-valued field.
Renders a standalone radio button input.
Renders a labeled group of radio buttons.
Renders a label.
Renders a data list.
Renders a modal.
Renders the container around one nested-form entry.
Renders the mark beside a required field's label.
Renders a simple form.
Renders a submit button that can be placed outside a form element.
Renders a table with generic styling.
Translates an error message using gettext.
Translates the errors for a field from a keyword list of errors.
Functions
Renders a back navigation link.
Examples
<.back navigate={~p"/posts"}>Back to posts</.back>Attributes
navigate(:any) (required)
Slots
inner_block(required)
Renders a button.
Examples
<.button>Send!</.button>
<.button phx-click="go" variant="primary">Send!</.button>Attributes
type(:string) - Defaults tonil.class(:any) - classes to use over the button defaults. Defaults tonil.variant(:string) - Must be one of"primary".- Global attributes are accepted. Supports all globals plus:
["disabled", "form", "name", "value"].
Slots
inner_block(required)
Renders the container around one group of form elements.
Groups (panel / <:group>) wrap their members in a card-like container
with padding, border, and rounded corners. A group can hold fields, nested
forms, and other groups.
type picks the layout, the same way input/1 dispatches on its own
type. Two are built in:
"horizontal"(default) — members share a row, wrapping when they run out of width. Each member is sized by its content, so a<:field>slot body can set an exact width (w-64) and the row honors it. Fractional widths (w-1/2) do not work: a percentage against a content-sized parent resolves asauto."vertical"— members stack.
Examples
<.dynamic_form_group type="horizontal" title="Age range">
<.input field={@form[:min]} label="From" />
<.input field={@form[:max]} label="To" />
</.dynamic_form_group>
<.dynamic_form_group type="vertical" title="Personal Information">
<.input field={@form[:name]} label="Name" />
</.dynamic_form_group>Attributes
type(:string) - Layout: "horizontal" or "vertical". Defaults to"horizontal".title(:string) - Optional group title. Defaults tonil.name(:string) - The group's name in the definition. Defaults tonil.disabled(:boolean) - Whether the group's members are disabled (its own enable_if, or inherited). Defaults tofalse.
Slots
inner_block(required)
Generates a generic error message.
Slots
inner_block(required)
Renders flash notices.
Examples
<.flash kind={:info} flash={@flash} />
<.flash kind={:info} phx-mounted={show("#flash")}>Welcome Back!</.flash>Attributes
id(:string) - the optional id of flash container.flash(:map) - the map of flash messages to display. Defaults to%{}.title(:string) - Defaults tonil.kind(:atom) - used for styling and flash lookup. Must be one of:info, or:error.- Global attributes are accepted. the arbitrary HTML attributes to add to the flash container.
Slots
inner_block- the optional inner block that renders the flash message.
Shows the flash group with standard titles and content.
Examples
<.flash_group flash={@flash} />Attributes
flash(:map) (required) - the map of flash messages.id(:string) - the optional id of flash container. Defaults to"flash-group".
Renders a header with title.
Attributes
class(:string) - Defaults tonil.
Slots
inner_block(required)subtitleactions
Renders a Heroicon.
Heroicons come in three styles – outline, solid, and mini.
By default, the outline style is used, but solid and mini may
be applied by using the -solid and -mini suffix.
You can customize the size and colors of the icons by setting width, height, and background color classes.
Icons are extracted from the deps/heroicons directory and bundled within
your compiled app.css by the plugin in your assets/tailwind.config.js.
Examples
<.icon name="hero-x-mark-solid" />
<.icon name="hero-arrow-path" class="ml-1 w-3 h-3 animate-spin" />Attributes
name(:string) (required)class(:string) - Defaults tonil.
Renders an input with label and error messages.
A Phoenix.HTML.FormField may be passed as argument,
which is used to retrieve the input name, id, and values.
Otherwise all attributes may be passed explicitly.
Types
This function accepts all HTML input types, considering that:
You may also set
type="select"to render a<select>tagtype="checkbox"is used exclusively to render boolean valuesFor live file uploads, see
Phoenix.Component.live_file_input/1
See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input for more information. Unsupported types, such as hidden and radio, are best written directly in your templates.
Examples
<.input field={@form[:email]} type="email" />
<.input name="my-input" errors={["oh no!"]} />Attributes
id(:any) - Defaults tonil.name(:any)label(:any) - Defaults tonil.value(:any)type(:string) - Defaults to"text". Must be one of"checkbox","color","date","datetime-local","email","file","hidden","month","number","password","range","search","select","tel","text","textarea","time","url","week","radio", or"radio-group".field(Phoenix.HTML.FormField) - a form field struct retrieved from the form, for example: @form[:email].errors(:list) - Defaults to[].required(:boolean) - whether the field is required. Defaults tofalse.required_label(:any) - mark shown beside the label of a required field; nil or false shows none. Defaults to"*".checked(:boolean) - the checked flag for checkbox inputs.prompt(:string) - the prompt for select inputs. Defaults tonil.options(:list) - the options to pass to Phoenix.HTML.Form.options_for_select/2.multiple(:boolean) - the multiple flag for select inputs. Defaults tofalse.style(:atom) - the layout style for radio-group inputs (:vertical or :horizontal).class(:any) - the input class to use over defaults. Defaults tonil.error_class(:any) - the input error class to use over defaults. Defaults tonil.- Global attributes are accepted. Supports all globals plus:
["accept", "autocomplete", "capture", "cols", "disabled", "form", "list", "max", "maxlength", "min", "minlength", "multiple", "pattern", "placeholder", "readonly", "rows", "size", "step"].
Renders a labeled group of checkboxes bound to an array-valued field.
Selected values are submitted as a list under name[]. A hidden empty
entry is included so clearing every checkbox still submits the field.
Examples
<.input_checkbox_group
field={@form[:toppings]}
label="Toppings"
options={[{"Cheese", "cheese"}, {"Mushrooms", "mushrooms"}]}
style={:vertical}
/>Attributes
id(:any) - Defaults tonil.name(:any)label(:any) - Defaults tonil.value(:any)field(Phoenix.HTML.FormField)errors(:list) - Defaults to[].required(:boolean) - whether the field is required. Defaults tofalse.required_label(:any) - mark shown beside the label of a required field; nil or false shows none. Defaults to"*".options(:list) (required) - List of {label, value} tuples for checkbox options.style(:atom) - Layout style: :vertical or :horizontal. Defaults to:vertical.- Global attributes are accepted. Supports all globals plus:
["disabled"].
Renders a standalone radio button input.
This is typically used for custom layouts where you need individual radio buttons.
For most use cases, use input_radio_group/1 instead.
Examples
<.input_radio
id="option-1"
name="choice"
value="option_1"
checked={@form[:choice].value == "option_1"}
/>Attributes
id(:any) (required)name(:any) (required)value(:any) (required)checked(:boolean) - Defaults tofalse.- Global attributes are accepted. Supports all globals plus:
["disabled"].
Renders a labeled group of radio buttons.
Examples
<.input_radio_group
field={@form[:notification_method]}
label="Notification Method"
options={[{"Email", "email"}, {"SMS", "sms"}]}
style={:vertical}
/>Attributes
id(:any) - Defaults tonil.name(:any)label(:any) - Defaults tonil.value(:any)field(Phoenix.HTML.FormField)errors(:list) - Defaults to[].required(:boolean) - whether the field is required. Defaults tofalse.required_label(:any) - mark shown beside the label of a required field; nil or false shows none. Defaults to"*".options(:list) (required) - List of {label, value} tuples for radio options.style(:atom) - Layout style: :vertical or :horizontal. Defaults to:vertical.- Global attributes are accepted. Supports all globals plus:
["disabled"].
Renders a label.
Attributes
for(:string) - Defaults tonil.required(:boolean) - Defaults tofalse.required_label(:any) - Defaults to"*".
Slots
inner_block(required)
Renders a data list.
Examples
<.list>
<:item title="Title">{@post.title}</:item>
<:item title="Views">{@post.views}</:item>
</.list>Slots
item(required) - Accepts attributes:title(:string) (required)
Renders a modal.
Examples
<.modal id="confirm-modal">
This is a modal.
</.modal>JS commands may be passed to the :on_cancel to configure
the closing/cancel event, for example:
<.modal id="confirm" on_cancel={JS.navigate(~p"/posts")}>
This is another modal.
</.modal>Attributes
id(:string) (required)show(:boolean) - Defaults tofalse.on_cancel(Phoenix.LiveView.JS) - Defaults to%Phoenix.LiveView.JS{ops: []}.
Slots
inner_block(required)
Renders the container around one nested-form entry.
Nested forms (paneldynamic / <:nested>) render each repeating entry
inside this container. The inner block carries everything the entry
contains — a two-column frame with the entry title and child fields on the
left and the remove button on the right — so overriding this component
restyles the box without touching the layout or the add/remove behavior.
Examples
<.nested_entry index={0} name="addresses">
...entry title, remove button, child fields...
</.nested_entry>Attributes
index(:integer) (required) - Zero-based position of the entry.name(:string) - The nested form's question name. Defaults tonil.class(:string) - Additional CSS classes. Defaults tonil.
Slots
inner_block(required)
Renders the mark beside a required field's label.
Renders nothing unless the field is required and a mark is set, so a field
with no label — or one that suppresses the mark with required_label={false}
— shows nothing while still being required server-side.
Attributes
required(:boolean) - Defaults tofalse.required_label(:any) - Defaults to"*".
Renders a simple form.
Examples
<.simple_form for={@form} phx-change="validate" phx-submit="save">
<.input field={@form[:email]} label="Email"/>
<.input field={@form[:username]} label="Username" />
<:actions>
<.button>Save</.button>
</:actions>
</.simple_form>Attributes
for(:any) (required) - the data structure for the form.as(:any) - the server side parameter to collect all input under. Defaults tonil.- Global attributes are accepted. the arbitrary HTML attributes to apply to the form tag. Supports all globals plus:
["autocomplete", "name", "rel", "action", "enctype", "method", "novalidate", "target", "multipart"].
Slots
inner_block(required)actions- the slot for form actions, such as a submit button.
Renders a submit button that can be placed outside a form element.
Uses the HTML form attribute to associate the button with a form by its ID.
This allows the submit button to be placed anywhere on the page, not just
inside the form element.
Examples
# Form with an ID
<.form id="my-form" for={@form} phx-submit="save">
<.input field={@form[:name]} label="Name" />
</.form>
# Submit button anywhere on the page
<.submit_button form="my-form">
Save Changes
</.submit_button>
# In a modal footer
<.modal id="edit-modal">
<.form id="edit-form" for={@form} phx-submit="save">
<.input field={@form[:title]} label="Title" />
</.form>
<:actions>
<.submit_button form="edit-form">Save</.submit_button>
</:actions>
</.modal>Attributes
form- The ID of the form element to submit (required)class- Additional CSS classes to apply to the buttondisabled- Whether the button is disabled
Attributes
form(:string) (required) - The ID of the form element to submit.class(:string) - Additional CSS classes. Defaults tonil.disabled(:boolean) - Whether the button is disabled. Defaults tofalse.- Global attributes are accepted. Supports all globals plus:
["name", "value"].
Slots
inner_block(required)
Renders a table with generic styling.
Examples
<.table id="users" rows={@users}>
<:col :let={user} label="id">{user.id}</:col>
<:col :let={user} label="username">{user.username}</:col>
</.table>Attributes
id(:string) (required)rows(:list) (required)row_id(:any) - the function for generating the row id. Defaults tonil.row_click(:any) - the function for handling phx-click on each row. Defaults tonil.row_item(:any) - the function for mapping each row before calling the :col and :action slots. Defaults to&Function.identity/1.
Slots
col(required) - Accepts attributes:label(:string)
action- the slot for showing user actions in the last table column.
Translates an error message using gettext.
Translates the errors for a field from a keyword list of errors.