Skip to content

Commit

Permalink
Merge pull request #26634 from storybookjs/shilman/add-tag-exclusion
Browse files Browse the repository at this point in the history
Tags: Add project tags, negation, `dev`/`autodocs`/`test` system tags
  • Loading branch information
shilman authored May 7, 2024
2 parents c6348d2 + 2dee030 commit e62d7f3
Show file tree
Hide file tree
Showing 42 changed files with 581 additions and 256 deletions.
46 changes: 43 additions & 3 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<h1>Migration</h1>

- [From version 8.0.x to 8.1.x](#from-version-80x-to-81x)
- [Subtitle block and `parameters.componentSubtitle`](#subtitle-block-and-parameterscomponentsubtitle)
- [Title block](#title-block)
- [Portable stories](#portable-stories)
- [@storybook/nextjs requires specific path aliases to be setup](#storybooknextjs-requires-specific-path-aliases-to-be-setup)
- [main.js `docs.autodocs` is deprecated](#mainjs-docsautodocs-is-deprecated)
- [`docs` and `story` system tags removed](#docs-and-story-system-tags-removed)
- [Subtitle block and `parameters.componentSubtitle`](#subtitle-block-and-parameterscomponentsubtitle)
- [Title block `of` prop](#title-block-of-prop)
- [From version 7.x to 8.0.0](#from-version-7x-to-800)
- [Portable stories](#portable-stories-1)
- [Project annotations are now merged instead of overwritten in composeStory](#project-annotations-are-now-merged-instead-of-overwritten-in-composestory)
Expand Down Expand Up @@ -430,13 +432,51 @@ module.exports = createJestConfig(customJestConfig);

This will make sure you end using the correct implementation of the packages and avoid having issues in your tests.

### main.js `docs.autodocs` is deprecated

The `docs.autodocs` setting in `main.js` is deprecated in 8.1 and will be removed in 9.0.

It has been replaced with a tags-based system which is more flexible than before.

`docs.autodocs` takes three values:
- `true`: generate autodocs for every component
- `false`: don't generate autodocs at all
- `tag`: generate autodocs for components that have been tagged `'autodocs'`.

Starting in 8.1, to generate autodocs for every component (`docs.autodocs = true`), add the following code to `.storybook/preview.js`:

```js
// .storybook/preview.js
export default {
tags: ['autodocs'],
}
```

Tags cascade, so setting `'autodocs'` at the project level automatically propagates to every component and story. If you set autodocs globally and want to opt-out for a particular component, you can remove the `'autodocs'` tag for a component like this:

```js
// Button.stories.ts
export default {
component: Button,
tags: ['!autodocs'],
}
```

If you had set `docs.autodocs = 'tag'`, the default setting, you can remove the setting from `.storybook/main.js`. That is now the default behavior.

If you had set `docs.autodocs = false`, this still works in 8.x, but will go away in 9.0 as a breaking change. If you don't want autodocs at all, simply remove the `'autodocs'` tag throughout your Storybook and autodocs will not be created.

### `docs` and `story` system tags removed

Storybook automatically added the tag `'docs'` to any docs entry in the index and `'story'` to any story entry in the index. This behavior was undocumented, and in an effort to reduce the number of tags we've removed them in 8.1. If you depended on these tags, please file an issue on the [Storybook monorepo](https://github.com/storybookjs/storybook) and let us know!

### Subtitle block and `parameters.componentSubtitle`

The `Subtitle` block now accepts an `of` prop, which can be a reference to a CSF file or a default export (meta).

`parameters.componentSubtitle` has been deprecated to be consistent with other parameters related to autodocs, instead use `parameters.docs.subtitle`.

##### Title block
### Title block `of` prop

The `Title` block now accepts an `of` prop, which can be a reference to a CSF file or a default export (meta).

Expand Down
4 changes: 3 additions & 1 deletion code/addons/docs/src/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export const parameters: any = {
filter: (story: PreparedStory) => {
const tags = story.tags || [];
return (
tags.filter((tag) => excludeTags[tag]).length === 0 && !story.parameters.docs?.disable
tags.includes('autodocs') &&
tags.filter((tag) => excludeTags[tag]).length === 0 &&
!story.parameters.docs?.disable
);
},
},
Expand Down
2 changes: 1 addition & 1 deletion code/addons/links/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/addon-bundle.ts"
},
"dependencies": {
"@storybook/csf": "^0.1.6",
"@storybook/csf": "^0.1.7",
"@storybook/global": "^5.0.0",
"ts-dedent": "^2.0.0"
},
Expand Down
92 changes: 66 additions & 26 deletions code/e2e-tests/tags.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,96 @@ test.describe('tags', () => {
await new SbPage(page).waitUntilLoaded();
});

test('@flaky: should correctly filter dev-only, docs-only, test-only stories', async ({
page,
}) => {
test('should correctly filter dev-only, docs-only, test-only stories', async ({ page }) => {
const sbPage = new SbPage(page);

await sbPage.navigateToStory('lib/preview-api/tags', 'docs');
await sbPage.navigateToStory('lib/preview-api/tags-config', 'docs');

// Sidebar should include dev-only and exclude docs-only and test-only
const devOnlyEntry = await page.locator('#lib-preview-api-tags--dev-only').all();
const devOnlyEntry = await page.locator('#lib-preview-api-tags-config--dev-only').all();
expect(devOnlyEntry.length).toBe(1);

const docsOnlyEntry = await page.locator('#lib-preview-api-tags--docs-only').all();
const docsOnlyEntry = await page.locator('#lib-preview-api-tags-config--docs-only').all();
expect(docsOnlyEntry.length).toBe(0);

const testOnlyEntry = await page.locator('#lib-preview-api-tags--test-only').all();
const testOnlyEntry = await page.locator('#lib-preview-api-tags-config--test-only').all();
expect(testOnlyEntry.length).toBe(0);

// Autodocs should include docs-only and exclude dev-only and test-only
const root = sbPage.previewRoot();

const devOnlyAnchor = await root.locator('#anchor--lib-preview-api-tags--dev-only').all();
const devOnlyAnchor = await root
.locator('#anchor--lib-preview-api-tags-config--dev-only')
.all();
expect(devOnlyAnchor.length).toBe(0);

const docsOnlyAnchor = await root.locator('#anchor--lib-preview-api-tags--docs-only').all();
const docsOnlyAnchor = await root
.locator('#anchor--lib-preview-api-tags-config--docs-only')
.all();
expect(docsOnlyAnchor.length).toBe(1);

const testOnlyAnchor = await root.locator('#anchor--lib-preview-api-tags--test-only').all();
const testOnlyAnchor = await root
.locator('#anchor--lib-preview-api-tags-config--test-only')
.all();
expect(testOnlyAnchor.length).toBe(0);
});

test('should correctly filter out test-only autodocs pages', async ({ page }) => {
test('should correctly add dev, autodocs, test stories', async ({ page }) => {
const sbPage = new SbPage(page);

await sbPage.selectToolbar('#lib-preview-api');
await sbPage.navigateToStory('lib/preview-api/tags-add', 'docs');

// Sidebar should exclude test-only stories and their docs
const componentEntry = await page.locator('#lib-preview-api-test-only-tag').all();
expect(componentEntry.length).toBe(0);
// Sidebar should include dev and exclude inheritance, autodocs, test
const devEntry = await page.locator('#lib-preview-api-tags-add--dev').all();
expect(devEntry.length).toBe(1);

// Even though test-only autodocs not sidebar, it is still in the preview
// Even though the test-only story is filtered out of the stories, it is still the primary story (should it be?)
await sbPage.deepLinkToStory(storybookUrl, 'lib/preview-api/test-only-tag', 'docs');
await sbPage.waitUntilLoaded();
const docsButton = await sbPage.previewRoot().locator('button', { hasText: 'Button' });
await expect(docsButton).toBeVisible();
const autodocsEntry = await page.locator('#lib-preview-api-tags-add--autodocs').all();
expect(autodocsEntry.length).toBe(0);

// Even though test-only story not sidebar, it is still in the preview
await sbPage.deepLinkToStory(storybookUrl, 'lib/preview-api/test-only-tag', 'default');
await sbPage.waitUntilLoaded();
const storyButton = await sbPage.previewRoot().locator('button', { hasText: 'Button' });
await expect(storyButton).toBeVisible();
const testOnlyEntry = await page.locator('#lib-preview-api-tags-add--test').all();
expect(testOnlyEntry.length).toBe(0);

// Autodocs should include autodocs and exclude dev, test
const root = sbPage.previewRoot();

const devAnchor = await root.locator('#anchor--lib-preview-api-tags-add--dev').all();
expect(devAnchor.length).toBe(0);

// FIXME: shows as primary story and also in stories, inconsistent btw dev/CI?
const autodocsAnchor = await root.locator('#anchor--lib-preview-api-tags-add--autodocs').all();
expect(autodocsAnchor.length).not.toBe(0);

const testAnchor = await root.locator('#anchor--lib-preview-api-tags-add--test').all();
expect(testAnchor.length).toBe(0);
});

test('should correctly remove dev, autodocs, test stories', async ({ page }) => {
const sbPage = new SbPage(page);

await sbPage.navigateToStory('lib/preview-api/tags-remove', 'docs');

// Sidebar should include inheritance, no-autodocs, no-test. and exclude no-dev
const noDevEntry = await page.locator('#lib-preview-api-tags-remove--no-dev').all();
expect(noDevEntry.length).toBe(0);

const noAutodocsEntry = await page.locator('#lib-preview-api-tags-remove--no-autodocs').all();
expect(noAutodocsEntry.length).toBe(1);

const noTestEntry = await page.locator('#lib-preview-api-tags-remove--no-test').all();
expect(noTestEntry.length).toBe(1);

// Autodocs should include inheritance, no-dev, no-test. and exclude no-autodocs
const root = sbPage.previewRoot();

const noDevAnchor = await root.locator('#anchor--lib-preview-api-tags-remove--no-dev').all();
expect(noDevAnchor.length).toBe(1);

const noAutodocsAnchor = await root
.locator('#anchor--lib-preview-api-tags-remove--no-autodocs')
.all();
expect(noAutodocsAnchor.length).toBe(0);

const noTestAnchor = await root.locator('#anchor--lib-preview-api-tags-remove--no-test').all();
expect(noTestAnchor.length).toBe(1);
});
});
1 change: 0 additions & 1 deletion code/lib/cli/src/generators/baseGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,6 @@ export async function baseGenerator(
},
prefixes,
storybookConfigFolder,
docs: { autodocs: 'tag' },
addons: shouldApplyRequireWrapperOnPackageNames
? addons.map((addon) => applyRequireWrapper(addon))
: addons,
Expand Down
2 changes: 1 addition & 1 deletion code/lib/codemod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"@babel/core": "^7.24.4",
"@babel/preset-env": "^7.24.4",
"@babel/types": "^7.24.0",
"@storybook/csf": "^0.1.6",
"@storybook/csf": "^0.1.7",
"@storybook/csf-tools": "workspace:*",
"@storybook/node-logger": "workspace:*",
"@storybook/types": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion code/lib/core-events/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"prep": "node --loader ../../../scripts/node_modules/esbuild-register/loader.js -r ../../../scripts/node_modules/esbuild-register/register.js ../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/csf": "^0.1.5",
"@storybook/csf": "^0.1.7",
"ts-dedent": "^2.0.0"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions code/lib/core-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@
"@storybook/channels": "workspace:*",
"@storybook/core-common": "workspace:*",
"@storybook/core-events": "workspace:*",
"@storybook/csf": "^0.1.6",
"@storybook/csf": "^0.1.7",
"@storybook/csf-tools": "workspace:*",
"@storybook/docs-mdx": "3.0.0",
"@storybook/docs-mdx": "3.1.0-next.0",
"@storybook/global": "^5.0.0",
"@storybook/manager": "workspace:*",
"@storybook/manager-api": "workspace:*",
Expand Down
8 changes: 6 additions & 2 deletions code/lib/core-server/src/presets/common-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ addons.register(STATIC_FILTER, (api) => {
);

api.experimental_setFilter(STATIC_FILTER, (item) => {
const tags = item.tags || [];
return tags.filter((tag) => excludeTags[tag]).length === 0;
const tags = item.tags ?? [];
return (
// we can filter out the primary story, but we still want to show autodocs
(tags.includes('dev') || item.type === 'docs') &&
tags.filter((tag) => excludeTags[tag]).length === 0
);
});
});
Loading

0 comments on commit e62d7f3

Please sign in to comment.