Corex.Switch (Corex v0.1.2)

View Source

Phoenix implementation of Zag.js Switch.

Anatomy

Minimal

<.switch class="switch" aria_label="Enable notifications" />

With label

<.switch class="switch">
  <:label>Enable</:label>
</.switch>

API

Requires a stable id on <.switch>.

FunctionActionReturns
set_checked/2Set checked state (client)%Phoenix.LiveView.JS{}
set_checked/3Set checked state (server)socket
toggle_checked/2Toggle checked (client)%Phoenix.LiveView.JS{}
toggle_checked/3Toggle checked (server)socket

Events

Pick an event name and pass it to on_* on <.switch>.

Server events

EventWhenPayload
on_checked_change="switch_changed"Checked state changes%{"id" => id, "checked" => boolean}

on_checked_change

<.switch class="switch" on_checked_change="switch_changed">
  <:label>Subscribe</:label>
</.switch>
def handle_event("switch_changed", %{"id" => id, "checked" => checked}, socket) do
  {:noreply, assign(socket, :checked, checked)}
end

Client events

EventWhenevent.detail
on_checked_change_client="switch-changed"Checked state changesid, checked

on_checked_change_client

<.switch id="switch-on-checked-change-client" class="switch" on_checked_change_client="switch-changed">
  <:label>Subscribe</:label>
</.switch>
const el = document.getElementById("switch-on-checked-change-client");
el?.addEventListener("switch-changed", (event) => console.log(event.detail));

Patterns

Controlled

For server-owned checked state, set controlled, bind checked, and handle on_checked_change in LiveView.

<.switch
  class="switch"
  controlled
  checked={@checked}
  on_checked_change="patterns_checked"
>
  <:label>Enable</:label>
</.switch>
def mount(_params, _session, socket) do
  {:ok, assign(socket, :checked, false)}
end

def handle_event("patterns_checked", %{"checked" => checked}, socket) do
  {:noreply, assign(socket, :checked, checked == true or checked == "true")}
end

Form

Set the form id in to_form/2 and use <.form for={@form}>. Use field={@form[:notifications]} so the switch name matches the form. For Ecto validation in LiveView, add phx-change on the form so params stay in sync.

For cross-cutting invalid styling and error presentation, see the Forms guide. Pass invalid={Corex.FormField.invalid?(@form[:notifications])} when you want alert borders after validation.

<.form for={@form} phx-change="validate">
  <.switch field={@form[:notifications]} class="switch">
    <:label>Enable notifications</:label>
    <:error :let={msg}>
      <.heroicon name="hero-exclamation-circle" class="icon" />
      {msg}
    </:error>
  </.switch>
</.form>

Style

Target parts with data-scope and data-part, or use Corex Design: import tokens and switch.css, then set class="switch" on <.switch>.

[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"] {}
@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/switch.css";

Stack modifiers on the host (class on <.switch>).

Color

ModifierClasses
Defaultswitch
Accentswitch switch--accent
Brandswitch switch--brand
Alertswitch switch--alert
Infoswitch switch--info
Successswitch switch--success

Size

ModifierClasses
SMswitch switch--sm
MDswitch switch--md
LGswitch switch--lg
XLswitch switch--xl

Summary

Components

Renders a switch component.

API

Set checked state from a control (phx-click).

Set checked state from handle_event.

Toggle checked state from a control (phx-click).

Toggle checked state from handle_event.

Components

switch(assigns)

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 to false.
  • controlled (:boolean) - Whether the switch is controlled. Defaults to false.
  • 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 to false.
  • 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 nil. Must be one of nil, "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 to false.
  • invalid (:boolean) - Whether the switch has validation errors. Defaults to false.
  • required (:boolean) - Whether the switch 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)
    • 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

set_checked(switch_id, checked)

Set checked state from a control (phx-click).

<.action phx-click={Corex.Switch.set_checked("my-switch", true)}>On</.action>
<.switch id="my-switch" class="switch" name="s" value="on">
  <:label>Notify</:label>
</.switch>
document.getElementById("my-switch")?.dispatchEvent(
  new CustomEvent("corex:switch:set-checked", {
    bubbles: false,
    detail: { checked: true },
  })
);

set_checked(socket, switch_id, checked)

Set checked state from handle_event.

<.action phx-click="switch_on">On</.action>
<.switch id="my-switch" class="switch" name="s" value="on">
  <:label>Notify</:label>
</.switch>
def handle_event("switch_on", _, socket) do
  {:noreply, Corex.Switch.set_checked(socket, "my-switch", true)}
end

toggle_checked(switch_id)

Toggle checked state from a control (phx-click).

<.action phx-click={Corex.Switch.toggle_checked("my-switch")}>Toggle</.action>
<.switch id="my-switch" class="switch" name="s" value="on">
  <:label>Notify</:label>
</.switch>
document.getElementById("my-switch")?.dispatchEvent(
  new CustomEvent("corex:switch:toggle-checked", { bubbles: false })
);

toggle_checked(socket, switch_id)

Toggle checked state from handle_event.

<.action phx-click="flip_switch">Toggle</.action>
<.switch id="my-switch" class="switch" name="s" value="on">
  <:label>Notify</:label>
</.switch>
def handle_event("flip_switch", _, socket) do
  {:noreply, Corex.Switch.toggle_checked(socket, "my-switch")}
end