---
id: "packages/active-ui/example-panel"
title: "ExamplePanel"
description: "A working example with its source - a title, a line about the example, and a switch between preview and code."
url: "/packages/active-ui/example-panel"
locale: "en"
revision: "f418baf1e284c083"
---

# ExamplePanel

`ExamplePanel` shows a working example next to its source, as on every page of this site: a header
with the title, a short description and a switch between Preview and Code, and a stage with the
example on the application background.

**Example: An example panel of your own**

Client: Runs entirely in your browser. Source: `examples/ui/example-panel.tsx`.

```tsx
// apps/docs/examples/ui/example-panel.tsx
'use client';

import {ExamplePanel} from '@workspace/active-ui/components/composed/example-panel';
import {Button} from '@workspace/active-ui/components/primitives/button';
import {
  CodeBlock,
  CodeBlockContent,
  CodeBlockLine,
} from '@workspace/active-ui/components/primitives/code-block';
import {useHighlightedCode} from '@workspace/active-ui/hooks/use-highlighted-code';

const SOURCE = `<Button variant="outline">Save draft</Button>`;

/**
 * An example panel of your own: a title, a line about the example, and a
 * switch between the running example and its source. Every example on this
 * site is shown in one.
 */
export default function ExamplePanelExample() {
  const lines = useHighlightedCode(SOURCE, 'tsx');
  return (
    <ExamplePanel
      className="w-full max-w-xl"
      title="An outline button"
      description="The secondary action of a form."
      previewLabel="Preview"
      codeLabel="Code"
      viewLabel="View"
      preview={<Button variant="outline">Save draft</Button>}
      code={
        <CodeBlock flush>
          <CodeBlockContent>
            {lines.map((line, index) => (
              <CodeBlockLine key={index}>{line}</CodeBlockLine>
            ))}
          </CodeBlockContent>
        </CodeBlock>
      }
    />
  );
}
```

## What the composition adds

- **The view switch is the panel's own**: `line` [tabs](/packages/active-ui/tabs) in the header.
  Settings of the demo itself belong inside the preview.
- **The stage is the application canvas** (`--background`), so a component looks as it does in an
  application. It centres a small example (`stage="centered"`, the default). A wide one (a grid, a
  chart) takes `stage="fill"`: the full width of the panel from its start, so a component that
  measures its container gets that width. What is wider still scrolls inside the stage.
- **Actions of the panel** (`actions`) sit beside the view switch: a link to the example on its own
  page, or a [FullScreen](/packages/active-ui/full-screen) button with the panel as its `target`.
  In full screen the panel fills the screen and scrolls.
- **The code stays mounted** while the preview shows, so search and tests can read it.
- **A named figure**: the panel is a `<figure>` named by its title.

## Usage

```tsx
import {ExamplePanel} from '@workspace/active-ui/components/composed/example-panel';

<ExamplePanel
  title="An outline button"
  previewLabel="Preview"
  codeLabel="Code"
  viewLabel="View"
  preview={<Button variant="outline">Save draft</Button>}
  code={<CodeBlock flush>…</CodeBlock>}
/>;
```

## What your application provides

- The example and its source, usually a [CodeBlock](/packages/active-ui/code-block) with `flush`,
  highlighted with [`useHighlightedCode`](/packages/active-ui/hooks) or on the server.
- The labels of the tabs and the switch, translated.

## Accessibility and keyboard

The view switch is a tab list named by `viewLabel`: the arrow keys move between Preview and Code,
`Enter` or `Space` activates one.

## API

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | `ReactNode` | yes | Its source, usually a `CodeBlock` with `flush`. |
| `codeLabel` | `string` | yes | The label of the code tab, for example "Code". |
| `preview` | `ReactNode` | yes | The running example. |
| `previewLabel` | `string` | yes | The label of the preview tab, for example "Preview". |
| `title` | `ReactNode` | yes | The name of the example; also the accessible name of the panel. |
| `viewLabel` | `string` | yes | The accessible name of the view switch, for example "View". |
| `actions` | `ReactNode` | no | Controls of the panel beside the view switch, such as a link to the example on its own page or a full-screen button. |
| `defaultView` | `"code" \| "preview"` | no | The view shown first. |
| `description` | `ReactNode` | no | One short line about what the example is or proves. |
| `stage` | `"centered" \| "fill"` | no | `centered` (default) for a small example, `fill` for a wide one. |

**ExamplePanelProps**

```ts
interface ExamplePanelProps extends Omit<
  React.ComponentProps<'figure'>,
  'title' | 'children'
> {
  title: React.ReactNode;
  description?: React.ReactNode;
  preview: React.ReactNode;
  code: React.ReactNode;
  previewLabel: string;
  codeLabel: string;
  viewLabel: string;
  defaultView?: 'preview' | 'code';
  actions?: React.ReactNode;
  stage?: 'centered' | 'fill';
}
```

A working example with its source: a header with the title, a short
description of what the example is, and a choice between the preview and
the code, as in a documentation site or a component lab.

**Two kinds of controls stay apart.** The view switch (Preview, Code) is
the panel's own control and sits in its header, as `line` tabs. The
settings of the demo itself (a language, a variant) belong to the demo and
render inside the preview stage, with the ordinary controls of the demo.

**The stage is the application canvas** (`--background`), so a component
looks as it does in an application, on the ground it was designed for. It
centres its content; what is wider than the panel scrolls from its start.

**The code** is the caller's: usually a `CodeBlock` with `flush` (the panel
is its frame), highlighted where the caller can read the source. It stays
mounted while the preview shows, so a test or a search can read it.

**The stage** centres a small example (`stage="centered"`, the default).
A wide example (a grid, a chart, a dashboard) takes the full width of the
panel from its start (`stage="fill"`); what is still wider scrolls inside
it. In full screen (for example through `FullScreen` with the panel as its
`target`, placed in `actions`) the panel fills the screen and scrolls.

All text is the caller's: the panel translates nothing. `previewLabel`,
`codeLabel` and `viewLabel` are required for that reason.
