Corex.Checkbox (Corex v0.1.0-alpha.24)

View Source

Phoenix implementation of Zag.js Checkbox.

Examples

Minimal

<.checkbox class="checkbox">
  <:label>Accept terms</:label>
</.checkbox>

Custom Control

This example assumes the import of .icon from Core Components, you are free to replace it

<.checkbox class="checkbox">
  <:label>
    Accept the terms
  </:label>
  <:control>
    <.icon name="hero-check" class="data-checked" />
  </:control>
</.checkbox>

Custom Error

This example assumes the import of .icon from Core Components, you are free to replace it

<.checkbox class="checkbox">
  <:label>
    Accept the terms
  </:label>
  <:error :let={msg}>
    <.icon name="hero-exclamation-circle" class="icon" />
    {msg}
  </:error>
</.checkbox>

Phoenix Form Integration

When using with Phoenix forms, you must add an id to the form using the Corex.Form.get_form_id/1 function.

Controller

defmodule MyAppWeb.PageController do
use MyAppWeb, :controller

def home(conn, params) do
  form = Phoenix.Component.to_form(Map.get(params, "user", %{}), as: :user)
  render(conn, :home, form: form)
end
end
<.form :let={f} as={:user} for={@form} id={get_form_id(@form)} method="get">
<.checkbox field={f[:terms]} class="checkbox">
  <:label>I accept the terms</:label>
    <:error :let={msg}>
  <.icon name="hero-exclamation-circle" class="icon" />
  {msg}
</:error>
</.checkbox>
<button type="submit">Submit</button>
</.form>

Live View

When using Phoenix form in a Live view you must also add controlled mode. This allows the Live view to be the source of truth and the component to be in sync accordingly

defmodule MyAppWeb.CheckboxLive do
use MyAppWeb, :live_view

def mount(_params, _session, socket) do
  form = to_form(%{"terms" => "false"}, as: :user)
  {:ok, socket |> assign(:form, form)}
end

def render(assigns) do
  ~H"""
  <.form as={:user} for={@form} id={get_form_id(@form)}>
  <.checkbox field={@form[:terms]} class="checkbox">
    <:label>I accept the terms</:label>
      <:error :let={msg}>
    <.icon name="hero-exclamation-circle" class="icon" />
    {msg}
  </:error>
  </.checkbox>
  <button type="submit">Submit</button>
</.form>
  """
end
end

With Ecto changeset

When using Ecto changeset for validation and inside a Live view you must enable the controlled mode.

This allows the Live View to be the source of truth and the component to be in sync accordingly

First lets create an embededed schema and changeset

defmodule MyApp.Account.User do
use Ecto.Schema
import Ecto.Changeset
alias MyApp.Account.User

embedded_schema do
  field :term, :boolean, default: false
end


@doc false
def changeset(%User{} = user, attrs) do
  user
  |> cast(attrs, [:term])
  |> validate_required([:term])
  |> validate_acceptance(:terms)
end
end
defmodule MyAppWeb.UserLive do
use MyAppWeb, :live_view
alias MyApp.Account.User

@impl true

def mount(_params, _session, socket) do
  {:ok,  assign(socket, :form, to_form(User.changeset(%User{}, %{})))}
end

@impl true
def handle_event("validate", %{"user" => user_params}, socket) do
  changeset = User.changeset(%User{}, user_params)
  {:noreply, assign(socket, form: to_form(changeset, action: :validate))}
end

@impl true
def render(assigns) do
  ~H"""
  <.form for={@form} id={get_form_id(@form)} phx-change="validate">
    <.checkbox field={@form[:terms]} class="checkbox" controlled>
      <:label>I accept the terms</:label>
      <:error :let={msg}>
        <.icon name="hero-exclamation-circle" class="icon" />
        {msg}
      </:error>
    </.checkbox>
  </.form>
  """
end
end

API Control

# Client-side
<button phx-click={Corex.Checkbox.set_checked("my-checkbox", true)}>
  Check
</button>

<button phx-click={Corex.Checkbox.toggle_checked("my-checkbox")}>
  Toggle
</button>

# Server-side
def handle_event("check", _, socket) do
  {:noreply, Corex.Checkbox.set_checked(socket, "my-checkbox", true)}
end

