Skip to content

Commit

Permalink
chore: update storybook IA (#1096)
Browse files Browse the repository at this point in the history
* chore: create a master storybook structure

* chore: fill out the storybook structure

* chore: add name spacing and use storybook structure for all components

* chore: enable renaming and add legacy tags

* chore: update CDAI story helper test
  • Loading branch information
dcwarwick authored Aug 18, 2021
1 parent 27a90aa commit 00c7afd
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 113 deletions.
8 changes: 0 additions & 8 deletions packages/cdai/config.js

This file was deleted.

13 changes: 9 additions & 4 deletions packages/cdai/src/component_helpers/StorybookHelper.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
//
// Copyright IBM Corp. 2020, 2020
// Copyright IBM Corp. 2020, 2021
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

import { sectionTitle } from '../../config';
import { getPathForComponent } from '../../../core/story-structure';

export const getComponentLabel = (component) => {
return `${sectionTitle}/${component}`;
export const getComponentLabel = (componentName) => {
const title =
// if the component isn't in the master structure, put it in a lost+found section
getPathForComponent('a', componentName) ||
`Cloud & Cognitive/Lost + found/${componentName}`;

return title;
};
4 changes: 3 additions & 1 deletion packages/cdai/src/component_helpers/StorybookHelper.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { getComponentLabel } from './StorybookHelper';

describe('getComponentLabel', () => {
it('returns the expected output for a component', () => {
expect(getComponentLabel('IdeButton')).toEqual('Legacy/CD&AI/IdeButton');
expect(getComponentLabel('IdeButton')).toEqual(
'CD&AI legacy/Components/IdeButton#legacy'
);
});
});
84 changes: 11 additions & 73 deletions packages/cloud-cognitive/src/global/js/utils/story-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,86 +7,24 @@

import { sanitize } from '@storybook/csf';
import pkg from '../package-settings';

// A set of title values, one for each component, that can be converted into
// a structure story title or into an individual story id in slug form.
const lib = 'Cloud & Cognitive';
const storybookStructure = {
AboutModal: `${lib}/$rci/$comp`,
ActionBar: `${lib}/$rci/$comp`,
ActionSet: `${lib}/$rci/$comp`,
APIKeyModal: `${lib}/$rci/$comp`,
BreadcrumbWithOverflow: `${lib}/$rci/$comp`,
ButtonMenu: `${lib}/$rci/$comp`,
ButtonSetWithOverflow: `${lib}/$rci/$comp`,

// cards
ExpressiveCard: `${lib}/$rci/Cards/$comp`,
ProductiveCard: `${lib}/$rci/Cards/$comp`,

ComboButton: `${lib}/$rci/$comp`,
CreateFullPage: `${lib}/$rci/$comp`,
CreateModal: `${lib}/$rci/$comp`,
CreateSidePanel: `${lib}/$rci/$comp`,
CreateTearsheet: `${lib}/$rci/$comp`,
CreateTearsheetNarrow: `${lib}/$rci/$comp`,

// empty states
EmptyState: `${lib}/$rci/EmptyStates/$comp`,
ErrorEmptyState: `${lib}/$rci/EmptyStates/$comp`,
NoDataEmptyState: `${lib}/$rci/EmptyStates/$comp`,
NoTagsEmptyState: `${lib}/$rci/EmptyStates/$comp`,
NotFoundEmptyState: `${lib}/$rci/EmptyStates/$comp`,
NotificationsEmptyState: `${lib}/$rci/EmptyStates/$comp`,
UnauthorizedEmptyState: `${lib}/$rci/EmptyStates/$comp`,

ExampleComponent: `${lib}/$rci/$comp`,
ExportModal: `${lib}/$rci/$comp`,

// HTTP errors
HTTPError403: `${lib}/$rci/HTTPErrors/$comp`,
HTTPError404: `${lib}/$rci/HTTPErrors/$comp`,
HTTPErrorOther: `${lib}/$rci/HTTPErrors/$comp`,

ImportModal: `${lib}/$rci/$comp`,
LoadingBar: `${lib}/$rci/$comp`,
ModifiedTabs: `${lib}/$rci/$comp`,
NotificationsPanel: `${lib}/$rci/$comp`,
PageHeader: `${lib}/$rci/$comp`,
RemoveModal: `${lib}/$rci/$comp`,
Saving: `${lib}/$rci/$comp`,
SidePanel: `${lib}/$rci/$comp`,
StatusIcon: `${lib}/$rci/$comp`,
TagSet: `${lib}/$rci/$comp`,
Toolbar: `${lib}/$rci/$comp`,
UserProfileImage: `${lib}/$rci/$comp`,
WebTerminal: `${lib}/$rci/$comp`,

// tearsheets
Tearsheet: `${lib}/$rci/Tearsheets/$comp`,
TearsheetNarrow: `${lib}/$rci/Tearsheets/$comp`,
TearsheetShell: `${lib}/$rci/$comp`,
};
import { getPathForComponent } from '../../../../../core/story-structure';

/**
* A helper function to return the structured story title for a component.
* @param {string} componentName The name of the component.
* @returns The structured story title.
*/
export const getStoryTitle = (componentName) => {
const replacements = {
$rci: pkg.isComponentEnabled(componentName, true)
? 'Released'
: pkg.isComponentPublic(componentName, true)
? 'Canary'
: 'Internal',
$comp: componentName,
};

return Object.keys(replacements).reduce(
(result, token) => result.replaceAll(token, replacements[token]),
storybookStructure[componentName] || `${lib}/Lost + Found/$comp`
);
const title =
// if the component isn't in the master structure, put it in a lost+found section
getPathForComponent('c', componentName) ||
`Cloud & Cognitive/Lost + found/${componentName}`;

// add a canary tag if the component is public but not normally enabled
return !pkg.isComponentEnabled(componentName, true) &&
pkg.isComponentPublic(componentName, true)
? `${title}#canary`
: title;
};

/**
Expand Down
28 changes: 28 additions & 0 deletions packages/core/.storybook/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,34 @@ addons.setConfig({
</div>
);

// if the name has #legacy then render a 'Legacy' tag on the right
case 'legacy':
return (
<div
style={{
flex: '1 0 auto',
display: 'flex',
alignItems: 'stretch',
justifyContent: 'space-between',
}}>
{parts[0]}
<div
style={{
background: dark ? '#3a3a3a' : '#eeeeee',
/* stylelint-disable-next-line carbon/type-token-use */
fontSize: '11px',
border: '.1px solid transparent',
/* stylelint-disable-next-line carbon/layout-token-use */
padding: '0 .5rem',
/* stylelint-disable-next-line carbon/layout-token-use */
margin: '0 .5em',
borderRadius: '8px',
}}>
Legacy
</div>
</div>
);

