Corex.Switch
(Corex v0.1.0-beta.1)
View Source
Phoenix implementation of Zag.js Switch.
Examples
Basic Usage
<.switch id="my-switch">
<:label>Enable notifications</:label>
</.switch>Label before control
<.switch id="my-switch">
<:label position={:pre}>Enable notifications</:label>
</.switch>Controlled Mode
<.switch
id="my-switch"
controlled
checked={@switch_checked}
on_checked_change="switch_changed">
<:label>Enable notifications</:label>
</.switch>def handle_event("switch_changed", %{"checked" => checked}, socket) do
{:noreply, assign(socket, :switch_checked, checked)}
endPhoenix Form Integration
When using with Phoenix forms, set the form id in to_form/2 (for example to_form(changeset, as: :name, id: "my-form")) and use id={@form.id} on <.form>.
Controller
Build the form from an Ecto changeset:
def form_page(conn, _params) do
form =
%MyApp.Form.Preferences{}
|> MyApp.Form.Preferences.changeset(%{})
|> Phoenix.Component.to_form(as: :preferences, id: "preferences-form")
render(conn, :form_page, form: form)
end<.form :let={f} for={@form} id={@form.id} action={@action} method="post">
<.switch field={f[:notifications]} class="switch">
<:label>Enable notifications</:label>
<:error :let={msg}>
<.heroicon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.switch>
<button type="submit">Submit</button>
</.form>Live View
When using Phoenix form in a Live view you must also add controlled mode. Prefer building the form from an Ecto changeset (see "With Ecto changeset" below).
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 create your schema and changeset:
defmodule MyApp.Accounts.User do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :notifications_enabled, :boolean, default: false
end
def changeset(user, attrs) do
user
|> cast(attrs, [:notifications_enabled])
|> validate_required([:notifications_enabled])
end
enddefmodule MyAppWeb.UserLive do
use MyAppWeb, :live_view
alias MyApp.Accounts.User
def mount(_params, _session, socket) do
{:ok, assign(socket, :form, to_form(User.changeset(%User{}, %{})))}
end
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
def render(assigns) do
~H"""
<.form for={@form} id={@form.id} phx-change="validate">
<.switch field={@form[:notifications_enabled]} class="switch" controlled>
<:label>Enable notifications</:label>
<:error :let={msg}>
<.heroicon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.switch>
</.form>
"""
end
endProgrammatic Control
# Client-side
<button phx-click={Corex.Switch.set_checked("my-switch", true)}>
Turn On
</button>
<button phx-click={Corex.Switch.toggle_checked("my-switch")}>
Toggle
</button>
# Server-side
def handle_event("turn_on", _, socket) do
{:noreply, Corex.Switch.set_checked(socket, "my-switch", true)}
end
def handle_event("toggle", _, socket) do
{:noreply, Corex.Switch.toggle_checked(socket, "my-switch")}
endStyling
Use data attributes to target elements:
[data-scope="switch"][data-part="root"] {}
[data-scope="switch"][data-part="control"] {}
[data-scope="switch"][data-part="thumb"] {}
[data-scope="switch"][data-part="label"] {}
[data-scope="switch"][data-part="input"] {}
[data-scope="switch"][data-part="error"] {}If you wish to use the default Corex styling, you can use the class switch on the component.
This requires to install Mix.Tasks.Corex.Design first and import the component css file.
@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/switch.css";You can then use modifiers
<.switch class="switch switch--accent switch--lg">
Summary
Components
Renders a switch component.
API
Sets the switch checked state from client-side. Returns a Phoenix.LiveView.JS command.
Sets the switch checked state from server-side. Pushes a LiveView event.
Toggles the switch checked state from client-side. Returns a Phoenix.LiveView.JS command.
Toggles the switch checked state from server-side. Pushes a LiveView event.
Components
Renders a switch component.
Attributes
id(:string) - The id of the switch, useful for API to identify the switch.checked(:boolean) - The initial checked state or the controlled checked state. Defaults tofalse.controlled(:boolean) - Whether the switch is controlled. Defaults tofalse.name(:string) - The name of the switch input for form submission.form(:string) - The form id to associate the switch with.aria_label(:string) - The accessible label for the switch. Defaults to"Label".disabled(:boolean) - Whether the switch is disabled. Defaults tofalse.value(:string) - The value of the switch when checked. Defaults to"true".dir(:string) - The direction of the switch. When nil, derived from document (html lang + config :rtl_locales). Defaults to"ltr". Must be one of"ltr", or"rtl".orientation(:string) - Layout orientation for CSS (vertical or horizontal). Defaults to"horizontal". Must be one of"vertical", or"horizontal".read_only(:boolean) - Whether the switch is read-only. Defaults tofalse.invalid(:boolean) - Whether the switch has validation errors. Defaults tofalse.required(:boolean) - Whether the switch is required. Defaults tofalse.on_checked_change(:string) - The server event name when the checked state changes. Defaults tonil.on_checked_change_client(:string) - The client event name when the checked state changes. Defaults tonil.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)position(:atom) - Place the label before (:pre) or after (:post) the control. Defaults to :post when omitted. Must be one of:pre, or:post.
error- Accepts attributes:class(:string)
API
Sets the switch checked state from client-side. Returns a Phoenix.LiveView.JS command.
Examples
<button phx-click={Corex.Switch.set_checked("my-switch", true)}>
Turn On
</button>
<button phx-click={Corex.Switch.set_checked("my-switch", false)}>
Turn Off
</button>
Sets the switch checked state from server-side. Pushes a LiveView event.
Examples
def handle_event("turn_on", _params, socket) do
socket = Corex.Switch.set_checked(socket, "my-switch", true)
{:noreply, socket}
end
Toggles the switch checked state from client-side. Returns a Phoenix.LiveView.JS command.
Examples
<button phx-click={Corex.Switch.toggle_checked("my-switch")}>
Toggle
</button>
Toggles the switch checked state from server-side. Pushes a LiveView event.
Examples
def handle_event("toggle", _params, socket) do
socket = Corex.Switch.toggle_checked(socket, "my-switch")
{:noreply, socket}
end