defmodule PhiaUi.Components.Checkbox do @moduledoc """ Native HTML checkbox component styled with Tailwind CSS. Integrates with `Phoenix.HTML.FormField` and Ecto changesets. Supports checked, unchecked, and indeterminate states. ## Sub-components - `checkbox/1` — standalone checkbox input - `form_checkbox/1` — checkbox with label and error messages, integrated with `Phoenix.HTML.FormField` ## Examples <%!-- Standalone checkbox --%> <.checkbox id="agree" name="agree" checked={true} /> <%!-- With indeterminate state --%> <.checkbox id="select-all" name="select_all" indeterminate={true} /> <%!-- Form-integrated checkbox --%> <.form_checkbox field={@form[:agreed]} label="I agree to the terms" /> <%!-- With phx-change --%> <.checkbox id="cb" name="cb" phx-change="toggle_item" /> """ use Phoenix.Component alias Phoenix.HTML.Form, as: HTMLForm import PhiaUi.ClassMerger, only: [cn: 1] attr(:id, :string, default: nil, doc: "Input ID") attr(:name, :string, default: nil, doc: "Input name") attr(:value, :string, default: "true", doc: "Checkbox value when checked") attr(:checked, :boolean, default: false, doc: "Whether the checkbox is checked") attr(:indeterminate, :boolean, default: false, doc: "Whether the checkbox is in indeterminate state (aria-checked=mixed)" ) attr(:disabled, :boolean, default: false, doc: "Whether the checkbox is disabled") attr(:class, :string, default: nil, doc: "Additional CSS classes (merged via cn/1, last wins)" ) attr(:rest, :global, include: ~w(phx-change phx-click form required aria-invalid), doc: "HTML attributes forwarded to the input element" ) @doc """ Renders a styled native `` element. Uses semantic Tailwind tokens (`border-primary`, `accent-primary`) so it respects the PhiaUI theme in both light and dark mode without any JS. The `data-state` attribute is set to `"checked"`, `"unchecked"`, or `"indeterminate"` and can be used for CSS-based styling. For the indeterminate state, `aria-checked="mixed"` is applied for screen readers. ## Examples <.checkbox id="agree" name="agree" /> <.checkbox id="agree" name="agree" checked={true} /> <.checkbox id="all" name="all" indeterminate={true} /> <.checkbox id="agree" name="agree" disabled={true} /> <.checkbox id="agree" name="agree" phx-change="toggle" /> """ def checkbox(assigns) do ~H""" """ end attr(:field, Phoenix.HTML.FormField, required: true, doc: "A `Phoenix.HTML.FormField` struct (e.g., `@form[:agreed]`)" ) attr(:label, :string, default: nil, doc: "Label text displayed next to the checkbox") attr(:indeterminate, :boolean, default: false, doc: "Whether the checkbox is in indeterminate state" ) attr(:disabled, :boolean, default: false, doc: "Whether the checkbox is disabled") attr(:class, :string, default: nil, doc: "Additional CSS classes for the wrapper element" ) attr(:rest, :global, include: ~w(phx-change phx-click form required), doc: "HTML attributes forwarded to the checkbox input" ) @doc """ Renders a checkbox integrated with `Phoenix.HTML.FormField`. Produces a `
` wrapper containing the checkbox input, an optional `