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

ComponentBest suited for
switch/1On/off toggle for an immediately applied setting (notifications, theme, feature flags).
Fluxon.Components.CheckboxOpt-in confirmations, terms acceptance, and grouped multi-select fields.
Fluxon.Components.RadioSingle 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.

SizeTrackUse case
"sm"h-4 w-6Dense layouts, table rows, inline toggles within tight UI.
"md"h-5 w-8Default. Pairs with text-sm labels and most form fields.
"lg"h-6 w-10Touch-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.

ColorUse 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.

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 suppliedResolution
checked (boolean)Used verbatim. Wins over any value comparison.
field and no checkedfield.value compared (as escaped HTML) against checked_value.
value and no checkedvalue compared against checked_value.
Neither value nor checkedRenders 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

switch(assigns)

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 to name when omitted; a field binding will reuse field.id instead.

    Defaults to nil.

  • name (:string) - Form field name applied to both the checkbox input and its hidden mirror input. Required when field is 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 any value versus checked_value comparison. Omit to let the component derive the state from value (or from field.value when bound to a form).

  • disabled (:boolean) - Disables the switch when true. 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 against checked_value (using Phoenix.HTML.html_escape/1 on both sides) to decide whether to render on. Provided automatically when field is 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 when label is nil.

    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 with text-sm labels 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 derives id, name, and value from the field.

  • Global attributes are accepted. Additional HTML attributes forwarded to both the checkbox <input> and the hidden mirror input. The form attribute is included in the allowlist so the switch can live outside the <form> element it belongs to by referencing the form's id. Supports all globals plus: ["form"].