Switch
A control that allows the user to toggle between checked and not checked.
Bundle Size Impact
this1.22 KB
shadcn11.42 KB(+834%)
baseui12.56 KB(+927%)
headlessui13.79 KB(+1027%)
chakraui29.07 KB(+2276%)
heroui29.46 KB(+2307%)
material36.6 KB(+2891%)
antd38.09 KB(+3013%)
Install
pnpm dlx shadcn@latest add https://p.livog.com/r/switch.json
Code
import { useId, type CSSProperties, type ComponentPropsWithoutRef, type ReactNode } from 'react'
import clsx from 'clsx'
export type SwitchProps = Omit<ComponentPropsWithoutRef<'input'>, 'size'> & {
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
enabledIcon?: ReactNode
disabledIcon?: ReactNode
}
export function Switch({
size = 'sm',
disabled = false,
id,
className,
style: styleProp,
checked,
defaultChecked,
enabledIcon,
disabledIcon,
...props
}: SwitchProps) {
const autoId = useId()
const generatedId = id ?? autoId
const style: CSSProperties & { [key: `--${string}`]: string | number } = { ...(styleProp ?? {}) }
const sizeValues = {
xs: '1rem',
sm: '1.25rem',
md: '1.5rem',
lg: '1.875rem',
xl: '2rem'
}
const sizeValue = sizeValues[size] ?? sizeValues.md
if (size !== 'md') style['--size'] = sizeValue
const controlProps = checked !== undefined ? { checked } : { defaultChecked }
if (enabledIcon || disabledIcon) {
return (
<label htmlFor={generatedId} className={clsx('switch', className)} style={style}>
<input
type="checkbox"
id={generatedId}
disabled={disabled}
{...props}
{...controlProps}
/>
{disabledIcon}
{enabledIcon}
</label>
)
}
return (
<input
type="checkbox"
id={generatedId}
className={clsx('switch peer', className)}
disabled={disabled}
style={style}
{...props}
{...controlProps}
/>
)
}
export default Switch