Merge remote-tracking branch 'origin/next' into pr/Marklb/28498

This commit is contained in:
Valentin Palkovic 2024-07-24 08:15:18 +02:00
commit 8fa89b9fdb
136 changed files with 2381 additions and 855 deletions

View File

@ -390,7 +390,7 @@ jobs:
parallelism:
type: integer
executor:
class: medium
class: large
name: sb_playwright
parallelism: << parameters.parallelism >>
steps:

View File

@ -1,3 +1,13 @@
## 8.2.5
- CPC: Add the globals export for manager - [#28650](https://github.com/storybookjs/storybook/pull/28650), thanks @ndelangen!
- CPC: Correct path to the `@storybook/theming/create` alias - [#28643](https://github.com/storybookjs/storybook/pull/28643), thanks @Averethel!
- Components: Remove external overrides - [#28632](https://github.com/storybookjs/storybook/pull/28632), thanks @kasperpeulen!
- Core: Fix header for MountMustBeDestructuredError message - [#28590](https://github.com/storybookjs/storybook/pull/28590), thanks @0916dhkim!
- Onboarding: Fix code snippet when story name differs from export name - [#28649](https://github.com/storybookjs/storybook/pull/28649), thanks @ghengeveld!
- Telemetry: Add mount, beforeEach, moduleMock stats - [#28624](https://github.com/storybookjs/storybook/pull/28624), thanks @shilman!
- Telemetry: CSF feature usage - [#28622](https://github.com/storybookjs/storybook/pull/28622), thanks @shilman!
## 8.2.4
- CLI: Add diagnostic when the `storybook` package is missing - [#28604](https://github.com/storybookjs/storybook/pull/28604), thanks @kasperpeulen!

View File

@ -1,3 +1,16 @@
## 8.3.0-alpha.2
- Addon-Interactions: Fix status in panel tab - [#28580](https://github.com/storybookjs/storybook/pull/28580), thanks @yannbf!
- Build: Remove external overrides, use package.json as source of truth - [#28632](https://github.com/storybookjs/storybook/pull/28632), thanks @kasperpeulen!
- CLI: Add conditional logging for manager and preview start - [#28603](https://github.com/storybookjs/storybook/pull/28603), thanks @tobiasdiez!
- CPC: Add the globals export for manager - [#28650](https://github.com/storybookjs/storybook/pull/28650), thanks @ndelangen!
- CPC: Correct path to the `@storybook/theming/create` alias - [#28643](https://github.com/storybookjs/storybook/pull/28643), thanks @Averethel!
- Core: Fix manager-builder `tsconfig` to emit `react-jsx` - [#28541](https://github.com/storybookjs/storybook/pull/28541), thanks @williamhelmrath!
- Fix: Add header for MountMustBeDestructuredError message - [#28590](https://github.com/storybookjs/storybook/pull/28590), thanks @0916dhkim!
- Fix: Prevent iframe from capturing mouse events in composed Storybooks - [#28568](https://github.com/storybookjs/storybook/pull/28568), thanks @Vincentdevreede!
- Onboarding: Fix code snippet when story name differs from export name - [#28649](https://github.com/storybookjs/storybook/pull/28649), thanks @ghengeveld!
- Vue: Fix out of memory error when using vue-component-meta - [#28589](https://github.com/storybookjs/storybook/pull/28589), thanks @larsrickert!
## 8.3.0-alpha.1
- Bug: Fix invalid docs links in Configure.mdx template page - [#28560](https://github.com/storybookjs/storybook/pull/28560), thanks @kylegach!

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Test component compliance with web accessibility standards",
"keywords": [
"a11y",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-actions",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Get UI feedback when an action is performed on an interactive element",
"keywords": [
"storybook",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-backgrounds",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Switch backgrounds to view components in different settings",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-controls",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Interact with component inputs dynamically in the Storybook UI",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-docs",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Document component usage and properties in Markdown",
"keywords": [
"addon",

View File

@ -68,11 +68,11 @@ async function webpack(
*
* In the future the `@storybook/theming` and `@storybook/components` can be removed, as they should be singletons in the future due to the peerDependency on `storybook` package.
*/
const cliPath = require.resolve('storybook/package.json');
const themingPath = join(cliPath, '..', 'core', 'theming', 'index.js');
const cliPath = dirname(require.resolve('storybook/package.json'));
const themingPath = join(cliPath, 'core', 'theming', 'index.js');
const themingCreatePath = join(cliPath, 'core', 'theming', 'create.js');
const componentsPath = join(cliPath, '..', 'core', 'components', 'index.js');
const componentsPath = join(cliPath, 'core', 'components', 'index.js');
const blocksPath = dirname(require.resolve('@storybook/blocks/package.json'));
if (Array.isArray(webpackConfig.resolve?.alias)) {
alias = [...webpackConfig.resolve?.alias];

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-essentials",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Curated addons to bring out the best of Storybook",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-mdx-gfm",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "GitHub Flavored Markdown in Storybook",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-highlight",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Highlight DOM nodes within your stories",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-interactions",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Automate, test and debug user interactions",
"keywords": [
"storybook-addons",

View File

@ -13,6 +13,7 @@ export default {
actions: { argTypesRegex: '^on[A-Z].*' },
chromatic: { disable: true },
},
tags: ['test-skip'],
};
export const Default = {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-jest",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "React storybook addon that show component jest report",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-links",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Link stories together to build demos and prototypes with your UI components",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-measure",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Inspect layouts by visualizing the box model",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-onboarding",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook Addon Onboarding - Introduces a new onboarding experience",
"keywords": [
"storybook-addons",

View File

@ -75,6 +75,7 @@ export default function Onboarding({ api }: { api: API }) {
const [createNewStoryForm, setCreateNewStoryForm] = useState<HTMLElement | null>();
const [createdStory, setCreatedStory] = useState<{
newStoryName: string;
newStoryExportName: string;
sourceFileContent: string;
sourceFileName: string;
} | null>();
@ -158,8 +159,8 @@ export default function Onboarding({ api }: { api: API }) {
}
const source = createdStory?.sourceFileContent;
const startIndex = source?.lastIndexOf(`export const ${createdStory?.newStoryName}`);
const snippet = source?.slice(startIndex);
const startIndex = source?.lastIndexOf(`export const ${createdStory?.newStoryExportName}`);
const snippet = source?.slice(startIndex).trim();
const startingLineNumber = source?.slice(0, startIndex).split('\n').length;
const steps: StepDefinition[] = [

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-outline",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Outline all elements with CSS to help with layout placement and alignment",
"keywords": [
"storybook-addons",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storysource",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "View a storys source code to see how it works and paste into your app",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-themes",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Switch between multiple themes for you components in Storybook",
"keywords": [
"css",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-toolbars",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Create your own toolbar items that control story rendering",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/addon-viewport",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Build responsive components by adjusting Storybooks viewport size and orientation",
"keywords": [
"addon",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-vite",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "A plugin to run and build Storybooks with Vite",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme",
"bugs": {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-webpack5",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"
@ -142,6 +142,11 @@
"import": "./dist/manager/globals-module-info.js",
"require": "./dist/manager/globals-module-info.cjs"
},
"./manager/globals": {
"types": "./dist/manager/globals.d.ts",
"import": "./dist/manager/globals.js",
"require": "./dist/manager/globals.cjs"
},
"./preview/globals": {
"types": "./dist/preview/globals.d.ts",
"import": "./dist/preview/globals.js",
@ -229,6 +234,9 @@
"manager/globals-module-info": [
"./dist/manager/globals-module-info.d.ts"
],
"manager/globals": [
"./dist/manager/globals.d.ts"
],
"preview/globals": [
"./dist/preview/globals.d.ts"
]
@ -277,7 +285,7 @@
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-slot": "^1.0.2",
"@storybook/docs-mdx": "4.0.0-next.0",
"@storybook/docs-mdx": "4.0.0-next.1",
"@storybook/global": "^5.0.0",
"@storybook/icons": "^1.2.5",
"@tanstack/react-virtual": "^3.3.0",

View File

@ -34,6 +34,7 @@ export const getEntries = (cwd: string) => {
define('src/docs-tools/index.ts', ['browser', 'node'], true),
define('src/manager/globals-module-info.ts', ['node'], true),
define('src/manager/globals.ts', ['node'], true),
define('src/preview/globals.ts', ['node'], true),
];
};

View File

@ -1,84 +1,84 @@
// auto generated file, do not edit
export default {
'@storybook/addon-a11y': '8.3.0-alpha.1',
'@storybook/addon-actions': '8.3.0-alpha.1',
'@storybook/addon-backgrounds': '8.3.0-alpha.1',
'@storybook/addon-controls': '8.3.0-alpha.1',
'@storybook/addon-docs': '8.3.0-alpha.1',
'@storybook/addon-essentials': '8.3.0-alpha.1',
'@storybook/addon-mdx-gfm': '8.3.0-alpha.1',
'@storybook/addon-highlight': '8.3.0-alpha.1',
'@storybook/addon-interactions': '8.3.0-alpha.1',
'@storybook/addon-jest': '8.3.0-alpha.1',
'@storybook/addon-links': '8.3.0-alpha.1',
'@storybook/addon-measure': '8.3.0-alpha.1',
'@storybook/addon-onboarding': '8.3.0-alpha.1',
'@storybook/addon-outline': '8.3.0-alpha.1',
'@storybook/addon-storysource': '8.3.0-alpha.1',
'@storybook/addon-themes': '8.3.0-alpha.1',
'@storybook/addon-toolbars': '8.3.0-alpha.1',
'@storybook/addon-viewport': '8.3.0-alpha.1',
'@storybook/builder-vite': '8.3.0-alpha.1',
'@storybook/builder-webpack5': '8.3.0-alpha.1',
'@storybook/core': '8.3.0-alpha.1',
'@storybook/builder-manager': '8.3.0-alpha.1',
'@storybook/channels': '8.3.0-alpha.1',
'@storybook/client-logger': '8.3.0-alpha.1',
'@storybook/components': '8.3.0-alpha.1',
'@storybook/core-common': '8.3.0-alpha.1',
'@storybook/core-events': '8.3.0-alpha.1',
'@storybook/core-server': '8.3.0-alpha.1',
'@storybook/csf-tools': '8.3.0-alpha.1',
'@storybook/docs-tools': '8.3.0-alpha.1',
'@storybook/manager': '8.3.0-alpha.1',
'@storybook/manager-api': '8.3.0-alpha.1',
'@storybook/node-logger': '8.3.0-alpha.1',
'@storybook/preview': '8.3.0-alpha.1',
'@storybook/preview-api': '8.3.0-alpha.1',
'@storybook/router': '8.3.0-alpha.1',
'@storybook/telemetry': '8.3.0-alpha.1',
'@storybook/theming': '8.3.0-alpha.1',
'@storybook/types': '8.3.0-alpha.1',
'@storybook/angular': '8.3.0-alpha.1',
'@storybook/ember': '8.3.0-alpha.1',
'@storybook/html-vite': '8.3.0-alpha.1',
'@storybook/html-webpack5': '8.3.0-alpha.1',
'@storybook/nextjs': '8.3.0-alpha.1',
'@storybook/preact-vite': '8.3.0-alpha.1',
'@storybook/preact-webpack5': '8.3.0-alpha.1',
'@storybook/react-vite': '8.3.0-alpha.1',
'@storybook/react-webpack5': '8.3.0-alpha.1',
'@storybook/server-webpack5': '8.3.0-alpha.1',
'@storybook/svelte-vite': '8.3.0-alpha.1',
'@storybook/svelte-webpack5': '8.3.0-alpha.1',
'@storybook/sveltekit': '8.3.0-alpha.1',
'@storybook/vue3-vite': '8.3.0-alpha.1',
'@storybook/vue3-webpack5': '8.3.0-alpha.1',
'@storybook/web-components-vite': '8.3.0-alpha.1',
'@storybook/web-components-webpack5': '8.3.0-alpha.1',
'@storybook/blocks': '8.3.0-alpha.1',
storybook: '8.3.0-alpha.1',
sb: '8.3.0-alpha.1',
'@storybook/cli': '8.3.0-alpha.1',
'@storybook/codemod': '8.3.0-alpha.1',
'@storybook/core-webpack': '8.3.0-alpha.1',
'@storybook/csf-plugin': '8.3.0-alpha.1',
'@storybook/instrumenter': '8.3.0-alpha.1',
'@storybook/react-dom-shim': '8.3.0-alpha.1',
'@storybook/source-loader': '8.3.0-alpha.1',
'@storybook/test': '8.3.0-alpha.1',
'@storybook/preset-create-react-app': '8.3.0-alpha.1',
'@storybook/preset-html-webpack': '8.3.0-alpha.1',
'@storybook/preset-preact-webpack': '8.3.0-alpha.1',
'@storybook/preset-react-webpack': '8.3.0-alpha.1',
'@storybook/preset-server-webpack': '8.3.0-alpha.1',
'@storybook/preset-svelte-webpack': '8.3.0-alpha.1',
'@storybook/preset-vue3-webpack': '8.3.0-alpha.1',
'@storybook/html': '8.3.0-alpha.1',
'@storybook/preact': '8.3.0-alpha.1',
'@storybook/react': '8.3.0-alpha.1',
'@storybook/server': '8.3.0-alpha.1',
'@storybook/svelte': '8.3.0-alpha.1',
'@storybook/vue3': '8.3.0-alpha.1',
'@storybook/web-components': '8.3.0-alpha.1',
'@storybook/addon-a11y': '8.3.0-alpha.2',
'@storybook/addon-actions': '8.3.0-alpha.2',
'@storybook/addon-backgrounds': '8.3.0-alpha.2',
'@storybook/addon-controls': '8.3.0-alpha.2',
'@storybook/addon-docs': '8.3.0-alpha.2',
'@storybook/addon-essentials': '8.3.0-alpha.2',
'@storybook/addon-mdx-gfm': '8.3.0-alpha.2',
'@storybook/addon-highlight': '8.3.0-alpha.2',
'@storybook/addon-interactions': '8.3.0-alpha.2',
'@storybook/addon-jest': '8.3.0-alpha.2',
'@storybook/addon-links': '8.3.0-alpha.2',
'@storybook/addon-measure': '8.3.0-alpha.2',
'@storybook/addon-onboarding': '8.3.0-alpha.2',
'@storybook/addon-outline': '8.3.0-alpha.2',
'@storybook/addon-storysource': '8.3.0-alpha.2',
'@storybook/addon-themes': '8.3.0-alpha.2',
'@storybook/addon-toolbars': '8.3.0-alpha.2',
'@storybook/addon-viewport': '8.3.0-alpha.2',
'@storybook/builder-vite': '8.3.0-alpha.2',
'@storybook/builder-webpack5': '8.3.0-alpha.2',
'@storybook/core': '8.3.0-alpha.2',
'@storybook/builder-manager': '8.3.0-alpha.2',
'@storybook/channels': '8.3.0-alpha.2',
'@storybook/client-logger': '8.3.0-alpha.2',
'@storybook/components': '8.3.0-alpha.2',
'@storybook/core-common': '8.3.0-alpha.2',
'@storybook/core-events': '8.3.0-alpha.2',
'@storybook/core-server': '8.3.0-alpha.2',
'@storybook/csf-tools': '8.3.0-alpha.2',
'@storybook/docs-tools': '8.3.0-alpha.2',
'@storybook/manager': '8.3.0-alpha.2',
'@storybook/manager-api': '8.3.0-alpha.2',
'@storybook/node-logger': '8.3.0-alpha.2',
'@storybook/preview': '8.3.0-alpha.2',
'@storybook/preview-api': '8.3.0-alpha.2',
'@storybook/router': '8.3.0-alpha.2',
'@storybook/telemetry': '8.3.0-alpha.2',
'@storybook/theming': '8.3.0-alpha.2',
'@storybook/types': '8.3.0-alpha.2',
'@storybook/angular': '8.3.0-alpha.2',
'@storybook/ember': '8.3.0-alpha.2',
'@storybook/html-vite': '8.3.0-alpha.2',
'@storybook/html-webpack5': '8.3.0-alpha.2',
'@storybook/nextjs': '8.3.0-alpha.2',
'@storybook/preact-vite': '8.3.0-alpha.2',
'@storybook/preact-webpack5': '8.3.0-alpha.2',
'@storybook/react-vite': '8.3.0-alpha.2',
'@storybook/react-webpack5': '8.3.0-alpha.2',
'@storybook/server-webpack5': '8.3.0-alpha.2',
'@storybook/svelte-vite': '8.3.0-alpha.2',
'@storybook/svelte-webpack5': '8.3.0-alpha.2',
'@storybook/sveltekit': '8.3.0-alpha.2',
'@storybook/vue3-vite': '8.3.0-alpha.2',
'@storybook/vue3-webpack5': '8.3.0-alpha.2',
'@storybook/web-components-vite': '8.3.0-alpha.2',
'@storybook/web-components-webpack5': '8.3.0-alpha.2',
'@storybook/blocks': '8.3.0-alpha.2',
storybook: '8.3.0-alpha.2',
sb: '8.3.0-alpha.2',
'@storybook/cli': '8.3.0-alpha.2',
'@storybook/codemod': '8.3.0-alpha.2',
'@storybook/core-webpack': '8.3.0-alpha.2',
'@storybook/csf-plugin': '8.3.0-alpha.2',
'@storybook/instrumenter': '8.3.0-alpha.2',
'@storybook/react-dom-shim': '8.3.0-alpha.2',
'@storybook/source-loader': '8.3.0-alpha.2',
'@storybook/test': '8.3.0-alpha.2',
'@storybook/preset-create-react-app': '8.3.0-alpha.2',
'@storybook/preset-html-webpack': '8.3.0-alpha.2',
'@storybook/preset-preact-webpack': '8.3.0-alpha.2',
'@storybook/preset-react-webpack': '8.3.0-alpha.2',
'@storybook/preset-server-webpack': '8.3.0-alpha.2',
'@storybook/preset-svelte-webpack': '8.3.0-alpha.2',
'@storybook/preset-vue3-webpack': '8.3.0-alpha.2',
'@storybook/html': '8.3.0-alpha.2',
'@storybook/preact': '8.3.0-alpha.2',
'@storybook/react': '8.3.0-alpha.2',
'@storybook/server': '8.3.0-alpha.2',
'@storybook/svelte': '8.3.0-alpha.2',
'@storybook/vue3': '8.3.0-alpha.2',
'@storybook/web-components': '8.3.0-alpha.2',
};

View File

@ -9,7 +9,9 @@ export interface SaveStoryResponsePayload {
csfId: string;
newStoryId?: string;
newStoryName?: string;
newStoryExportName?: string;
sourceFileContent?: string;
sourceFileName?: string;
sourceStoryName?: string;
sourceStoryExportName?: string;
}

View File

@ -68,7 +68,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex, stats } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"a--story-one": {
@ -89,6 +90,18 @@ describe('StoryIndexGenerator', () => {
"v": 5,
}
`);
expect(stats).toMatchInlineSnapshot(`
{
"beforeEach": 0,
"loaders": 0,
"moduleMock": 0,
"mount": 0,
"play": 0,
"render": 0,
"storyFn": 0,
}
`);
});
});
describe('single file .story specifier', () => {
@ -101,7 +114,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"f--story-one": {
@ -133,7 +147,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"stories--story-one": {
@ -165,7 +180,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"componentpath-extension--story-one": {
@ -245,7 +261,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex, stats } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"a--story-one": {
@ -336,6 +353,68 @@ describe('StoryIndexGenerator', () => {
"title": "first-nested/deeply/F",
"type": "story",
},
"first-nested-deeply-features--with-csf-1": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-csf-1",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With CSF 1",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-play": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-play",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Play",
"tags": [
"dev",
"test",
"play-fn",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-render": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-render",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Render",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-story-fn": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-story-fn",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Story Fn",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-test": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-test",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Test",
"tags": [
"dev",
"test",
"play-fn",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"h--story-one": {
"componentPath": undefined,
"id": "h--story-one",
@ -378,6 +457,18 @@ describe('StoryIndexGenerator', () => {
"v": 5,
}
`);
expect(stats).toMatchInlineSnapshot(`
{
"beforeEach": 1,
"loaders": 1,
"moduleMock": 0,
"mount": 1,
"play": 2,
"render": 1,
"storyFn": 1,
}
`);
});
});
@ -395,7 +486,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], autodocsOptions);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex, stats } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"a--story-one": {
@ -512,6 +604,68 @@ describe('StoryIndexGenerator', () => {
"title": "first-nested/deeply/F",
"type": "story",
},
"first-nested-deeply-features--with-csf-1": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-csf-1",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With CSF 1",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-play": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-play",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Play",
"tags": [
"dev",
"test",
"play-fn",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-render": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-render",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Render",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-story-fn": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-story-fn",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Story Fn",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-test": {
"componentPath": undefined,
"id": "first-nested-deeply-features--with-test",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Test",
"tags": [
"dev",
"test",
"play-fn",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"h--docs": {
"id": "h--docs",
"importPath": "./src/H.stories.mjs",
@ -567,6 +721,18 @@ describe('StoryIndexGenerator', () => {
"v": 5,
}
`);
expect(stats).toMatchInlineSnapshot(`
{
"beforeEach": 1,
"loaders": 1,
"moduleMock": 0,
"mount": 1,
"play": 2,
"render": 1,
"storyFn": 1,
}
`);
});
const autodocsTrueOptions = {
@ -603,6 +769,12 @@ describe('StoryIndexGenerator', () => {
"componentpath-package--story-one",
"first-nested-deeply-f--docs",
"first-nested-deeply-f--story-one",
"first-nested-deeply-features--docs",
"first-nested-deeply-features--with-play",
"first-nested-deeply-features--with-story-fn",
"first-nested-deeply-features--with-render",
"first-nested-deeply-features--with-test",
"first-nested-deeply-features--with-csf-1",
"nested-button--docs",
"nested-button--story-one",
"second-nested-g--docs",
@ -639,6 +811,12 @@ describe('StoryIndexGenerator', () => {
"componentpath-package--story-one",
"first-nested-deeply-f--docs",
"first-nested-deeply-f--story-one",
"first-nested-deeply-features--docs",
"first-nested-deeply-features--with-play",
"first-nested-deeply-features--with-story-fn",
"first-nested-deeply-features--with-render",
"first-nested-deeply-features--with-test",
"first-nested-deeply-features--with-csf-1",
"nested-button--docs",
"nested-button--story-one",
"second-nested-g--docs",
@ -730,7 +908,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([csfSpecifier, docsSpecifier], autodocsOptions);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"b--docs": {
@ -794,7 +973,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([csfSpecifier, docsSpecifier], autodocsOptions);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"b--docs": {
@ -862,7 +1042,8 @@ describe('StoryIndexGenerator', () => {
);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"a--docs": {
@ -919,7 +1100,8 @@ describe('StoryIndexGenerator', () => {
generator.getProjectTags = () => ['dev', 'test', 'autodocs'];
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"a--docs": {
@ -970,7 +1152,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], autodocsOptions);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"duplicate-a--docs": {
@ -1030,7 +1213,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([csfSpecifier], autodocsOptions);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {},
"v": 5,
@ -1047,7 +1231,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([csfSpecifier], autodocsOptions);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"my-component-a--docs": {
@ -1088,7 +1273,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([storiesSpecifier, docsSpecifier], options);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"a--metaof": {
@ -1222,7 +1408,8 @@ describe('StoryIndexGenerator', () => {
});
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"a--metaof": {
@ -1328,7 +1515,8 @@ describe('StoryIndexGenerator', () => {
options
);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"a--story-one": {
@ -1395,7 +1583,8 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([csfSpecifier, docsSpecifier], options);
await generator.initialize();
expect(await generator.getIndex()).toMatchInlineSnapshot(`
const { storyIndex } = await generator.getIndexAndStats();
expect(storyIndex).toMatchInlineSnapshot(`
{
"entries": {
"my-component-b--docs": {
@ -1603,6 +1792,11 @@ describe('StoryIndexGenerator', () => {
"componentpath-noextension--story-one",
"componentpath-package--story-one",
"first-nested-deeply-f--story-one",
"first-nested-deeply-features--with-play",
"first-nested-deeply-features--with-story-fn",
"first-nested-deeply-features--with-render",
"first-nested-deeply-features--with-test",
"first-nested-deeply-features--with-csf-1",
]
`);
});
@ -1621,7 +1815,7 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
await generator.getIndex();
expect(readCsfMock).toHaveBeenCalledTimes(10);
expect(readCsfMock).toHaveBeenCalledTimes(11);
readCsfMock.mockClear();
await generator.getIndex();
@ -1679,7 +1873,7 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
await generator.getIndex();
expect(readCsfMock).toHaveBeenCalledTimes(10);
expect(readCsfMock).toHaveBeenCalledTimes(11);
generator.invalidate(specifier, './src/B.stories.ts', false);
@ -1764,7 +1958,7 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
await generator.getIndex();
expect(readCsfMock).toHaveBeenCalledTimes(10);
expect(readCsfMock).toHaveBeenCalledTimes(11);
generator.invalidate(specifier, './src/B.stories.ts', true);
@ -1803,7 +1997,7 @@ describe('StoryIndexGenerator', () => {
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
await generator.getIndex();
expect(readCsfMock).toHaveBeenCalledTimes(10);
expect(readCsfMock).toHaveBeenCalledTimes(11);
generator.invalidate(specifier, './src/B.stories.ts', true);

View File

@ -1,3 +1,4 @@
/* eslint-disable no-underscore-dangle */
import path from 'node:path';
import chalk from 'chalk';
import fs from 'fs-extra';
@ -17,6 +18,7 @@ import type {
StoryIndex,
Indexer,
StorybookConfigRaw,
IndexInputStats,
} from '@storybook/core/types';
import { userOrAutoTitleFromSpecifier, sortStoriesV7 } from '@storybook/core/preview-api';
import { commonGlobOptions, normalizeStoryPath } from '@storybook/core/common';
@ -26,14 +28,17 @@ import { storyNameFromExport, toId, combineTags } from '@storybook/csf';
import { dedent } from 'ts-dedent';
import { autoName } from './autoName';
import { IndexingError, MultipleIndexingError } from './IndexingError';
import { addStats, type IndexStatsSummary } from './summarizeStats';
// Extended type to keep track of the csf meta id so we know the component id when referencing docs in `extractDocs`
type StoryIndexEntryWithMetaId = StoryIndexEntry & { metaId?: string };
type StoryIndexEntryWithExtra = StoryIndexEntry & {
extra: { metaId?: string; stats: IndexInputStats };
};
/** A .mdx file will produce a docs entry */
type DocsCacheEntry = DocsIndexEntry;
/** A *.stories.* file will produce a list of stories and possibly a docs entry */
type StoriesCacheEntry = {
entries: (StoryIndexEntryWithMetaId | DocsIndexEntry)[];
entries: (StoryIndexEntryWithExtra | DocsIndexEntry)[];
dependents: Path[];
type: 'stories';
};
@ -103,6 +108,9 @@ export class StoryIndexGenerator {
// - the preview changes [not yet implemented]
private lastIndex?: StoryIndex | null;
// Cache the last value stats calculation, mirroring lastIndex
private lastStats?: IndexStatsSummary;
// Same as the above but for the error case
private lastError?: Error | null;
@ -221,7 +229,7 @@ export class StoryIndexGenerator {
projectTags,
}: {
projectTags?: Tag[];
}): Promise<(IndexEntry | ErrorEntry)[]> {
}): Promise<{ entries: (IndexEntry | ErrorEntry)[]; stats: IndexStatsSummary }> {
// First process all the story files. Then, in a second pass,
// process the docs files. The reason for this is that the docs
// files may use the `<Meta of={XStories} />` syntax, which requires
@ -236,7 +244,8 @@ export class StoryIndexGenerator {
this.extractDocs(specifier, absolutePath, projectTags)
);
return this.specifiers.flatMap((specifier) => {
const statsSummary = {} as IndexStatsSummary;
const entries = this.specifiers.flatMap((specifier) => {
const cache = this.specifierToCache.get(specifier);
invariant(
cache,
@ -251,12 +260,17 @@ export class StoryIndexGenerator {
return entry.entries.map((item) => {
if (item.type === 'docs') return item;
// Drop the meta id as it isn't part of the index, we just used it for record keeping in `extractDocs`
const { metaId, ...existing } = item;
addStats(item.extra.stats, statsSummary);
// Drop extra data used for internal bookkeeping
const { extra, ...existing } = item;
return existing;
});
});
});
return { entries, stats: statsSummary };
}
findDependencies(absoluteImports: Path[]) {
@ -340,7 +354,7 @@ export class StoryIndexGenerator {
]);
}
const entries: ((StoryIndexEntryWithMetaId | DocsCacheEntry) & { tags: Tag[] })[] =
const entries: ((StoryIndexEntryWithExtra | DocsCacheEntry) & { tags: Tag[] })[] =
indexInputs.map((input) => {
const name = input.name ?? storyNameFromExport(input.exportName);
const componentPath =
@ -348,14 +362,16 @@ export class StoryIndexGenerator {
this.resolveComponentPath(input.rawComponentPath, absolutePath, matchPath);
const title = input.title ?? defaultMakeTitle();
// eslint-disable-next-line no-underscore-dangle
const id = input.__id ?? toId(input.metaId ?? title, storyNameFromExport(input.exportName));
const tags = combineTags(...projectTags, ...(input.tags ?? []));
return {
type: 'story',
id,
metaId: input.metaId,
extra: {
metaId: input.metaId,
stats: input.__stats ?? {},
},
name,
title,
importPath,
@ -428,12 +444,12 @@ export class StoryIndexGenerator {
// Also, if `result.of` is set, it means that we're using the `<Meta of={XStories} />` syntax,
// so find the `title` defined the file that `meta` points to.
let csfEntry: StoryIndexEntryWithMetaId | undefined;
let csfEntry: StoryIndexEntryWithExtra | undefined;
if (result.of) {
const absoluteOf = makeAbsolute(result.of, normalizedPath, this.options.workingDir);
dependencies.forEach((dep) => {
if (dep.entries.length > 0) {
const first = dep.entries.find((e) => e.type !== 'docs') as StoryIndexEntryWithMetaId;
const first = dep.entries.find((e) => e.type !== 'docs') as StoryIndexEntryWithExtra;
if (
path
@ -475,7 +491,7 @@ export class StoryIndexGenerator {
result.name ||
(csfEntry ? autoName(importPath, csfEntry.importPath, defaultName) : defaultName);
const id = toId(csfEntry?.metaId || title, name);
const id = toId(csfEntry?.extra.metaId || title, name);
const tags = combineTags(
...projectTags,
@ -598,7 +614,12 @@ export class StoryIndexGenerator {
}
async getIndex() {
if (this.lastIndex) return this.lastIndex;
return (await this.getIndexAndStats()).storyIndex;
}
async getIndexAndStats(): Promise<{ storyIndex: StoryIndex; stats: IndexStatsSummary }> {
if (this.lastIndex && this.lastStats)
return { storyIndex: this.lastIndex, stats: this.lastStats };
if (this.lastError) throw this.lastError;
const previewCode = await this.getPreviewCode();
@ -606,7 +627,7 @@ export class StoryIndexGenerator {
// Extract any entries that are currently missing
// Pull out each file's stories into a list of stories, to be composed and sorted
const storiesList = await this.ensureExtracted({ projectTags });
const { entries: storiesList, stats } = await this.ensureExtracted({ projectTags });
try {
const errorEntries = storiesList.filter((entry) => entry.type === 'error');
@ -635,12 +656,13 @@ export class StoryIndexGenerator {
previewCode && getStorySortParameter(previewCode)
);
this.lastStats = stats;
this.lastIndex = {
v: 5,
entries: sorted,
};
return this.lastIndex;
return { storyIndex: this.lastIndex, stats: this.lastStats };
} catch (err) {
this.lastError = err == null || err instanceof Error ? err : undefined;
invariant(this.lastError);

View File

@ -0,0 +1,27 @@
const component = {};
export default {
component,
};
export const WithPlay = {
play: async () => {},
};
export const WithStoryFn = () => {};
export const WithRender = {
render: () => {},
};
export const WithTest = {
beforeEach: async () => {},
play: async ({ mount }) => {
await mount();
},
};
export const WithCSF1 = {
parameters: {},
decorators: [],
loaders: [],
};

View File

@ -62,9 +62,12 @@ describe('story extraction', () => {
"entries": [
{
"componentPath": undefined,
"extra": {
"metaId": "a",
"stats": {},
},
"id": "a--story-one",
"importPath": "./src/A.stories.js",
"metaId": "a",
"name": "Story One",
"tags": [
"story-tag-from-indexer",
@ -74,9 +77,12 @@ describe('story extraction', () => {
},
{
"componentPath": undefined,
"extra": {
"metaId": "custom-id",
"stats": {},
},
"id": "some-fully-custom-id",
"importPath": "./src/A.stories.js",
"metaId": "custom-id",
"name": "Another Story Name",
"tags": [
"story-tag-from-indexer",
@ -118,9 +124,12 @@ describe('story extraction', () => {
"entries": [
{
"componentPath": undefined,
"extra": {
"metaId": undefined,
"stats": {},
},
"id": "f--story-one",
"importPath": "./src/first-nested/deeply/F.stories.js",
"metaId": undefined,
"name": "Story One",
"tags": [],
"title": "F",
@ -164,9 +173,12 @@ describe('story extraction', () => {
"entries": [
{
"componentPath": undefined,
"extra": {
"metaId": "a",
"stats": {},
},
"id": "a--story-one",
"importPath": "./src/first-nested/deeply/F.stories.js",
"metaId": "a",
"name": "Story One",
"tags": [
"story-tag-from-indexer",
@ -212,9 +224,12 @@ describe('story extraction', () => {
"entries": [
{
"componentPath": undefined,
"extra": {
"metaId": "a",
"stats": {},
},
"id": "a--story-one",
"importPath": "./src/A.stories.js",
"metaId": "a",
"name": "Story One",
"tags": [
"story-tag-from-indexer",
@ -278,9 +293,12 @@ describe('story extraction', () => {
"entries": [
{
"componentPath": undefined,
"extra": {
"metaId": undefined,
"stats": {},
},
"id": "a--story-one",
"importPath": "./src/A.stories.js",
"metaId": undefined,
"name": "Story One",
"tags": [
"story-tag-from-indexer",
@ -290,9 +308,12 @@ describe('story extraction', () => {
},
{
"componentPath": undefined,
"extra": {
"metaId": undefined,
"stats": {},
},
"id": "custom-title--story-two",
"importPath": "./src/A.stories.js",
"metaId": undefined,
"name": "Custom Name For Second Story",
"tags": [
"story-tag-from-indexer",
@ -302,9 +323,12 @@ describe('story extraction', () => {
},
{
"componentPath": undefined,
"extra": {
"metaId": "custom-meta-id",
"stats": {},
},
"id": "custom-meta-id--story-three",
"importPath": "./src/A.stories.js",
"metaId": "custom-meta-id",
"name": "Story Three",
"tags": [
"story-tag-from-indexer",
@ -347,9 +371,12 @@ describe('story extraction', () => {
"entries": [
{
"componentPath": undefined,
"extra": {
"metaId": undefined,
"stats": {},
},
"id": "a--story-one",
"importPath": "./src/A.stories.js",
"metaId": undefined,
"name": "Story One",
"tags": [
"story-tag-from-indexer",
@ -397,9 +424,12 @@ describe('docs entries from story extraction', () => {
"entries": [
{
"componentPath": undefined,
"extra": {
"metaId": undefined,
"stats": {},
},
"id": "a--story-one",
"importPath": "./src/A.stories.js",
"metaId": undefined,
"name": "Story One",
"tags": [
"story-tag-from-indexer",
@ -457,9 +487,12 @@ describe('docs entries from story extraction', () => {
},
{
"componentPath": undefined,
"extra": {
"metaId": undefined,
"stats": {},
},
"id": "a--story-one",
"importPath": "./src/A.stories.js",
"metaId": undefined,
"name": "Story One",
"tags": [
"autodocs",
@ -506,9 +539,12 @@ describe('docs entries from story extraction', () => {
"entries": [
{
"componentPath": undefined,
"extra": {
"metaId": undefined,
"stats": {},
},
"id": "a--story-one",
"importPath": "./src/A.stories.js",
"metaId": undefined,
"name": "Story One",
"tags": [
"autodocs",

View File

@ -15,9 +15,9 @@ export async function doTelemetry(
) {
if (!core?.disableTelemetry) {
initializedStoryIndexGenerator.then(async (generator) => {
let storyIndex: StoryIndex | undefined;
let indexAndStats;
try {
storyIndex = await generator?.getIndex();
indexAndStats = await generator?.getIndexAndStats();
} catch (err) {
// If we fail to get the index, treat it as a recoverable error, but send it up to telemetry
// as if we crashed. In the future we will revisit this to send a distinct error
@ -36,10 +36,11 @@ export async function doTelemetry(
const payload = {
precedingUpgrade: await getPrecedingUpgrade(),
};
if (storyIndex) {
if (indexAndStats) {
Object.assign(payload, {
versionStatus: versionUpdates && versionCheck ? versionStatus(versionCheck) : 'disabled',
storyIndex: summarizeIndex(storyIndex),
storyIndex: summarizeIndex(indexAndStats.storyIndex),
storyStats: indexAndStats.stats,
});
}
telemetry('dev', payload, { configDir: options.configDir });

View File

@ -111,9 +111,11 @@ export function initializeSaveStory(channel: Channel, options: Options, coreConf
csfId,
newStoryId,
newStoryName,
newStoryExportName: name,
sourceFileContent: code,
sourceFileName,
sourceStoryName,
sourceStoryExportName: storyName,
},
error: null,
} satisfies ResponseData<SaveStoryResponsePayload>);

View File

@ -263,6 +263,63 @@ describe('useStoriesJson', () => {
"title": "first-nested/deeply/F",
"type": "story",
},
"first-nested-deeply-features--with-csf-1": {
"id": "first-nested-deeply-features--with-csf-1",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With CSF 1",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-play": {
"id": "first-nested-deeply-features--with-play",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Play",
"tags": [
"dev",
"test",
"play-fn",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-render": {
"id": "first-nested-deeply-features--with-render",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Render",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-story-fn": {
"id": "first-nested-deeply-features--with-story-fn",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Story Fn",
"tags": [
"dev",
"test",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"first-nested-deeply-features--with-test": {
"id": "first-nested-deeply-features--with-test",
"importPath": "./src/first-nested/deeply/Features.stories.jsx",
"name": "With Test",
"tags": [
"dev",
"test",
"play-fn",
],
"title": "first-nested/deeply/Features",
"type": "story",
},
"h--story-one": {
"id": "h--story-one",
"importPath": "./src/H.stories.mjs",

View File

@ -0,0 +1,18 @@
import { it, expect } from 'vitest';
import { summarizeStats } from './summarizeStats';
it('should summarize stats', () => {
const stats = [
{ play: true, render: true, storyFn: false },
{ play: true, render: false, storyFn: false },
{ play: false, render: false, storyFn: false },
];
const result = summarizeStats(stats);
expect(result).toMatchInlineSnapshot(`
{
"play": 2,
"render": 1,
"storyFn": 0,
}
`);
});

View File

@ -0,0 +1,18 @@
import type { IndexInputStats } from '@storybook/core/types';
export type IndexStatsSummary = Record<keyof IndexInputStats, number>;
export const addStats = (stat: IndexInputStats, acc: IndexStatsSummary) => {
Object.entries(stat).forEach(([key, value]) => {
const statsKey = key as keyof IndexInputStats;
if (!acc[statsKey]) acc[statsKey] = 0;
acc[statsKey] += value ? 1 : 0;
});
};
export const summarizeStats = (stats: IndexInputStats[]): IndexStatsSummary => {
return stats.reduce((acc, stat) => {
addStats(stat, acc);
return acc;
}, {} as IndexStatsSummary);
};

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,18 @@ import bt from '@babel/traverse';
import * as recast from 'recast';
import { toId, isExportStory, storyNameFromExport } from '@storybook/csf';
import type { ComponentAnnotations, StoryAnnotations, Tag } from '@storybook/core/types';
import type {
Tag,
StoryAnnotations,
ComponentAnnotations,
IndexedCSFFile,
IndexInput,
IndexInputStats,
} from '@storybook/core/types';
import type { Options } from 'recast';
import { babelParse } from './babelParse';
import { findVarInitialization } from './findVarInitialization';
import type { PrintResultType } from './PrintResultType';
import type { IndexInput, IndexedCSFFile } from '@storybook/core/types';
// @ts-expect-error (needed due to it's use of `exports.default`)
const traverse = (bt.default || bt) as typeof bt;
@ -54,6 +60,8 @@ const formatLocation = (node: t.Node, fileName?: string) => {
return `${fileName || ''} (line ${line}, col ${column})`.trim();
};
export const isModuleMock = (importPath: string) => MODULE_MOCK_REGEX.test(importPath);
const isArgsStory = (init: t.Node, parent: t.Node, csf: CsfFile) => {
let storyFn: t.Node = init;
// export const Foo = Bar.bind({})
@ -110,6 +118,25 @@ const sortExports = (exportByName: Record<string, any>, order: string[]) => {
);
};
const hasMount = (play: t.Node | undefined) => {
if (t.isArrowFunctionExpression(play) || t.isFunctionDeclaration(play)) {
const params = play.params;
if (params.length >= 1) {
const [arg] = params;
if (t.isObjectPattern(arg)) {
return !!arg.properties.find((prop) => {
if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) {
return prop.key.name === 'mount';
}
});
}
}
}
return false;
};
const MODULE_MOCK_REGEX = /^[.\/#].*\.mock($|\.[^.]*$)/i;
export interface CsfOptions {
fileName?: string;
makeTitle: (userTitle: string) => string;
@ -136,6 +163,7 @@ export interface StaticMeta
export interface StaticStory extends Pick<StoryAnnotations, 'name' | 'parameters' | 'tags'> {
id: string;
__stats: IndexInputStats;
}
export class CsfFile {
@ -392,6 +420,7 @@ export class CsfFile {
id: 'FIXME',
name,
parameters,
__stats: {},
};
}
});
@ -422,7 +451,12 @@ export class CsfFile {
}
} else {
self._storyAnnotations[exportName] = {};
self._stories[exportName] = { id: 'FIXME', name: exportName, parameters: {} };
self._stories[exportName] = {
id: 'FIXME',
name: exportName,
parameters: {},
__stats: {},
};
}
}
});
@ -520,7 +554,8 @@ export class CsfFile {
parameters.docsOnly = true;
}
acc[key] = { ...story, id, parameters };
const { tags, play } = self._storyAnnotations[key];
const storyAnnotations = self._storyAnnotations[key];
const { tags, play } = storyAnnotations;
if (tags) {
const node = t.isIdentifier(tags)
? findVarInitialization(tags.name, this._ast.program)
@ -530,6 +565,18 @@ export class CsfFile {
if (play) {
acc[key].tags = [...(acc[key].tags || []), 'play-fn'];
}
const stats = acc[key].__stats;
['play', 'render', 'loaders', 'beforeEach'].forEach((annotation) => {
stats[annotation as keyof IndexInputStats] =
!!storyAnnotations[annotation] || !!self._metaAnnotations[annotation];
});
const storyExport = self.getStoryExport(key);
stats.storyFn = !!(
t.isArrowFunctionExpression(storyExport) || t.isFunctionDeclaration(storyExport)
);
stats.mount = hasMount(storyAnnotations.play ?? self._metaAnnotations.play);
stats.moduleMock = !!self.imports.find((fname) => isModuleMock(fname));
return acc;
},
{} as Record<string, StaticStory>
@ -589,6 +636,7 @@ export class CsfFile {
metaId: this.meta?.id,
tags,
__id: story.id,
__stats: story.__stats,
};
});
}

View File

@ -1 +1 @@
export const version = '8.3.0-alpha.1';
export const version = '8.3.0-alpha.2';

View File

@ -87,6 +87,16 @@ export type DocsIndexEntry = BaseIndexEntry & {
export type IndexEntry = StoryIndexEntry | DocsIndexEntry;
export interface IndexInputStats {
loaders?: boolean;
play?: boolean;
render?: boolean;
storyFn?: boolean;
mount?: boolean;
beforeEach?: boolean;
moduleMock?: boolean;
}
/**
* The base input for indexing a story or docs entry.
*/
@ -115,6 +125,10 @@ export type BaseIndexInput = {
* Only use this if you need to override the auto-generated id.
*/
__id?: StoryId;
/**
* Stats about language feature usage that the indexer can optionally report
*/
__stats?: IndexInputStats;
};
/**

View File

@ -6,6 +6,7 @@ import type {
CleanupCallback,
StepRunner,
Canvas,
BeforeAll,
} from '@storybook/csf';
import type {
@ -57,13 +58,14 @@ export type NamedOrDefaultProjectAnnotations<TRenderer extends Renderer = Render
export type NormalizedProjectAnnotations<TRenderer extends Renderer = Renderer> = Omit<
ProjectAnnotations<TRenderer>,
'decorators' | 'loaders' | 'runStep'
'decorators' | 'loaders' | 'runStep' | 'beforeAll'
> & {
argTypes?: StrictArgTypes;
globalTypes?: StrictGlobalTypes;
decorators?: DecoratorFunction<TRenderer>[];
loaders?: LoaderFunction<TRenderer>[];
runStep: StepRunner<TRenderer>;
beforeAll: BeforeAll;
};
export type NormalizedComponentAnnotations<TRenderer extends Renderer = Renderer> = Omit<

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/builder-manager",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook manager builder",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/channels",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/client-logger",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/components",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Core Storybook Components",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-common",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-events",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Event names used in storybook core",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/core-server",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/csf-tools",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Parse and manipulate CSF and Storybook config files",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/docs-tools",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Shared utility functions for frameworks to implement docs",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/manager-api",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Core Storybook Manager API & Context",
"keywords": [
"storybook"

View File

@ -0,0 +1 @@
module.exports = require('storybook/internal/manager/globals');

2
code/deprecated/manager/globals.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export * from 'storybook/internal/manager/globals';
export type * from 'storybook/internal/manager/globals';

View File

@ -0,0 +1 @@
export * from 'storybook/internal/manager/globals';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/manager",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Core Storybook UI",
"keywords": [
"storybook"
@ -20,6 +20,14 @@
},
"license": "MIT",
"sideEffects": false,
"type": "module",
"exports": {
"./globals": {
"type": "./globals.d.ts",
"import": "./globals.js",
"require": "./globals.cjs"
}
},
"files": [
"README.md",
"*.js",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/node-logger",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preview-api",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "",
"keywords": [
"storybook"

View File

@ -0,0 +1 @@
module.exports = require('storybook/internal/preview/globals');

2
code/deprecated/preview/globals.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export * from 'storybook/internal/preview/globals';
export type * from 'storybook/internal/preview/globals';

View File

@ -0,0 +1 @@
export * from 'storybook/internal/preview/globals';

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preview",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "",
"keywords": [
"storybook"
@ -20,6 +20,14 @@
},
"license": "MIT",
"sideEffects": false,
"type": "module",
"exports": {
"./globals": {
"type": "./globals.d.ts",
"import": "./globals.js",
"require": "./globals.cjs"
}
},
"files": [
"README.md",
"*.js",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/router",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Core Storybook Router",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/telemetry",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Telemetry logging for crash reports and usage statistics",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/theming",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Core Storybook Components",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/types",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Core Storybook TS Types",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/angular",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.",
"keywords": [
"storybook",

View File

@ -8,6 +8,35 @@ import {
import { ISomeInterface, ButtonAccent, InputComponent } from './__testfixtures__/input.component';
describe('angular template decorator', () => {
it('with props should generate tag with properties', () => {
const component = InputComponent;
const props = {
isDisabled: true,
label: 'Hello world',
accent: ButtonAccent.High,
counter: 4,
'aria-label': 'Hello world',
};
const source = computesTemplateFromComponent(component, props);
expect(source).toEqual(
`<doc-button [counter]="counter" [accent]="accent" [isDisabled]="isDisabled" [label]="label" [aria-label]="this['aria-label']"></doc-button>`
);
});
it('with props should generate tag with outputs', () => {
const component = InputComponent;
const props = {
isDisabled: true,
label: 'Hello world',
onClick: ($event: any) => {},
'dash-out': ($event: any) => {},
};
const source = computesTemplateFromComponent(component, props);
expect(source).toEqual(
`<doc-button [isDisabled]="isDisabled" [label]="label" (onClick)="onClick($event)" (dash-out)="this['dash-out']($event)"></doc-button>`
);
});
it('with no props should generate simple tag', () => {
const component = InputComponent;
const props = {};
@ -545,11 +574,12 @@ describe('angular source decorator', () => {
label: 'Hello world',
accent: ButtonAccent.High,
counter: 4,
'aria-label': 'Hello world',
};
const argTypes: ArgTypes = {};
const source = computesTemplateSourceFromComponent(component, props, argTypes);
expect(source).toEqual(
`<doc-button [counter]="4" [accent]="'High'" [isDisabled]="true" [label]="'Hello world'"></doc-button>`
`<doc-button [counter]="4" [accent]="'High'" [isDisabled]="true" [label]="'Hello world'" [aria-label]="'Hello world'"></doc-button>`
);
});
@ -559,11 +589,12 @@ describe('angular source decorator', () => {
isDisabled: true,
label: 'Hello world',
onClick: ($event: any) => {},
'dash-out': ($event: any) => {},
};
const argTypes: ArgTypes = {};
const source = computesTemplateSourceFromComponent(component, props, argTypes);
expect(source).toEqual(
`<doc-button [isDisabled]="true" [label]="'Hello world'" (onClick)="onClick($event)"></doc-button>`
`<doc-button [isDisabled]="true" [label]="'Hello world'" (onClick)="onClick($event)" (dash-out)="this['dash-out']($event)"></doc-button>`
);
});

View File

@ -7,6 +7,20 @@ import {
getComponentInputsOutputs,
} from './utils/NgComponentAnalyzer';
/**
* Check if the name matches the criteria for a valid identifier.
* A valid identifier can only contain letters, digits, underscores, or dollar signs.
* It cannot start with a digit.
*/
const isValidIdentifier = (name: string): boolean => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
/**
* Returns the property name, if it can be accessed with dot notation. If not,
* it returns `this['propertyName']`.
*/
export const formatPropInTemplate = (propertyName: string) =>
isValidIdentifier(propertyName) ? propertyName : `this['${propertyName}']`;
const separateInputsOutputsAttributes = (
ngComponentInputsOutputs: ComponentInputsOutputs,
props: ICollection = {}
@ -50,10 +64,12 @@ export const computesTemplateFromComponent = (
);
const templateInputs =
initialInputs.length > 0 ? ` ${initialInputs.map((i) => `[${i}]="${i}"`).join(' ')}` : '';
initialInputs.length > 0
? ` ${initialInputs.map((i) => `[${i}]="${formatPropInTemplate(i)}"`).join(' ')}`
: '';
const templateOutputs =
initialOutputs.length > 0
? ` ${initialOutputs.map((i) => `(${i})="${i}($event)"`).join(' ')}`
? ` ${initialOutputs.map((i) => `(${i})="${formatPropInTemplate(i)}($event)"`).join(' ')}`
: '';
return buildTemplate(
@ -153,7 +169,7 @@ export const computesTemplateSourceFromComponent = (
: '';
const templateOutputs =
initialOutputs.length > 0
? ` ${initialOutputs.map((i) => `(${i})="${i}($event)"`).join(' ')}`
? ` ${initialOutputs.map((i) => `(${i})="${formatPropInTemplate(i)}($event)"`).join(' ')}`
: '';
return buildTemplate(ngComponentMetadata.selector, '', templateInputs, templateOutputs);

View File

@ -40,9 +40,13 @@ export class InputComponent<T> {
@Input()
public label: string;
@Input('aria-label') public ariaLabel: string;
/** Specifies some arbitrary object */
@Input() public someDataObject: ISomeInterface;
@Output()
public onClick = new EventEmitter<Event>();
@Output('dash-out') public dashOut = new EventEmitter<any>();
}

View File

@ -100,4 +100,10 @@ describe('argsToTemplate', () => {
const result = argsToTemplate(args, {});
expect(result).toEqual('[input]="input" (event1)="event1($event)"');
});
it('should format for non dot notation', () => {
const args = { 'non-dot': 'Value1', 'dash-out': () => {} };
const result = argsToTemplate(args, {});
expect(result).toEqual('[non-dot]="this[\'non-dot\']" (dash-out)="this[\'dash-out\']($event)"');
});
});

View File

@ -1,3 +1,5 @@
import { formatPropInTemplate } from './angular-beta/ComputesTemplateFromComponent';
/**
* Options for controlling the behavior of the argsToTemplate function.
*
@ -68,7 +70,9 @@ export function argsToTemplate<A extends Record<string, any>>(
return true;
})
.map(([key, value]) =>
typeof value === 'function' ? `(${key})="${key}($event)"` : `[${key}]="${key}"`
typeof value === 'function'
? `(${key})="${formatPropInTemplate(key)}($event)"`
: `[${key}]="${formatPropInTemplate(key)}"`
)
.join(' ');
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/ember",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember",
"bugs": {

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/html-vite",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/html-webpack5",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/nextjs",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Next.js",
"keywords": [
"storybook",

View File

@ -31,6 +31,7 @@ function Component() {
export default {
component: Component,
tags: ['test-skip'],
parameters: {
nextjs: {
appDirectory: true,

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preact-vite",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/preact-webpack5",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Preact: Develop Preact Component in isolation.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/react-vite",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/react-webpack5",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for React: Develop React Component in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/server-webpack5",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/svelte-vite",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/svelte-webpack5",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/sveltekit",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for SvelteKit",
"keywords": [
"storybook",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/vue3-vite",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -9,6 +9,7 @@ import {
createCheckerByJson,
type ComponentMeta,
type MetaCheckerOptions,
type PropertyMetaSchema,
} from 'vue-component-meta';
import { parseMulti } from 'vue-docgen-api';
@ -52,21 +53,14 @@ export async function vueComponentMeta(tsconfigPath = 'tsconfig.json'): Promise<
// we remove nested object schemas here since they are not used inside Storybook (we don't generate controls for object properties)
// and they can cause "out of memory" issues for large/complex schemas (e.g. HTMLElement)
// it also reduced the bundle size when running "Storybook build" when such schemas are used
(['props', 'exposed'] as const).forEach((key) => {
// it also reduced the bundle size when running "storybook build" when such schemas are used
(['props', 'events', 'slots', 'exposed'] as const).forEach((key) => {
meta[key].forEach((value) => {
if (typeof value.schema !== 'object') return;
// we need to use Object.defineProperty here since schema is a getter so we can not set it directly
Object.defineProperty(value, 'schema', {
configurable: true,
enumerable: true,
value: {
kind: value.schema.kind,
type: value.schema.type,
// note that value.schema.schema is not included here (see comment above)
},
});
if (Array.isArray(value.schema)) {
value.schema.forEach((eventSchema) => removeNestedSchemas(eventSchema));
} else {
removeNestedSchemas(value.schema);
}
});
});
@ -270,3 +264,12 @@ async function getTsConfigReferences(tsConfigPath: string) {
return [];
}
}
/**
* Removes any nested schemas from the given main schema (e.g. from a prop, event, slot or exposed).
* Useful to drastically reduce build size and prevent out of memory issues when large schemas (e.g. HTMLElement, MouseEvent) are used.
*/
function removeNestedSchemas(schema: PropertyMetaSchema) {
if (typeof schema !== 'object') return;
delete schema.schema;
}

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/vue3-webpack5",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/web-components-vite",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/web-components-webpack5",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.",
"keywords": [
"lit",

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/blocks",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook Doc Blocks",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "sb",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook CLI",
"keywords": [
"storybook"

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/cli",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook CLI",
"keywords": [
"storybook"

View File

@ -0,0 +1 @@
module.exports = require('@storybook/core/manager/globals');

View File

@ -0,0 +1,2 @@
export * from '@storybook/core/manager/globals';
export type * from '@storybook/core/manager/globals';

View File

@ -0,0 +1 @@
export * from '@storybook/core/manager/globals';

View File

@ -1,6 +1,6 @@
{
"name": "storybook",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "Storybook's CLI - install, dev, build, upgrade, and more",
"keywords": [
"cli",
@ -167,6 +167,11 @@
"types": "./core/preview/globals.d.ts",
"import": "./core/preview/globals.js",
"require": "./core/preview/globals.cjs"
},
"./internal/manager/globals": {
"types": "./core/manager/globals.d.ts",
"import": "./core/manager/globals.js",
"require": "./core/manager/globals.cjs"
}
},
"main": "dist/index.cjs",
@ -219,6 +224,9 @@
"internal/manager-errors": [
"./core/manager-errors.d.ts"
],
"internal/manager/globals": [
"./core/manager/globals.d.ts"
],
"internal/manager/globals-module-info": [
"./core/manager/globals-module-info.d.ts"
],

View File

@ -1,6 +1,6 @@
{
"name": "@storybook/codemod",
"version": "8.3.0-alpha.1",
"version": "8.3.0-alpha.2",
"description": "A collection of codemod scripts written with JSCodeshift",
"keywords": [
"storybook"

Some files were not shown because too many files have changed in this diff Show More