From 580eb8fcfc30fd9ba0dd38e6c4be633eb5540ed7 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Fri, 1 Dec 2023 19:41:36 -0700 Subject: [PATCH 01/13] Merge pull request #25084 from storybookjs/docs_fix_vite_link (cherry picked from commit 4a90af162b15753705d9d4f67ea891876aa520ae) --- docs/builders/vite.md | 2 +- docs/essentials/actions.md | 2 +- docs/essentials/controls.md | 6 +++--- docs/writing-docs/autodocs.md | 4 ++-- docs/writing-docs/doc-blocks.md | 2 +- docs/writing-stories/decorators.md | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/builders/vite.md b/docs/builders/vite.md index 2302191fcae3..5a2025ed0a51 100644 --- a/docs/builders/vite.md +++ b/docs/builders/vite.md @@ -114,7 +114,7 @@ If you need to override it, you can use the `viteFinal` function and adjust it. ### ArgTypes are not generated automatically -Currently, [automatic argType inference](../api/argtypes.md#automatic-argtype-inference) is only available for React, Vue3 and Svelte (JSDocs only). With React, the Vite builder defaults to `react-docgen-typescript` if TypeScript is listed as a dependency. If you run into any issues, you can revert to `react-docgen` by updating your Storybook configuration file as follows: +Currently, [automatic argType inference](../api/arg-types.md#automatic-argtype-inference) is only available for React, Vue3 and Svelte (JSDocs only). With React, the Vite builder defaults to `react-docgen-typescript` if TypeScript is listed as a dependency. If you run into any issues, you can revert to `react-docgen` by updating your Storybook configuration file as follows: diff --git a/docs/essentials/actions.md b/docs/essentials/actions.md index 31ae0f5d5c60..99f56c1d7905 100644 --- a/docs/essentials/actions.md +++ b/docs/essentials/actions.md @@ -41,7 +41,7 @@ When Storybook sees this argType, it will create an arg set to a special “acti ### Automatically matching args -Another option is to use a global parameter to match all [argTypes](../api/argtypes.md) that match a certain pattern. The following configuration automatically creates actions for each `on` argType (which you can either specify manually or can be [inferred automatically](../api/argtypes.md#automatic-argtype-inference)). +Another option is to use a global parameter to match all [argTypes](../api/arg-types.md) that match a certain pattern. The following configuration automatically creates actions for each `on` argType (which you can either specify manually or can be [inferred automatically](../api/arg-types.md#automatic-argtype-inference)). diff --git a/docs/essentials/controls.md b/docs/essentials/controls.md index 131a38be6b8c..2fb67af32861 100644 --- a/docs/essentials/controls.md +++ b/docs/essentials/controls.md @@ -19,7 +19,7 @@ Controls do not require any modification to your components. Stories for control - Portable. Reuse your interactive stories in documentation, tests, and even in designs. - Rich. Customize the controls and interactive data to suit your exact needs. -To use the Controls addon, you need to write your stories using [args](../writing-stories/args.md). Storybook will automatically generate UI controls based on your args and what it can infer about your component. Still, you can configure the controls further using [argTypes](../api/argtypes.md), see below. +To use the Controls addon, you need to write your stories using [args](../writing-stories/args.md). Storybook will automatically generate UI controls based on your args and what it can infer about your component. Still, you can configure the controls further using [argTypes](../api/arg-types.md), see below. @@ -70,7 +70,7 @@ By default, Storybook will render a free text input for the `variant` arg: It works as long as you type a valid string into the auto-generated text control. Still, it's not the best UI for our scenario, given that the component only accepts `primary` or `secondary` as variants. Let’s replace it with Storybook’s radio component. -We can specify which controls get used by declaring a custom [argType](../api/argtypes.md) for the `variant` property. ArgTypes encode basic metadata for args, such as name, description, defaultValue for an arg. These get automatically filled in by Storybook Docs. +We can specify which controls get used by declaring a custom [argType](../api/arg-types.md) for the `variant` property. ArgTypes encode basic metadata for args, such as name, description, defaultValue for an arg. These get automatically filled in by Storybook Docs. `ArgTypes` can also contain arbitrary annotations, which the user can override. Since `variant` is a property of the component, let's put that annotation on the default export. @@ -209,7 +209,7 @@ The Controls addon can be configured in two ways: ### Annotation -As shown above, you can configure individual controls with the “control" annotation in the [argTypes](../api/argtypes.md) field of either a component or story. Below is a condensed example and table featuring all available controls. +As shown above, you can configure individual controls with the “control" annotation in the [argTypes](../api/arg-types.md) field of either a component or story. Below is a condensed example and table featuring all available controls. | Data Type | Control | Description | | ----------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/docs/writing-docs/autodocs.md b/docs/writing-docs/autodocs.md index 427db5c7e79b..61026e2d981b 100644 --- a/docs/writing-docs/autodocs.md +++ b/docs/writing-docs/autodocs.md @@ -29,7 +29,7 @@ To enable auto-generated documentation for your stories, you'll need to add the ![Storybook autodocs](./autodocs.png) -Once the story loads, Storybook infers the relevant metadata (e.g., [`args`](../writing-stories/args.md), [`argTypes`](../api/argtypes.md), [`parameters`](../writing-stories/parameters.md)) and automatically generates a documentation page with this information positioned at the root-level of your component tree in the sidebar. +Once the story loads, Storybook infers the relevant metadata (e.g., [`args`](../writing-stories/args.md), [`argTypes`](../api/arg-types.md), [`parameters`](../writing-stories/parameters.md)) and automatically generates a documentation page with this information positioned at the root-level of your component tree in the sidebar. ### Configure @@ -78,7 +78,7 @@ Going over the code snippet in more detail. When Storybook starts up, it will ov 1. A header with the component's metadata retrieved by the `Title`, `Subtitle`, and `Description` Doc Blocks. 2. The first story defined in the file via the `Primary` Doc Block with a handy set of UI controls to zoom in and out of the component. -3. An interactive table with all the relevant [`args`](../writing-stories/args.md) and [`argTypes`](../api/argtypes.md) defined in the story via the `Controls` Doc Block. +3. An interactive table with all the relevant [`args`](../writing-stories/args.md) and [`argTypes`](../api/arg-types.md) defined in the story via the `Controls` Doc Block. 4. A overview of the remaining stories via the `Stories` Doc Block. #### With MDX diff --git a/docs/writing-docs/doc-blocks.md b/docs/writing-docs/doc-blocks.md index faacdf5fa588..12cfaee8317b 100644 --- a/docs/writing-docs/doc-blocks.md +++ b/docs/writing-docs/doc-blocks.md @@ -135,7 +135,7 @@ Accepts parameters in the namespace `parameters.docs.argTypes`. -The `ArgTypes` block can be used to show a static table of [arg types](../api/argtypes.md) for a given component as a way to document its interface. +The `ArgTypes` block can be used to show a static table of [arg types](../api/arg-types.md) for a given component as a way to document its interface. ![Screenshot of ArgTypes block](../api/doc-block-argtypes.png) diff --git a/docs/writing-stories/decorators.md b/docs/writing-stories/decorators.md index d80bf565afe4..f6c5305877cd 100644 --- a/docs/writing-stories/decorators.md +++ b/docs/writing-stories/decorators.md @@ -71,7 +71,7 @@ In the example above, the values provided are hardcoded. Still, you may want to The second argument to a decorator function is the **story context** which in particular contains the keys: - `args` - the story arguments. You can use some [`args`](./args.md) in your decorators and drop them in the story implementation itself. -- `argTypes`- Storybook's [argTypes](../api/argtypes.md) allow you to customize and fine-tune your stories [`args`](./args.md). +- `argTypes`- Storybook's [argTypes](../api/arg-types.md) allow you to customize and fine-tune your stories [`args`](./args.md). - `globals` - Storybook-wide [globals](../essentials/toolbars-and-globals.md#globals). In particular you can use the [toolbars feature](../essentials/toolbars-and-globals.md#global-types-toolbar-annotations) to allow you to change these values using Storybook’s UI. - `hooks` - Storybook's API hooks (e.g., useArgs). - `parameters`- the story's static metadata, most commonly used to control Storybook's behavior of features and addons. From d22314501998da3c0e51fa6706b76b62e703670a Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 4 Dec 2023 21:39:22 +0100 Subject: [PATCH 02/13] Merge pull request #25098 from storybookjs/valentin/fix-csf-loader-for-angular-second-attempt Angular: Fix CSF Plugin (cherry picked from commit 96bcc58d5d75b0bdc981f639c6cda569c854ca9c) --- code/addons/storysource/package.json | 2 +- code/lib/csf-plugin/src/index.ts | 15 +- code/lib/csf-tools/src/enrichCsf.test.ts | 392 +++++++++++++++++------ code/lib/csf-tools/src/enrichCsf.ts | 22 +- 4 files changed, 321 insertions(+), 110 deletions(-) diff --git a/code/addons/storysource/package.json b/code/addons/storysource/package.json index cd767bfa3ead..2b3ffaed914e 100644 --- a/code/addons/storysource/package.json +++ b/code/addons/storysource/package.json @@ -47,6 +47,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/source-loader": "workspace:*", "estraverse": "^5.2.0", "tiny-invariant": "^1.3.1" }, @@ -56,7 +57,6 @@ "@storybook/manager-api": "workspace:*", "@storybook/preview-api": "workspace:*", "@storybook/router": "workspace:*", - "@storybook/source-loader": "workspace:*", "@storybook/theming": "workspace:*", "@types/react": "^16.14.34", "@types/react-syntax-highlighter": "11.0.5", diff --git a/code/lib/csf-plugin/src/index.ts b/code/lib/csf-plugin/src/index.ts index aed7a531ee32..ec0aaa1d52a9 100644 --- a/code/lib/csf-plugin/src/index.ts +++ b/code/lib/csf-plugin/src/index.ts @@ -12,15 +12,18 @@ const logger = console; export const unplugin = createUnplugin((options) => { return { name: 'unplugin-csf', - enforce: 'pre', - loadInclude(id) { + transformInclude(id) { return STORIES_REGEX.test(id); }, - async load(fname) { - const code = await fs.readFile(fname, 'utf-8'); + async transform(code, id) { + const sourceCode = await fs.readFile(id, 'utf-8'); try { - const csf = loadCsf(code, { makeTitle: (userTitle) => userTitle || 'default' }).parse(); - enrichCsf(csf, options); + const makeTitle = (userTitle: string) => userTitle || 'default'; + const csf = loadCsf(code, { makeTitle }).parse(); + const csfSource = loadCsf(sourceCode, { + makeTitle, + }).parse(); + enrichCsf(csf, csfSource, options); return formatCsf(csf, { sourceMaps: true }); } catch (err: any) { // This can be called on legacy storiesOf files, so just ignore diff --git a/code/lib/csf-tools/src/enrichCsf.test.ts b/code/lib/csf-tools/src/enrichCsf.test.ts index a8f5f3aaa09c..d793f730cecc 100644 --- a/code/lib/csf-tools/src/enrichCsf.test.ts +++ b/code/lib/csf-tools/src/enrichCsf.test.ts @@ -11,11 +11,16 @@ expect.addSnapshotSerializer({ test: (val) => true, }); -const enrich = (code: string, options?: EnrichCsfOptions) => { +const enrich = (code: string, originalCode: string, options?: EnrichCsfOptions) => { // we don't actually care about the title - const csf = loadCsf(code, { makeTitle: (userTitle) => userTitle || 'default' }).parse(); - enrichCsf(csf, options); + const csf = loadCsf(code, { + makeTitle: (userTitle) => userTitle || 'default', + }).parse(); + const csfSource = loadCsf(originalCode, { + makeTitle: (userTitle) => userTitle || 'default', + }).parse(); + enrichCsf(csf, csfSource, options); return formatCsf(csf); }; @@ -23,17 +28,28 @@ describe('enrichCsf', () => { describe('source', () => { it('csf1', () => { expect( - enrich(dedent` + enrich( + dedent` + // compiled code export default { title: 'Button', } - export const Basic = () =>