Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Add renderLabel to customize sidebar tree labels #13121

Merged
merged 5 commits into from
Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/configure/features-and-behavior.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ The following options are configurable under the `sidebar` namespace:
| ----------------------|:-------------:|:-------------------------------------------------------------:|:----------------------------------------------:|
| **showRoots** | Boolean |Display the top-level nodes as a "root" in the sidebar |`false` |
| **collapsedRoots** | Array |Set of root node IDs to visually collapse by default |`['misc', 'other']` |
| **renderLabel** | Function |Create a custom label for tree nodes; must return a ReactNode |`(item) => <abbr title="...">{item.name}</abbr>`|
42 changes: 41 additions & 1 deletion examples/official-storybook/manager.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import React from 'react';
import { addons } from '@storybook/addons';
import { themes } from '@storybook/theming';
import { themes, styled } from '@storybook/theming';
import { Icons } from '@storybook/components';

import addHeadWarning from './head-warning';

addHeadWarning('manager-head-not-loaded', 'Manager head not loaded');

const PrefixIcon = styled(Icons)(({ theme }) => ({
marginRight: 8,
fontSize: 'inherit',
height: '1em',
width: '1em',
display: 'inline',
alignSelf: 'center',
}));

addons.setConfig({
theme: themes.light, // { base: 'dark', brandTitle: 'Storybook!' },
previewTabs: {
Expand All @@ -17,5 +28,34 @@ addons.setConfig({
},
sidebar: {
collapsedRoots: ['other'],
renderLabel: ({ id, name }) => {
const map = {
addons: (
<>
<PrefixIcon icon="power" />
{name}
</>
),
'addons-a11y': (
<>
<PrefixIcon icon="certificate" />
{name}
</>
),
'addons-a11y-basebutton': (
<>
<PrefixIcon icon="calendar" />
{name}
</>
),
'addons-a11y-basebutton--default': (
<>
<PrefixIcon icon="star" />
{name}
</>
),
};
return map[id];
},
},
});
19 changes: 14 additions & 5 deletions lib/api/src/lib/stories.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from 'react';
import deprecate from 'util-deprecate';
import dedent from 'ts-dedent';
import { sanitize } from '@storybook/csf';
Expand All @@ -19,6 +20,7 @@ export interface Root {
isComponent: false;
isRoot: true;
isLeaf: false;
label?: React.ReactNode;
startCollapsed?: boolean;
}

Expand All @@ -32,6 +34,7 @@ export interface Group {
isComponent: boolean;
isRoot: false;
isLeaf: false;
label?: React.ReactNode;
// MDX docs-only stories are "Group" type
parameters?: {
docsOnly?: boolean;
Expand All @@ -50,6 +53,7 @@ export interface Story {
isComponent: boolean;
isRoot: false;
isLeaf: true;
label?: React.ReactNode;
parameters?: {
fileName: string;
options: {
Expand Down Expand Up @@ -153,7 +157,7 @@ export const transformStoriesRawToStoriesHash = (
const storiesHashOutOfOrder = values.reduce((acc, item) => {
const { kind, parameters } = item;
const { sidebar = {}, showRoots: deprecatedShowRoots } = provider.getConfig();
const { showRoots = deprecatedShowRoots, collapsedRoots = [] } = sidebar;
const { showRoots = deprecatedShowRoots, collapsedRoots = [], renderLabel } = sidebar;

if (typeof deprecatedShowRoots !== 'undefined') {
warnLegacyShowRoots();
Expand Down Expand Up @@ -182,7 +186,7 @@ export const transformStoriesRawToStoriesHash = (
}

if (root.length && index === 0) {
list.push({
const rootElement: Root = {
id,
name,
depth: index,
Expand All @@ -191,9 +195,10 @@ export const transformStoriesRawToStoriesHash = (
isLeaf: false,
isRoot: true,
startCollapsed: collapsedRoots.includes(id),
});
};
list.push({ ...rootElement, label: renderLabel?.(rootElement) });
} else {
list.push({
const groupElement: Group = {
id,
name,
parent,
Expand All @@ -206,6 +211,10 @@ export const transformStoriesRawToStoriesHash = (
docsOnly: parameters?.docsOnly,
viewMode: parameters?.viewMode,
},
};
list.push({
...groupElement,
label: renderLabel?.(groupElement),
});
}

Expand All @@ -232,7 +241,7 @@ export const transformStoriesRawToStoriesHash = (
isComponent: false,
isRoot: false,
};
acc[item.id] = story;
acc[item.id] = { ...story, label: renderLabel?.(story) };

return acc;
}, {} as StoriesHash);
Expand Down
3 changes: 2 additions & 1 deletion lib/api/src/modules/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { ReactNode } from 'react';
import { Channel } from '@storybook/channels';
import { ThemeVars } from '@storybook/theming';

import { API, State, ModuleFn } from '../index';
import { API, State, ModuleFn, Root, Group, Story } from '../index';
import { StoryMapper, Refs } from './refs';
import { UIOptions } from './layout';

interface SidebarOptions {
showRoots?: boolean;
collapsedRoots?: string[];
renderLabel?: (item: Root | Group | Story) => ReactNode;
}

type IframeRenderer = (
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/src/components/sidebar/Tree.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const singleStoryComponent = {
isComponent: true,
isLeaf: false,
isRoot: false,
label: <span>🔥 Single</span>,
},
'single--single': {
id: 'single--single',
Expand All @@ -58,6 +59,7 @@ const singleStoryComponent = {
isLeaf: true,
isComponent: false,
isRoot: false,
label: <span>🔥 Single</span>,
},
};

Expand Down
6 changes: 3 additions & 3 deletions lib/ui/src/components/sidebar/Tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const Node = React.memo<NodeProps>(
onSelectStoryId(item.id);
}}
>
{item.name}
{item.label || item.name}
</LeafNode>
);
}
Expand All @@ -162,7 +162,7 @@ const Node = React.memo<NodeProps>(
}}
>
<CollapseIcon isExpanded={isExpanded} />
{item.name}
{item.label || item.name}
</CollapseButton>
{isExpanded && (
<Action
Expand Down Expand Up @@ -205,7 +205,7 @@ const Node = React.memo<NodeProps>(
if (item.isComponent && !isExpanded) onSelectStoryId(item.id);
}}
>
{item.name}
{item.label || item.name}
</BranchNode>
);
}
Expand Down