---
name: toolbar
description: Use this skill when asked to add or build a canvas-style icon toolbar using the @cratis/components Toolbar component. Covers Toolbar, ToolbarButton, ToolbarSeparator, ToolbarSection, ToolbarContext, and ToolbarFanOutItem. Use whenever building tool panels, drawing tool selectors, zoom controls, or any icon-button group with active states, context switching, or fan-out sub-panels.
---
## When to use the Toolbar
The `Toolbar` component is designed for **canvas-style tool panels** — the kind you find in drawing or diagram editors. It groups `ToolbarButton` elements into a pill-shaped bar with hover tooltips and active highlights. Use it when you need:
- A tool selector with an "active tool" state
- A set of action buttons that animate between tool modes
- A toolbar that fans out sub-panels for grouped tools
For a standard page action menu (Create / Edit / Delete over a data table), use `DataPage.MenuItems` instead.
---
## Component overview
| Component | Purpose |
| --- | --- |
| `Toolbar` | Container — renders a pill-shaped bar of buttons |
| `ToolbarButton` | Icon or text button with tooltip and optional active state |
| `ToolbarSeparator` | Visual divider between button groups |
| `ToolbarSection` | Animated section that transitions between named contexts |
| `ToolbarContext` | Named set of buttons inside a `ToolbarSection` |
| `ToolbarFanOutItem` | Button that slides out a horizontal sub-panel on click |
All components import from the `@cratis/components/Toolbar` subpath (never the root barrel — see [components.md](https://github.com/Cratis/AI/blob/main/.ai/rules/components.md)):
```tsx
import { Toolbar, ToolbarButton, ToolbarSeparator, ToolbarSection, ToolbarContext, ToolbarFanOutItem } from '@cratis/components/Toolbar';
```
---
## Step 1 — Basic vertical toolbar
Place `ToolbarButton` elements inside `Toolbar`. The default orientation is vertical.
```tsx
import { Toolbar, ToolbarButton } from '@cratis/components/Toolbar';
export const DrawingToolbar = () => (
);
```
---
## Step 2 — Active state (selected tool)
Use the `active` prop to highlight the currently selected tool. Drive it from state:
```tsx
import { useState } from 'react';
import { Toolbar, ToolbarButton } from '@cratis/components/Toolbar';
export const DrawingToolbar = () => {
const [activeTool, setActiveTool] = useState('select');
return (
setActiveTool('select')}
/>
setActiveTool('draw')}
/>
setActiveTool('rect')}
/>
);
};
```
---
## Step 3 — Separators
`ToolbarSeparator` draws a thin divider line between groups. Pass the same `orientation` as the enclosing `Toolbar`:
```tsx
```
---
## Step 4 — Horizontal toolbar with text buttons
Pass `orientation='horizontal'` for a horizontal layout. Use `text` for buttons that display a value (e.g. zoom percentage):
```tsx
import { useState } from 'react';
import { Toolbar, ToolbarButton, ToolbarSeparator } from '@cratis/components/Toolbar';
export const ZoomToolbar = () => {
const [zoom, setZoom] = useState(100);
return (
setZoom(z => z - 10)} />
setZoom(100)} />
setZoom(z => z + 10)} />
);
};
```
> For horizontal toolbars, set `tooltipPosition='bottom'` (or `'top'`) so tooltips do not overlap the toolbar.
---
## Step 5 — Animated context switching
`ToolbarSection` + `ToolbarContext` allows the toolbar to show different sets of buttons depending on the active mode. When `activeContext` changes, the buttons fade out, the section morphs to the new size, and the new buttons fade in.
```tsx
import { useState } from 'react';
import { Toolbar, ToolbarButton, ToolbarSection, ToolbarContext } from '@cratis/components/Toolbar';
export const ContextualToolbar = () => {
const [mode, setMode] = useState<'drawing' | 'text'>('drawing');
return (
);
};
```
Only the `ToolbarSection` transitions. Buttons outside the section are unaffected.
---
## Step 6 — Fan-out sub-panel
`ToolbarFanOutItem` replaces a regular button with one that fans out a horizontal panel of additional tools. Clicking the button again or anywhere outside closes the panel.
```tsx
import { Toolbar, ToolbarButton, ToolbarFanOutItem } from '@cratis/components/Toolbar';
export const ShapesToolbar = () => (
);
```
When the toolbar is on the **right side** of the screen, fan out to the left:
```tsx
...
```
---
## Props reference
### `Toolbar`
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | — | `ToolbarButton`, `ToolbarSeparator`, `ToolbarSection`, or `ToolbarFanOutItem` elements |
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction |
### `ToolbarButton`
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `icon` | `string` | — | PrimeIcons CSS class (e.g. `'pi pi-pencil'`) |
| `text` | `string` | — | Text shown inside the button (use for values like zoom %) |
| `tooltip` | `string` | **required** | Tooltip text on hover |
| `active` | `boolean` | `false` | Highlights the button as selected |
| `onClick` | `() => void` | — | Click handler |
| `tooltipPosition` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` | Tooltip position |
### `ToolbarSeparator`
| Prop | Type | Default | Description |
|---|---|---|---|
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Match the enclosing `Toolbar` orientation |
### `ToolbarSection`
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `activeContext` | `string` | first context name | Name of the active `ToolbarContext` |
| `children` | `ToolbarContext[]` | — | `ToolbarContext` children |
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Match the enclosing `Toolbar` |
### `ToolbarContext`
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` | **required** | Identifier matched by `ToolbarSection.activeContext` |
| `children` | `ReactNode` | — | `ToolbarButton` elements for this context |
### `ToolbarFanOutItem`
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `icon` | `string` | **required** | PrimeIcons CSS class for the trigger button |
| `tooltip` | `string` | **required** | Tooltip for the trigger button |
| `tooltipPosition` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` | Tooltip position |
| `fanOutDirection` | `'right' \| 'left'` | `'right'` | Direction the sub-panel slides out |
| `children` | `ReactNode` | — | `ToolbarButton` elements inside the fan-out panel |
---
## Multiple toolbar groups
Render separate `Toolbar` instances to create distinct groups:
```tsx
```
---
## Validation
After creating or modifying a Toolbar component, run:
```bash
yarn lint
npx tsc -b
```
Fix all errors before proceeding.