mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-05 16:11:33 +08:00
Merge branch 'next' into norbert/sb-799-create-a-storybooktypes-cleanup
This commit is contained in:
commit
d809d34be2
@ -1,3 +1,3 @@
|
||||
import '@storybook/addon-actions/manager';
|
||||
import '@storybook/addon-links/manager';
|
||||
import '@storybook/addon-knobs/manager';
|
||||
import '@storybook/addon-actions/register';
|
||||
import '@storybook/addon-links/register';
|
||||
import '@storybook/addon-knobs/register';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { dedent } from 'ts-dedent';
|
||||
import type { Options } from '@storybook/types';
|
||||
import { getFrameworkName } from './get-framework-name';
|
||||
|
||||
/**
|
||||
* Render is set as a string on core. It must be set by the framework
|
||||
@ -8,11 +8,9 @@ export async function getRendererName(options: Options) {
|
||||
const { renderer } = await options.presets.apply('core', {}, options);
|
||||
|
||||
if (!renderer) {
|
||||
throw new Error(dedent`
|
||||
You must specify a framework in '.storybook/main.js' config.
|
||||
|
||||
https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-field-mandatory
|
||||
`);
|
||||
// At the moment some frameworks (Angular/Ember) do not define a renderer, but themselves
|
||||
// serve the purpose (in particular exporting the symbols needed by entrypoints)
|
||||
return getFrameworkName(options);
|
||||
}
|
||||
|
||||
return renderer;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/// <reference types="@types/jest" />;
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import { dedent } from 'ts-dedent';
|
||||
import yaml from 'js-yaml';
|
||||
@ -690,4 +692,104 @@ describe('CsfFile', () => {
|
||||
expect(csf.imports).toMatchInlineSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('tags', () => {
|
||||
it('csf2', () => {
|
||||
expect(
|
||||
parse(
|
||||
dedent`
|
||||
export default { title: 'foo/bar', tags: ['X'] };
|
||||
export const A = () => {};
|
||||
A.tags = ['Y'];
|
||||
`
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
meta:
|
||||
title: foo/bar
|
||||
tags:
|
||||
- X
|
||||
stories:
|
||||
- id: foo-bar--a
|
||||
name: A
|
||||
tags:
|
||||
- 'Y'
|
||||
`);
|
||||
});
|
||||
|
||||
it('csf3', () => {
|
||||
expect(
|
||||
parse(
|
||||
dedent`
|
||||
export default { title: 'foo/bar', tags: ['X'] };
|
||||
export const A = {
|
||||
render: () => {},
|
||||
tags: ['Y'],
|
||||
};
|
||||
`
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
meta:
|
||||
title: foo/bar
|
||||
tags:
|
||||
- X
|
||||
stories:
|
||||
- id: foo-bar--a
|
||||
name: A
|
||||
tags:
|
||||
- 'Y'
|
||||
`);
|
||||
});
|
||||
|
||||
it('variables', () => {
|
||||
expect(
|
||||
parse(
|
||||
dedent`
|
||||
const x = ['X'];
|
||||
const y = ['Y'];
|
||||
export default { title: 'foo/bar', tags: x };
|
||||
export const A = {
|
||||
render: () => {},
|
||||
tags: y,
|
||||
};
|
||||
`
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
meta:
|
||||
title: foo/bar
|
||||
tags:
|
||||
- X
|
||||
stories:
|
||||
- id: foo-bar--a
|
||||
name: A
|
||||
tags:
|
||||
- 'Y'
|
||||
`);
|
||||
});
|
||||
|
||||
it('array error', () => {
|
||||
expect(() =>
|
||||
parse(
|
||||
dedent`
|
||||
export default { title: 'foo/bar', tags: 'X' };
|
||||
export const A = {
|
||||
render: () => {},
|
||||
};
|
||||
`
|
||||
)
|
||||
).toThrow('CSF: Expected tags array');
|
||||
});
|
||||
|
||||
it('array element handling', () => {
|
||||
expect(() =>
|
||||
parse(
|
||||
dedent`
|
||||
export default { title: 'foo/bar', tags: [10] };
|
||||
export const A = {
|
||||
render: () => {},
|
||||
};
|
||||
`
|
||||
)
|
||||
).toThrow('CSF: Expected tag to be string literal');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ import * as t from '@babel/types';
|
||||
import generate from '@babel/generator';
|
||||
import traverse from '@babel/traverse';
|
||||
import { toId, isExportStory, storyNameFromExport } from '@storybook/csf';
|
||||
import type { CSF_Meta, CSF_Story } from '@storybook/types';
|
||||
import type { CSF_Meta, CSF_Story, CSF_Tag } from '@storybook/types';
|
||||
import { babelParse } from './babelParse';
|
||||
|
||||
const logger = console;
|
||||
@ -26,6 +26,17 @@ function parseIncludeExclude(prop: t.Node) {
|
||||
throw new Error(`Unknown include/exclude: ${prop}`);
|
||||
}
|
||||
|
||||
function parseTags(prop: t.Node) {
|
||||
if (!t.isArrayExpression(prop)) {
|
||||
throw new Error('CSF: Expected tags array');
|
||||
}
|
||||
|
||||
return prop.elements.map((e) => {
|
||||
if (t.isStringLiteral(e)) return e.value;
|
||||
throw new Error(`CSF: Expected tag to be string literal`);
|
||||
}) as CSF_Tag[];
|
||||
}
|
||||
|
||||
const findVarInitialization = (identifier: string, program: t.Program) => {
|
||||
let init: t.Expression = null;
|
||||
let declarations: t.VariableDeclarator[] = null;
|
||||
@ -184,6 +195,12 @@ export class CsfFile {
|
||||
} else if (p.key.name === 'component') {
|
||||
const { code } = generate(p.value, {});
|
||||
meta.component = code;
|
||||
} else if (p.key.name === 'tags') {
|
||||
let node = p.value;
|
||||
if (t.isIdentifier(node)) {
|
||||
node = findVarInitialization(node.name, this._ast.program);
|
||||
}
|
||||
meta.tags = parseTags(node);
|
||||
} else if (p.key.name === 'id') {
|
||||
if (t.isStringLiteral(p.value)) {
|
||||
meta.id = p.value.value;
|
||||
@ -404,6 +421,13 @@ export class CsfFile {
|
||||
parameters.docsOnly = true;
|
||||
}
|
||||
acc[key] = { ...story, id, parameters };
|
||||
const { tags } = self._storyAnnotations[key];
|
||||
if (tags) {
|
||||
const node = t.isIdentifier(tags)
|
||||
? findVarInitialization(tags.name, this._ast.program)
|
||||
: tags;
|
||||
acc[key].tags = parseTags(node);
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}, {} as Record<string, CSF_Story>);
|
||||
|
@ -114,18 +114,22 @@ export {
|
||||
StrictInputType,
|
||||
};
|
||||
|
||||
export type CSF_Tag = string;
|
||||
|
||||
export interface CSF_Meta {
|
||||
id?: string;
|
||||
title?: string;
|
||||
component?: string;
|
||||
includeStories?: string[] | RegExp;
|
||||
excludeStories?: string[] | RegExp;
|
||||
tags?: CSF_Tag[];
|
||||
}
|
||||
|
||||
export interface CSF_Story {
|
||||
id: string;
|
||||
name: string;
|
||||
parameters: Parameters;
|
||||
tags?: CSF_Tag[];
|
||||
}
|
||||
|
||||
export type ViewMode = ViewModeBase | 'story' | 'info' | 'settings' | string | undefined;
|
||||
|
Loading…
x
Reference in New Issue
Block a user