// if the name doesn't have a recognized # label, just render the name
default:
return parts[0];
Expand Down
38 changes: 13 additions & 25 deletions packages/core/.storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { withCarbonTheme } from '@carbon/storybook-addon-theme/react';
import { pkg } from '../../cloud-cognitive/src/settings';

import index from './index.scss';
import { getSectionSequence } from '../story-structure';

// Enable all components, whether released or not, for storybook purposes
pkg._silenceWarnings(true);
Expand Down Expand Up @@ -45,18 +46,6 @@ const decorators = [
withCarbonTheme,
];

const order = [
'Cloud & Cognitive/Released',
'Cloud & Cognitive/Canary',
'Cloud & Cognitive/Internal',
'Legacy',
];
const toOrder = (value) => {
const inOrder = order.findIndex((item) => value.startsWith(item));
// length is last index + 1
return inOrder < 0 ? order.length : inOrder;
};

const makeViewport = (name, width, shadow) => ({
name,
styles: {
Expand Down Expand Up @@ -90,19 +79,18 @@ const parameters = {
layout: 'centered',
options: {
storySort: (a, b) => {
// const storybookOrder = ['Cloud & Cognitive', ['Released', 'Canary'], 'Legacy'];
const aInOrder = toOrder(a[1].kind);
const bInOrder = toOrder(b[1].kind);

if (aInOrder !== bInOrder) {
return aInOrder - bInOrder;
} else {
// from storybook doc example https://storybook.js.org/docs/react/writing-stories/naming-components-and-hierarchy
return a[1].kind === b[1].kind
? (a[1]?.parameters?.ccsSettings?.sequence || 0) -
(b[1]?.parameters?.ccsSettings?.sequence || 0)
: a[1].id.localeCompare(b[1].id, undefined, { numeric: true });
}
const aPosition = getSectionSequence(a[1].kind);
const bPosition = getSectionSequence(b[1].kind);

return aPosition !== bPosition
? // if stories have different positions in the structure, sort by that
aPosition - bPosition
: a[1].kind === b[1].kind
? // if they have the same kind, use their sequence numbers
(a[1]?.parameters?.ccsSettings?.sequence || 0) -
(b[1]?.parameters?.ccsSettings?.sequence || 0)
: // they must both be unrecognized: fall back to sorting by id (slug)
a[1].id.localeCompare(b[1].id, undefined, { numeric: true });
},
},

Expand Down
Loading

0 comments on commit 00c7afd

Please sign in to comment.