{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitives-headless-switch",
  "title": "Headless Switch",
  "description": "Switches are a pleasant interface for toggling a value between two states, and offer the same semantics and keyboard navigation as native checkbox elements.",
  "dependencies": [
    "motion",
    "@headlessui/react"
  ],
  "registryDependencies": [
    "@animate-ui/lib-get-strict-context"
  ],
  "files": [
    {
      "path": "registry/primitives/headless/switch/index.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport {\n  Switch as SwitchPrimitive,\n  type SwitchProps as SwitchPrimitiveProps,\n} from '@headlessui/react';\nimport {\n  motion,\n  type TargetAndTransition,\n  type VariantLabels,\n  type HTMLMotionProps,\n  type LegacyAnimationControls,\n} from 'motion/react';\n\nimport { getStrictContext } from '@/lib/get-strict-context';\n\ntype SwitchContextType = {\n  isChecked: boolean;\n  isPressed: boolean;\n};\n\nconst [SwitchProvider, useSwitch] =\n  getStrictContext<SwitchContextType>('SwitchContext');\n\ntype SwitchProps<TTag extends React.ElementType = typeof motion.button> =\n  SwitchPrimitiveProps<TTag> &\n    HTMLMotionProps<'button'> & {\n      as?: TTag;\n    };\n\nfunction Switch<TTag extends React.ElementType = typeof motion.button>(\n  props: SwitchProps<TTag>,\n) {\n  const { as = motion.button, children, ...rest } = props;\n\n  const [isPressed, setIsPressed] = React.useState(false);\n\n  return (\n    <SwitchPrimitive\n      data-slot=\"switch\"\n      whileTap=\"tap\"\n      initial={false}\n      onTapStart={() => setIsPressed(true)}\n      onTapCancel={() => setIsPressed(false)}\n      onTap={() => setIsPressed(false)}\n      {...rest}\n      as={as}\n    >\n      {(bag) => (\n        <SwitchProvider value={{ isPressed, isChecked: bag.checked }}>\n          {typeof children === 'function' ? children(bag) : children}\n        </SwitchProvider>\n      )}\n    </SwitchPrimitive>\n  );\n}\n\ntype SwitchThumbProps<TTag extends React.ElementType = typeof motion.div> =\n  HTMLMotionProps<'div'> & {\n    as?: TTag;\n    pressedAnimation?:\n      | TargetAndTransition\n      | VariantLabels\n      | boolean\n      | LegacyAnimationControls;\n  };\n\nfunction SwitchThumb<TTag extends React.ElementType = typeof motion.div>(\n  props: SwitchThumbProps<TTag>,\n) {\n  const { isPressed, isChecked } = useSwitch();\n\n  const {\n    transition = { type: 'spring', stiffness: 300, damping: 25 },\n    pressedAnimation,\n    as: Component = motion.div,\n    ...rest\n  } = props;\n\n  return (\n    <Component\n      data-slot=\"switch-thumb\"\n      whileTap=\"tab\"\n      layout\n      transition={transition}\n      animate={isPressed ? pressedAnimation : undefined}\n      {...(isChecked && { 'data-checked': true })}\n      {...rest}\n    />\n  );\n}\n\ntype SwitchIconPosition = 'left' | 'right' | 'thumb';\n\ntype SwitchIconProps<TTag extends React.ElementType = typeof motion.div> =\n  HTMLMotionProps<'div'> & {\n    position: SwitchIconPosition;\n    as?: TTag;\n  };\n\nfunction SwitchIcon<TTag extends React.ElementType = typeof motion.div>(\n  props: SwitchIconProps<TTag>,\n) {\n  const {\n    position,\n    transition = { type: 'spring', bounce: 0 },\n    as: Component = motion.div,\n    ...rest\n  } = props;\n  const { isChecked } = useSwitch();\n\n  const isAnimated = React.useMemo(() => {\n    if (position === 'right') return !isChecked;\n    if (position === 'left') return isChecked;\n    if (position === 'thumb') return true;\n    return false;\n  }, [position, isChecked]);\n\n  return (\n    <Component\n      data-slot={`switch-${position}-icon`}\n      animate={isAnimated ? { scale: 1, opacity: 1 } : { scale: 0, opacity: 0 }}\n      transition={transition}\n      {...rest}\n    />\n  );\n}\n\nexport {\n  Switch,\n  SwitchThumb,\n  SwitchIcon,\n  type SwitchProps,\n  type SwitchThumbProps,\n  type SwitchIconProps,\n};\n",
      "type": "registry:ui",
      "target": "components/animate-ui/primitives/headless/switch.tsx"
    }
  ],
  "type": "registry:ui"
}