---
title: Toggle
desc: Form element that allows users to switch between two states, such as on and off.
ico: mdi:toggle-switch
keywords:
  - boolean
  - checkbox
  - form
  - switch

props:
  - class: .prs-toggle
    type: component
    desc: For <input>
  - class: .prs-toggle-label
    type: component
    desc: For <label>
  - class: .prs-toggle-secondary
    type: modifier
    desc: Secondary color variant
  - class: .prs-toggle-accent
    type: modifier
    desc: Accent color variant
  - class: .prs-toggle-info
    type: modifier
    desc: Red variant
  - class: .prs-toggle-success
    type: modifier
    desc: Green variant
  - class: .prs-toggle-warning
    type: modifier
    desc: Yellow variant
  - class: .prs-toggle-danger
    type: modifier
    desc: Red variant
  - class: .prs-toggle-neutral
    type: modifier
    desc: Gray variant
  - class: .prs-toggle-sm
    type: modifier
    desc: Small size
  - class: .prs-toggle_focus
    type: state
    desc: Manually apply visual focus
  - class: .prs-toggle_disabled
    type: state
    desc: Manually apply visual disabled

controls:
  - name: label
    type: text
    label: Label
    desc: As always, keep it simple.
    default: Label

  - name: trailingLabel
    type: toggle
    label: Trailing label
    desc: If you want a more a more consistent layout please use the Form Control component with the Column layout option.
    default: false

  - name: variant
    type: radio
    label: Variant
    desc: Color variants (only visible when checked).
    default: default
    options:
      - default
      - secondary
      - accent
      - info
      - success
      - warning
      - danger
      - neutral

  - name: icon
    type: toggle
    label: Icon mode
    desc: Use an icon inside the handle.
    default: false

  - name: small
    type: toggle
    label: Small
    desc: A smaller version.
    default: false

  - name: checked
    type: toggle
    label: Checked
    desc: Default state or checked.
    default: false

  - name: indeterminate
    type: toggle
    label: Indeterminate
    desc: Partial group selected state. This overrides the checked/unchecked model.
    default: false

  - name: state
    type: radio
    label: State
    desc: Focus and disabled states.
    default: default
    options:
      - default
      - focus
      - disabled

alert:
  ico: mdi:wheelchair-accessibility
  body: |
    **For best accessibility:**  
    Use **role="switch"** on the **input** so it represents **on**/**off** instead of _checked/unchecked_. Make sure to ALWAYS use a **label** wrapped around the toggle to ensure a more accessible target click area.

preview: |
  <div
    x-init="
      $watch('checked', value => {
        indeterminate = false;
      });
      $watch('indeterminate', value => {
        $nextTick(() => {
          $refs.prsToggle.indeterminate = value;
          $refs.prsToggleIcon.indeterminate = value;
        });
      });
    "
    class="w-fit max-w-sm"
  > <!-- <- this is just for demo purposes -->
    <label class="prs-toggle-label">
      <span x-show="!trailingLabel" class="prs-label-text" x-text="label"></span>
      <input
        type="checkbox"
        x-show="!icon"
        x-model="checked"
        x-ref="prsToggle"
        x-init="$el.indeterminate = indeterminate"
        :class="{
          'prs-toggle-sm': small,
          ['prs-toggle-'+ variant]: variant !== 'default',
          'prs-toggle_focus': state === 'focus',
        }"
        class="prs-toggle"
        role="switch"
        :disabled="state === 'disabled'"
      />
      <span
        x-show="icon"
        :class="{
          'prs-toggle-sm': small,
          ['prs-toggle-'+ variant]: variant !== 'default',
          'prs-toggle_focus': state === 'focus',
        }"
        class="prs-toggle"
      >
        <input type="checkbox" x-model="checked" x-ref="prsToggleIcon" x-init="$el.indeterminate = indeterminate" :aria-label="label" role="switch" :disabled="state === 'disabled'" />
        <span><iconify-icon icon="mdi:close" noobserver></iconify-icon></span>
        <span><iconify-icon icon="mdi:check" noobserver></iconify-icon></span>
      </span>
      <span x-show="trailingLabel" class="prs-label-text" x-text="label"></span>
    </label>
  </div>

code:
  html: |
    <label class="prs-toggle-label">
      {labelStart}{input}{labelEnd}
    </label>
  logic:
    input: "this.icon ? '<span class=\"prs-toggle{variant}{small}{focus}\">\\n    <input type=\"checkbox\" role=\"switch\"{checked}{disabled} />\\n    <span><svg>OFF</svg></span>\\n    <span><svg>ON</svg></span>\\n  </span>' : '<input type=\"checkbox\" class=\"prs-toggle{variant}{small}{focus}\" role=\"switch\"{checked}{disabled} />'"
    labelStart: "this.trailingLabel ? '' : '<span class=\"prs-label-text\">{label}</span>\\n  '"
    labelEnd: "this.trailingLabel ? '\\n  <span class=\"prs-label-text\">{label}</span>' : ''"
    label: "this.label"
    variant: " this.variant !== 'default' ? (' prs-toggle-'+ this.variant) : ''"
    small: "this.small ? ' prs-toggle-sm' : ''"
    checked: "this.checked ? ' checked' : ''"
    focus: "this.state === 'focus' ? ' prs-toggle_focus' : ''"
    disabled: "this.state === 'disabled' ? ' disabled' : ''"
---
