{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "switch",
  "title": "Switch",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-react/components/switch/Switch.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport * as SwitchPrimitive from '@radix-ui/react-switch'\nimport { Loader2 } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface SwitchProps\n  extends Omit<React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>, 'children'> {\n  size?: 'sm' | 'default' | 'lg'\n  /** Text shown on the left side when checked. */\n  checkedChildren?: React.ReactNode\n  /** Text shown on the right side when unchecked. */\n  unCheckedChildren?: React.ReactNode\n  loading?: boolean\n  color?: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | string\n  /** Custom content rendered inside the thumb. Receives the checked state. */\n  thumb?: (state: { checked: boolean }) => React.ReactNode\n}\n\nconst colorMap: Record<string, string> = {\n  primary: 'var(--primary)',\n  secondary: 'var(--secondary)',\n  success: 'var(--success)',\n  warning: 'var(--warning)',\n  error: 'var(--destructive)',\n  info: 'var(--info)',\n}\n\nconst thumbSizes = {\n  sm: 'size-3',\n  default: 'size-4',\n  lg: 'size-5',\n}\n\nconst thumbTranslate = {\n  sm: 'data-[state=checked]:translate-x-[calc(100%-2px)]',\n  default: 'data-[state=checked]:translate-x-[calc(100%-2px)]',\n  lg: 'data-[state=checked]:translate-x-[calc(100%-5px)]',\n}\n\nconst textSizes = {\n  sm: 'text-[7px]',\n  default: 'text-xs',\n  lg: 'text-xs',\n}\n\nconst thumbIconSizes = {\n  sm: 'size-2',\n  default: 'size-2.5',\n  lg: 'size-3',\n}\n\nconst Switch = React.forwardRef<React.ElementRef<typeof SwitchPrimitive.Root>, SwitchProps>(\n  (\n    {\n      className,\n      style,\n      size = 'default',\n      checkedChildren,\n      unCheckedChildren,\n      loading,\n      color,\n      disabled,\n      thumb,\n      checked,\n      defaultChecked,\n      onCheckedChange,\n      ...props\n    },\n    ref,\n  ) => {\n    // Track checked state so children-visibility / thumb slot can react in both\n    // controlled and uncontrolled usage (Radix doesn't surface checked to children).\n    const [internalChecked, setInternalChecked] = React.useState<boolean>(defaultChecked ?? false)\n    const isControlled = checked !== undefined\n    const isChecked = isControlled ? !!checked : internalChecked\n\n    const handleChange = React.useCallback(\n      (next: boolean) => {\n        if (!isControlled) setInternalChecked(next)\n        onCheckedChange?.(next)\n      },\n      [isControlled, onCheckedChange],\n    )\n\n    const hasChildren = Boolean(checkedChildren || unCheckedChildren)\n\n    const height = {\n      sm: 'h-4',\n      default: 'h-[1.15rem]',\n      lg: 'h-6',\n    }[size]\n\n    const width = hasChildren\n      ? {\n          sm: 'min-w-8 w-fit',\n          default: 'min-w-10 w-fit',\n          lg: 'min-w-[3.25rem] w-fit',\n        }[size]\n      : {\n          sm: 'w-6',\n          default: 'w-8',\n          lg: 'w-11',\n        }[size]\n\n    const sizeClasses = `${height} ${width}`\n\n    const trackStyle = {\n      ...style,\n      '--switch-checked-bg': color ? colorMap[color] || color : 'var(--primary)',\n    } as React.CSSProperties\n\n    return (\n      <SwitchPrimitive.Root\n        ref={ref}\n        data-slot=\"switch\"\n        disabled={disabled || loading}\n        checked={checked}\n        defaultChecked={defaultChecked}\n        onCheckedChange={handleChange}\n        className={cn(\n          'peer focus-visible:ring-ring/50 focus-visible:border-ring data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80 relative inline-flex shrink-0 items-center overflow-hidden rounded-full border border-transparent shadow-xs transition-[background-color,border-color,box-shadow] duration-150 outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-[var(--switch-checked-bg)]',\n          sizeClasses,\n          className,\n        )}\n        style={trackStyle}\n        {...props}\n      >\n        {/* Checked children (left side, visible when checked) */}\n        {hasChildren && (\n          <div\n            className={cn(\n              'pointer-events-none absolute inset-y-0 left-0 flex items-center pl-1 transition-opacity duration-150',\n              isChecked ? 'opacity-100' : 'opacity-0',\n              textSizes[size],\n            )}\n          >\n            <span className=\"text-primary-foreground truncate font-medium\">{checkedChildren}</span>\n          </div>\n        )}\n\n        {/* Unchecked children (right side, visible when unchecked) */}\n        {hasChildren && (\n          <div\n            className={cn(\n              'pointer-events-none absolute inset-y-0 right-0 flex items-center pr-1 transition-opacity duration-150',\n              !isChecked ? 'opacity-100' : 'opacity-0',\n              textSizes[size],\n            )}\n          >\n            <span className=\"text-muted-foreground truncate font-medium\">{unCheckedChildren}</span>\n          </div>\n        )}\n\n        <SwitchPrimitive.Thumb\n          data-uipkge=\"\"\n          data-slot=\"switch-thumb\"\n          className={cn(\n            'bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none z-10 block rounded-full ring-0 transition-transform duration-200 ease-[cubic-bezier(0.34,1.56,0.64,1)] data-[state=unchecked]:translate-x-0',\n            thumbSizes[size],\n            thumbTranslate[size],\n          )}\n        >\n          {loading ? (\n            <Loader2 className={cn(thumbIconSizes[size], 'text-muted-foreground animate-spin')} />\n          ) : (\n            thumb?.({ checked: isChecked })\n          )}\n        </SwitchPrimitive.Thumb>\n      </SwitchPrimitive.Root>\n    )\n  },\n)\nSwitch.displayName = 'Switch'\n\nexport { Switch }\n",
      "type": "registry:ui",
      "target": "~/components/ui/switch/Switch.tsx"
    },
    {
      "path": "packages/registry-react/components/switch/index.ts",
      "content": "export { Switch, type SwitchProps } from './Switch'\n",
      "type": "registry:ui",
      "target": "~/components/ui/switch/index.ts"
    }
  ],
  "dependencies": [
    "@radix-ui/react-switch",
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "On/off toggle — visual analog of a hardware switch. Use for binary settings where the change takes effect immediately, not for form fields that submit later (use Checkbox there).",
  "categories": [
    "form"
  ]
}