Code Block
Shiki wired to the phosphor palette, with a copy button. Takes a string of code and highlights it on the server.
import { Led } from "@/components/led";
export function Relay({ name, ok }: { name: string; ok: boolean }) {
// The light is the status. There is no second copy of it in text.
return (
<p className="flex items-center gap-2 font-mono text-xs">
<Led tone={ok ? "ok" : "error"} />
{name}
</p>
);
}Installation
npx shadcn@latest add @afterglow/code-blockComposition
Component structure.
- CodeBlockTitle
- CodeBlockBody
- CodeBlockCopy
With a title
A title puts the file name above the code and names the copy button after it.
{
"registries": {
"@afterglow": "https://afterglow.thebuilder.dk/r/{name}.json"
}
}Languages
The highlighter loads five grammars up front, and the theme maps all of them onto the phosphor tokens. A shell command and a stylesheet come out of the same palette.
npx shadcn@latest add @afterglow/code-block.log {
font-family: var(--font-mono);
color: var(--phosphor-dim);
}API Reference
The highlighter runs on the server, so CodeBlock is an async component and Shiki never reaches the browser. Only the copy button ships as client code.
Shiki writes the theme's CSS variables onto the tokens instead of hex, so a block follows whichever phosphor the page is set to.
lang takes any language Shiki bundles. Its grammar loads the first time a block asks for it.
CodeBlock
Highlights code and draws it in a bordered panel. label names the copy button for a screen reader, and defaults to the title.
| Prop | Type | Default |
|---|---|---|
| code | string | - |
| lang | BundledLanguage | "tsx" |
| title | string | - |
| label | string | - |
CodeBlockTitle
The file name or caption above the code. CodeBlock renders one when you pass a title.
CodeBlockBody
The highlighted code and the copy button. Use it directly when you already hold Shiki's HTML, which is what a site that highlights once at build time will have.
Everything else is Shiki's API, documented there.