{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-abort-controller-demo",
  "title": "UseAbortControllerDemo",
  "description": "use-abort-controller's hook in action.",
  "registryDependencies": [
    "button",
    "card",
    "badge",
    "https://guarahooks.com/r/use-abort-controller.json"
  ],
  "files": [
    {
      "path": "registry/example/use-abort-controller-demo.tsx",
      "content": "'use client';\n\nimport React, { useState } from 'react';\n\nimport { DownloadIcon, Loader2Icon, RefreshCwIcon, XIcon } from 'lucide-react';\n\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from '@/components/ui/card';\n\nimport { useAbortController } from '@/hooks/guarahooks/use-abort-controller';\n\ninterface Post {\n  userId: number;\n  id: number;\n  title: string;\n  body: string;\n}\n\ninterface HttpBinResponse {\n  args: Record<string, string>;\n  data: string;\n  files: Record<string, string>;\n  form: Record<string, string>;\n  headers: Record<string, string>;\n  json: Record<string, string | number | boolean | null> | null;\n  origin: string;\n  url: string;\n}\n\nexport default function UseAbortControllerDemo() {\n  const [fetchStatus, setFetchStatus] = useState<\n    'idle' | 'loading' | 'success' | 'error' | 'aborted'\n  >('idle');\n  const [data, setData] = useState<Post | HttpBinResponse | null>(null);\n  const [error, setError] = useState<string | null>(null);\n\n  const {\n    signal,\n    abort,\n    reset,\n    fetch: abortableFetch,\n    aborted,\n  } = useAbortController();\n\n  const handleFetch = async () => {\n    setFetchStatus('loading');\n    setError(null);\n    setData(null);\n\n    try {\n      // Simulate a slow API call\n      const response = await abortableFetch(\n        'https://jsonplaceholder.typicode.com/posts/1',\n      );\n\n      if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`);\n      }\n\n      const result: Post = await response.json();\n      setData(result);\n      setFetchStatus('success');\n    } catch (err: unknown) {\n      if (err instanceof Error && err.name === 'AbortError') {\n        setFetchStatus('aborted');\n        setError('Request was aborted');\n      } else {\n        setFetchStatus('error');\n        setError(err instanceof Error ? err.message : 'An error occurred');\n      }\n    }\n  };\n\n  const handleLongFetch = async () => {\n    setFetchStatus('loading');\n    setError(null);\n    setData(null);\n\n    try {\n      // Simulate a very slow API call using httpbin delay\n      const response = await abortableFetch('https://httpbin.org/delay/5');\n\n      if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`);\n      }\n\n      const result: HttpBinResponse = await response.json();\n      setData(result);\n      setFetchStatus('success');\n    } catch (err: unknown) {\n      if (err instanceof Error && err.name === 'AbortError') {\n        setFetchStatus('aborted');\n        setError('Long request was aborted');\n      } else {\n        setFetchStatus('error');\n        setError(err instanceof Error ? err.message : 'An error occurred');\n      }\n    }\n  };\n\n  const handleAbort = () => {\n    abort('User cancelled the request');\n  };\n\n  const handleReset = () => {\n    reset();\n    setFetchStatus('idle');\n    setError(null);\n    setData(null);\n  };\n\n  const getStatusBadge = () => {\n    switch (fetchStatus) {\n      case 'loading':\n        return <Badge variant=\"secondary\">Loading</Badge>;\n      case 'success':\n        return <Badge variant=\"default\">Success</Badge>;\n      case 'error':\n        return <Badge variant=\"destructive\">Error</Badge>;\n      case 'aborted':\n        return <Badge variant=\"outline\">Aborted</Badge>;\n      default:\n        return <Badge variant=\"outline\">Idle</Badge>;\n    }\n  };\n\n  return (\n    <div className=\"w-full max-w-2xl mx-auto space-y-6\">\n      <Card>\n        <CardHeader>\n          <CardTitle className=\"flex items-center gap-2\">\n            <DownloadIcon className=\"h-5 w-5\" />\n            Abort Controller Demo\n          </CardTitle>\n          <CardDescription>\n            Demonstrates canceling HTTP requests using AbortController\n          </CardDescription>\n        </CardHeader>\n        <CardContent className=\"space-y-4\">\n          {/* Status display */}\n          <div className=\"flex items-center gap-4\">\n            <span className=\"text-sm font-medium\">Status:</span>\n            {getStatusBadge()}\n            {aborted && <Badge variant=\"outline\">Controller Aborted</Badge>}\n          </div>\n\n          {/* Action buttons */}\n          <div className=\"flex flex-wrap gap-2\">\n            <Button\n              onClick={handleFetch}\n              disabled={fetchStatus === 'loading'}\n              variant=\"default\"\n            >\n              {fetchStatus === 'loading' ? (\n                <Loader2Icon className=\"h-4 w-4 animate-spin mr-2\" />\n              ) : (\n                <DownloadIcon className=\"h-4 w-4 mr-2\" />\n              )}\n              Quick Fetch\n            </Button>\n\n            <Button\n              onClick={handleLongFetch}\n              disabled={fetchStatus === 'loading'}\n              variant=\"secondary\"\n            >\n              {fetchStatus === 'loading' ? (\n                <Loader2Icon className=\"h-4 w-4 animate-spin mr-2\" />\n              ) : (\n                <DownloadIcon className=\"h-4 w-4 mr-2\" />\n              )}\n              Long Fetch (5s)\n            </Button>\n\n            <Button\n              onClick={handleAbort}\n              disabled={fetchStatus !== 'loading'}\n              variant=\"destructive\"\n            >\n              <XIcon className=\"h-4 w-4 mr-2\" />\n              Abort\n            </Button>\n\n            <Button\n              onClick={handleReset}\n              disabled={fetchStatus === 'loading'}\n              variant=\"outline\"\n            >\n              <RefreshCwIcon className=\"h-4 w-4 mr-2\" />\n              Reset\n            </Button>\n          </div>\n\n          {/* Results display */}\n          {error && (\n            <div className=\"p-4 bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-800 rounded-lg\">\n              <p className=\"text-sm text-red-600 dark:text-red-400\">\n                <strong>Error:</strong> {error}\n              </p>\n            </div>\n          )}\n\n          {data && (\n            <div className=\"p-4 bg-green-50 dark:bg-green-950/20 border border-green-200 dark:border-green-800 rounded-lg\">\n              <p className=\"text-sm text-green-600 dark:text-green-400 mb-2\">\n                <strong>Success!</strong> Data received:\n              </p>\n              <pre className=\"text-xs bg-white dark:bg-gray-900 p-2 rounded border overflow-x-auto\">\n                {JSON.stringify(data, null, 2)}\n              </pre>\n            </div>\n          )}\n\n          <div className=\"text-xs text-muted-foreground space-y-1\">\n            <p>\n              • <strong>Quick Fetch:</strong> Fast request that completes\n              immediately\n            </p>\n            <p>\n              • <strong>Long Fetch:</strong> 5-second delay to test cancellation\n            </p>\n            <p>\n              • <strong>Abort:</strong> Cancel the current request\n            </p>\n            <p>\n              • <strong>Reset:</strong> Create a new controller and clear state\n            </p>\n            <p>\n              • <strong>Auto-abort:</strong> Requests are automatically aborted\n              when component unmounts\n            </p>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  );\n}\n",
      "type": "registry:example",
      "target": "components/example/use-abort-controller-demo.tsx"
    }
  ],
  "type": "registry:example"
}