PhiaUi.Components.Checkbox (phia_ui v0.1.17)

Copy Markdown View Source

Native HTML checkbox component styled with Tailwind CSS.

Integrates with Phoenix.HTML.FormField and Ecto changesets. Supports checked, unchecked, and indeterminate states with full WAI-ARIA semantics.

Sub-components

FunctionPurpose
checkbox/1Standalone styled checkbox input, no form context needed
form_checkbox/1Checkbox with label and changeset error display via FormField

Standalone usage

<%!-- Basic --%>
<.checkbox id="agree" name="agree" />

<%!-- Pre-checked --%>
<.checkbox id="agree" name="agree" checked={true} />

<%!-- Indeterminate state (e.g. "select all" that is partially selected) --%>
<.checkbox id="select-all" name="select_all" indeterminate={true} />

<%!-- With LiveView event --%>
<.checkbox id="cb" name="cb" phx-change="toggle_item" />

Form-integrated usage

<%!-- Accept terms and conditions --%>
<.form_checkbox
  field={@form[:agreed_to_terms]}
  label="I agree to the Terms of Service"
/>

<%!-- Newsletter opt-in --%>
<.form_checkbox
  field={@form[:marketing_emails]}
  label="Send me product updates and offers"
/>

<%!-- Disabled state --%>
<.form_checkbox
  field={@form[:required_field]}
  label="This cannot be changed"
  disabled={true}
/>

Select-all pattern with indeterminate

The indeterminate state is commonly used for a "select all" checkbox when some but not all items in a list are selected:

<%!-- In your LiveView --%>
defp all_selected?(items), do: Enum.all?(items, & &1.selected)
defp some_selected?(items), do: Enum.any?(items, & &1.selected)

<%!-- In your template --%>
<.checkbox
  id="select-all"
  name="select_all"
  checked={all_selected?(@items)}
  indeterminate={some_selected?(@items) && !all_selected?(@items)}
  phx-click="toggle_all"
/>

Accessibility

  • Native <input type="checkbox"> is used, so keyboard (Space to toggle) and screen reader support is provided by the browser
  • data-state attribute reflects "checked", "unchecked", or "indeterminate" for CSS-based custom styling
  • aria-checked="mixed" is set for the indeterminate state
  • aria-invalid="true" is set on form_checkbox/1 when the field has errors
  • Labels are associated via for/id for click-to-focus behaviour

Summary

Functions

Renders a styled native <input type="checkbox"> element.

Renders a checkbox integrated with Phoenix.HTML.FormField.

Functions

checkbox(assigns)

Renders a styled native <input type="checkbox"> element.

Uses semantic Tailwind tokens (border-primary, accent-primary) so it respects the PhiaUI theme in both light and dark mode without any JavaScript.

The data-state attribute is set to "checked", "unchecked", or "indeterminate" and can be targeted by CSS for custom indicator styling. For the indeterminate state, aria-checked="mixed" is applied for screen readers.

Examples

<%!-- Basic unchecked --%>
<.checkbox id="agree" name="agree" />

<%!-- Pre-checked --%>
<.checkbox id="agree" name="agree" checked={true} />

<%!-- Indeterminate (partially-selected "select all") --%>
<.checkbox id="all" name="all" indeterminate={true} />

<%!-- Disabled --%>
<.checkbox id="agree" name="agree" disabled={true} />

<%!-- LiveView event handler --%>
<.checkbox id="agree" name="agree" phx-change="toggle" />

<%!-- Custom class override --%>
<.checkbox id="lg" name="lg" class="h-5 w-5" />

Attributes

  • id (:string) - The id attribute of the input element. Required for associating with an external <label for="...">. When using form_checkbox/1, this is derived from the field struct automatically.

    Defaults to nil.

  • name (:string) - The name attribute of the input element. Determines the key in the form submission payload. When using form_checkbox/1, this is derived from the field struct automatically.

    Defaults to nil.

  • value (:string) - The value submitted when the checkbox is checked. Defaults to "true", which works well with boolean changeset fields. For multi-value checkboxes (e.g. selecting multiple tags), set this to the specific item value.

    Defaults to "true".

  • checked (:boolean) - Whether the checkbox is in the checked state. Defaults to false.

  • indeterminate (:boolean) - When true, renders the checkbox in the indeterminate state. Indeterminate checkboxes typically appear with a dash (-) inside the box and signal a "partially selected" condition (e.g. some items in a list are selected). Sets aria-checked="mixed" and data-state="indeterminate". Note: indeterminate takes visual precedence over checked.

    Defaults to false.

  • disabled (:boolean) - When true, disables the checkbox. It cannot be toggled and appears faded. Defaults to false.

  • class (:string) - Additional CSS classes merged into the input element via cn/1. Last-wins merge means your classes override the defaults.

    Defaults to nil.

  • Global attributes are accepted. Additional HTML attributes forwarded to the <input> element. Commonly used: phx-change or phx-click to handle toggle events in LiveView, form to associate with a form outside the DOM hierarchy, required for native browser validation. Supports all globals plus: ["phx-change", "phx-click", "form", "required", "aria-invalid"].

form_checkbox(assigns)

Renders a checkbox integrated with Phoenix.HTML.FormField.

Produces a <div> wrapper containing the checkbox input and an optional <label>. Changeset errors from field.errors are displayed as <p> elements below the wrapper in destructive colour.

The checked state is derived from field.value via Phoenix.HTML.Form.normalize_value/2, which handles the common case where the field value may be true, "true", "on", or false.

When field.errors is non-empty, aria-invalid="true" is set on the input element for screen reader accessibility.

Examples

<%!-- Terms of service --%>
<.form_checkbox field={@form[:agreed_to_terms]} label="I accept the Terms of Service" />

<%!-- Newsletter subscription with phx-change --%>
<.form_checkbox
  field={@form[:subscribed]}
  label="Subscribe to newsletter"
  phx-change="toggle_subscription"
/>

<%!-- Disabled field --%>
<.form_checkbox
  field={@form[:agreed_to_terms]}
  label="Terms accepted (cannot be changed)"
  disabled={true}
/>

<%!-- Inside a settings form --%>
<.form for={@form} phx-submit="save_settings">
  <.form_checkbox field={@form[:email_notifications]} label="Email notifications" />
  <.form_checkbox field={@form[:sms_notifications]}   label="SMS notifications" />
  <.form_checkbox field={@form[:push_notifications]}  label="Push notifications" />
  <.button type="submit">Save</.button>
</.form>

Attributes

  • field (Phoenix.HTML.FormField) (required) - A Phoenix.HTML.FormField struct obtained via @form[:field_name]. Provides the input id, name, and current value (used to derive checked state via Phoenix.HTML.Form.normalize_value/2), plus errors for validation.

  • label (:string) - Text rendered in a <label> next to the checkbox. The label is associated via for/id so clicking it toggles the checkbox. When nil, only the checkbox is rendered with no label.

    Defaults to nil.

  • indeterminate (:boolean) - When true, renders the checkbox in the indeterminate state. Useful for "select all" controls. See the standalone checkbox/1 docs for details.

    Defaults to false.

  • disabled (:boolean) - When true, disables the entire field (checkbox + label). The wrapper gains opacity-50 pointer-events-none to visually communicate the disabled state.

    Defaults to false.

  • class (:string) - Additional CSS classes applied to the flex wrapper <div> element. Defaults to nil.

  • Global attributes are accepted. HTML attributes forwarded to the underlying checkbox input element. Supports all globals plus: ["phx-change", "phx-click", "form", "required"].