Skip to content

Commit

Permalink
Components Storybook: Show badges in sidebar (#58518)
Browse files Browse the repository at this point in the history
Co-authored-by: andrewhayward <[email protected]>
Co-authored-by: ciampo <[email protected]>
Co-authored-by: mirka <[email protected]>
  • Loading branch information
4 people authored Feb 16, 2024
1 parent 26deca1 commit 0e0fd19
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const meta: Meta< typeof CustomSelect > = {
children: { control: { type: null } },
value: { control: { type: null } },
},
tags: [ 'status-wip' ],
parameters: {
badges: [ 'wip' ],
actions: { argTypesRegex: '^on.*' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const meta: Meta< typeof DropdownMenu > = {
children: { control: { type: null } },
trigger: { control: { type: null } },
},
tags: [ 'status-private' ],
parameters: {
actions: { argTypesRegex: '^on.*' },
badges: [ 'private' ],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const meta: Meta< typeof ProgressBar > = {
argTypes: {
value: { control: { type: 'number', min: 0, max: 100, step: 1 } },
},
tags: [ 'status-private' ],
parameters: {
badges: [ 'private' ],
controls: {
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/tabs/stories/index.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const meta: Meta< typeof Tabs > = {
// @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
'Tabs.TabPanel': Tabs.TabPanel,
},
tags: [ 'status-private' ],
parameters: {
actions: { argTypesRegex: '^on.*' },
badges: [ 'private' ],
Expand Down
1 change: 1 addition & 0 deletions packages/components/src/theme/stories/index.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const meta: Meta< typeof Theme > = {
accent: { control: { type: 'color' } },
background: { control: { type: 'color' } },
},
tags: [ 'status-private' ],
parameters: {
badges: [ 'private' ],
controls: { expanded: true },
Expand Down
30 changes: 30 additions & 0 deletions storybook/badges.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Provides badge configuration options.
* See https://github.com/geometricpanda/storybook-addon-badges
*/

export default {
private: {
icon: '🔒',
title: '🔒 Private',
tooltip: {
title: 'Component is locked as a private API',
desc: 'We do not yet recommend using this outside of the Gutenberg codebase.',
links: [
{
title: 'About @wordpress/private-apis',
href: 'https://developer.wordpress.org/block-editor/reference-guides/packages/packages-private-apis/',
},
],
},
},
wip: {
icon: '🚧',
title: '🚧 WIP',
styles: { backgroundColor: '#FFF0BD' },
tooltip: {
title: 'Component is a work in progress',
desc: 'This component is not ready for use in production, including the Gutenberg codebase. DO NOT export outside of @wordpress/components.',
},
},
};
2 changes: 2 additions & 0 deletions storybook/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import { addons } from '@storybook/addons';
* Internal dependencies
*/
import theme from './theme';
import sidebar from './sidebar';

addons.setConfig( {
sidebar,
theme,
} );
25 changes: 2 additions & 23 deletions storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { WithMarginChecker } from './decorators/with-margin-checker';
import { WithMaxWidthWrapper } from './decorators/with-max-width-wrapper';
import { WithRTL } from './decorators/with-rtl';
import { WithTheme } from './decorators/with-theme';
import badgesConfig from './badges';

export const globalTypes = {
direction: {
Expand Down Expand Up @@ -100,29 +101,7 @@ export const decorators = [

export const parameters = {
// For @geometricpanda/storybook-addon-badges
badgesConfig: {
private: {
title: '🔒 Private',
tooltip: {
title: 'Component is locked as a private API',
desc: 'We do not yet recommend using this outside of the Gutenberg codebase.',
links: [
{
title: 'About @wordpress/private-apis',
href: 'https://developer.wordpress.org/block-editor/reference-guides/packages/packages-private-apis/',
},
],
},
},
wip: {
title: '🚧 WIP',
styles: { backgroundColor: '#FFF0BD' },
tooltip: {
title: 'Component is a work in progress',
desc: 'This component is not ready for use in production, including the Gutenberg codebase. DO NOT export outside of @wordpress/components.',
},
},
},
badgesConfig,
controls: {
sort: 'requiredFirst',
},
Expand Down
79 changes: 79 additions & 0 deletions storybook/sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Provides sidebar configuration options.
* See https://storybook.js.org/docs/configure/features-and-behavior
*/

/**
* External dependencies
*/
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import { createElement, useMemo } from 'react';
import { useStorybookApi } from '@storybook/manager-api';
import { styled } from '@storybook/theming';

/**
* Internal dependencies
*/
import badges from './badges';

const Wrapper = styled.span( {
flexGrow: 1,
display: 'flex',
paddingRight: '20px',
} );

const Title = styled.span( {
flexGrow: 1,
} );

const Icons = styled.span( {} );

const Icon = styled.span( {} );

/**
* Fetches tags from the Storybook API, and returns Icon
* elements for any that have matching badge data
*/
function useIcons( item ) {
const api = useStorybookApi();
const prefix = 'status-';

return useMemo( () => {
let data = {};

if ( item.isComponent && item.children?.length ) {
data = api.getData( item.children[ 0 ] ) ?? {};
}

const { tags = [] } = data;

return tags
.filter( ( tag ) => tag.startsWith( prefix ) )
.map( ( tag ) => badges[ tag.substring( prefix.length ) ] )
.map( ( { icon, title, tooltip } ) =>
icon
? createElement(
Icon,
{ title: tooltip?.title ?? title },
icon
)
: null
);
}, [ api, item.children, item.isComponent ] );
}

/**
* Renders the item name and any associated badge icons.
*/
function Label( { item } ) {
const iconSet = useIcons( item );
const title = createElement( Title, {}, item.name );
const icons = createElement( Icons, { 'aria-hidden': true }, ...iconSet );

return createElement( Wrapper, {}, title, icons );
}

export default {
// Renders status icons for items tagged with `status-*`
renderLabel: ( item ) => createElement( Label, { item } ),
};

0 comments on commit 0e0fd19

Please sign in to comment.