diff --git a/examples/official-storybook/stories/addon-docs/mixed-leaves-component.stories.js b/examples/official-storybook/stories/addon-docs/mixed-leaves-component.stories.js new file mode 100644 index 000000000000..3d6a49874f1c --- /dev/null +++ b/examples/official-storybook/stories/addon-docs/mixed-leaves-component.stories.js @@ -0,0 +1,13 @@ +// This example exists solely to demonstrate nav hierarchy +// in --docs mode when a folder contains both a component and +// individual stories +// +// See also ./mixed-leaves-folder.stories.js + +export default { + title: 'Addons/Docs/Mixed Leaves/Component', + parameters: { chromatic: { disable: true } }, +}; + +export const B = () => 'b'; +export const C = () => 'c'; diff --git a/examples/official-storybook/stories/addon-docs/mixed-leaves-folder.stories.js b/examples/official-storybook/stories/addon-docs/mixed-leaves-folder.stories.js new file mode 100644 index 000000000000..2f9216606fe9 --- /dev/null +++ b/examples/official-storybook/stories/addon-docs/mixed-leaves-folder.stories.js @@ -0,0 +1,12 @@ +// This example exists solely to demonstrate nav hierarchy +// in --docs mode when a folder contains both a component and +// individual stories +// +// See also ./mixed-leaves-component.stories.js + +export default { + title: 'Addons/Docs/Mixed Leaves', + parameters: { chromatic: { disable: true } }, +}; + +export const A = () => 'a'; diff --git a/examples/official-storybook/stories/core/named-export-order.stories.js b/examples/official-storybook/stories/core/named-export-order.stories.js index 34c54ca0e2e8..03fda7eb5bcf 100644 --- a/examples/official-storybook/stories/core/named-export-order.stories.js +++ b/examples/official-storybook/stories/core/named-export-order.stories.js @@ -1,7 +1,6 @@ -import React from 'react'; - export default { title: 'Core/Named Export Order', + parameters: { chromatic: { disable: true } }, }; export const Story1 = () => 'story1'; diff --git a/lib/ui/src/containers/nav.js b/lib/ui/src/containers/nav.js index 9bc5dc0533e8..0989c6ac84d0 100755 --- a/lib/ui/src/containers/nav.js +++ b/lib/ui/src/containers/nav.js @@ -4,7 +4,6 @@ import memoize from 'memoizerific'; import { Badge } from '@storybook/components'; import { Consumer } from '@storybook/api'; -import { logger } from '@storybook/client-logger'; import { shortcutToHumanString } from '../libs/shortcut'; @@ -114,11 +113,19 @@ export const collapseAllStories = stories => { const componentIdToLeafId = {}; // 1) remove all leaves - const leavesRemoved = Object.values(stories).filter(item => !item.isLeaf); + const leavesRemoved = Object.values(stories).filter( + item => !(item.isLeaf && stories[item.parent].isComponent) + ); // 2) make all components leaves and rewrite their ID's to the first leaf child const componentsFlattened = leavesRemoved.map(item => { const { id, isComponent, children, ...rest } = item; + + // this is a folder, so just leave it alone + if (!isComponent) { + return item; + } + const nonLeafChildren = []; const leafChildren = []; children.forEach(child => (stories[child].isLeaf ? leafChildren : nonLeafChildren).push(child)); @@ -131,21 +138,13 @@ export const collapseAllStories = stories => { const component = { ...rest, id: leafId, isLeaf: true, isComponent: true }; componentIdToLeafId[id] = leafId; - if ( - (isComponent && nonLeafChildren.length > 0) || - (!isComponent && nonLeafChildren.length === 0) - ) { + // this is a component, so it should not have any non-leaf children + if (nonLeafChildren.length !== 0) { throw new Error( `Unexpected '${item.id}': ${JSON.stringify({ isComponent, nonLeafChildren })}` ); } - if (nonLeafChildren.length > 0) { - logger.error( - `Node ${item.id} contains non-leaf nodes that are getting removed: ${nonLeafChildren}!` - ); - } - return component; }); diff --git a/lib/ui/src/containers/nav.test.js b/lib/ui/src/containers/nav.test.js index 91ece2ac1feb..96ef56a634f2 100644 --- a/lib/ui/src/containers/nav.test.js +++ b/lib/ui/src/containers/nav.test.js @@ -58,12 +58,35 @@ describe('collapse all stories', () => { ...stories, a1: { ...a1, ...docsOnly }, }; - const filtered = collapseAllStories(hasDocsOnly); - expect(filtered.a1).toEqual({ + const collapsed = collapseAllStories(hasDocsOnly); + expect(collapsed.a1).toEqual({ id: 'a1', isComponent: true, isLeaf: true, parent: 'root', }); }); + it('collapses mixtures of leaf and non-leaf children', () => { + const mixedRoot = { id: 'root', parent: false, children: ['a', 'b1'] }; + const mixed = { root: mixedRoot, a, a1, b1: { ...b1, parent: 'root' } }; + const collapsed = collapseAllStories(mixed); + expect(collapsed).toEqual({ + a1: { + id: 'a1', + isComponent: true, + isLeaf: true, + parent: 'root', + }, + b1: { + id: 'b1', + isLeaf: true, + parent: 'root', + }, + root: { + children: ['a1', 'b1'], + id: 'root', + parent: false, + }, + }); + }); });