Fluxon.Components.Form (Fluxon v3.1.2)

Provides <.label> and <.error>, the building blocks for labelling form controls and surfacing validation messages.

These two components handle the text that surrounds an input: the label that names a field (with room for a secondary note and a longer description) and the error message that reports a validation failure. They are intentionally small and composable so you can assemble custom field layouts, and they are the same primitives the higher-level inputs render internally.

Most of the time you never call these components directly. Fluxon.Components.Input and the other form controls render <.label> and <.error> for you from their label, sublabel, description, field, and errors attributes. Reach for <.label> and <.error> on their own when you build a bespoke field arrangement that the standard input wrappers do not cover, or when you want to place a label or an error somewhere the input component would not put it.

Relationship to the form inputs

<.input>, <.textarea>, <.select>, <.radio_group>, and <.checkbox_group> already call these components. Pass label, sublabel, and description to those inputs to get a <.label>, and let them translate field.errors into <.error> messages automatically. Use <.label> and <.error> standalone only when you are composing a field layout by hand.

Usage

Label a control and describe the expectation with a sublabel and description:

<.label for="email" sublabel="Required" description="We'll never share your email.">
  Email address
</.label>

Report a validation failure below the control:

<.error>This field is required.</.error>

Composed together into a hand-built field:

<div>
  <.label for="username" sublabel="3-20 characters">Username</.label>
  <input id="username" name="username" type="text" />
  <.error>Username is already taken.</.error>
</div>

Label anatomy

The label is a small grid with three optional pieces of text arranged for scannability:

PartPlacementUse Case
Main text (inner_block)The bold labelNames the field. Always present.
sublabelInline, right of the main text, in a muted toneShort qualifiers such as "Required", "Optional", or a character limit.
descriptionOn its own line below the labelA fuller sentence explaining the field or how the value is used.

A label rendered immediately before a field element gains top spacing automatically, so stacked label-and-input pairs keep consistent vertical rhythm without extra classes.

Associating a label with its control

The for attribute wires the label to the control it names. Pass either a plain string id or a Phoenix form field:

<!-- Plain id, matches the control's id attribute -->
<.label for="email">Email address</.label>
<input id="email" name="email" type="email" />

<!-- Phoenix form field: the label reads the field's id for you -->
<.label for={@form[:email]}>Email address</.label>

When you pass a Phoenix.HTML.FormField, the component extracts field.id and uses it as the for value, so the label points at the same element the matching input renders.

Error messages

<.error> renders a danger-colored message with a leading warning icon. It carries role="alert" so the message is announced when it appears, which makes it suitable for validation output that shows up after a form submission or a live change event.

Hide the icon when the message sits in a context that already communicates the error state, or when you want a plain-text treatment:

<.error icon={false}>Password must be at least 8 characters long.</.error>

Give the error a stable id when a control needs to reference it (for example through aria-describedby). The bundled form components set this id for you; you only need it when wiring an error to a control by hand:

<input type="text" aria-describedby="username-error" />
<.error id="username-error">Username is already taken.</.error>

Examples

A complete hand-composed field with a changeset-backed form:

<.form :let={f} for={@changeset} phx-submit="save" phx-change="validate">
  <.label for={f[:email]} sublabel="Required" description="Used for sign-in and receipts.">
    Email address
  </.label>

  <.input field={f[:email]} type="email" />

  <.error :for={msg <- Enum.map(f[:email].errors, &translate_error/1)} id={"#{f[:email].id}-error"}>
    {msg}
  </.error>
</.form>

A standalone error tied to a control through aria-describedby:

<label for="coupon">Coupon code</label>
<input id="coupon" name="coupon" type="text" aria-describedby="coupon-error" />
<.error id="coupon-error" icon={false}>That code has expired.</.error>

A form-level summary error placed above the fields:

<.error :if={@form_error} class="mb-4">
  {@form_error}
</.error>

