Switch

Examples

Size Examples

Demonstrate the Switch component in different sizes (xs, sm, md, lg, xl):

Colors

Disabled Example

Show how the Switch component looks when disabled:

Code

To include the Switch component's code in your documentation:

import { cva, VariantProps } from 'class-variance-authority'
import { useId } from 'react'

const switchBase = cva(['relative inline-block rounded-full peer'], {
  variants: {
    size: {
      xs: 'w-8 h-5',
      sm: 'w-10 h-6',
      md: 'w-12 h-7',
      lg: 'w-14 h-8',
      xl: 'w-16 h-9'
    },
    disabled: {
      true: 'opacity-70',
      false: ''
    }
  },
  defaultVariants: {
    size: 'md',
    disabled: false
  }
})

const ballBase = cva(
  [
    "absolute left-0 top-0 bottom-0 w-full cursor-pointer rounded-full duration-300 before:absolute before:transition-all before:duration-300 before:bottom-1 before:left-1 before:aspect-square before:rounded-full before:duration-300 before:content-['']",
    'before:bg-zinc-100'
  ],
  {
    variants: {
      size: {
        xs: 'before:w-3 before:h-3 active:before:w-4 peer-checked:before:ml-3 peer-checked:active:before:ml-2',
        sm: 'before:w-4 before:h-4 active:before:w-5 peer-checked:before:ml-4 peer-checked:active:before:ml-3',
        md: 'before:w-5 before:h-5 active:before:w-6 peer-checked:before:ml-5 peer-checked:active:before:ml-4',
        lg: 'before:w-6 before:h-6 active:before:w-7 peer-checked:before:ml-6 peer-checked:active:before:ml-5',
        xl: 'before:w-7 before:h-7 active:before:w-8 peer-checked:before:ml-7 peer-checked:active:before:ml-6'
      },
      color: {
        zinc: 'bg-zinc-200 dark:bg-zinc-700 peer-checked:bg-zinc-600',
        blue: 'bg-zinc-200 dark:bg-zinc-700 peer-checked:bg-blue-500',
        green: 'bg-zinc-200 dark:bg-zinc-700 peer-checked:bg-green-500',
        red: 'bg-zinc-200 dark:bg-zinc-700 peer-checked:bg-red-500',
        yellow: 'bg-zinc-200 dark:bg-zinc-700 peer-checked:bg-yellow-500'
      }
    },
    defaultVariants: {
      size: 'md',
      color: 'zinc'
    }
  }
)

type SwitchProps = VariantProps<typeof switchBase> &
  VariantProps<typeof ballBase> & {
    className?: string
    checked?: boolean | null
    defaultChecked?: boolean | null
    onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void
  }

const Switch = ({ size = 'md', className = '', onChange, defaultChecked = false, disabled = false, checked = false, color, ...props }: SwitchProps) => {
  const id = useId()
  const effectiveChecked = checked != null && onChange ? { checked } : defaultChecked != null ? { defaultChecked } : {}

  return (
    <label htmlFor={id} className={`${switchBase({ size, disabled })} ${className}`}>
      <input type="checkbox" className="peer h-0 w-0 opacity-0" {...{ ...props, id, ...effectiveChecked, onChange, disabled: !!disabled }} />
      <span className={ballBase({ size, color })} />
    </label>
  )
}

export default Switch

Usage

Provide a simple usage example of the Switch component:

<Switch size="md" defaultChecked onChange={(e) => console.log(e.target.checked)} />

Props

Detail the props available for the Switch component:

  • size: Determines the size of the switch. Options: xs, sm, md, lg, xl.
  • disabled: If true, the switch is disabled. Options: true, false.
  • checked: Controls the checked state. Options: true, false, null.
  • defaultChecked: Sets the initial checked state. Options: true, false, null.
  • onChange: Callback function when the state changes.
  • className: Additional custom classes for the component.