{
  "name": "angle-slider-controlled-demo",
  "type": "registry:example",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "angle-slider",
    "button"
  ],
  "files": [
    {
      "path": "examples/angle-slider-controlled-demo.tsx",
      "type": "registry:example",
      "content": "\"use client\";\n\nimport { RotateCcwIcon, ShuffleIcon } from \"lucide-react\";\nimport { animate } from \"motion/react\";\nimport * as React from \"react\";\n\nimport {\n  AngleSlider,\n  AngleSliderRange,\n  AngleSliderThumb,\n  AngleSliderTrack,\n  AngleSliderValue,\n} from \"@/registry/bases/radix/ui/angle-slider\";\nimport { Button } from \"@/registry/bases/radix/ui/button\";\n\nexport default function AngleSliderControlledDemo() {\n  const [value, setValue] = React.useState([180]);\n  const animationRef = React.useRef<ReturnType<typeof animate> | null>(null);\n\n  const animateToValue = React.useCallback(\n    (targetValue: number) => {\n      if (animationRef.current) {\n        animationRef.current.stop();\n      }\n\n      const currentValue = value[0] ?? 0;\n\n      let diff = targetValue - currentValue;\n      if (diff > 180) {\n        diff -= 360;\n      } else if (diff < -180) {\n        diff += 360;\n      }\n\n      animationRef.current = animate(0, diff, {\n        duration: 0.4,\n        ease: [0.25, 0.46, 0.45, 0.94],\n        onUpdate: (progress: number) => {\n          const animatedValue = currentValue + progress;\n          const normalizedValue = Math.round(\n            ((animatedValue % 360) + 360) % 360,\n          );\n          setValue([normalizedValue]);\n        },\n        onComplete: () => {\n          setValue([targetValue]);\n          animationRef.current = null;\n        },\n      });\n    },\n    [value],\n  );\n\n  const onReset = React.useCallback(() => {\n    animateToValue(0);\n  }, [animateToValue]);\n\n  const onRandomize = React.useCallback(() => {\n    animateToValue(Math.floor(Math.random() * 360));\n  }, [animateToValue]);\n\n  React.useEffect(() => {\n    return () => {\n      if (animationRef.current) {\n        animationRef.current.stop();\n      }\n    };\n  }, []);\n\n  return (\n    <div className=\"flex flex-col gap-4\">\n      <div className=\"flex items-center gap-3\">\n        <Button variant=\"outline\" size=\"sm\" onClick={onReset}>\n          <RotateCcwIcon />\n          Reset\n        </Button>\n        <Button size=\"sm\" onClick={onRandomize}>\n          <ShuffleIcon />\n          Randomize\n        </Button>\n      </div>\n      <AngleSlider\n        value={value}\n        onValueChange={setValue}\n        max={360}\n        min={0}\n        step={1}\n        size={80}\n      >\n        <AngleSliderTrack>\n          <AngleSliderRange />\n        </AngleSliderTrack>\n        <AngleSliderThumb />\n        <AngleSliderValue />\n      </AngleSlider>\n    </div>\n  );\n}\n",
      "target": ""
    }
  ]
}