Switch

Checkboxes let users select one or more items from a list, or turn an item on or off

Usage

Switches are best used to adjust settings and other standalone options. They make a binary selection, like on and off or true and false.

The effects of a switch should start immediately without needing to save.

Instalation

Run the following command if is not already installed:

npm i @radix-ui/react-switch

Copy and paste the following code into your project.

'use client'

import * as React from 'react'
import * as SwitchPrimitives from '@radix-ui/react-switch'

import { cn } from '@/lib/utils'
import { Icon } from '@/components/ui/icon'

const Switch = React.forwardRef<
  React.ElementRef<typeof SwitchPrimitives.Root>,
  React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> & {
    widthIconOnChecked?: boolean
    withIcons?: boolean
    customIcons?: {
      unChecked?: React.ReactNode
      checked?: React.ReactNode
    }
  }
>(
  (
    { className, widthIconOnChecked, withIcons, customIcons, ...props },
    ref
  ) => (
    <SwitchPrimitives.Root
      ref={ref}
      className={cn(
        'group peer inline-flex h-8 w-[52px] shrink-0 cursor-pointer items-center rounded-full border-2 border-outline bg-surfaceContainerHighest focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/38 focus-visible:ring-offset-2 focus-visible:ring-offset-surface disabled:cursor-not-allowed disabled:border-onSurface/12 disabled:bg-surfaceContainerHighest/12 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:disabled:border-transparent data-[state=checked]:disabled:bg-onSurface/12',
        className
      )}
      {...props}
    >
      <SwitchPrimitives.Thumb
        className={cn(
          'pointer-events-none flex aspect-square h-4 items-center justify-center rounded-full bg-outline ring-0 transition-[transform,width,height] group-active:scale-125 group-disabled:bg-onSurface/38 data-[state=checked]:h-6 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-1.5 data-[state=checked]:bg-onPrimary data-[state=unchecked]:group-active:scale-[1.8] data-[state=checked]:group-disabled:bg-surface',
          withIcons &&
            'h-6 data-[state=unchecked]:translate-x-0.5 data-[state=unchecked]:group-active:scale-125'
        )}
      >
        {(widthIconOnChecked || withIcons) && (
          <>
            <span className="hidden text-onPrimaryContainer animate-in zoom-in-0 group-disabled:text-onSurface group-disabled:opacity-38 group-data-[state=checked]:flex [&>i]:text-[16px] [&>svg]:h-4 [&>svg]:w-4">
              {customIcons?.checked || <Icon symbol="check" />}
            </span>
            {withIcons && (
              <span className="hidden text-surfaceContainerHighest animate-in zoom-in-0 group-disabled:text-surface group-data-[state=unchecked]:flex [&>i]:text-[16px] [&>svg]:h-4 [&>svg]:w-4">
                {customIcons?.unChecked || <Icon symbol="close" />}
              </span>
            )}
          </>
        )}
      </SwitchPrimitives.Thumb>
    </SwitchPrimitives.Root>
  )
)
Switch.displayName = SwitchPrimitives.Root.displayName

export { Switch }

Update the import paths to match your project setup.

Examples

Simple switch

import { Switch } from '@/components/ui/switch'

export const SimpleSwitch = () => {
  return <Switch />
}

With selected icon

The switch handle can contain an optional icon.

import { Switch } from '@/components/ui/switch'

export const SwitchWithCheckedIcon = () => {
  return <Switch widthIconOnChecked />
}

With icons

Icons can be used to visually emphasize the switch’s selected state.

import { Switch } from '@/components/ui/switch'

export const SwitchWithIcons = () => {
  return <Switch withIcons />
}

With custom icons

The icon’s meaning should be clear and unambiguous to help the user understand whether switch is on or off.

import { Switch } from '@/components/ui/switch'

export const SimpleSwitch = () => {
  return (
    <Switch
      withIcons
      customIcons={{
        unChecked: <Icon symbol="check_indeterminate_small" />,
        checked: <Icon symbol="check" />,
      }}
    />
  )
}