Import
Highlighting happens on the server, and shiki never reaches the browser. It imports server-only, so importing it from a Client Component fails the build, which is why it has an entry of its own.
import { CodeBlock } from '@k8ordo/ui/code-block';Usage
export function Total({ items }: { items: Item[] }) {
const done = items.filter((item) => item.done).length;
return <p>{done} / {items.length}</p>;
}<CodeBlock code={source} lang="tsx" />File Name
With title, the header shows it in place of the language, as the figure’s figcaption.
export function Total({ items }: { items: Item[] }) {
const done = items.filter((item) => item.done).length;
return <p>{done} / {items.length}</p>;
}<CodeBlock code={source} lang="tsx" title="total.tsx" />Line Marks
marks marks lines by their 1-based number with highlight, add, or remove. Additions and removals are shown with + and −, not by color alone.
const done = items.filter((item) => item.done).length;
const rate = done / items.length;
const rate = items.length === 0 ? 0 : done / items.length;<CodeBlock
code={source}
lang="ts"
marks={{ 1: 'highlight', 2: 'remove', 3: 'add' }}
/>Callouts
callouts puts a note right under a line, indented like the line (an array puts several, in order). The copy button copies code exactly, without the marks or the notes.
const done = items.filter((item) => item.done).length;
const rate = done / items.length;
const rate = items.length === 0 ? 0 : done / items.length;
Guard the division when the list is empty<CodeBlock
callouts={{ 3: 'Guard the division when the list is empty' }}
code={source}
lang="ts"
/>Colors and Dark Mode
It uses shiki’s css-variables theme, with each --shiki-token-* mapped to a design token. The tokens switch under .dark, so there is no second theme. A language name shiki does not know renders as plain text.
Props
code- Type:
string - Default: -
callouts?- Type:
Readonly<Record<number, string | readonly string[]>> - Default: -
lang?- Type:
string - Default:
'text' marks?- Type:
Readonly<Record<number, 'highlight' | 'add' | 'remove'>> - Default: -
title?- Type:
string - Default: -
| Prop | Type | Default |
|---|---|---|
code | string | - |
callouts? | Readonly<Record<number, string | readonly string[]>> | - |
lang? | string | 'text' |
marks? | Readonly<Record<number, 'highlight' | 'add' | 'remove'>> | - |
title? | string | - |
Type base (some attrs are managed internally): HTMLAttributes<HTMLElement>
Wording this component renders (labels, placeholders, and the like) comes from the message dictionary when no prop sets it. To change it, see: i18n