docs(ui): update Header docs with tags, description, and metadata props
Add new props to the Header API reference and examples on ui.backstage.io. Also adds deprecated badge support to the shared PropsTable component so the breadcrumbs prop is visually marked as deprecated. Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -29,10 +29,25 @@ const breadcrumbs = [
|
||||
},
|
||||
];
|
||||
|
||||
const tags = [
|
||||
{ label: 'TypeScript' },
|
||||
{ label: 'Platform', href: '/platform' },
|
||||
{ label: 'Gold' },
|
||||
];
|
||||
|
||||
const metadata = [
|
||||
{ label: 'Owner', value: 'platform-team' },
|
||||
{ label: 'Type', value: 'website' },
|
||||
{ label: 'Tier', value: 'gold' },
|
||||
];
|
||||
|
||||
export const WithEverything = () => (
|
||||
<MemoryRouter initialEntries={['/overview']}>
|
||||
<Header
|
||||
title="Page Title"
|
||||
tags={tags}
|
||||
description="A short description of this page. Supports [inline links](https://backstage.io) and **bold text**."
|
||||
metadata={metadata}
|
||||
tabs={tabs.slice(0, 2)}
|
||||
breadcrumbs={breadcrumbs.slice(0, 2)}
|
||||
customActions={
|
||||
@@ -45,6 +60,27 @@ export const WithEverything = () => (
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
export const WithTags = () => (
|
||||
<MemoryRouter>
|
||||
<Header title="Page Title" tags={tags} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
export const WithDescription = () => (
|
||||
<MemoryRouter>
|
||||
<Header
|
||||
title="Page Title"
|
||||
description="A short description of this page. Supports [inline links](https://backstage.io) and **bold text**."
|
||||
/>
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
export const WithMetadata = () => (
|
||||
<MemoryRouter>
|
||||
<Header title="Page Title" metadata={metadata} />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
export const WithLongBreadcrumbs = () => (
|
||||
<MemoryRouter>
|
||||
<Header title="Page Title" breadcrumbs={breadcrumbs.slice(0, 2)} />
|
||||
|
||||
@@ -5,6 +5,9 @@ import {
|
||||
WithEverything,
|
||||
WithLongBreadcrumbs,
|
||||
WithTabs,
|
||||
WithTags,
|
||||
WithDescription,
|
||||
WithMetadata,
|
||||
WithCustomActions,
|
||||
WithMenu,
|
||||
} from './components';
|
||||
@@ -13,6 +16,9 @@ import {
|
||||
usage,
|
||||
defaultSnippet,
|
||||
withTabs,
|
||||
withTags,
|
||||
withDescription,
|
||||
withMetadata,
|
||||
withBreadcrumbs,
|
||||
withCustomActions,
|
||||
withMenu,
|
||||
@@ -24,7 +30,7 @@ import { ChangelogComponent } from '@/components/ChangelogComponent';
|
||||
|
||||
<PageTitle
|
||||
title="Header"
|
||||
description="A secondary header with title, breadcrumbs, tabs, and actions."
|
||||
description="A secondary header with title, tags, description, metadata, tabs, and actions."
|
||||
/>
|
||||
|
||||
<Snippet py={4} preview={<WithEverything />} code={defaultSnippet} />
|
||||
@@ -39,11 +45,23 @@ import { ChangelogComponent } from '@/components/ChangelogComponent';
|
||||
|
||||
## Examples
|
||||
|
||||
### Breadcrumbs
|
||||
### Tags
|
||||
|
||||
Labels are truncated at 240px.
|
||||
Tags are rendered above the title. Each tag with an `href` renders as a link; tags without `href` render as plain text. Tags are separated by a small circle divider.
|
||||
|
||||
<Snippet open preview={<WithLongBreadcrumbs />} code={withBreadcrumbs} />
|
||||
<Snippet open preview={<WithTags />} code={withTags} />
|
||||
|
||||
### Description
|
||||
|
||||
The description accepts a markdown string. Only inline elements are supported — links, bold, and italic.
|
||||
|
||||
<Snippet open preview={<WithDescription />} code={withDescription} />
|
||||
|
||||
### Metadata
|
||||
|
||||
Key-value pairs displayed below the description.
|
||||
|
||||
<Snippet open preview={<WithMetadata />} code={withMetadata} />
|
||||
|
||||
### Tabs
|
||||
|
||||
@@ -61,6 +79,12 @@ Use `customActions` to add a dropdown menu.
|
||||
|
||||
<Snippet open preview={<WithMenu />} code={withMenu} />
|
||||
|
||||
### Breadcrumbs (deprecated)
|
||||
|
||||
The `breadcrumbs` prop is deprecated and will be removed in a future release. Labels are truncated at 240px.
|
||||
|
||||
<Snippet open preview={<WithLongBreadcrumbs />} code={withBreadcrumbs} />
|
||||
|
||||
<Theming definition={HeaderDefinition} />
|
||||
|
||||
<ChangelogComponent component={['header', 'header-page']} />
|
||||
|
||||
@@ -5,6 +5,50 @@ export const headerPagePropDefs: Record<string, PropDef> = {
|
||||
type: 'string',
|
||||
description: 'Page heading displayed in the header.',
|
||||
},
|
||||
tags: {
|
||||
type: 'complex',
|
||||
description:
|
||||
'Items displayed above the title. Each tag renders as a link when href is provided, or as plain text otherwise. Tags are separated by a small circle divider.',
|
||||
complexType: {
|
||||
name: 'HeaderTag[]',
|
||||
properties: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'Display text for the tag.',
|
||||
},
|
||||
href: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'URL to navigate to when the tag is clicked.',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description:
|
||||
'Markdown string rendered below the title. Only inline elements are supported: links, bold, and italic. Block-level markdown such as headings or lists is not rendered.',
|
||||
},
|
||||
metadata: {
|
||||
type: 'complex',
|
||||
description: 'Key-value pairs displayed below the description.',
|
||||
complexType: {
|
||||
name: 'HeaderMetadataItem[]',
|
||||
properties: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'The key label, displayed in bold.',
|
||||
},
|
||||
value: {
|
||||
type: 'ReactNode',
|
||||
required: true,
|
||||
description: 'The value to display alongside the label.',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
customActions: {
|
||||
type: 'enum',
|
||||
values: ['ReactNode'],
|
||||
@@ -49,6 +93,7 @@ export const headerPagePropDefs: Record<string, PropDef> = {
|
||||
},
|
||||
breadcrumbs: {
|
||||
type: 'complex',
|
||||
deprecated: true,
|
||||
description: 'Breadcrumb trail displayed above the title.',
|
||||
complexType: {
|
||||
name: 'HeaderBreadcrumb[]',
|
||||
|
||||
@@ -4,9 +4,16 @@ export const usage = `import { Header } from '@backstage/ui';
|
||||
|
||||
export const defaultSnippet = `<Header
|
||||
title="Page Title"
|
||||
breadcrumbs={[
|
||||
{ label: 'Home', href: '/' },
|
||||
{ label: 'Dashboard', href: '/dashboard' },
|
||||
tags={[
|
||||
{ label: 'TypeScript' },
|
||||
{ label: 'Platform', href: '/platform' },
|
||||
{ label: 'Gold' },
|
||||
]}
|
||||
description="A short description. Supports [inline links](https://backstage.io) and **bold text**."
|
||||
metadata={[
|
||||
{ label: 'Owner', value: 'platform-team' },
|
||||
{ label: 'Type', value: 'website' },
|
||||
{ label: 'Tier', value: 'gold' },
|
||||
]}
|
||||
tabs={[
|
||||
{ id: 'overview', label: 'Overview', href: '/overview' },
|
||||
@@ -54,3 +61,26 @@ export const withMenu = `<Header
|
||||
</MenuTrigger>
|
||||
}
|
||||
/>`;
|
||||
|
||||
export const withTags = `<Header
|
||||
title="Page Title"
|
||||
tags={[
|
||||
{ label: 'TypeScript' },
|
||||
{ label: 'Platform', href: '/platform' },
|
||||
{ label: 'Gold' },
|
||||
]}
|
||||
/>`;
|
||||
|
||||
export const withDescription = `<Header
|
||||
title="Page Title"
|
||||
description="A short description. Supports [inline links](https://backstage.io) and **bold text**."
|
||||
/>`;
|
||||
|
||||
export const withMetadata = `<Header
|
||||
title="Page Title"
|
||||
metadata={[
|
||||
{ label: 'Owner', value: 'platform-team' },
|
||||
{ label: 'Type', value: 'website' },
|
||||
{ label: 'Tier', value: 'gold' },
|
||||
]}
|
||||
/>`;
|
||||
|
||||
@@ -4,12 +4,18 @@ import styles from './styles.module.css';
|
||||
export const Chip = ({
|
||||
children,
|
||||
head = false,
|
||||
deprecated = false,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
head?: boolean;
|
||||
deprecated?: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<span className={`${styles.chip} ${head ? styles.head : ''}`}>
|
||||
<span
|
||||
className={`${styles.chip} ${head ? styles.head : ''} ${
|
||||
deprecated ? styles.deprecated : ''
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.deprecated {
|
||||
background-color: #fff4e5;
|
||||
color: #b45309;
|
||||
}
|
||||
|
||||
[data-theme-mode='dark'] .chip {
|
||||
background-color: #2c2c2c;
|
||||
color: #fff;
|
||||
@@ -22,3 +27,8 @@
|
||||
[data-theme-mode='dark'] .chip.head {
|
||||
background-color: #33405b;
|
||||
}
|
||||
|
||||
[data-theme-mode='dark'] .chip.deprecated {
|
||||
background-color: #3d2a10;
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,12 @@ export const PropsTable = <T extends Record<string, PropData>>({
|
||||
|
||||
switch (column) {
|
||||
case 'prop':
|
||||
return <Chip head>{propName}</Chip>;
|
||||
return (
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.375rem' }}>
|
||||
<Chip head>{propName}</Chip>
|
||||
{propData.deprecated && <Chip deprecated>deprecated</Chip>}
|
||||
</div>
|
||||
);
|
||||
|
||||
case 'type':
|
||||
return (
|
||||
|
||||
@@ -44,6 +44,7 @@ export type PropDef = {
|
||||
required?: boolean;
|
||||
responsive?: boolean;
|
||||
description?: ReactNode;
|
||||
deprecated?: boolean;
|
||||
};
|
||||
|
||||
export { breakpoints };
|
||||
|
||||
Reference in New Issue
Block a user