{
  "name": "circular-progress-interactive-demo",
  "type": "registry:example",
  "registryDependencies": [
    "button",
    "circular-progress"
  ],
  "files": [
    {
      "path": "examples/circular-progress-interactive-demo.tsx",
      "type": "registry:example",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Button } from \"@/registry/bases/radix/ui/button\";\nimport {\n  CircularProgress,\n  CircularProgressIndicator,\n  CircularProgressRange,\n  CircularProgressTrack,\n  CircularProgressValueText,\n} from \"@/registry/bases/radix/ui/circular-progress\";\n\nexport default function CircularProgressControlledDemo() {\n  const [uploadProgress, setUploadProgress] = React.useState<number | null>(0);\n  const [isUploading, setIsUploading] = React.useState(false);\n  const intervalRef = React.useRef<NodeJS.Timeout | null>(null);\n\n  const onUploadStart = React.useCallback(() => {\n    setIsUploading(true);\n    setUploadProgress(0);\n  }, []);\n\n  const onUploadReset = React.useCallback(() => {\n    setUploadProgress(0);\n    setIsUploading(false);\n    if (intervalRef.current) {\n      clearInterval(intervalRef.current);\n      intervalRef.current = null;\n    }\n  }, []);\n\n  React.useEffect(() => {\n    if (isUploading) {\n      intervalRef.current = setInterval(() => {\n        setUploadProgress((prev) => {\n          if (prev === null) return 0;\n          if (prev >= 100) {\n            if (intervalRef.current) {\n              clearInterval(intervalRef.current);\n              intervalRef.current = null;\n            }\n            setIsUploading(false);\n            return 100;\n          }\n          return Math.min(100, prev + Math.random() * 15);\n        });\n      }, 200);\n    }\n\n    return () => {\n      if (intervalRef.current) {\n        clearInterval(intervalRef.current);\n        intervalRef.current = null;\n      }\n    };\n  }, [isUploading]);\n\n  return (\n    <div className=\"flex flex-col items-center gap-6\">\n      <div className=\"flex items-center gap-6\">\n        <CircularProgress\n          value={uploadProgress}\n          min={0}\n          max={100}\n          size={80}\n          thickness={6}\n        >\n          <CircularProgressIndicator>\n            <CircularProgressTrack />\n            <CircularProgressRange />\n          </CircularProgressIndicator>\n          <CircularProgressValueText className=\"text-base font-semibold\" />\n        </CircularProgress>\n        <div className=\"flex flex-col gap-2\">\n          <div className=\"text-sm font-medium\">Upload Progress</div>\n          <div className=\"text-xs text-muted-foreground\">\n            Status:{\" \"}\n            {isUploading\n              ? \"Uploading...\"\n              : uploadProgress === 100\n                ? \"Complete\"\n                : \"Ready\"}\n          </div>\n          <div className=\"text-xs text-muted-foreground\">\n            Progress:{\" \"}\n            {uploadProgress === null\n              ? \"Indeterminate\"\n              : `${Math.round(uploadProgress)}%`}\n          </div>\n        </div>\n      </div>\n      <div className=\"flex items-center gap-2\">\n        <Button size=\"sm\" onClick={onUploadStart} disabled={isUploading}>\n          Start upload\n        </Button>\n        <Button size=\"sm\" onClick={onUploadReset} disabled={isUploading}>\n          Reset\n        </Button>\n        <Button\n          variant=\"secondary\"\n          size=\"sm\"\n          onClick={() => setUploadProgress(null)}\n          disabled={isUploading}\n        >\n          Indeterminate\n        </Button>\n      </div>\n    </div>\n  );\n}\n",
      "target": ""
    }
  ]
}