{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "toggles-neon",
  "title": "Neon toggles",
  "description": "Styled toggles: the Neon set. 5 decorative toggles variations (NeonToggle, OutlineNeonToggle, PulseNeonToggle, TubeToggle, FlickerToggle) on the ai2 token system, powered by framer-motion, reduced-motion aware and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "motion@^12.42.2"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/toggles-neon.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { motion, useReducedMotion } from \"motion/react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Neon toggle family: 5 glowing switches. role=\"switch\", keyboard accessible. The\n   color and the glow come ONLY from tokens (box-shadow). The thumb slides with the\n   framer-motion `layout` and switches instantly under reduced-motion; the continuous\n   flicker/pulse stops under reduced-motion. Used uncontrolled (defaultChecked) or\n   controlled. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst trackSize: Record<StyledSize, string> = {\n  sm: \"h-5 w-9 p-0.5\",\n  md: \"h-6 w-11 p-0.5\",\n  lg: \"h-7 w-[52px] p-1\",\n  xl: \"h-8 w-[60px] p-1\",\n}\nconst thumbSize: Record<StyledSize, string> = {\n  sm: \"size-4\",\n  md: \"size-5\",\n  lg: \"size-5\",\n  xl: \"size-6\",\n}\n\nconst trackBase =\n  \"relative inline-flex shrink-0 cursor-pointer items-center outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50\"\n\ninterface ToggleProps extends Omit<React.ComponentProps<\"button\">, \"onChange\"> {\n  size?: StyledSize\n  checked?: boolean\n  defaultChecked?: boolean\n  onCheckedChange?: (checked: boolean) => void\n}\n\nfunction useToggle(props: ToggleProps) {\n  const { checked, defaultChecked, onCheckedChange } = props\n  const reduce = useReducedMotion()\n  const [internal, setInternal] = React.useState(defaultChecked ?? false)\n  const on = checked ?? internal\n  const toggle = () => {\n    if (checked === undefined) setInternal((v) => !v)\n    onCheckedChange?.(!on)\n  }\n  const spring = reduce ? { duration: 0 } : ({ type: \"spring\", stiffness: 500, damping: 30 } as const)\n  return { on, toggle, spring }\n}\n\nfunction stripToggleProps(props: ToggleProps) {\n  const { checked, defaultChecked, onCheckedChange, size, className, children, ...rest } = props\n  return rest\n}\n\n/* Neon: acikken izin cevresinde token neon isima. */\nexport function NeonToggle(props: ToggleProps) {\n  const { on, toggle, spring } = useToggle(props)\n  const size = props.size ?? \"md\"\n  return (\n    <button\n      type=\"button\"\n      role=\"switch\"\n      aria-checked={on}\n      data-slot=\"styled-toggle\"\n      onClick={toggle}\n      className={cn(trackBase, trackSize[size], \"rounded-full transition-[background-color,box-shadow]\", on ? \"justify-end bg-info\" : \"justify-start bg-input\", props.className)}\n      style={on ? { boxShadow: \"0 0 12px 2px color-mix(in oklab, var(--info) 70%, transparent)\" } : undefined}\n      {...stripToggleProps(props)}\n    >\n      <motion.span layout transition={spring} className={cn(thumbSize[size], \"rounded-full bg-background shadow-sm\")} />\n    </button>\n  )\n}\n\n/* OutlineNeon: a token line outline that glows while on. */\nexport function OutlineNeonToggle(props: ToggleProps) {\n  const { on, toggle, spring } = useToggle(props)\n  const size = props.size ?? \"md\"\n  return (\n    <button\n      type=\"button\"\n      role=\"switch\"\n      aria-checked={on}\n      data-slot=\"styled-toggle\"\n      onClick={toggle}\n      className={cn(\n        trackBase,\n        trackSize[size],\n        \"rounded-full border-2 bg-transparent transition-[border-color,box-shadow]\",\n        on ? \"justify-end border-success\" : \"justify-start border-field-border\",\n        props.className\n      )}\n      style={on ? { boxShadow: \"0 0 8px 1px color-mix(in oklab, var(--success) 65%, transparent), inset 0 0 6px 0 color-mix(in oklab, var(--success) 40%, transparent)\" } : undefined}\n      {...stripToggleProps(props)}\n    >\n      <motion.span layout transition={spring} className={cn(thumbSize[size], \"rounded-full\", on ? \"bg-success\" : \"bg-input\")} />\n    </button>\n  )\n}\n\n/* PulseNeon: acikken iz token isimayi nabiz gibi atar. */\nexport function PulseNeonToggle(props: ToggleProps) {\n  const { on, toggle, spring } = useToggle(props)\n  const reduce = useReducedMotion()\n  const size = props.size ?? \"md\"\n  const animate =\n    on && !reduce\n      ? {\n          boxShadow: [\n            \"0 0 6px 1px color-mix(in oklab, var(--primary) 45%, transparent)\",\n            \"0 0 16px 3px color-mix(in oklab, var(--primary) 80%, transparent)\",\n            \"0 0 6px 1px color-mix(in oklab, var(--primary) 45%, transparent)\",\n          ],\n        }\n      : { boxShadow: on ? \"0 0 12px 2px color-mix(in oklab, var(--primary) 70%, transparent)\" : \"0 0 0px 0px transparent\" }\n  return (\n    <button\n      type=\"button\"\n      role=\"switch\"\n      aria-checked={on}\n      data-slot=\"styled-toggle\"\n      onClick={toggle}\n      className={cn(trackBase, trackSize[size], \"rounded-full transition-colors\", on ? \"justify-end bg-primary\" : \"justify-start bg-input\", props.className)}\n      {...stripToggleProps(props)}\n    >\n      <motion.span\n        aria-hidden\n        className=\"pointer-events-none absolute inset-0 rounded-full\"\n        animate={animate}\n        transition={on && !reduce ? { duration: 1.4, repeat: Infinity, ease: \"easeInOut\" } : { duration: 0 }}\n      />\n      <motion.span layout transition={spring} className={cn(thumbSize[size], \"relative z-10 rounded-full bg-background shadow-sm\")} />\n    </button>\n  )\n}\n\n/* Tube: a neon-tube look, with a thumb glowing at its ends. */\nexport function TubeToggle(props: ToggleProps) {\n  const { on, toggle, spring } = useToggle(props)\n  const size = props.size ?? \"md\"\n  return (\n    <button\n      type=\"button\"\n      role=\"switch\"\n      aria-checked={on}\n      data-slot=\"styled-toggle\"\n      onClick={toggle}\n      className={cn(\n        trackBase,\n        trackSize[size],\n        \"rounded-full border transition-[background-color,box-shadow]\",\n        on ? \"justify-end border-info bg-info/20\" : \"justify-start border-field-border bg-input\",\n        props.className\n      )}\n      style={on ? { boxShadow: \"0 0 10px 1px color-mix(in oklab, var(--info) 60%, transparent), inset 0 0 8px 0 color-mix(in oklab, var(--info) 55%, transparent)\" } : undefined}\n      {...stripToggleProps(props)}\n    >\n      <motion.span\n        layout\n        transition={spring}\n        className={cn(thumbSize[size], \"rounded-full\", on ? \"bg-info\" : \"bg-background\")}\n        style={on ? { boxShadow: \"0 0 8px 1px color-mix(in oklab, var(--info) 75%, transparent)\" } : undefined}\n      />\n    </button>\n  )\n}\n\n/* Flicker: acikken isimada ince neon titremesi. */\nexport function FlickerToggle(props: ToggleProps) {\n  const { on, toggle, spring } = useToggle(props)\n  const reduce = useReducedMotion()\n  const size = props.size ?? \"md\"\n  const animate = on && !reduce ? { opacity: [1, 0.6, 1, 0.8, 1] } : { opacity: on ? 1 : 0 }\n  return (\n    <button\n      type=\"button\"\n      role=\"switch\"\n      aria-checked={on}\n      data-slot=\"styled-toggle\"\n      onClick={toggle}\n      className={cn(trackBase, trackSize[size], \"rounded-full transition-colors\", on ? \"justify-end bg-success\" : \"justify-start bg-input\", props.className)}\n      {...stripToggleProps(props)}\n    >\n      <motion.span\n        aria-hidden\n        className=\"pointer-events-none absolute inset-0 rounded-full\"\n        style={{ boxShadow: \"0 0 12px 2px color-mix(in oklab, var(--success) 70%, transparent)\" }}\n        animate={animate}\n        transition={on && !reduce ? { duration: 1.1, repeat: Infinity, ease: \"easeInOut\", times: [0, 0.2, 0.4, 0.7, 1] } : { duration: 0 }}\n      />\n      <motion.span layout transition={spring} className={cn(thumbSize[size], \"relative z-10 rounded-full bg-background shadow-sm\")} />\n    </button>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/toggles-neon.tsx"
    }
  ],
  "categories": [
    "styled",
    "toggles"
  ],
  "type": "registry:component"
}