<!-- Protocore Design System — CodeHighlight -->
# CodeHighlight

- **Category:** Data Display (`data-display`)
- **Slug:** `data-display/code-highlight`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { CodeHighlight } from "@protocore/pds";`
- **Docs:** https://pds.protocore.io/components/data-display/code-highlight

> A syntax-highlighted code surface — Shiki-backed, dual-theme, with an optional filename/language header and copy button. Highlights any of the major programming languages.

## Installation

`CodeHighlight` ships from the **`@protocore/pds/code`** subpath so its highlighter (**Shiki**, plus the language grammars) never enters the core bundle — the same way charts keep recharts out and the editor keeps tiptap out. `shiki` (>=4) is an **optional peer**; install it in any app that renders CodeHighlight.

```bash
pnpm add shiki
```

```tsx
import { CodeHighlight } from "@protocore/pds/code";
```

Shiki is loaded through a **lazy dynamic import** inside the component, so it costs nothing until a CodeHighlight actually mounts. Until the async highlight resolves — and if JavaScript is disabled — the component renders a fully-styled plain-text `<pre>` with identical metrics, so there is **no layout shift** and it degrades gracefully.

## CodeHighlight vs CodeBlock vs CodeRef

Three code surfaces, three jobs:

- **CodeHighlight** — *real syntax highlighting* for arbitrary source in any major language, via Shiki (optional peer, subpath). Reach for it when the language matters and you want tokens coloured.
- **CodeBlock** — a *static, dependency-free* mono panel in the core entry. Hand-authored spans (`CodeComment`, `CodeLiteral`) for the rare highlighted line; no grammar engine.
- **CodeRef** — an *inline* mono reference for a symbol, path, or key inside prose — not a block.

## Examples

### TypeScript

Pass `code` and a `language`. The surface is a sunken, hairline-bordered mono panel; the header carries a `filename` (mono), the language chip, and a copy button. Highlight colours are dual-theme — they flip with the design system's `data-theme`.

```tsx
import { CodeHighlight } from "@protocore/pds/code";

const code = `import { createServer } from "node:http";

const server = createServer((req, res) => {
  res.writeHead(200, { "content-type": "application/json" });
  res.end(JSON.stringify({ ok: true, path: req.url }));
});

server.listen(3000, () => console.log("listening on :3000"));`;

export default function CodeHighlightTypeScript() {
  return <CodeHighlight code={code} language="typescript" filename="server.ts" />;
}
```

### Shell

Use `bash`/`shell` for terminal snippets. Drop the `filename` and pass a `label` instead to caption the block without implying a file on disk.

```tsx
import { CodeHighlight } from "@protocore/pds/code";

const code = `# install and start the dev server
pnpm add @protocore/pds shiki
pnpm --filter web dev

# tail the logs
pnpm --filter web logs --since 5m | grep -i error`;

export default function CodeHighlightBash() {
  return <CodeHighlight code={code} language="bash" label="Terminal" />;
}
```

## Usage

**Do**

- Install the `shiki` optional peer in apps that render CodeHighlight; without it the component stays in its plain-text fallback.
- Pass a `language` that matches the source so tokens color correctly.
- Use `filename` for on-disk files and `label` for non-file captions (a shell session, a request body).
- Let long lines scroll; use `wrap` for narrow columns or wrapped prose.

**Don't**

- Import CodeHighlight from `@protocore/pds/code`, not the main entry; that keeps Shiki out of the base bundle.
- For a single inline symbol, use CodeRef.
- For dependency-free static panels, use CodeBlock's manual spans.
- Pair color with the copy button and structure; color alone doesn't carry meaning.

## Accessibility

**Notes**

- The surface is a labelled `region` (`aria-label` derived from the filename/label and language), and the scrollable `<pre>` is `tabIndex=0` so keyboard users can scroll overflowing code.
- The copy button is a real `<button>` with an accessible name and announces its 'Copied' state politely to assistive tech.
- Before the async Shiki highlight resolves — and with JS disabled — the same code renders as styled plain text with identical metrics, so the content is always present and never shifts.
- Token colours are dual-theme via per-token CSS variables switched on `data-theme`; because the code text is always present regardless of colour, snippets stay legible for colour-blind and monochrome readers.

## Related

`code-ref`, `copy-button`, `json-viewer`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
