Corex. Toggle
(Corex v0.1.0)
View Source
Phoenix implementation of Zag.js Toggle.
Anatomy
Minimal
<.toggle class="toggle">
lorem
</.toggle>With indicator
<.toggle class="toggle">
<:indicator><.heroicon name="hero-bold" /></:indicator>
Bold
</.toggle>
<.toggle class="toggle">
<:indicator><.heroicon name="hero-bold" /></:indicator>
<span class="sr-only">Bold</span>
</.toggle>Dual label
Set data-toggle-dual-label on the host to swap visible label text when pressed. Use a second <span data-pressed> for the on-state label.
<.toggle class="toggle" data-toggle-dual-label>
<span>lorem</span>
<span data-pressed>donec</span>
</.toggle>API
Requires a stable id on <.toggle>.
| Function | Action | Returns |
|---|---|---|
set_pressed/2 | Set pressed state (client) | %Phoenix.LiveView.JS{} |
set_pressed/3 | Set pressed state (server) | socket |
toggle_pressed/2 | Toggle pressed (client) | %Phoenix.LiveView.JS{} |
toggle_pressed/3 | Toggle pressed (server) | socket |
Events
Pick an event name and pass it to on_* on <.toggle>.
Server events
| Event | When | Payload |
|---|---|---|
on_pressed_change="toggle_pressed_changed" | Pressed state changes | %{"id" => id, "pressed" => boolean} |
on_pressed_change
<.toggle
class="toggle"
controlled
pressed={false}
on_pressed_change="toggle_pressed_changed"
>
lorem
</.toggle>def handle_event("toggle_pressed_changed", %{"pressed" => pressed}, socket) do
p = pressed == true or pressed == "true"
{:noreply, assign(socket, :pressed, p)}
endClient events
| Event | When | event.detail |
|---|---|---|
on_pressed_change_client="toggle-client-changed" | Pressed state changes | id, pressed |
on_pressed_change_client
<.toggle
id="toggle-on-pressed-change-client"
class="toggle"
on_pressed_change_client="toggle-client-changed"
>
lorem
</.toggle>const el = document.getElementById("toggle-on-pressed-change-client");
el?.addEventListener("toggle-client-changed", (e) => console.log(e.detail));Patterns
Controlled
For server-owned pressed state, set controlled, bind pressed, and handle on_pressed_change in LiveView.
<.toggle
class="toggle"
controlled
pressed={@pressed}
on_pressed_change="toggle_patterns_pressed"
>
lorem
</.toggle>def mount(_params, _session, socket) do
{:ok, assign(socket, :pressed, false)}
end
def handle_event("toggle_patterns_pressed", %{"pressed" => pressed}, socket) do
{:noreply, assign(socket, :pressed, pressed == true or pressed == "true")}
endStyle
Target parts with data-scope and data-part, or use Corex Design: import tokens and toggle.css, then set class="toggle" on <.toggle>.
[data-scope="toggle"][data-part="root"] {}
[data-scope="toggle"][data-part="indicator"] {}@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/toggle.css";Stack modifiers on the host (class on <.toggle>).
Color
| Modifier | Classes |
|---|---|
| Default | toggle |
| Accent | toggle toggle--accent |
| Brand | toggle toggle--brand |
| Alert | toggle toggle--alert |
| Info | toggle toggle--info |
| Success | toggle toggle--success |
Size
| Modifier | Classes |
|---|---|
| SM | toggle toggle--sm |
| MD | toggle toggle--md |
| LG | toggle toggle--lg |
| XL | toggle toggle--xl |
Rounded
| Modifier | Classes |
|---|---|
| None | toggle toggle--rounded-none |
| SM | toggle toggle--rounded-sm |
| MD | toggle toggle--rounded-md |
| LG | toggle toggle--rounded-lg |
| XL | toggle toggle--rounded-xl |
| Full | toggle toggle--rounded-full |
Summary
API
Set pressed state from a control (phx-click).
Set pressed state from handle_event.
Flip pressed state from a control (phx-click).
Flip pressed state from handle_event.
Components
Attributes
id(:string)pressed(:boolean) - Initial or controlled pressed state. Defaults tofalse.controlled(:boolean) - Defaults tofalse.disabled(:boolean) - Defaults tofalse.dir(:string) - When nil, derived from document. Defaults tonil. Must be one ofnil,"ltr", or"rtl".on_pressed_change(:string) - Defaults tonil.on_pressed_change_client(:string) - Defaults tonil.- Global attributes are accepted.
Slots
inner_blockindicator- Accepts attributes:class(:string)
API
Set pressed state from a control (phx-click).
<.action phx-click={Corex.Toggle.set_pressed("my-toggle", true)}>On</.action>
<.toggle id="my-toggle" class="toggle">Label</.toggle>document.getElementById("my-toggle")?.dispatchEvent(
new CustomEvent("corex:toggle:set-pressed", {
bubbles: false,
detail: { pressed: true },
})
);
Set pressed state from handle_event.
<.action phx-click="press_toggle">On</.action>
<.toggle id="my-toggle" class="toggle">Label</.toggle>def handle_event("press_toggle", _, socket) do
{:noreply, Corex.Toggle.set_pressed(socket, "my-toggle", true)}
end
Flip pressed state from a control (phx-click).
<.action phx-click={Corex.Toggle.toggle_pressed("my-toggle")}>Toggle</.action>
<.toggle id="my-toggle" class="toggle">Label</.toggle>document.getElementById("my-toggle")?.dispatchEvent(
new CustomEvent("corex:toggle:toggle-pressed", { bubbles: false })
);
Flip pressed state from handle_event.
<.action phx-click="flip_toggle">Toggle</.action>
<.toggle id="my-toggle" class="toggle">Label</.toggle>def handle_event("flip_toggle", _, socket) do
{:noreply, Corex.Toggle.toggle_pressed(socket, "my-toggle")}
end