Fluxon.Components.Switch (Fluxon v2.0.0)

A toggle switch component for binary choices and settings.

The switch component provides an accessible and customizable toggle control that serves as an alternative to checkboxes, particularly suited for immediate actions and settings toggles. While checkboxes are better suited for form submissions and multiple selections, switches are designed for toggling states with immediate effect, making them suitable for settings panels, feature toggles, and preference controls.

Basic Usage

The switch component can be used standalone or within forms:

<.switch
  name="notifications"
  label="Enable Notifications"
  checked={@settings.notifications}
  phx-click="toggle_setting"
  phx-value-setting="notifications"
/>

The component supports both controlled and uncontrolled usage patterns, adapting to your application's state management needs.

Size Variants

The switch component offers three size variants to accommodate different interface needs:

<!-- Small switch for compact interfaces -->
<.switch
  name="small_switch"
  label="Small Switch"
  size="sm"
  checked={@settings.compact_mode}
/>

<!-- Default size for most use cases -->
<.switch
  name="default_switch"
  label="Default Switch"
  size="md"
  checked={@settings.default_setting}
/>

<!-- Large switch for touch interfaces or emphasis -->
<.switch
  name="large_switch"
  label="Large Switch"
  size="lg"
  checked={@settings.important_setting}
/>

Each size variant adjusts the track and thumb dimensions proportionally:

  • "sm": Small (h-4 w-6), suitable for dense layouts and compact UIs
  • "md": Default (h-5 w-8), recommended for most use cases
  • "lg": Large (h-6 w-10), suitable for touch interfaces and prominent settings

Labels and Context

Provide detailed context and guidance with various labeling options:

<!-- Basic label -->
<.switch
  name="simple"
  label="Enable Feature"
  checked={@feature_enabled}
/>

<!-- Label with sublabel for additional context -->
<.switch
  name="with_sublabel"
  label="Auto Save"
  sublabel="Recommended"
  checked={@settings.auto_save}
/>

<!-- Label with detailed description -->
<.switch
  name="with_description"
  label="Public Profile"
  description="Make your profile visible to other users on the platform"
  checked={@settings.public_profile}
/>

<!-- Complete example with all text features -->
<.switch
  name="comprehensive"
  label="Advanced Analytics"
  sublabel="Beta"
  description="Share detailed usage patterns to help improve the product experience"
  checked={@settings.analytics_enabled}
/>

Color Variants

Use semantic colors to convey meaning and context:

<!-- Primary color (default) -->
<.switch
  name="primary"
  label="Default Setting"
  color="primary"
  checked={@settings.default}
/>

<!-- Success color for positive actions -->
<.switch
  name="success"
  label="Enable Backup"
  color="success"
  checked={@settings.backup_enabled}
/>

<!-- Warning color for caution -->
<.switch
  name="warning"
  label="Beta Features"
  sublabel="Experimental"
  color="warning"
  checked={@settings.beta_features}
/>

<!-- Danger color for sensitive settings -->
<.switch
  name="danger"
  label="Public Profile"
  color="danger"
  checked={@settings.public_profile}
/>

<!-- Info color for informational toggles -->
<.switch
  name="info"
  label="Usage Analytics"
  color="info"
  checked={@settings.analytics}
/>

Form Integration

The switch component integrates with Phoenix forms in two ways: using the field attribute for form integration or using the name attribute for standalone inputs.

Use the field attribute to bind the switch to a form field:

<.form :let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.switch
    field={f[:notifications_enabled]}
    label="Push Notifications"
    sublabel="Real-time updates"
    description="Receive notifications about important account activity"
  />

  <.switch
    field={f[:email_marketing]}
    label="Email Marketing"
    sublabel="Optional"
    description="Receive promotional emails about new features"
  />
</.form>

Using the field attribute provides:

  • Automatic value handling from form data
  • Integration with changesets and validation
  • Proper form submission with correct field names
  • Error handling and display

Complete Form Example

defmodule MyApp.UserSettings do
  use Ecto.Schema
  import Ecto.Changeset

  schema "user_settings" do
    field :notifications_enabled, :boolean, default: true
    field :email_marketing, :boolean, default: false
    field :dark_mode, :boolean, default: false
    belongs_to :user, MyApp.User
    timestamps()
  end

  def changeset(settings, attrs) do
    settings
    |> cast(attrs, [:notifications_enabled, :email_marketing, :dark_mode])
    |> validate_required([])
  end
end

# In your LiveView
def mount(_params, _session, socket) do
  settings = MyApp.Accounts.get_user_settings(socket.assigns.current_user)
  changeset = UserSettings.changeset(settings, %{})

  {:ok, assign(socket, settings: settings, form: to_form(changeset))}
end

