{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "code-block",
  "dependencies": [
    "shiki"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "./components/ui/code-block.tsx",
      "content": "'use client';\n\nimport { CopyButton } from '@/components/website/code-components/copy-button';\nimport { cn } from '@/lib/utils';\nimport { useEffect, useState } from 'react';\nimport { codeToHtml } from 'shiki/bundle/web';\n\nexport function CodeBlock({\n  code,\n  lang = 'tsx',\n  className,\n}: {\n  code: string;\n  lang?: string;\n  className?: string;\n}) {\n  const [html, setHtml] = useState('');\n  const [isLoading, setIsLoading] = useState(true);\n\n  useEffect(() => {\n    let cancelled = false;\n\n    const highlightCode = async () => {\n      try {\n        const highlightedHtml = await codeToHtml(code, {\n          lang,\n          themes: { light: 'github-light', dark: 'slack-dark' },\n        });\n\n        if (!cancelled) {\n          setHtml(highlightedHtml);\n          setIsLoading(false);\n        }\n      } catch (error) {\n        console.error('Error highlighting code:', error);\n        if (!cancelled) {\n          setIsLoading(false);\n        }\n      }\n    };\n\n    highlightCode();\n\n    return () => {\n      cancelled = true;\n    };\n  }, [code, lang]);\n\n  if (isLoading) {\n    return (\n      <div className={cn('relative', className)}>\n        <div className='p-6 w-full mx-auto h-[400px] dark:bg-neutral-800 bg-neutral-200 animate-pulse rounded-xl'></div>\n      </div>\n    );\n  }\n\n  return (\n    <div className={cn('relative', className)}>\n      <CopyButton code={code} classname='right-2 top-2 bg-white dark:bg-neutral-800' />\n\n      <div\n        className='not-prose max-h-[550px] overflow-x-hidden rounded-md text-sm border dark:border-neutral-800'\n        dangerouslySetInnerHTML={{ __html: html }}\n      />\n    </div>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "./components/website/code-components/copy-button.tsx",
      "content": "'use client';\n\nimport { cn } from '@/lib/utils';\nimport { Check, CheckCheck, Copy } from 'lucide-react';\nimport { useState } from 'react';\n\nexport function CopyButton({ code, classname }: { code: string; classname?: string }) {\n  const [hasCheckIcon, setHasCheckIcon] = useState(false);\n\n  const onCopy = () => {\n    navigator.clipboard.writeText(code);\n    setHasCheckIcon(true);\n\n    setTimeout(() => {\n      setHasCheckIcon(false);\n    }, 1000);\n  };\n\n  return (\n    <>\n      <div\n        className={cn(\n          'absolute right-2 top-2 cursor-pointer dark:hover:shadow-[0px_1px_10px_5px_#3f7ef3] hover:shadow-[0px_1px_10px_5px_#9abaf7] dark:hover:border-blue-500 hover:border-blue-300  dark:bg-zinc-800 backdrop-blur-2xl bg-white rounded-md border-2',\n          classname\n        )}\n        onClick={onCopy}\n      >\n        <div\n          className={` inset-0 transform transition-all duration-300  w-9 h-8 grid place-content-center  ${\n            hasCheckIcon ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n          }`}\n        >\n          <Copy className='h-4 w-4 text-foreground/80' />\n        </div>\n        <div\n          className={`absolute inset-0 transform transition-all duration-300 w-8 h-8 grid place-content-center  ${\n            hasCheckIcon ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n          }`}\n        >\n          <CheckCheck className='h-4 w-4 text-foreground/80' />\n        </div>\n      </div>\n    </>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}