DetailPageBar
<DetailPageBar> is the canonical top bar for entity-detail pages — back button + entity title (optionally inline-editable) + optional subtitle on line 1; route-driven tabs on line 2.
When to use
- Every entity-detail page (
/agents/:id,/deals/:id). - Multi-tab detail pages where each tab is a route.
Don’t use DetailPageBar for: list pages (ListPageBar), focus flows (FocusLayout), or in-page sub-section navigation (Tabs).
Default
Marketing Bot
OverviewActivitySettings
Active tab content…
The preview above is a visual mock — the live
<DetailPageBar>requires areact-router-domprovider to wire active-tab matching, which doesn’t survive Astro’s SSR pass. In a real app, mount it inside your router and the tabs become real routes.
<DetailPageBar backTo="/agents" title={agent.name} subtitle={agent.purpose} basePath={`/agents/${agent.id}`} tabs={[ { label: 'Overview', path: '' }, { label: 'Activity', path: 'activity' }, { label: 'Settings', path: 'settings' }, ]} actions={<Button size="sm">Run</Button>}/>API
| Prop | Type | Default | Description |
|---|---|---|---|
backTo * | string | — | Parent list URL — back button always navigates here. |
title * | string | — | Entity name. Truncates at max-w-64. |
basePath * | string | — | Base path for tab matching (e.g. "/agents/123"). |
tabs | Tab[] | — | { label, path }[]. Max 8. Path is appended to basePath. |
actions | ReactNode | — | Right-aligned action buttons. |
subtitle | string | — | Optional entity description, separated by ·. Hidden on <md. |
titleEditable | boolean | false | Renders title via InlineEditField. Requires onTitleSave. |
onTitleSave | (next: string) => void | Promise<unknown> | — | Commit handler for the title. |
subtitleEditable | boolean | false | Inline-edit the subtitle. |
onSubtitleSave | (next: string) => void | Promise<unknown> | — | Commit handler for the subtitle. |
subtitlePlaceholder | string | — | Shown when subtitle is empty in edit mode. |
Design guidelines
✓ Do
- Always set backTo. The back button is a contract — users expect it on every detail page.
- Keep tabs ≤ 5. More belongs in a sub-page tree, not a tab strip.
- Use titleEditable only for entities the user owns and renames frequently.
✗ Don't
- Use DetailPageBar on list pages. ListPageBar is correct.
- Hide the back button — even when the user came via deep link, they expect it.
- Stuff complex controls into the subtitle. Keep it to one factual phrase.
Accessibility
- Composes
PageHeaderandInlineEditField. - Tabs are real
<a>links via react-router — keyboard reachable, browser back-button works. - Inline-edit fields have proper aria-label semantics for screen readers.
Related
PageHeader— Underlying primitive.ListPageBar— List-page sibling.InlineEditField— Inline title/subtitle editor.