<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# CodeBlock

Code or a command on a muted surface in the theme's monospace font, with a caption and a button that copies it. The code shows exactly as given and scrolls sideways rather than wrapping (unless `wrap`), fading out at the side where a long line goes on, and the block becomes a tab stop while it overflows, so a keyboard can scroll it. Copying says "Copied" to screen readers.

```tsx
import { CodeBlock } from "@/components/ouro/code-block/code-block";
```

## Example

```tsx
<CodeBlock language="bash" code="npx shadcn@latest add button" />
<CodeBlock title="vite.config.ts" code={config} className="max-h-80" />
```

## Usage

It does not color the code; to highlight it, set colors on the `data-language` block from a highlighter of your own, or pass highlighted code to your own `<pre>`. With `catalogue`, the emoji characters in the code show as an image catalogue's pictures.

## Use instead when

- Use `Kbd` instead for a key or shortcut in a sentence, `<code>` for a short name in running text, and `CopyButton` for one value without a block around it.

## Props

Type: `CodeBlockProps`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `catalogue` | `EmojiCatalogue` |  | An image emoji catalogue: emoji characters in the code that it lists show as its pictures, 1em square, over the characters themselves, which stay in place unseen. The lines keep their length and wrapping, and copying or selecting gives the code's own characters. `:shortcode:` text stays text, since in code it means something else. |
| `className` | `string` |  | Layout only: margins, width, a maximum height that scrolls (`max-h-80`). Appearance classes warn in development. |
| `code` (required) | `string` |  | The code, as plain text. It shows exactly as given, whitespace and all, and is what the copy button copies. |
| `copy` | `boolean` | `true` | The copy button in the bar above the code. Turn it off for code nobody should paste, such as output. |
| `copyLabel` | `string` | `"Copy code"` | The copy button's name for screen readers. |
| `language` | `string` |  | The language, shown in the block's caption when there is no `title` and set as `data-language` on the block for a highlighter of your own: `language="bash"`. |
| `ref` | `Ref<HTMLElement>` |  | Reaches the rendered element. |
| `title` | `ReactNode` |  | A caption above the code, such as its file name: `title="vite.config.ts"`. |
| `wrap` | `boolean` |  | Wraps long lines instead of scrolling them sideways. Scrolling keeps code as written, so leave it off for code and turn it on for prose-like text such as a long command. |

## Native attributes