def render(assigns) do
  ~H"""
  <.form :let={f} for={@form} phx-change="validate" phx-submit="save">
    <div class="space-y-4">
      <.switch
        field={f[:notifications_enabled]}
        label="Push Notifications"
        description="Receive real-time notifications on your devices"
      />

      <.switch
        field={f[:email_marketing]}
        label="Marketing Emails"
        description="Get updates about new features and promotions"
      />

      <.switch
        field={f[:dark_mode]}
        label="Dark Mode"
        description="Switch to dark theme for better viewing in low light"
      />
    </div>

    <.button type="submit">Save Settings</.button>
  </.form>
  """
end

def handle_event("validate", %{"user_settings" => params}, socket) do
  changeset =
    socket.assigns.settings
    |> UserSettings.changeset(params)
    |> Map.put(:action, :validate)

  {:noreply, assign(socket, form: to_form(changeset))}
end

def handle_event("save", %{"user_settings" => params}, socket) do
  case MyApp.Accounts.update_user_settings(socket.assigns.settings, params) do
    {:ok, settings} ->
      {:noreply, assign(socket, settings: settings) |> put_flash(:info, "Settings updated!")}
    {:error, changeset} ->
      {:noreply, assign(socket, form: to_form(changeset))}
  end
end

Using Standalone Switches

For simpler cases or when not using Phoenix forms, use the name attribute with event handlers:

<.switch
  name="theme_toggle"
  label="Dark Mode"
  checked={@dark_mode}
  phx-click="toggle_theme"
/>

Switch States

The switch component supports various states for different use cases:

Disabled State

Disable switches to prevent user interaction:

<!-- Disabled in off state -->
<.switch
  name="disabled_off"
  label="Unavailable Feature"
  description="This feature is currently unavailable"
  disabled
  checked={false}
/>

<!-- Disabled in on state -->
<.switch
  name="disabled_on"
  label="Premium Feature"
  sublabel="Upgrade required"
  description="This feature requires a premium subscription"
  disabled
  checked={true}
/>

Disabled switches are visually muted and cannot be toggled by the user, making them suitable for representing features that are unavailable due to permissions, subscription status, or system state.

Settings Panels

Switches work well in settings interfaces where users need to toggle multiple preferences:

<!-- Notification Settings Panel -->
<div class="space-y-4">
  <h3 class="font-semibold">Notification Preferences</h3>

  <.switch
    name="push_notifications"
    label="Push Notifications"
    sublabel="Mobile & Desktop"
    description="Receive push notifications on your devices 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"
    description="Receive promotional emails about new features and updates"
    color="info"
    checked={@settings.marketing_emails}
    phx-click="toggle_setting"
    phx-value-setting="marketing_emails"
  />
</div>

Summary

Components

Renders a switch component for toggling between two states.

Components

switch(assigns)

Renders a switch component for toggling between two states.

This component provides an accessible toggle switch that can be used standalone or within forms. It supports various sizes, colors, and states, making it suitable for different UI contexts.

Attributes

  • id (:any) - The unique identifier for the switch. When not provided, the name attribute will be used. Defaults to nil.

  • name (:string) - The form name for the switch. Required when not using the field attribute.

  • class (:any) - Additional CSS classes to apply to the switch wrapper. Useful for controlling layout and spacing.

    Defaults to nil.

  • checked (:boolean) - Whether the switch is in the on position. When using forms, this is automatically handled by the field attribute.

  • disabled (:boolean) - When true, disables the switch. Disabled switches cannot be interacted with and appear visually muted.

    Defaults to false.

  • value (:any) - The value associated with the switch. This value is submitted when the switch is in the on position.

  • label (:string) - The primary label for the switch. This text is displayed next to the switch and is used for accessibility purposes.

    Defaults to nil.

  • sublabel (:string) - Additional context displayed to the side of the main label. Useful for providing extra information without cluttering the main label.

    Defaults to nil.

  • description (:string) - Detailed description of the switch option. This text appears below the label and can contain longer explanatory text.

    Defaults to nil.

  • size (:string) - Controls the size of the switch:

    • "sm": Small switch, suitable for compact UIs
    • "md": Default size, works well in most contexts
    • "lg": Large switch, good for touch interfaces or emphasis

    Defaults to "md".

  • color (:string) - The color theme of the switch when in the on position. Supports semantic colors from the theme:

    • "primary": Default theme color
    • "danger": Red color for destructive actions
    • "success": Green color for positive actions
    • "warning": Yellow color for cautionary actions
    • "info": Blue color for informational actions

    Defaults to "primary".

  • field (Phoenix.HTML.FormField) - The form field to bind to. When provided, the component automatically handles value tracking and form submission.

  • Global attributes are accepted. Additional attributes to pass to the form element. Supports all globals plus: ["form"].