Summary

Components

Renders a validation error message with an optional leading warning icon.

Renders a form label with an optional inline sublabel and a longer description.

Components

error(assigns)

Renders a validation error message with an optional leading warning icon.

Use this to surface a validation failure for a form control. The message renders in the danger color with a warning icon, and it carries role="alert" so it is announced when it appears, which fits errors that show up after a submission or a live change event. It works both inside a form and on its own, so you can also use it for form-level messages that are not tied to a single field.

The bundled form inputs already translate field.errors into <.error> messages for you; reach for this component directly when you compose a field by hand or need an error somewhere the input wrappers would not place one.

Attributes

  • id (:string) - Sets the id of the error element. Provide it when a control needs a stable target to reference, for example through aria-describedby. The bundled form components such as input, textarea, radio_group, and checkbox_group set this automatically. Defaults to nil.

    Defaults to nil.

  • icon (:boolean) - Controls whether the leading warning icon is shown. When true, a warning icon renders before the message. Set to false for a plain-text error, or when the surrounding context already signals the error state. Defaults to true.

    Defaults to true.

  • class (:any) - Sets additional CSS classes on the error container. Useful for adjusting spacing or layout, for example adding a top or bottom margin around a form-level message.

    Defaults to nil.

Slots

  • inner_block (required) - The error message text describing the validation failure. Always rendered.

Examples

A basic field error:

<.error>This field is required.</.error>

Without the icon, for a plainer treatment:

<.error icon={false}>
  Password must be at least 8 characters long.
</.error>

With an id so a control can reference it through aria-describedby:

<input type="text" aria-describedby="username-error" />
<.error id="username-error">Username is already taken.</.error>

A form-level message spaced above the fields:

<.error class="mb-4">
  Please fix the errors above before continuing.
</.error>

label(assigns)

Renders a form label with an optional inline sublabel and a longer description.

Use this to name a form control in a custom field layout, when you are not relying on the label, sublabel, and description attributes of the higher-level inputs. The main label text comes from the slot, the sublabel sits inline beside it in a muted tone for short qualifiers, and the description renders on its own line below for a fuller explanation.

Associate the label with its control through for, which accepts either a plain element id or a Phoenix.HTML.FormField. When you pass a field, the component reads field.id so the label points at the element the matching input renders. A label placed directly before a field element also gains top spacing automatically, keeping stacked label-and-input pairs evenly spaced.

Attributes

  • for (:any) - Specifies the control this label names, rendered as the for attribute. Accepts a plain element id string or a Phoenix.HTML.FormField; when given a field, the label uses the field's id so it points at the same element the matching input renders. Defaults to nil.

    Defaults to nil.

  • class (:any) - Sets additional CSS classes on the <label> element. Useful for adjusting typography, color, or spacing of the main label text beyond the defaults.

    Defaults to nil.

  • description (:string) - Provides a longer explanatory sentence rendered on its own line below the label. Use it to clarify what the field is for or how the value will be used. Defaults to nil (no description).

    Defaults to nil.

  • sublabel (:string) - Sets a short supplementary note displayed inline to the right of the main label in a muted tone. Best suited for brief qualifiers such as "Required", "Optional", or a character limit. Defaults to nil (no sublabel).

    Defaults to nil.

  • Global attributes are accepted. Additional HTML attributes passed through to the <label> element, such as data-* hooks or event bindings.

Slots

  • inner_block (required) - The main label text that names the field. This is the primary, bold text of the label and is always rendered.

Examples

Label with a sublabel and description:

<.label for="email" sublabel="Required" description="We'll never share your email.">
  Email address
</.label>

Bound to a Phoenix form field, so the for id is derived from the field:

<.form :let={f} for={@changeset} phx-submit="save">
  <.label for={f[:email]} sublabel="We'll never share your email.">
    Email address
  </.label>

  <.input field={f[:email]} type="email" />
</.form>