Also accepts the attributes in React's `HTMLAttributes` (`id`, `aria-*`, event handlers), passed to the rendered element, except those named on this page.

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `children`: Not a prop. The code is `code`, a string: `<CodeBlock code={source} />`.
- `filename`: Not a prop. The caption is `title`: `<CodeBlock code={source} title="app.tsx" />`.
- `lang`: Not a prop. Ouro UI uses `language`: `<CodeBlock code={source} language="tsx" />`.
- `showCopyButton`: Not a prop. The copy button is on by default; `copy={false}` turns it off.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`).

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

## Types

### `EmojiCatalogue`

An image-based emoji set, by category: what `EmojiPicker`, `ReactionBar`, `Autocomplete` and `EmojiText` draw instead of the platform's emoji font when an app passes it. Put an organization's custom emoji in a category of their own, labelled by the app. The image addresses are used as they are, so an app that loads images its own way (a content security policy, a custom scheme, signed or `blob:` URLs) puts the addresses it can load in the catalogue when it builds it. Ouro indexes a catalogue's emoji once, to find them in text. Build the catalogue once and pass that object, or give each copy the same `id`: a catalogue of new emoji objects on every render is indexed again each time, and warns in development. Adding or removing emoji is seen in a new catalogue object, even in the same array; to edit an emoji's shortcodes or text, pass a new emoji object, or a new `id`.

```ts
interface EmojiCatalogue {
  /**
   * Names this set of emoji, for an app that makes a new catalogue object, emoji and all, each
   * time it draws: catalogues with the same id share one index of their emoji, so change it when
   * the emoji change (`"contoso-2026-11"`), an emoji edited in place included. Without one, a
   * new catalogue object shares the index when it holds the same emoji objects in the same order,
   * and a catalogue of new emoji objects builds its own.
   */
  id?: string | undefined;
  /** The categories, in the order they show. An emoji in more than one counts once, by its id. */
  categories: readonly EmojiCatalogueCategory[];
}
```

### `EmojiCatalogueCategory`

A category of a catalogue: its name, the icon its button shows, and its emoji in order.

```ts
interface EmojiCatalogueCategory {
  /** Identifies the category, unique in the catalogue: `"people"`, `"custom"`. */
  id: string;
  /** Its name, shown as its heading and read for its button: `"People"`, or the organization's name for its custom emoji. */
  label: string;
  /** What its button in a picker's category bar shows: an icon element. Defaults to its first emoji's image. */
  icon?: ReactNode;
  /** Its emoji, in the order they show. */
  items: readonly EmojiItem[];
}
```

### `EmojiFilmstrip`

An animation drawn as a filmstrip: square frames stacked top to bottom in one image, so the frames are the image's height over its width.

```ts
interface EmojiFilmstrip {
  /** The filmstrip image's address. */
  src: string;
  /** Frames a second. */
  fps: number;
}
```

### `EmojiItem`

One emoji in an image catalogue: its id, its name and the image that draws it. An app maps its own emoji set to this, whether a standard set or an organization's custom emoji.

```ts
interface EmojiItem {
  /** Identifies the emoji, unique in the catalogue: `"party"`. Reactions, recents and `:id:` tokens use it. */
  id: string;
  /** Its name, which is the image's `alt`, what screen readers hear and what the search matches first: `"Party popper"`. */
  name: string;
  /**
   * The still image's address. It shows whenever the emoji is not playing, and always with reduced motion.
   */
  src: string;
  /** Sizes of the still image for sharper screens, as `<img srcset>`: `"party-2x.png 2x"`. */
  srcSet?: string | undefined;
  /**
   * An animated image (GIF, animated WebP or PNG), which plays while the pointer is on the emoji
   * or on the button around it, or that button has focus. With reduced motion it never plays.
   */
  animatedSrc?: string | undefined;
  /**
   * The animation as a filmstrip, square frames stacked top to bottom in one image, for an
   * emoji without `animatedSrc`: while the emoji plays, it steps through the frames at `fps`;
   * otherwise, and always with reduced motion, `src` shows.
   */
  filmstrip?: EmojiFilmstrip | undefined;
  /** The still image's width in pixels, given to the `<img>` so the page keeps its shape while it loads. It shows at the text's size. */
  width?: number | undefined;
  /** The still image's height in pixels, as `width`. */
  height?: number | undefined;
  /** Short names typed between colons, without them: `["party", "tada"]`. The first makes the emoji's token, `:party:`. */
  shortcodes?: readonly string[] | undefined;
  /** More words the search matches: `["celebrate", "hooray"]`. */
  keywords?: readonly string[] | undefined;
  /**
   * The emoji as plain text, such as its Unicode character (`"🎉"`), for places an image cannot
   * go (a copied message, a notification). `EmojiText` finds it in messages and draws the image;
   * Ouro never draws it as text.
   */
  text?: string | undefined;
  /** It is the organization's or app's own emoji rather than one of the standard set. Ouro draws it the same; apps can label or treat it apart. */
  custom?: boolean | undefined;
  /**
   * The emoji in Unicode's five skin tones, light to dark; leave it out for an emoji without tones.
   */
  skinTones?: readonly EmojiItemTone[] | undefined;
}
```

### `EmojiItemTone`

An emoji's image in one skin tone: `skinTones` on an `EmojiItem`.

```ts
interface EmojiItemTone {
  /** Identifies the emoji in this tone, unique in the catalogue: `"thumbs-up-tone3"`. Reactions and tokens use it. */
  id: string;
  /** The still image's address. */
  src: string;
  /** Sizes of the still image for sharper screens, as `<img srcset>`: `"wave-2x.png 2x"`. */
  srcSet?: string | undefined;
  /** An animated image (GIF, animated WebP or PNG), shown while the emoji plays; the still one shows otherwise. */
  animatedSrc?: string | undefined;
  /** The animation as a filmstrip of square frames, played while the emoji plays, for a tone without `animatedSrc`. */
  filmstrip?: EmojiFilmstrip | undefined;
  /**
   * The emoji in this tone as text (`"👍🏽"`), which `EmojiText` finds in messages; Ouro never draws it as text.
   */
  text?: string | undefined;
}
```
