{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "code-block",
  "title": "Code Block",
  "description": "Shiki-highlighted code in warm stone and cream themes, with a file title bar and language pill, a copy button that morphs into a check while \"Copied\" slides out, highlighted and focused lines, and long blocks that collapse under a progressive blur with \"Show 22 more lines\".",
  "dependencies": [
    "motion",
    "shiki"
  ],
  "registryDependencies": [
    "https://eased.dev/r/eased-tokens.json",
    "https://eased.dev/r/eased-code-core.json"
  ],
  "files": [
    {
      "path": "src/registry/eased/code-block/code-block.tsx",
      "content": "\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { CopyButton } from \"../_primitives/code-core/copy\";\nimport { CODE_FRAME, CODE_HEADER, LangGlyph, LangPill } from \"../_primitives/code-core/code-chrome\";\nimport { CodeCollapse, CodeLines, useCodeLines } from \"../_primitives/code-core/code-lines\";\nimport { langFromFilename, type CodeLang, type CodeLine } from \"../_primitives/code-core/highlighter\";\nimport type { LineDecorations } from \"../_primitives/code-core/lines\";\n\nexport type CodeBlockProps = LineDecorations & {\n  /** The source to show and copy. One trailing newline is ignored. */\n  code: string;\n  /**\n   * tsx, ts, js, jsx, json, css, bash, html, md, python or diff (aliases like \"typescript\",\n   * \"sh\" and \"py\" work). Default: from the `title`'s extension; anything else is plain text.\n   */\n  lang?: CodeLang | (string & {});\n  /** A file name for the title bar. Without it, the copy button floats over the code. */\n  title?: string;\n  /** Replace the file glyph in the title bar. */\n  icon?: ReactNode;\n  /** Show the language pill in the title bar. Default true. */\n  showLang?: boolean;\n  /** A line-number gutter. Default false. */\n  lineNumbers?: boolean;\n  /** Number of the first line, for excerpts. Default 1. */\n  startLine?: number;\n  /**\n   * Collapse blocks longer than this many lines under a progressive blur with \"Show N more\n   * lines\". Default 20; 0 never collapses. Blocks collapse only when 3 or more lines would hide.\n   */\n  collapseAfter?: number;\n  /** Start a collapsible block expanded. Default false. */\n  defaultExpanded?: boolean;\n  /** Show the copy button. Default true. */\n  copy?: boolean;\n  onCopy?: (code: string) => void;\n  /** Soft-wrap long lines instead of scrolling sideways. Default false. */\n  wrap?: boolean;\n  /** Pre-highlighted lines from `highlight()` (e.g. on the server), so the first paint is already coloured. */\n  tokens?: CodeLine[];\n  className?: string;\n};\n\n/**\n * Code Block: Shiki highlighting in Eased's stone (dark) and cream (light) themes, a file\n * title bar with a language pill, a copy button that morphs into a check while \"Copied\"\n * slides out, highlighted and focused lines, and long blocks that collapse under a\n * progressive blur. Grammars load on demand; the theme follows `.dark`/`data-theme`.\n */\nexport function CodeBlock({\n  code,\n  lang,\n  title,\n  icon,\n  showLang = true,\n  lineNumbers = false,\n  startLine,\n  collapseAfter = 20,\n  defaultExpanded,\n  copy = true,\n  onCopy,\n  wrap,\n  tokens,\n  highlight,\n  focus,\n  added,\n  removed,\n  className = \"\",\n}: CodeBlockProps) {\n  const language = lang ?? langFromFilename(title) ?? undefined;\n  const { lines } = useCodeLines(code, language, tokens);\n  const label = title ? `Copy ${title}` : \"Copy code\";\n\n  return (\n    <figure className={`m-0 ${CODE_FRAME} ${className}`}>\n      {title !== undefined && (\n        <figcaption className={CODE_HEADER}>\n          {icon ?? <LangGlyph lang={language} />}\n          <span className=\"min-w-0 flex-1 truncate font-mono text-ui-sm text-text-secondary\">{title}</span>\n          {showLang && <LangPill lang={language} />}\n          {copy && <CopyButton text={code} label={label} onCopy={onCopy} />}\n        </figcaption>\n      )}\n      <CodeCollapse lines={lines.length} collapseAfter={collapseAfter} defaultExpanded={defaultExpanded}>\n        <CodeLines\n          lines={lines}\n          lineNumbers={lineNumbers}\n          startLine={startLine}\n          wrap={wrap}\n          label={title}\n          highlight={highlight}\n          focus={focus}\n          added={added}\n          removed={removed}\n          className={title === undefined && copy ? \"[&_[data-line]:first-child]:pr-12\" : \"\"}\n        />\n      </CodeCollapse>\n      {title === undefined && copy && (\n        // Pointer devices reveal it on hover or focus; touch screens always show it.\n        <div className=\"absolute top-1.5 right-1.5 z-10 rounded-control-sm bg-surface-sunken transition-opacity duration-150 ease-standard pointer-fine:opacity-0 pointer-fine:group-hover:opacity-100 pointer-fine:focus-within:opacity-100\">\n          <CopyButton text={code} label={label} showLabel={false} onCopy={onCopy} />\n        </div>\n      )}\n    </figure>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@components/eased/code-block/code-block.tsx"
    }
  ],
  "docs": "Import CodeBlock from components/eased/code-block/code-block. Grammars load on demand; pass `tokens` from highlight() (components/eased/_primitives/code-core/highlighter) on the server for a first paint that is already coloured. Dark mode follows .dark or data-theme=\"dark\".",
  "type": "registry:ui"
}