{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "aurora-ai-snippet",
  "title": "Aurora AI Snippet",
  "author": "jmagar <https://github.com/jmagar>",
  "description": "Aurora-native snippet parity surface from AI Elements.",
  "dependencies": [
    "lucide-react@^0.487.0"
  ],
  "registryDependencies": [
    "@aurora/aurora-tokens",
    "@aurora/aurora-ai-elements"
  ],
  "files": [
    {
      "path": "registry/aurora/blocks/ai/elements/snippet.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Check, CodeXml, Copy } from \"lucide-react\"\nimport { Badge } from \"@/registry/aurora/ui/badge\"\nimport { Button } from \"@/registry/aurora/ui/button\"\nimport { useClipboard } from \"@/registry/aurora/lib/use-clipboard\"\n\nexport interface SnippetProps extends React.HTMLAttributes<HTMLPreElement> {\n  code: string\n  /** Short language identifier shown in the header chip (e.g. \"ts\", \"tsx\", \"py\"). */\n  language?: string\n}\n\n/**\n * Lightweight token highlighter that reproduces the Claude Design Snippet\n * coloring: keywords in rose, member/function calls in cyan, numbers in orange,\n * strings in success-teal, everything else in primary text. Deliberately simple\n * (no external grammar) so it stays in sync with the registry token palette.\n */\nconst KEYWORDS = new Set([\n  \"export\",\n  \"import\",\n  \"from\",\n  \"default\",\n  \"const\",\n  \"let\",\n  \"var\",\n  \"function\",\n  \"async\",\n  \"await\",\n  \"return\",\n  \"if\",\n  \"else\",\n  \"for\",\n  \"while\",\n  \"new\",\n  \"class\",\n  \"extends\",\n  \"typeof\",\n  \"in\",\n  \"of\",\n  \"yield\",\n  \"try\",\n  \"catch\",\n  \"finally\",\n  \"throw\",\n  \"def\",\n  \"lambda\",\n  \"true\",\n  \"false\",\n  \"null\",\n  \"undefined\",\n  \"None\",\n  \"True\",\n  \"False\",\n])\n\nconst TOKEN_RE =\n  /(\\/\\/[^\\n]*|#[^\\n]*)|(\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`)|(\\b\\d[\\d_.]*\\b)|([A-Za-z_$][\\w$]*)|(\\s+)|([^\\s\\w$])/g\n\nfunction tokenColor(word: string, prevSig: string, nextSig: string): string | undefined {\n  if (KEYWORDS.has(word)) return \"var(--aurora-accent-pink)\"\n  // member access (foo.bar) or call (bar(...)) → cyan identifier\n  if (prevSig === \".\" || nextSig === \"(\") return \"var(--aurora-accent-primary)\"\n  return undefined\n}\n\nfunction highlight(code: string): React.ReactNode[] {\n  const out: React.ReactNode[] = []\n  let match: RegExpExecArray | null\n  TOKEN_RE.lastIndex = 0\n  let key = 0\n  // Track the last non-whitespace token to resolve member-access / call coloring.\n  let prevSig = \"\"\n  // Pre-scan to know the \"next significant\" char for each identifier.\n  const tokens: { text: string; type: number }[] = []\n  while ((match = TOKEN_RE.exec(code)) !== null) {\n    if (match[1]) tokens.push({ text: match[1], type: 1 })\n    else if (match[2]) tokens.push({ text: match[2], type: 2 })\n    else if (match[3]) tokens.push({ text: match[3], type: 3 })\n    else if (match[4]) tokens.push({ text: match[4], type: 4 })\n    else if (match[5]) tokens.push({ text: match[5], type: 5 })\n    else tokens.push({ text: match[6] ?? \"\", type: 6 })\n  }\n  for (let i = 0; i < tokens.length; i += 1) {\n    const t = tokens[i]\n    if (t.type === 5) {\n      out.push(<React.Fragment key={key++}>{t.text}</React.Fragment>)\n      continue\n    }\n    let color: string | undefined\n    if (t.type === 1) color = \"var(--aurora-text-muted)\"\n    else if (t.type === 2) color = \"var(--aurora-success)\"\n    else if (t.type === 3) color = \"var(--axon-orange)\"\n    else if (t.type === 4) {\n      let j = i + 1\n      while (j < tokens.length && tokens[j].type === 5) j += 1\n      const nextSig = j < tokens.length ? tokens[j].text : \"\"\n      color = tokenColor(t.text, prevSig, nextSig)\n    }\n    if (t.type !== 5) prevSig = t.text.trim() ? t.text : prevSig\n    out.push(\n      <span key={key++} style={color ? { color } : undefined}>\n        {t.text}\n      </span>\n    )\n  }\n  return out\n}\n\nfunction CopyIconButton({ value }: { value: string }) {\n  const { copied, error, copy } = useClipboard(1200)\n  const handleCopy = React.useCallback(() => void copy(value), [copy, value])\n\n  return (\n    <Button\n      type=\"button\"\n      variant=\"ghost\"\n      size=\"icon\"\n      onClick={handleCopy}\n      aria-label={copied ? \"Copied to clipboard\" : error ? \"Unable to copy code\" : \"Copy code\"}\n    >\n      {copied ? <Check className=\"size-3.5\" aria-hidden /> : <Copy className=\"size-3.5\" aria-hidden />}\n      <span className=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\">\n        {copied ? \"Copied\" : error ? \"Unable to copy\" : \"Copy code\"}\n      </span>\n    </Button>\n  )\n}\n\n/**\n * Snippet — a recessed code surface with a language chip and an icon-only copy\n * control, matching the Claude Design AI-element spec. Keeps the registry\n * architecture: `forwardRef` to the underlying `<pre>`, `displayName`, full\n * prop spread, and an accessible copy affordance.\n */\nconst Snippet = ({ ref, code, language = \"tsx\", className, style, ...props }: SnippetProps & { ref?: React.Ref<HTMLPreElement> }) => (\n    <div\n      className={className}\n      style={{\n        background: \"var(--aurora-panel-strong)\",\n        border: \"1px solid var(--aurora-border-default)\",\n        borderRadius: \"var(--aurora-radius-2)\",\n        boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n        overflow: \"hidden\",\n        ...style,\n      }}\n    >\n      <div\n        className=\"flex items-center justify-between gap-3\"\n        style={{\n          padding: \"12px 14px\",\n          borderBottom: \"1px solid var(--aurora-border-default)\",\n          background:\n            \"linear-gradient(180deg, color-mix(in srgb, var(--aurora-panel-strong-top) 70%, transparent), transparent)\",\n        }}\n      >\n        <div className=\"flex items-center gap-2.5\">\n          <CodeXml className=\"size-4\" aria-hidden style={{ color: \"var(--aurora-text-muted)\" }} />\n          <Badge tone=\"rose\" size=\"sm\">\n            {language}\n          </Badge>\n        </div>\n        <CopyIconButton value={code} />\n      </div>\n      <pre\n        ref={ref}\n        className=\"overflow-auto aurora-text-code\"\n        style={{\n          margin: 0,\n          padding: \"16px 18px\",\n          background: \"transparent\",\n          color: \"var(--aurora-text-primary)\",\n          lineHeight: 1.7,\n          whiteSpace: \"pre\",\n        }}\n        {...props}\n      >\n        <code>{highlight(code)}</code>\n      </pre>\n    </div>\n  )\nSnippet.displayName = \"Snippet\"\n\nexport { Snippet }\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/snippet.tsx"
    }
  ],
  "meta": {
    "namespace": "@aurora",
    "style": "aurora",
    "family": "block",
    "requiresTokens": true,
    "sourcePath": "registry/aurora/blocks/ai/elements/snippet.tsx",
    "installTarget": "@components/aurora/ai/snippet.tsx",
    "taxonomy": "ai"
  },
  "docs": "Aurora block that expects `aurora-tokens` to be installed first.\n\nDefault install target: `@components/aurora/ai/snippet.tsx`.\n\nRegistry dependencies: `aurora-tokens`, `aurora-ai-elements`.",
  "categories": [
    "aurora",
    "block",
    "ai"
  ],
  "type": "registry:block"
}