def handle_event("toggle", _, socket) do
  {:noreply, Corex.Checkbox.toggle_checked(socket, "my-checkbox")}
end

Styling

Use data attributes to target elements:

  • [data-scope="checkbox"][data-part="root"] - Label wrapper
  • [data-scope="checkbox"][data-part="control"] - Checkbox control
  • [data-scope="checkbox"][data-part="label"] - Label text
  • [data-scope="checkbox"][data-part="input"] - Hidden input
  • [data-scope="checkbox"][data-part="error"] - Error message

State-specific styling:

  • [data-state="checked"] - When checkbox is checked
  • [data-state="unchecked"] - When checkbox is unchecked
  • [data-disabled] - When checkbox is disabled
  • [data-readonly] - When checkbox is read-only
  • [data-invalid] - When checkbox has validation errors

If you wish to use the default Corex styling, you can use the class checkbox on the component. This requires to install mix corex.design first and import the component css file.

@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/checkbox.css";

You can then use modifiers

<.checkbox class="checkbox checkbox--accent checkbox--lg">

Learn more about modifiers and Corex Design

Summary

Components

Renders a checkbox component.

API

Sets the checkbox checked state from client-side. Returns a Phoenix.LiveView.JS command.

Sets the checkbox checked state from server-side. Pushes a LiveView event.

Toggles the checkbox checked state from client-side. Returns a Phoenix.LiveView.JS command.

Toggles the checkbox checked state from server-side. Pushes a LiveView event.

Components

checkbox(assigns)

Renders a checkbox component.

Attributes

  • id (:string) - The id of the checkbox, useful for API to identify the checkbox.
  • checked (:boolean) - The initial checked state or the controlled checked state. Defaults to false.
  • controlled (:boolean) - Whether the checkbox is controlled. Defaults to false.
  • name (:string) - The name of the checkbox input for form submission.
  • form (:string) - The form id to associate the checkbox with.
  • aria_label (:string) - The accessible label for the checkbox. Defaults to "Label".
  • disabled (:boolean) - Whether the checkbox is disabled. Defaults to false.
  • value (:string) - The value of the checkbox when checked. Defaults to "true".
  • dir (:string) - The direction of the checkbox. When nil, derived from document (html lang + config :rtl_locales). Defaults to nil. Must be one of nil, "ltr", or "rtl".
  • read_only (:boolean) - Whether the checkbox is read-only. Defaults to false.
  • invalid (:boolean) - Whether the checkbox has validation errors. Defaults to false.
  • required (:boolean) - Whether the checkbox is required. Defaults to false.
  • on_checked_change (:string) - The server event name when the checked state changes. Defaults to nil.
  • on_checked_change_client (:string) - The client event name when the checked state changes. Defaults to nil.
  • errors (:list) - List of error messages to display. Defaults to [].
  • field (Phoenix.HTML.FormField) - A form field struct retrieved from the form, for example: @form[:email]. Automatically sets id, name, checked state, and errors from the form field.
  • Global attributes are accepted.

Slots

  • label - Accepts attributes:
    • class (:string)
  • control - Accepts attributes:
    • class (:string)
  • error - Accepts attributes:
    • class (:string)

API

set_checked(checkbox_id, checked)

Sets the checkbox checked state from client-side. Returns a Phoenix.LiveView.JS command.

Examples

<button phx-click={Corex.Checkbox.set_checked("my-checkbox", true)}>
  Check
</button>

<button phx-click={Corex.Checkbox.set_checked("my-checkbox", false)}>
  Uncheck
</button>

set_checked(socket, checkbox_id, checked)

Sets the checkbox checked state from server-side. Pushes a LiveView event.

Examples

def handle_event("check", _params, socket) do
  socket = Corex.Checkbox.set_checked(socket, "my-checkbox", true)
  {:noreply, socket}
end

toggle_checked(checkbox_id)

Toggles the checkbox checked state from client-side. Returns a Phoenix.LiveView.JS command.

Examples

<button phx-click={Corex.Checkbox.toggle_checked("my-checkbox")}>
  Toggle
</button>

toggle_checked(socket, checkbox_id)

Toggles the checkbox checked state from server-side. Pushes a LiveView event.

Examples

def handle_event("toggle", _params, socket) do
  socket = Corex.Checkbox.toggle_checked(socket, "my-checkbox")
  {:noreply, socket}
end