Preview Rail
Compact section navigation that previews each destination.
Installation
pnpm dlx shadcn@latest add @paneui/preview-railUsage
Examples
Accessibility
Each tick is a button (or a link with href) named by its label; the selected one gets aria-current. Keyboard focus drives the same highlight and preview as hover. On touch, the first tap on a link reveals its preview and the second follows it.
Motion
Under reduced motion the ticks change without animating and the card only fades.
PreviewRail
A rail of ticks with a preview card for the pointed or focused item. Children render beside the rail. Also accepts every prop of div.
- items*
- PreviewRailItem[]
- The destinations, in order.
- value
- string
- Controlled selected id.
- defaultValue= items[0].id
- string
- Initial selection when uncontrolled.
- onValueChange
- (id: string, item: PreviewRailItem) => void
- Called when a tick is clicked.
- orientation= "vertical"
- "vertical" | "horizontal"
- Rail direction.
- side= "end"
- "start" | "end"
- Which side of the rail the preview appears on.
- renderPreview
- (item: PreviewRailItem) => ReactNode
- Custom preview contents; return
nullto show nothing for an item. - preview= true
- boolean
- Show the preview card at all (ticks still form the pyramid).
- showActive= true
- boolean
- Keep the selected tick tall and tinted while nothing is pointed at.
- itemSize= 22
- number
- Pitch between ticks, px.
- tickLength= 40
- number
- Length of a fully grown tick, px.
- label= "Sections"
- string
- Accessible name of the nav.
- railClassName
- string
- Class for the rail
nav. - previewClassName
- string
- Class for the preview card.
| Prop | Type | Default | Description |
|---|---|---|---|
| items* | PreviewRailItem[] | — | The destinations, in order. |
| value | string | — | Controlled selected id. |
| defaultValue | string | items[0].id | Initial selection when uncontrolled. |
| onValueChange | (id: string, item: PreviewRailItem) => void | — | Called when a tick is clicked. |
| orientation | "vertical" | "horizontal" | "vertical" | Rail direction. |
| side | "start" | "end" | "end" | Which side of the rail the preview appears on. |
| renderPreview | (item: PreviewRailItem) => ReactNode | — | Custom preview contents; return null to show nothing for an item. |
| preview | boolean | true | Show the preview card at all (ticks still form the pyramid). |
| showActive | boolean | true | Keep the selected tick tall and tinted while nothing is pointed at. |
| itemSize | number | 22 | Pitch between ticks, px. |
| tickLength | number | 40 | Length of a fully grown tick, px. |
| label | string | "Sections" | Accessible name of the nav. |
| railClassName | string | — | Class for the rail nav. |
| previewClassName | string | — | Class for the preview card. |
- data-orientation
verticalorhorizontal, on the root.- data-highlighted
- On the tick that is pointed at, focused, or selected at rest.
| Data attribute | Description |
|---|---|
| data-orientation | vertical or horizontal, on the root. |
| data-highlighted | On the tick that is pointed at, focused, or selected at rest. |
PreviewRailItem
Type of each entry in items.
- id*
- string
- Unique id.
- label*
- string
- Accessible name and preview title.
- description
- ReactNode
- Preview body text.
- icon
- ReactNode
- Leading icon, shown in an
IconChipin the default preview. - href
- string
- Render the tick as a link.
- target
- HTMLAttributeAnchorTarget
- Link target.
- rel
- string
- Link rel. Defaults to
noreferrer noopenerfor_blank. - disabled
- boolean
- Dim the tick and ignore it.
| Prop | Type | Default | Description |
|---|---|---|---|
| id* | string | — | Unique id. |
| label* | string | — | Accessible name and preview title. |
| description | ReactNode | — | Preview body text. |
| icon | ReactNode | — | Leading icon, shown in an IconChip in the default preview. |
| href | string | — | Render the tick as a link. |
| target | HTMLAttributeAnchorTarget | — | Link target. |
| rel | string | — | Link rel. Defaults to noreferrer noopener for _blank. |
| disabled | boolean | — | Dim the tick and ignore it. |