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

Indexer: Add metaTags and make autodocs inherit them #25537

Merged
merged 7 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
48 changes: 48 additions & 0 deletions code/e2e-tests/tags.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { test, expect } from '@playwright/test';
import { SbPage } from './util';

const storybookUrl = process.env.STORYBOOK_URL || 'http://localhost:8001';

test.describe('tags', () => {
test.beforeEach(async ({ page }) => {
await page.goto(storybookUrl);
await new SbPage(page).waitUntilLoaded();
});

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');

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

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

const testOnlyEntry = await page.locator('#lib-preview-api-tags--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();
expect(devOnlyAnchor.length).toBe(0);

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

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

test('should correctly filter out test-only autodocs pages', async ({ page }) => {
const sbPage = new SbPage(page);
await sbPage.selectToolbar('#lib-preview-api');

// 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);
});
});
7 changes: 1 addition & 6 deletions code/lib/core-server/src/presets/common-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ const excludeTags = Object.entries(global.TAGS_OPTIONS ?? {}).reduce((acc, entry
addons.register(STATIC_FILTER, (api) => {
api.experimental_setFilter(STATIC_FILTER, (item) => {
const tags = item.tags || [];
// very strange behavior here. Auto-generated docs entries get
// the tags of the primary story by default, so if that story
// happens to be `docs-only`, then filtering it out of the sidebar
// ALSO filter out the sidebar entry, which is not what we want.
// Here we special case it, but there should be a better solution.
return tags.includes('docs') || tags.filter((tag) => excludeTags[tag]).length === 0;
return tags.filter((tag) => excludeTags[tag]).length === 0;
});
});
5 changes: 3 additions & 2 deletions code/lib/core-server/src/utils/StoryIndexGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,15 @@ export class StoryIndexGenerator {
const name = this.options.docs.defaultName ?? 'Docs';
const { metaId } = indexInputs[0];
const { title } = entries[0];
const tags = indexInputs[0].tags || [];
const metaTags = indexInputs[0].metaTags || [];
const id = toId(metaId ?? title, name);
entries.unshift({
id,
title,
name,
importPath,
type: 'docs',
tags: [...tags, 'docs', ...(!hasAutodocsTag && !isStoriesMdx ? [AUTODOCS_TAG] : [])],
tags: [...metaTags, 'docs', ...(!hasAutodocsTag && !isStoriesMdx ? [AUTODOCS_TAG] : [])],
storiesImports: [],
});
}
Expand Down Expand Up @@ -438,6 +438,7 @@ export class StoryIndexGenerator {
importPath,
storiesImports: sortedDependencies.map((dep) => dep.entries[0].importPath),
type: 'docs',
// FIXME: update this to use the index entry's metaTags once we update this to run on `IndexInputs`
tags: [...(result.tags || []), csfEntry ? 'attached-mdx' : 'unattached-mdx', 'docs'],
};
return docsEntry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,6 @@ describe('docs entries from story extraction', () => {
"name": "docs",
"storiesImports": [],
"tags": [
"story-tag-from-indexer",
"docs",
"autodocs",
],
Expand Down Expand Up @@ -467,8 +466,6 @@ describe('docs entries from story extraction', () => {
"name": "docs",
"storiesImports": [],
"tags": [
"autodocs",
"story-tag-from-indexer",
"docs",
],
"title": "A",
Expand Down Expand Up @@ -578,8 +575,6 @@ describe('docs entries from story extraction', () => {
"name": "docs",
"storiesImports": [],
"tags": [
"stories-mdx",
"story-tag-from-indexer",
"docs",
],
"title": "A",
Expand Down
10 changes: 10 additions & 0 deletions code/lib/csf-tools/src/CsfFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,8 @@ describe('CsfFile', () => {
- component-tag
- story-tag
- play-fn
metaTags: &ref_0
- component-tag
__id: component-id--a
- type: story
importPath: foo/bar.stories.js
Expand All @@ -1109,6 +1111,7 @@ describe('CsfFile', () => {
- component-tag
- story-tag
- play-fn
metaTags: *ref_0
__id: component-id--b
`);
});
Expand Down Expand Up @@ -1138,6 +1141,8 @@ describe('CsfFile', () => {
metaId: component-id
tags:
- component-tag
metaTags:
- component-tag
__id: custom-story-id
`);
});
Expand Down Expand Up @@ -1169,6 +1174,11 @@ describe('CsfFile', () => {
- inherit-tag-dup
- story-tag
- story-tag-dup
metaTags:
- component-tag
- component-tag-dup
- component-tag-dup
- inherit-tag-dup
__id: custom-foo-title--a
`);
});
Expand Down
1 change: 1 addition & 0 deletions code/lib/csf-tools/src/CsfFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ export class CsfFile {
title: this.meta?.title,
metaId: this.meta?.id,
tags,
metaTags: this.meta?.tags,
__id: story.id,
};
});
Expand Down
16 changes: 15 additions & 1 deletion code/lib/preview-api/template/stories/tags.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { expect } from '@storybook/jest';

export default {
component: globalThis.Components.Pre,
tags: ['component-one', 'component-two'],
tags: ['component-one', 'component-two', 'autodocs'],
decorators: [
(storyFn: PartialStoryFn, context: StoryContext) => {
return storyFn({
args: { object: { tags: context.tags } },
});
},
],
parameters: { chromatic: { disable: true } },
};

export const Inheritance = {
Expand All @@ -23,4 +24,17 @@ export const Inheritance = {
tags: ['story-one', 'story-two', 'story'],
});
},
parameters: { chromatic: { disable: false } },
};

export const DocsOnly = {
tags: ['docs-only'],
};

export const TestOnly = {
tags: ['test-only'],
};

export const DevOnly = {
tags: ['dev-only'],
};
11 changes: 11 additions & 0 deletions code/lib/preview-api/template/stories/test-only-tag.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { global as globalThis } from '@storybook/global';

export default {
component: globalThis.Components.Button,
tags: ['autodocs', 'test-only'],
parameters: { chromatic: { disable: true } },
};

export const Default = {
args: { label: 'Button' },
};
2 changes: 2 additions & 0 deletions code/lib/types/src/modules/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ export type BaseIndexInput = {
metaId?: MetaId;
/** Tags for filtering entries in Storybook and its tools. */
tags?: Tag[];
/** Tags from the meta for filtering entries in Storybook and its tools. */
metaTags?: Tag[];
/**
* The id of the entry, auto-generated from {@link title}/{@link metaId} and {@link exportName} if unspecified.
* If specified, the story in the CSF file _must_ have a matching id set at `parameters.__id`, to be correctly matched.
Expand Down