Fluxon.Components.Switch
(Fluxon v3.0.0)
Toggle switch for on/off settings that take effect immediately.
Renders a styled checkbox input as a sliding track and thumb, with built-in label,
sublabel, and description rendering. Integrates directly with Phoenix forms via the
field attribute, ships size and color variants, and always submits a value (checked
or unchecked) thanks to a hidden mirror input.
Choosing between switch and checkbox
| Component | Best suited for |
|---|---|
switch/1 | On/off toggle for an immediately applied setting (notifications, theme, feature flags). |
Fluxon.Components.Checkbox | Opt-in confirmations, terms acceptance, and grouped multi-select fields. |
Fluxon.Components.Radio | Single selection from a mutually exclusive set of options. |
Reach for switch/1 when flipping the control is the action itself. Reach for
checkbox/1 when the value is one input among many in a form the user submits.
Usage
The simplest form takes a name and a label:
<.switch name="notifications" label="Enable notifications" />By default the switch submits "true" when on and "false" when off. Both values are
always present in the form payload because a hidden input mirrors the field name with
the unchecked value:
# on
%{"notifications" => "true"}
# off (hidden input still submits)
%{"notifications" => "false"}Override the wire values with checked_value and unchecked_value to match the schema
the server expects:
<.switch name="active" label="Active" checked_value="1" unchecked_value="0" />Add sublabel for a short inline qualifier and description for longer explanatory copy
rendered beneath the label:
<.switch
name="auto_save"
label="Auto save"
sublabel="Recommended"
description="Automatically save your changes every few seconds."
/>Sizes
The size attribute scales the track and thumb together so the switch fits its
surrounding context.
| Size | Track | Use case |
|---|---|---|
"sm" | h-4 w-6 | Dense layouts, table rows, inline toggles within tight UI. |
"md" | h-5 w-8 | Default. Pairs with text-sm labels and most form fields. |
"lg" | h-6 w-10 | Touch-friendly surfaces, primary settings, and emphasized toggles. |
<.switch name="compact" label="Compact mode" size="sm" />
<.switch name="default" label="Default" size="md" />
<.switch name="emphasis" label="Important setting" size="lg" />Colors
The color attribute controls the track color when the switch is on. Use it to
reinforce the meaning of the setting being toggled.
| Color | Use case |
|---|---|
"primary" | Default. Neutral toggles where no extra meaning is needed. |
"success" | Positive opt-ins such as enabling backups, two-factor auth, or auto-save. |
"warning" | Cautionary toggles such as beta features or experimental flags. |
"danger" | Sensitive or potentially destructive settings such as making data public. |
"info" | Informational toggles such as analytics, telemetry, or marketing opt-in. |
<.switch name="backup" label="Automatic backups" color="success" />
<.switch name="beta" label="Beta features" sublabel="Experimental" color="warning" />
<.switch name="public" label="Public profile" color="danger" />Disabled State
Setting disabled disables the underlying checkbox input and propagates the disabled
attribute to the hidden mirror input as well, so the field is omitted from the submitted
payload entirely (matching native HTML form behavior). The label, sublabel, and
description carry the disabled styling automatically.
<.switch
name="premium_feature"
label="Premium feature"
sublabel="Upgrade required"
description="This feature is included with the Pro plan."
disabled
/>Use disabled to represent toggles that are unavailable due to permissions,
subscription tier, or system state, while still showing the user that the option exists.
Form Integration
The component offers two ways to wire form data: the field attribute for Phoenix form
bindings, or the name attribute for standalone controls.
Using with Phoenix forms (recommended)
Pass a Phoenix.HTML.FormField to field and the component derives id, name, and
the current value automatically. The displayed state is computed by comparing the
field's value against checked_value.
<.form :let={f} for={@form} phx-change="validate" phx-submit="save">
<.switch
field={f[:notifications_enabled]}
label="Push notifications"
description="Receive real-time updates about your account."
/>
<.switch
field={f[:dark_mode]}
label="Dark mode"
sublabel="Beta"
/>
<.switch
field={f[:active]}
label="Active"
checked_value="1"
unchecked_value="0"
/>
</.form>Using standalone switches
When not bound to a form, supply name, manage checked yourself, and wire interaction
through phx-click or any other LiveView binding:
<.switch
name="theme_toggle"
label="Dark mode"
checked={@dark_mode}
phx-click="toggle_theme"
/>When to use each approach
Use field when the toggle belongs to a changeset-backed form that gets submitted as
a unit. Use name for ambient toggles such as theme switchers, feature flags, or
settings panels where each switch fires its own LiveView event on change.
Checked State Resolution
How the rendered checked attribute is computed depends on which inputs you provide:
| Inputs supplied | Resolution |
|---|---|
checked (boolean) | Used verbatim. Wins over any value comparison. |
field and no checked | field.value compared (as escaped HTML) against checked_value. |
value and no checked | value compared against checked_value. |
Neither value nor checked | Renders off. |
The comparison uses Phoenix.HTML.html_escape/1 on both sides, so integers and strings
with the same string representation match (for example value={1} against
checked_value="1").
Examples
Theme toggle wired to a LiveView event:
<.switch
name="theme"
label="Dark mode"
checked={@dark_mode}
phx-click="toggle_theme"
/>Notification preferences panel where each switch toggles a single setting:
<div class="flex flex-col gap-4">
<.switch
name="push_notifications"
label="Push notifications"
sublabel="Mobile and desktop"
description="Receive notifications when new activity occurs."
checked={@settings.push_notifications}
phx-click="toggle_setting"
phx-value-setting="push_notifications"
/>
<.switch
name="email_notifications"
label="Email notifications"
description="Receive email updates about important account activity."
checked={@settings.email_notifications}
phx-click="toggle_setting"
phx-value-setting="email_notifications"
/>
<.switch
name="marketing_emails"
label="Marketing communications"
sublabel="Optional"
color="info"
checked={@settings.marketing_emails}
phx-click="toggle_setting"
phx-value-setting="marketing_emails"
/>
</div>Account settings form bound to a changeset:
<.form :let={f} for={@form} phx-change="validate" phx-submit="save">
<.switch
field={f[:two_factor_enabled]}
label="Two-factor authentication"
description="Require a verification code in addition to your password."
color="success"
/>
<.switch
field={f[:public_profile]}
label="Public profile"
description="Allow other users on the platform to view your profile."
color="danger"
/>
<.switch
field={f[:active]}
label="Account active"
checked_value="1"
unchecked_value="0"
/>
<.button type="submit">Save changes</.button>
</.form>Switch rendered outside its associated form by referencing the form id. Useful
when the toggle visually belongs to a sidebar, header, or sticky footer that sits
outside the <form> element the field submits with:
<form id="signup-form" phx-submit="register">
<%!-- form fields --%>
</form>
<div class="sticky bottom-0 p-4">
<.switch name="agree" label="I agree to the terms" form="signup-form" />
<button type="submit" form="signup-form">Sign up</button>
</div>
Summary
Components
Renders a toggle switch alongside its label, sublabel, and description.
Components
Renders a toggle switch alongside its label, sublabel, and description.
Use for on/off settings that take effect immediately, such as enabling notifications,
switching themes, or flipping feature flags. The component renders a hidden mirror input
with the unchecked value so the field is always present in submitted form data, even
when the switch is off. Pair with field for Phoenix form binding, or with name for
standalone control such as settings panels and LiveView event handlers.
Attributes
id(:any) - Identifier applied to the checkbox<input>and referenced by the surrounding<label>for pointer association. Defaults tonamewhen omitted; afieldbinding will reusefield.idinstead.Defaults to
nil.name(:string) - Form field name applied to both the checkbox input and its hidden mirror input. Required whenfieldis not provided.class(:any) - Extra classes merged onto the outer wrapper<div>(not the track or thumb). Use to control surrounding layout such as spacing or width within a settings list.Defaults to
nil.checked(:boolean) - Forces the on/off state when supplied, taking precedence over anyvalueversuschecked_valuecomparison. Omit to let the component derive the state fromvalue(or fromfield.valuewhen bound to a form).disabled(:boolean) - Disables the switch whentrue. Both the checkbox input and the hidden mirror input are marked disabled, so the field is omitted from the submitted payload entirely. The label, sublabel, and description carry the disabled styling automatically.Defaults to
false.value(:any) - Current value associated with the field. The component compares it againstchecked_value(usingPhoenix.HTML.html_escape/1on both sides) to decide whether to render on. Provided automatically whenfieldis set.checked_value(:any) - Value submitted when the switch is on. Defaults to"true". Override to match the underlying schema, for example"1"for boolean integer columns or domain-specific strings such as"on"or"enabled".Examples
# boolean integer column <.switch name="active" checked_value="1" unchecked_value="0" /> # explicit on/off values <.switch name="feature" checked_value="on" unchecked_value="off" />Defaults to
"true".unchecked_value(:any) - Value submitted via the hidden mirror input when the switch is off. Defaults to"false". Browsers do not submit unchecked checkboxes, so this hidden input is what keeps the field present in the payload.Defaults to
"false".label(:string) - Primary label rendered next to the switch. Omit to render only the toggle, for example when the surrounding markup provides its own labeling.Defaults to
nil.sublabel(:string) - Short inline qualifier rendered beside the main label (for example "Optional", "Recommended", "Beta"). Has no effect whenlabelisnil.Defaults to
nil.description(:string) - Longer explanatory copy rendered beneath the label. Use to clarify what flipping the switch will do or what the underlying setting controls.Defaults to
nil.size(:string) - Scales the track and thumb together."sm": Compact (h-4 w-6). Use for dense layouts, table rows, and inline toggles."md": Default (h-5 w-8). Pairs withtext-smlabels and most form fields."lg": Prominent (h-6 w-10). Use for touch surfaces and emphasized settings.
Defaults to
"md". Must be one of"sm","md", or"lg".color(:string) - Color of the track when the switch is on. Use to reinforce the meaning of the setting being toggled."primary": Default. Neutral toggles where no extra meaning is needed."success": Positive opt-ins (backups, auto-save, two-factor auth)."warning": Cautionary toggles (beta features, experimental flags)."danger": Sensitive or potentially destructive settings (public profile)."info": Informational toggles (analytics, telemetry, marketing opt-in).
Defaults to
"primary". Must be one of"primary","danger","success","warning", or"info".field(Phoenix.HTML.FormField) - Phoenix form field to bind to. When provided, the component derivesid,name, andvaluefrom the field.Global attributes are accepted. Additional HTML attributes forwarded to both the checkbox
<input>and the hidden mirror input. Theformattribute is included in the allowlist so the switch can live outside the<form>element it belongs to by referencing the form'sid. Supports all globals plus:["form"].