From e7beea4fbf014362bd665bfaf31f68b77894f162 Mon Sep 17 00:00:00 2001 From: Donald Pipowitch <1152805+donaldpipowitch@users.noreply.github.com> Date: Wed, 21 Jun 2023 15:28:11 +0200 Subject: [PATCH 01/69] hide runtime errors --- code/builders/builder-webpack5/src/presets/preview-preset.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/builders/builder-webpack5/src/presets/preview-preset.ts b/code/builders/builder-webpack5/src/presets/preview-preset.ts index eba1e361bbdf..12a95b544278 100644 --- a/code/builders/builder-webpack5/src/presets/preview-preset.ts +++ b/code/builders/builder-webpack5/src/presets/preview-preset.ts @@ -9,7 +9,7 @@ export const entries = async (_: unknown, options: any) => { // Suppress informational messages when --quiet is specified. webpack-hot-middleware's quiet // parameter would also suppress warnings. result = result.concat( - `${require.resolve('webpack-hot-middleware/client')}?reload=true&quiet=false&noInfo=${ + `${require.resolve('webpack-hot-middleware/client')}?reload=true&quiet=false&overlay=${JSON.stringify({ errors: true, warnings:false, runtimeErrors: false })}&noInfo=${ options.quiet }` ); From 599e7f50124ddca0eca36044803dfd56aa7323d4 Mon Sep 17 00:00:00 2001 From: Donald Pipowitch <1152805+donaldpipowitch@users.noreply.github.com> Date: Thu, 22 Jun 2023 08:35:56 +0200 Subject: [PATCH 02/69] linting --- .../builder-webpack5/src/presets/preview-preset.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/builders/builder-webpack5/src/presets/preview-preset.ts b/code/builders/builder-webpack5/src/presets/preview-preset.ts index 12a95b544278..6835925b7df3 100644 --- a/code/builders/builder-webpack5/src/presets/preview-preset.ts +++ b/code/builders/builder-webpack5/src/presets/preview-preset.ts @@ -9,9 +9,13 @@ export const entries = async (_: unknown, options: any) => { // Suppress informational messages when --quiet is specified. webpack-hot-middleware's quiet // parameter would also suppress warnings. result = result.concat( - `${require.resolve('webpack-hot-middleware/client')}?reload=true&quiet=false&overlay=${JSON.stringify({ errors: true, warnings:false, runtimeErrors: false })}&noInfo=${ - options.quiet - }` + `${require.resolve( + 'webpack-hot-middleware/client' + )}?reload=true&quiet=false&overlay=${JSON.stringify({ + errors: true, + warnings: false, + runtimeErrors: false, + })}&noInfo=${options.quiet}` ); } From 556b02e59e86da1ffde7878f6b4a00e117910299 Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Wed, 20 Sep 2023 15:30:00 -0700 Subject: [PATCH 03/69] fix: avoid relying on document for preview file used in the compose/testing api --- .../src/modules/preview-web/UrlStore.ts | 32 ++++++++++--------- .../src/modules/preview-web/WebView.ts | 32 ++++++++++--------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/code/lib/preview-api/src/modules/preview-web/UrlStore.ts b/code/lib/preview-api/src/modules/preview-web/UrlStore.ts index 16d66ba7f6b6..0e31b9fef810 100644 --- a/code/lib/preview-api/src/modules/preview-web/UrlStore.ts +++ b/code/lib/preview-api/src/modules/preview-web/UrlStore.ts @@ -22,7 +22,7 @@ const getQueryString = ({ selection?: Selection; extraParams?: qs.ParsedQs; }) => { - const { search = '' } = document.location; + const search = (document && document.location && document.location.search) || ''; const { path, selectedKind, selectedStory, ...rest } = qs.parse(search, { ignoreQueryPrefix: true, }); @@ -65,20 +65,22 @@ const getFirstString = (v: ValueOf): string | void => { }; export const getSelectionSpecifierFromPath: () => SelectionSpecifier | null = () => { - const query = qs.parse(document.location.search, { ignoreQueryPrefix: true }); - const args = typeof query.args === 'string' ? parseArgsParam(query.args) : undefined; - const globals = typeof query.globals === 'string' ? parseArgsParam(query.globals) : undefined; - - let viewMode = getFirstString(query.viewMode) as ViewMode; - if (typeof viewMode !== 'string' || !viewMode.match(/docs|story/)) { - viewMode = 'story'; - } - - const path = getFirstString(query.path); - const storyId = path ? pathToId(path) : getFirstString(query.id); - - if (storyId) { - return { storySpecifier: storyId, args, globals, viewMode }; + if (document && document.location && document.location.search) { + const query = qs.parse(document.location.search, { ignoreQueryPrefix: true }); + const args = typeof query.args === 'string' ? parseArgsParam(query.args) : undefined; + const globals = typeof query.globals === 'string' ? parseArgsParam(query.globals) : undefined; + + let viewMode = getFirstString(query.viewMode) as ViewMode; + if (typeof viewMode !== 'string' || !viewMode.match(/docs|story/)) { + viewMode = 'story'; + } + + const path = getFirstString(query.path); + const storyId = path ? pathToId(path) : getFirstString(query.id); + + if (storyId) { + return { storySpecifier: storyId, args, globals, viewMode }; + } } return null; diff --git a/code/lib/preview-api/src/modules/preview-web/WebView.ts b/code/lib/preview-api/src/modules/preview-web/WebView.ts index 6f02568934c3..0f1aa060f967 100644 --- a/code/lib/preview-api/src/modules/preview-web/WebView.ts +++ b/code/lib/preview-api/src/modules/preview-web/WebView.ts @@ -46,22 +46,24 @@ export class WebView implements View { constructor() { // Special code for testing situations - // eslint-disable-next-line @typescript-eslint/naming-convention - const { __SPECIAL_TEST_PARAMETER__ } = qs.parse(document.location.search, { - ignoreQueryPrefix: true, - }); - switch (__SPECIAL_TEST_PARAMETER__) { - case 'preparing-story': { - this.showPreparingStory(); - this.testing = true; - break; - } - case 'preparing-docs': { - this.showPreparingDocs(); - this.testing = true; - break; + if (document && document.location && document.location.search) { + // eslint-disable-next-line @typescript-eslint/naming-convention + const { __SPECIAL_TEST_PARAMETER__ } = qs.parse(document.location.search, { + ignoreQueryPrefix: true, + }); + switch (__SPECIAL_TEST_PARAMETER__) { + case 'preparing-story': { + this.showPreparingStory(); + this.testing = true; + break; + } + case 'preparing-docs': { + this.showPreparingDocs(); + this.testing = true; + break; + } + default: // pass; } - default: // pass; } } From 43240c4e2b22a6ec534b71324d48cc8e12103bcd Mon Sep 17 00:00:00 2001 From: Joe Vaughan <122215197+joevaugh4n@users.noreply.github.com> Date: Wed, 6 Mar 2024 09:59:47 +0000 Subject: [PATCH 04/69] Update remove-argtypes-regex.ts Changed copy in the remove-argtypes-regex script --- .../automigrate/fixes/remove-argtypes-regex.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/remove-argtypes-regex.ts b/code/lib/cli/src/automigrate/fixes/remove-argtypes-regex.ts index 78dd25049b27..3220bbeeec9d 100644 --- a/code/lib/cli/src/automigrate/fixes/remove-argtypes-regex.ts +++ b/code/lib/cli/src/automigrate/fixes/remove-argtypes-regex.ts @@ -39,17 +39,20 @@ export const removeArgtypesRegex: Fix<{ argTypesRegex: NodePath; previewConfigPa ${argTypesRegex.buildCodeFrameError(`${previewConfigPath}`).message} - In Storybook you can write so-called play functions, which are used to render your stories interactively. - Mocking action args in play functions was done implicitly by analyzing the argTypesRegex. - - Since Storybook 8, implicit action args mocking isn't supported anymore. + Storybook's play functions let you render your stories interactively. + + In the past, play functions mocked action args implicitly by analyzing the argTypesRegex + in your preview.js|ts file. + + However, Storybook 8 changes this behavior, and we now recommend using the + (fn) function to mock your component's methods instead. - Use the following command to check for mocked action usages in your play functions: + Use the following command to check for implied mocked actions in your play functions: ${chalk.cyan( 'npx storybook migrate find-implicit-spies --glob="**/*.stories.@(js|jsx|ts|tsx)"' )} - And follow the documentation to migrate your play functions: + Then, refer to our docs to migrate your play functions to Storybook 8: ${chalk.yellow( 'https://storybook.js.org/docs/8.0/essentials/actions#via-storybooktest-fn-spy-function' )} From ba41ad7ee15847ac0d38e9c6cb1dcc6919cec472 Mon Sep 17 00:00:00 2001 From: Yuki Kitagata <45357311+YukiKitagata@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:38:11 +0900 Subject: [PATCH 05/69] escape filename given as argument --- code/lib/codemod/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/codemod/src/index.ts b/code/lib/codemod/src/index.ts index b55c790adf83..5e9046ad2f77 100644 --- a/code/lib/codemod/src/index.ts +++ b/code/lib/codemod/src/index.ts @@ -89,7 +89,7 @@ export async function runCodemod( '-t', `${TRANSFORM_DIR}/${codemod}.js`, ...parserArgs, - ...files, + ...files.map(file => `"${file}"`), ], { stdio: 'inherit', From be1ccf4a250201b7c8a56da37251848de14f54f3 Mon Sep 17 00:00:00 2001 From: Hendrik Schmitz <36853386+drik98@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:05:51 +0100 Subject: [PATCH 06/69] Fix missing support for mts vite config --- code/lib/cli/src/automigrate/fixes/vite-config-file.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts index 9203b45f225f..aee8a1ed985e 100644 --- a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts +++ b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts @@ -20,7 +20,7 @@ export const viteConfigFile = { async check({ mainConfig, packageManager, mainConfigPath }) { let isViteConfigFileFound = !!(await findUp( - ['vite.config.js', 'vite.config.mjs', 'vite.config.cjs', 'vite.config.ts'], + ['vite.config.js', 'vite.config.mjs', 'vite.config.cjs', 'vite.config.ts', 'vite.config.mts'], { cwd: mainConfigPath ? path.join(mainConfigPath, '..') : process.cwd() } )); From 14a6893359bca6355e5a65845bcab2004dae2789 Mon Sep 17 00:00:00 2001 From: Arnab Sen Date: Tue, 12 Mar 2024 15:32:28 -0400 Subject: [PATCH 07/69] Add storybook/test as dev dependency --- .../cli/src/automigrate/fixes/remove-jest-testing-library.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/cli/src/automigrate/fixes/remove-jest-testing-library.ts b/code/lib/cli/src/automigrate/fixes/remove-jest-testing-library.ts index 3eed2c36ab70..59ce82d3cbbe 100644 --- a/code/lib/cli/src/automigrate/fixes/remove-jest-testing-library.ts +++ b/code/lib/cli/src/automigrate/fixes/remove-jest-testing-library.ts @@ -43,7 +43,7 @@ export const removeJestTestingLibrary: Fix<{ incompatiblePackages: string[] }> = const versionToInstall = getStorybookVersionSpecifier(packageJson); - await packageManager.addDependencies({ packageJson }, [ + await packageManager.addDependencies({ installAsDevDependencies: true, packageJson }, [ `@storybook/test@${versionToInstall}`, ]); From 3fca53414b463615bddeb6244278d5de096432e4 Mon Sep 17 00:00:00 2001 From: Andreas Deininger Date: Fri, 15 Mar 2024 21:55:21 +0100 Subject: [PATCH 08/69] Fix typos --- CHANGELOG.v1-5.md | 6 +++--- CHANGELOG.v6.md | 4 ++-- MIGRATION.md | 4 ++-- code/addons/actions/src/models/ActionOptions.ts | 2 +- code/addons/actions/src/runtime/action.ts | 2 +- code/addons/docs/ember/README.md | 2 +- code/addons/docs/web-components/README.md | 2 +- code/e2e-tests/util.ts | 2 +- code/lib/cli/src/automigrate/index.test.ts | 4 ++-- code/lib/core-webpack/src/importPipeline.ts | 4 ++-- code/lib/instrumenter/src/instrumenter.ts | 2 +- code/lib/manager-api/src/tests/stories.test.ts | 6 +++--- .../preview-api/src/modules/preview-web/render/Render.ts | 2 +- code/lib/preview-api/src/modules/store/GlobalsStore.test.ts | 2 +- .../preview-api/src/modules/store/csf/prepareStory.test.ts | 2 +- code/lib/types/src/modules/story.ts | 2 +- code/renderers/preact/src/render.tsx | 2 +- code/ui/blocks/src/blocks/useStory.ts | 2 +- code/ui/blocks/src/examples/Button.stories.tsx | 2 +- .../individual-snapshot-tests-portable-stories.jest.js.mdx | 4 ++-- .../individual-snapshot-tests-portable-stories.jest.ts.mdx | 4 ++-- ...individual-snapshot-tests-portable-stories.vitest.js.mdx | 4 ++-- ...individual-snapshot-tests-portable-stories.vitest.ts.mdx | 4 ++-- docs/writing-tests/storyshots-migration-guide.md | 2 +- scripts/build-package.ts | 4 ++-- scripts/check-package.ts | 4 ++-- scripts/release/version.ts | 2 +- scripts/sandbox/utils/git.ts | 2 +- 28 files changed, 42 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.v1-5.md b/CHANGELOG.v1-5.md index 77b7589e5539..2a965d45f9f3 100644 --- a/CHANGELOG.v1-5.md +++ b/CHANGELOG.v1-5.md @@ -3527,7 +3527,7 @@ See [the RC announcement](https://gist.github.com/shilman/0332090b63f1798a58ed8d - UI: Fix ie 11 ([#5599](https://github.com/storybookjs/storybook/pull/5599)) - CLI: Fix for when outputDir is an absolute path ([#5573](https://github.com/storybookjs/storybook/pull/5573)) - CLI: Avoid false-negative checks for port ([#5565](https://github.com/storybookjs/storybook/pull/5565)) -- Core: Prioritise programatic configuration ([#5564](https://github.com/storybookjs/storybook/pull/5564)) +- Core: Prioritise programmatic configuration ([#5564](https://github.com/storybookjs/storybook/pull/5564)) - UI: FIX clear search ([#5550](https://github.com/storybookjs/storybook/pull/5550)) - Core: Transpile safe-eval package ([#5498](https://github.com/storybookjs/storybook/pull/5498)) - UI: Add default backgrounds to official example ([#5585](https://github.com/storybookjs/storybook/pull/5585)) @@ -5258,7 +5258,7 @@ NOTE: As part of the generic addon decorators, we've reversed the order of addon #### Features - Storybook for Marko [#3504](https://github.com/storybookjs/storybook/pull/3504) -- Storybook addon Jest angular suport [#3532](https://github.com/storybookjs/storybook/pull/3532) +- Storybook addon Jest angular support [#3532](https://github.com/storybookjs/storybook/pull/3532) - Storybook for HTML snippets [#3475](https://github.com/storybookjs/storybook/pull/3475) - Feature/config custom chrome executable path [#3518](https://github.com/storybookjs/storybook/pull/3518) - Channel-postmessage: handle events from the same window [#3519](https://github.com/storybookjs/storybook/pull/3519) @@ -9224,7 +9224,7 @@ Minor features including a new "events" addon, as well as the usual bugfixes, cl - Fixed knobs addon editing bug [#1233](https://github.com/storybookjs/storybook/pull/1233) - Fix bug in addons/graphql in reIndentQuery [#1207](https://github.com/storybookjs/storybook/pull/1207) -- Marksy initialized with mtrcConf intead of marksyConf [#1205](https://github.com/storybookjs/storybook/pull/1205) +- Marksy initialized with mtrcConf instead of marksyConf [#1205](https://github.com/storybookjs/storybook/pull/1205) #### Documentation diff --git a/CHANGELOG.v6.md b/CHANGELOG.v6.md index 8501b232d289..5e7ce4179aee 100644 --- a/CHANGELOG.v6.md +++ b/CHANGELOG.v6.md @@ -1950,7 +1950,7 @@ Fix bad publish of `6.4.0-alpha.27` to the `latest` tag ### Bug Fixes - Controls: Don't set arg in validateOptions if it would be `undefined` ([#15654](https://github.com/storybookjs/storybook/pull/15654)) -- Trailing comma handling for "-s" command line paramenter ([#15615](https://github.com/storybookjs/storybook/pull/15615)) +- Trailing comma handling for "-s" command line parameter ([#15615](https://github.com/storybookjs/storybook/pull/15615)) - Controls: Fix color matching behavior for non-string types ([#15549](https://github.com/storybookjs/storybook/pull/15549)) - Composition: Fix refs ordering ([#15527](https://github.com/storybookjs/storybook/pull/15527)) @@ -1963,7 +1963,7 @@ Fix bad publish of `6.4.0-alpha.27` to the `latest` tag ### Bug Fixes -- CLI: Fix trailing comma handling for "-s" command line paramenter ([#15615](https://github.com/storybookjs/storybook/pull/15615)) +- CLI: Fix trailing comma handling for "-s" command line parameter ([#15615](https://github.com/storybookjs/storybook/pull/15615)) - Components: Lazy-load syntax highlighter ([#15607](https://github.com/storybookjs/storybook/pull/15607)) ### Maintenance diff --git a/MIGRATION.md b/MIGRATION.md index 561a9a61b899..d8b041ba7b0b 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -4177,7 +4177,7 @@ For more information, [see the documentation](https://github.com/storybookjs/sto Storybook has built-in Typescript support in 6.0. That means you should remove your complex Typescript configurations from your `.storybook` config. We've tried to pick sensible defaults that work out of the box, especially for nice prop table generation in `@storybook/addon-docs`. -To migrate from an old setup, we recommend deleting any typescript-specific webpack/babel configurations in your project. You should also remove `@storybook/preset-typescript`, which is superceded by the built-in configuration. +To migrate from an old setup, we recommend deleting any typescript-specific webpack/babel configurations in your project. You should also remove `@storybook/preset-typescript`, which is superseded by the built-in configuration. If you want to override the defaults, see the [typescript configuration docs](https://storybook.js.org/docs/react/configure/typescript). @@ -5570,7 +5570,7 @@ The `@storybook/react-native` had built-in addons (`addon-actions` and `addon-li 1. `imageSnapshot` test function was extracted from `addon-storyshots` and moved to a new package - `addon-storyshots-puppeteer` that now will - be dependant on puppeteer. [README](https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-puppeteer) + be dependent on puppeteer. [README](https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-puppeteer) 2. `getSnapshotFileName` export was replaced with the `Stories2SnapsConverter` class that now can be overridden for a custom implementation of the snapshot-name generation. [README](https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core#stories2snapsconverter) diff --git a/code/addons/actions/src/models/ActionOptions.ts b/code/addons/actions/src/models/ActionOptions.ts index ffd8d373b3fa..c3e831801b50 100644 --- a/code/addons/actions/src/models/ActionOptions.ts +++ b/code/addons/actions/src/models/ActionOptions.ts @@ -1,7 +1,7 @@ import type { Options as TelejsonOptions } from 'telejson'; interface Options { - depth: number; // backards compatibility, remove in 7.0 + depth: number; // backwards compatibility, remove in 7.0 clearOnStoryChange: boolean; limit: number; implicit: boolean; diff --git a/code/addons/actions/src/runtime/action.ts b/code/addons/actions/src/runtime/action.ts index a647a8eb0d1b..737ff6f83ea8 100644 --- a/code/addons/actions/src/runtime/action.ts +++ b/code/addons/actions/src/runtime/action.ts @@ -84,7 +84,7 @@ export function action(name: string, options: ActionOptions = {}): HandlerFuncti } const channel = addons.getChannel(); - // this makes sure that in js enviroments like react native you can still get an id + // this makes sure that in js environments like react native you can still get an id const id = generateId(); const minDepth = 5; // anything less is really just storybook internals const serializedArgs = args.map(serializeArg); diff --git a/code/addons/docs/ember/README.md b/code/addons/docs/ember/README.md index e1d907435883..7491de442845 100644 --- a/code/addons/docs/ember/README.md +++ b/code/addons/docs/ember/README.md @@ -55,7 +55,7 @@ import docJson from '../dist/storybook-docgen/index.json'; setJSONDoc(docJson); ``` -Finally, be sure to fill in the `component` field in your story metadata. This should be a string that matches the name of the `@class` used in your souce comments: +Finally, be sure to fill in the `component` field in your story metadata. This should be a string that matches the name of the `@class` used in your source comments: ```ts export default { diff --git a/code/addons/docs/web-components/README.md b/code/addons/docs/web-components/README.md index 0aae578e47d8..c5417be88e43 100644 --- a/code/addons/docs/web-components/README.md +++ b/code/addons/docs/web-components/README.md @@ -31,7 +31,7 @@ In order to get [Props tables](..docs/../../docs/props-tables.md) documentation for web-components you will need to have a [custom-elements.json](https://github.com/webcomponents/custom-elements-json) file. -You can hand write it or better generate it. Depending on the web components sugar you are choosing your milage may vary. +You can hand write it or better generate it. Depending on the web components sugar you are choosing your mileage may vary. Known analyzers that output `custom-elements.json` v1.0.0: diff --git a/code/e2e-tests/util.ts b/code/e2e-tests/util.ts index df5ca4ff59a8..9ab050961891 100644 --- a/code/e2e-tests/util.ts +++ b/code/e2e-tests/util.ts @@ -84,7 +84,7 @@ export class SbPage { } async waitUntilLoaded() { - // make sure we start every test with clean state – to avoid possible flakyness + // make sure we start every test with clean state – to avoid possible flakiness await this.page.context().addInitScript(() => { const storeState = { layout: { diff --git a/code/lib/cli/src/automigrate/index.test.ts b/code/lib/cli/src/automigrate/index.test.ts index 78a098e9c8d7..11824e58d8a3 100644 --- a/code/lib/cli/src/automigrate/index.test.ts +++ b/code/lib/cli/src/automigrate/index.test.ts @@ -102,8 +102,8 @@ const runFixWrapper = async ({ describe('runFixes', () => { beforeEach(() => { retrievePackageJson.mockResolvedValue({ - depedencies: [], - devDepedencies: [], + dependencies: [], + devDependencies: [], }); getPackageVersion.mockImplementation((packageName) => { return beforeVersion; diff --git a/code/lib/core-webpack/src/importPipeline.ts b/code/lib/core-webpack/src/importPipeline.ts index c4a7a220a94b..167bae11c100 100644 --- a/code/lib/core-webpack/src/importPipeline.ts +++ b/code/lib/core-webpack/src/importPipeline.ts @@ -3,9 +3,9 @@ type ModuleExports = Record; // If an import is in flight when another import arrives, block it until the first completes. // This is to avoid a situation where webpack kicks off a second compilation whilst the // first is still completing, cf: https://github.com/webpack/webpack/issues/15541#issuecomment-1143138832 -// Note the way this code works if N futher `import()`s occur while the first is in flight, +// Note the way this code works if N further `import()`s occur while the first is in flight, // they will all be kicked off in the same tick and not block each other. This is by design, -// Webpack can handle multiple invalidations simutaneously, just not in quick succession. +// Webpack can handle multiple invalidations simultaneously, just not in quick succession. export function importPipeline() { let importGate: Promise = Promise.resolve(); diff --git a/code/lib/instrumenter/src/instrumenter.ts b/code/lib/instrumenter/src/instrumenter.ts index 3eeb6ea86ed8..b4c57e1b95a1 100644 --- a/code/lib/instrumenter/src/instrumenter.ts +++ b/code/lib/instrumenter/src/instrumenter.ts @@ -572,7 +572,7 @@ export class Instrumenter { update(call: Call) { this.channel.emit(EVENTS.CALL, call); this.setState(call.storyId, ({ calls }) => { - // Omit earlier calls for the same ID, which may have been superceded by a later invocation. + // Omit earlier calls for the same ID, which may have been superseded by a later invocation. // This typically happens when calls are part of a callback which runs multiple times. const callsById = calls .concat(call) diff --git a/code/lib/manager-api/src/tests/stories.test.ts b/code/lib/manager-api/src/tests/stories.test.ts index ba45fb688c31..9adec207d158 100644 --- a/code/lib/manager-api/src/tests/stories.test.ts +++ b/code/lib/manager-api/src/tests/stories.test.ts @@ -225,7 +225,7 @@ describe('stories API', () => { }, }); const { index } = store.getState(); - // We need exact key ordering, even if in theory JS doens't guarantee it + // We need exact key ordering, even if in theory JS doesn't guarantee it expect(Object.keys(index!)).toEqual(['a', 'a-b', 'a-b--1']); expect(index!.a).toMatchObject({ type: 'root', @@ -264,7 +264,7 @@ describe('stories API', () => { }, }); const { index } = store.getState(); - // We need exact key ordering, even if in theory JS doens't guarantee it + // We need exact key ordering, even if in theory JS doesn't guarantee it expect(Object.keys(index!)).toEqual(['a', 'a--1']); expect(index!.a).toMatchObject({ type: 'component', @@ -295,7 +295,7 @@ describe('stories API', () => { }, }); const { index } = store.getState(); - // We need exact key ordering, even if in theory JS doens't guarantee it + // We need exact key ordering, even if in theory JS doesn't guarantee it expect(Object.keys(index!)).toEqual(['a', 'a--1', 'a--2', 'b', 'b--1']); expect(index!.a).toMatchObject({ type: 'component', diff --git a/code/lib/preview-api/src/modules/preview-web/render/Render.ts b/code/lib/preview-api/src/modules/preview-web/render/Render.ts index 9ed82484900e..e1a82c998410 100644 --- a/code/lib/preview-api/src/modules/preview-web/render/Render.ts +++ b/code/lib/preview-api/src/modules/preview-web/render/Render.ts @@ -5,7 +5,7 @@ export type RenderType = 'story' | 'docs'; /** * A "Render" represents the rendering of a single entry to a single location * - * The implemenations of render are used for two key purposes: + * The implementations of render are used for two key purposes: * - Tracking the state of the rendering as it moves between preparing, rendering and tearing down. * - Tracking what is rendered to know if a change requires re-rendering or teardown + recreation. */ diff --git a/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts b/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts index 5d67a641b454..7cee817d2261 100644 --- a/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts +++ b/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts @@ -146,7 +146,7 @@ describe('GlobalsStore', () => { arg2: { defaultValue: 'arg2' }, }, }); - // However undeclared valuse aren't persisted + // However undeclared values aren't persisted expect(store.get()).toEqual({ arg1: 'new-arg1', arg2: 'new-arg2' }); }); }); diff --git a/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts b/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts index 0e76648dd5cb..b05485e5a506 100644 --- a/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts @@ -150,7 +150,7 @@ describe('prepareStory', () => { }); }); - it('can be overriden by `undefined`', () => { + it('can be overridden by `undefined`', () => { const { initialArgs } = prepareStory( { id, name, args: { a: undefined }, moduleExport }, { id, title, args: { a: 'component' } }, diff --git a/code/lib/types/src/modules/story.ts b/code/lib/types/src/modules/story.ts index f22d18ad7a3d..ee34ad43ce79 100644 --- a/code/lib/types/src/modules/story.ts +++ b/code/lib/types/src/modules/story.ts @@ -79,7 +79,7 @@ export type NormalizedStoryAnnotations = 'storyName' | 'story' | 'decorators' | 'loaders' > & { moduleExport: ModuleExport; - // You cannot actually set id on story annotations, but we normalize it to be there for convience + // You cannot actually set id on story annotations, but we normalize it to be there for convenience id: StoryId; argTypes?: StrictArgTypes; name: StoryName; diff --git a/code/renderers/preact/src/render.tsx b/code/renderers/preact/src/render.tsx index 014a6ec19733..e4c4ab64b485 100644 --- a/code/renderers/preact/src/render.tsx +++ b/code/renderers/preact/src/render.tsx @@ -16,7 +16,7 @@ export const render: ArgsStoryFn = (args, context) => { } // @ts-expect-error I think the type of Component should be Preact.ComponentType, but even that - // doens't make TS happy, I suspect because TS wants "react" components. + // doesn't make TS happy, I suspect because TS wants "react" components. return ; }; diff --git a/code/ui/blocks/src/blocks/useStory.ts b/code/ui/blocks/src/blocks/useStory.ts index 63b2581e2d39..95edc5b7392a 100644 --- a/code/ui/blocks/src/blocks/useStory.ts +++ b/code/ui/blocks/src/blocks/useStory.ts @@ -16,7 +16,7 @@ export function useStories( context: DocsContextProps ): (PreparedStory | void)[] { // Legacy docs pages can reference any story by id. Those stories will need to be - // asyncronously loaded; we use the state for this + // asynchronously loaded; we use the state for this const [storiesById, setStories] = useState>>({}); useEffect(() => { diff --git a/code/ui/blocks/src/examples/Button.stories.tsx b/code/ui/blocks/src/examples/Button.stories.tsx index d99917fdfee8..e5fc5b2e3457 100644 --- a/code/ui/blocks/src/examples/Button.stories.tsx +++ b/code/ui/blocks/src/examples/Button.stories.tsx @@ -53,7 +53,7 @@ _this description was written as a string in \`parameters.docs.description.story /** * This is the large button - * _this description was written as a comment above the story, and should never be shown because it should be overriden by the description in the parameters_ + * _this description was written as a comment above the story, and should never be shown because it should be overridden by the description in the parameters_ */ export const Large: Story = { args: { diff --git a/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.js.mdx b/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.js.mdx index e9523fa3b322..cad4f70539a7 100644 --- a/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.js.mdx +++ b/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.js.mdx @@ -59,8 +59,8 @@ describe('Stories Snapshots', () => { // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. await new Promise((resolve) => setTimeout(resolve, 1)); // Defines the custom snapshot path location and file name - const customSnaphotPath = `./__snapshots__/${componentName}.test.js.snap`; - expect(mounted.container).toMatchSpecificSnapshot(customSnaphotPath); + const customSnapshotPath = `./__snapshots__/${componentName}.test.js.snap`; + expect(mounted.container).toMatchSpecificSnapshot(customSnapshotPath); }); }); }); diff --git a/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.ts.mdx b/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.ts.mdx index e245ec4c1ee9..b0542c789af8 100644 --- a/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.ts.mdx +++ b/docs/snippets/common/individual-snapshot-tests-portable-stories.jest.ts.mdx @@ -73,8 +73,8 @@ describe("Stories Snapshots", () => { // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. await new Promise((resolve) => setTimeout(resolve, 1)); // Defines the custom snapshot path location and file name - const customSnaphotPath = `./__snapshots__/${componentName}.test.ts.snap`; - expect(mounted.container).toMatchSpecificSnapshot(customSnaphotPath); + const customSnapshotPath = `./__snapshots__/${componentName}.test.ts.snap`; + expect(mounted.container).toMatchSpecificSnapshot(customSnapshotPath); }); }); }); diff --git a/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.js.mdx b/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.js.mdx index 111149d958bb..35ad9d6b3341 100644 --- a/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.js.mdx +++ b/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.js.mdx @@ -54,8 +54,8 @@ describe('Stories Snapshots', () => { // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. await new Promise((resolve) => setTimeout(resolve, 1)); // Defines the custom snapshot path location and file name - const customSnaphotPath = `./__snapshots__/${componentName}.spec.js.snap`; - expect(mounted.container).toMatchFileSnapshot(customSnaphotPath); + const customSnapshotPath = `./__snapshots__/${componentName}.spec.js.snap`; + expect(mounted.container).toMatchFileSnapshot(customSnapshotPath); }); }); }); diff --git a/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.ts.mdx b/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.ts.mdx index 5c3f6097dae8..b761a1ba1aa8 100644 --- a/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.ts.mdx +++ b/docs/snippets/common/individual-snapshot-tests-portable-stories.vitest.ts.mdx @@ -64,8 +64,8 @@ describe('Stories Snapshots', () => { // Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot. await new Promise((resolve) => setTimeout(resolve, 1)); // Defines the custom snapshot path location and file name - const customSnaphotPath = `./__snapshots__/${componentName}.spec.ts.snap`; - expect(mounted.container).toMatchFileSnapshot(customSnaphotPath); + const customSnapshotPath = `./__snapshots__/${componentName}.spec.ts.snap`; + expect(mounted.container).toMatchFileSnapshot(customSnapshotPath); }); }); }); diff --git a/docs/writing-tests/storyshots-migration-guide.md b/docs/writing-tests/storyshots-migration-guide.md index 42f0545dc57b..ff4b06eb273e 100644 --- a/docs/writing-tests/storyshots-migration-guide.md +++ b/docs/writing-tests/storyshots-migration-guide.md @@ -26,7 +26,7 @@ This guide will teach you how to migrate your snapshot tests from the Storyshots Before you begin the migration process, ensure that you have: -- A fully functional Storybook configured with one of the [suppported frameworks](../configure/frameworks.md) running the latest stable version (i.e., 7.6 or higher). +- A fully functional Storybook configured with one of the [supported frameworks](../configure/frameworks.md) running the latest stable version (i.e., 7.6 or higher). - Familiarity with your current Storybook and its testing setup. ### With the test-runner diff --git a/scripts/build-package.ts b/scripts/build-package.ts index 7ee1002f65cc..d0aacac1b38a 100644 --- a/scripts/build-package.ts +++ b/scripts/build-package.ts @@ -115,13 +115,13 @@ async function run() { } selection?.filter(Boolean).forEach(async (v) => { - const commmand = (await readJSON(resolve('../code', v.location, 'package.json'))).scripts.prep + const command = (await readJSON(resolve('../code', v.location, 'package.json'))).scripts.prep .split(posix.sep) .join(sep); const cwd = resolve(__dirname, '..', 'code', v.location); const sub = execaCommand( - `${commmand}${watchMode ? ' --watch' : ''}${prodMode ? ' --optimized' : ''}`, + `${command}${watchMode ? ' --watch' : ''}${prodMode ? ' --optimized' : ''}`, { cwd, buffer: false, diff --git a/scripts/check-package.ts b/scripts/check-package.ts index 6248ad54797a..21ad297fb901 100644 --- a/scripts/check-package.ts +++ b/scripts/check-package.ts @@ -98,9 +98,9 @@ async function run() { } selection?.filter(Boolean).forEach(async (v) => { - const commmand = (await readJSON(resolve('../code', v.location, 'package.json'))).scripts.check; + const command = (await readJSON(resolve('../code', v.location, 'package.json'))).scripts.check; const cwd = resolve(__dirname, '..', 'code', v.location); - const sub = execaCommand(`${commmand}${watchMode ? ' --watch' : ''}`, { + const sub = execaCommand(`${command}${watchMode ? ' --watch' : ''}`, { cwd, buffer: false, shell: true, diff --git a/scripts/release/version.ts b/scripts/release/version.ts index 53365fd2d499..687911fafbda 100644 --- a/scripts/release/version.ts +++ b/scripts/release/version.ts @@ -18,7 +18,7 @@ program '-R, --release-type ', 'Which release type to use to bump the version' ) - .option('-P, --pre-id ', 'Which prerelease identifer to change to, eg. "alpha", "beta", "rc"') + .option('-P, --pre-id ', 'Which prerelease identifier to change to, eg. "alpha", "beta", "rc"') .option( '-E, --exact ', 'Use exact version instead of calculating from current version, eg. "7.2.0-canary.123". Can not be combined with --release-type or --pre-id' diff --git a/scripts/sandbox/utils/git.ts b/scripts/sandbox/utils/git.ts index 71de33aa38fe..807daebf2bf7 100644 --- a/scripts/sandbox/utils/git.ts +++ b/scripts/sandbox/utils/git.ts @@ -43,7 +43,7 @@ const getTheLastCommitHashThatUpdatedTheSandboxRepo = async (branch: string) => }; /** - * When commiting the changes to the sandboxes repo, we want to include the PRs that were merged since the last commit that updated the sandboxes. + * When committing the changes to the sandboxes repo, we want to include the PRs that were merged since the last commit that updated the sandboxes. * This might help us debug issues or changes that affected the sandboxes at some point in time. */ export async function commitAllToGit({ cwd, branch }: { cwd: string; branch: string }) { From d7c8b4da548333e0f1e72953466195dc7ca33b47 Mon Sep 17 00:00:00 2001 From: Jeroen Zwartepoorte Date: Sat, 16 Mar 2024 17:48:58 +0100 Subject: [PATCH 09/69] Fix missing in viewport addon --- code/addons/viewport/src/Tool.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/code/addons/viewport/src/Tool.tsx b/code/addons/viewport/src/Tool.tsx index 37bc22500e9b..da600e576675 100644 --- a/code/addons/viewport/src/Tool.tsx +++ b/code/addons/viewport/src/Tool.tsx @@ -74,6 +74,7 @@ const flip = ({ width, height, ...styles }: ViewportStyles) => ({ const ActiveViewportSize = styled.div(() => ({ display: 'inline-flex', + alignItems: 'center', })); const ActiveViewportLabel = styled.div(({ theme }) => ({ From 3a91e2461fe66aa0c9cf817774544d4da4eff75e Mon Sep 17 00:00:00 2001 From: AriPerkkio Date: Sun, 17 Mar 2024 16:03:50 +0200 Subject: [PATCH 10/69] Docs: Fix migration guide scripts --- docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx | 2 +- docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx | 2 +- docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx b/docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx index fdb2e942e377..1058c451d943 100644 --- a/docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx +++ b/docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx @@ -1,4 +1,4 @@ ```shell # Convert stories in MDX to CSF -npx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx” +npx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx" ``` diff --git a/docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx b/docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx index 48f8f5fb5ec7..21b956b0fd2a 100644 --- a/docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx +++ b/docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx @@ -1,4 +1,4 @@ ```sh # Convert stories in MDX to CSF -pnpm dlx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx” +pnpm dlx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx" ``` diff --git a/docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx b/docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx index ce45b320d7de..93dca5ba3158 100644 --- a/docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx +++ b/docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx @@ -1,4 +1,4 @@ ```sh # Convert stories in MDX to CSF -yarn dlx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx” +yarn dlx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx" ``` From 7290a2c2d87e92a8be116a4f96ad0eca3c4f41fc Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 18 Mar 2024 16:09:29 +0100 Subject: [PATCH 11/69] add explicit react-dom/server alias for vite --- code/addons/docs/src/preset.ts | 2 ++ .../template/stories/docs2/ResolvedReact.mdx | 3 +++ .../stories/docs2/ResolvedReactVersion.jsx | 5 ++++ code/e2e-tests/addon-docs.spec.ts | 24 ++++++++++++------- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/code/addons/docs/src/preset.ts b/code/addons/docs/src/preset.ts index 68c7efb39f8b..8f59e5e64138 100644 --- a/code/addons/docs/src/preset.ts +++ b/code/addons/docs/src/preset.ts @@ -147,6 +147,8 @@ export const viteFinal = async (config: any, options: Options) => { resolve: { alias: { react, + // Vite doesn't respect export maps when resolving a path, so we need to do that manually here + 'react-dom/server': `${reactDom}/server.browser.js`, 'react-dom': reactDom, '@mdx-js/react': mdx, /** diff --git a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx index 7a5f04ab6bc8..b0a889de7d08 100644 --- a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx +++ b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx @@ -1,5 +1,6 @@ import { version as reactVersion } from 'react'; import { version as reactDomVersion } from 'react-dom'; +import { version as reactDomServerVersion } from 'react-dom/server'; import { ResolvedReactVersion } from './ResolvedReactVersion'; ## In MDX @@ -8,6 +9,8 @@ import { ResolvedReactVersion } from './ResolvedReactVersion'; react-dom: {reactDomVersion} +react-dom/server: {reactDomServerVersion} + ## In `ResolvedReactVersion` component diff --git a/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx b/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx index 6e094c1e64d0..bf83c94ea386 100644 --- a/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx +++ b/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx @@ -1,5 +1,6 @@ import React, { version as reactVersion } from 'react'; import { version as reactDomVersion } from 'react-dom'; +import { version as reactDomServerVersion } from 'react-dom/server'; export const ResolvedReactVersion = () => { return ( @@ -10,6 +11,10 @@ export const ResolvedReactVersion = () => {

react-dom: {reactDomVersion}

+

+ react-dom/server:{' '} + {reactDomServerVersion} +

); }; diff --git a/code/e2e-tests/addon-docs.spec.ts b/code/e2e-tests/addon-docs.spec.ts index 72470acb62ab..30056ea0055c 100644 --- a/code/e2e-tests/addon-docs.spec.ts +++ b/code/e2e-tests/addon-docs.spec.ts @@ -189,26 +189,34 @@ test.describe('addon-docs', () => { await sbPage.navigateToUnattachedDocs('addons/docs/docs2', 'ResolvedReact'); const root = sbPage.previewRoot(); - let expectedReactVersion = /^18/; + let expectedReactVersionRange = /^18/; if ( templateName.includes('preact') || templateName.includes('react-webpack/17') || templateName.includes('react-vite/17') ) { - expectedReactVersion = /^17/; + expectedReactVersionRange = /^17/; } else if (templateName.includes('react16')) { - expectedReactVersion = /^16/; + expectedReactVersionRange = /^16/; } const mdxReactVersion = await root.getByTestId('mdx-react'); const mdxReactDomVersion = await root.getByTestId('mdx-react-dom'); + const mdxReactDomServerVersion = await root.getByTestId('mdx-react-dom-server'); const componentReactVersion = await root.getByTestId('component-react'); const componentReactDomVersion = await root.getByTestId('component-react-dom'); - - await expect(mdxReactVersion).toHaveText(expectedReactVersion); - await expect(mdxReactDomVersion).toHaveText(expectedReactVersion); - await expect(componentReactVersion).toHaveText(expectedReactVersion); - await expect(componentReactDomVersion).toHaveText(expectedReactVersion); + const componentReactDomServerVersion = await root.getByTestId('component-react-dom-server'); + + // Assert that the versions are in the expected range + await expect(mdxReactVersion).toHaveText(expectedReactVersionRange); + + const actualReactVersion = (await mdxReactVersion.textContent())!; + // ... then assert that the versions are all the same + await expect(mdxReactDomVersion).toHaveText(actualReactVersion); + await expect(mdxReactDomServerVersion).toHaveText(actualReactVersion); + await expect(componentReactVersion).toHaveText(actualReactVersion); + await expect(componentReactDomVersion).toHaveText(actualReactVersion); + await expect(componentReactDomServerVersion).toHaveText(actualReactVersion); }); test('should have stories from multiple CSF files in autodocs', async ({ page }) => { From 8699394358d9a9bf32d0b6ccc11c1bdd2ad41fd4 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 20 Mar 2024 13:38:50 +0100 Subject: [PATCH 12/69] add stories and autodocs for resolved react in addon-docs templates --- ...lvedReactVersion.jsx => ResolvedReact.jsx} | 2 +- .../template/stories/docs2/ResolvedReact.mdx | 19 +++++- .../stories/docs2/resolved-react.stories.ts | 58 +++++++++++++++++++ code/e2e-tests/addon-docs.spec.ts | 32 +++++++++- code/e2e-tests/util.ts | 9 ++- 5 files changed, 108 insertions(+), 12 deletions(-) rename code/addons/docs/template/stories/docs2/{ResolvedReactVersion.jsx => ResolvedReact.jsx} (93%) create mode 100644 code/addons/docs/template/stories/docs2/resolved-react.stories.ts diff --git a/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx b/code/addons/docs/template/stories/docs2/ResolvedReact.jsx similarity index 93% rename from code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx rename to code/addons/docs/template/stories/docs2/ResolvedReact.jsx index bf83c94ea386..8a565da1d38c 100644 --- a/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx +++ b/code/addons/docs/template/stories/docs2/ResolvedReact.jsx @@ -2,7 +2,7 @@ import React, { version as reactVersion } from 'react'; import { version as reactDomVersion } from 'react-dom'; import { version as reactDomServerVersion } from 'react-dom/server'; -export const ResolvedReactVersion = () => { +export const ResolvedReact = () => { return ( <>

diff --git a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx index b0a889de7d08..fcbb82da0c68 100644 --- a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx +++ b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx @@ -1,7 +1,20 @@ +import { Meta } from '@storybook/blocks'; import { version as reactVersion } from 'react'; import { version as reactDomVersion } from 'react-dom'; import { version as reactDomServerVersion } from 'react-dom/server'; -import { ResolvedReactVersion } from './ResolvedReactVersion'; +import * as ResolvedReactStories from './resolved-react.stories'; +import { ResolvedReact } from './ResolvedReact'; + + + +This doc is used to display the resolved version of React and its related packages. +As long as `@storybook/addon-docs` is installed, `react` and `react-dom` should be available to import from and should resolve to the same version. + +The MDX here ensures that it works in an MDX file. + +- See the [autodocs](/docs/addons-docs-docs2-resolvedreact--docs) for how it resolves in MDX. +- See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story. + ## In MDX @@ -11,6 +24,6 @@ import { ResolvedReactVersion } from './ResolvedReactVersion'; react-dom/server: {reactDomServerVersion} -## In `ResolvedReactVersion` component +## In `ResolvedReact` component - + diff --git a/code/addons/docs/template/stories/docs2/resolved-react.stories.ts b/code/addons/docs/template/stories/docs2/resolved-react.stories.ts new file mode 100644 index 000000000000..ec7f54a5e884 --- /dev/null +++ b/code/addons/docs/template/stories/docs2/resolved-react.stories.ts @@ -0,0 +1,58 @@ +import { within, expect } from '@storybook/test'; +import { version as reactVersion } from 'react'; +import { version as reactDomVersion } from 'react-dom'; +import { version as reactDomServerVersion } from 'react-dom/server'; + +/** + * This component is used to display the resolved version of React and its related packages. + * As long as `@storybook/addon-docs` is installed, `react` and `react-dom` should be available to import from and should resolve to the same version. + * + * The autodocs here ensures that it also works in the generated documentation. + * + * - See the [MDX docs](/docs/addons-docs-docs2-resolvedreact--mdx) for how it resolves in MDX. + * - See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story. + */ +export default { + title: 'Docs2/ResolvedReact', + component: globalThis.Components.Html, + tags: ['autodocs'], + argTypes: { + content: { table: { disable: true } }, + }, + args: { + content: ` +

+ react: ${reactVersion} +

+

+ react-dom: ${reactDomVersion} +

+

+ react-dom/server: ${reactDomServerVersion} +

+ `, + }, + parameters: { + docs: { + name: 'ResolvedReact', + }, + }, +}; + +export const Story = { + // This test is more or less the same as the E2E test we have for MDX and autodocs entries in addon-docs.spec.ts + play: async ({ canvasElement, step }: any) => { + const canvas = await within(canvasElement); + + const actualReactVersion = (await canvas.findByTestId('react')).textContent; + const actualReactDomVersion = (await canvas.findByTestId('react-dom')).textContent; + const actualReactDomServerVersion = await ( + await canvas.findByTestId('react-dom-server') + ).textContent; + + step('Expect React packages to all resolve to the same version', () => { + expect(actualReactVersion).toBe(actualReactDomVersion); + expect(actualReactVersion).toBe(actualReactDomServerVersion); + }); + }, +}; diff --git a/code/e2e-tests/addon-docs.spec.ts b/code/e2e-tests/addon-docs.spec.ts index 30056ea0055c..c89cc011215e 100644 --- a/code/e2e-tests/addon-docs.spec.ts +++ b/code/e2e-tests/addon-docs.spec.ts @@ -185,8 +185,9 @@ test.describe('addon-docs', () => { }); test('should resolve react to the correct version', async ({ page }) => { + // Arrange - Navigate to MDX docs and setup expectations const sbPage = new SbPage(page); - await sbPage.navigateToUnattachedDocs('addons/docs/docs2', 'ResolvedReact'); + await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'mdx', 'docs'); const root = sbPage.previewRoot(); let expectedReactVersionRange = /^18/; @@ -200,6 +201,7 @@ test.describe('addon-docs', () => { expectedReactVersionRange = /^16/; } + // Arrange - Get the actual versions const mdxReactVersion = await root.getByTestId('mdx-react'); const mdxReactDomVersion = await root.getByTestId('mdx-react-dom'); const mdxReactDomServerVersion = await root.getByTestId('mdx-react-dom-server'); @@ -207,16 +209,40 @@ test.describe('addon-docs', () => { const componentReactDomVersion = await root.getByTestId('component-react-dom'); const componentReactDomServerVersion = await root.getByTestId('component-react-dom-server'); - // Assert that the versions are in the expected range + // Assert - Tthe versions are in the expected range await expect(mdxReactVersion).toHaveText(expectedReactVersionRange); const actualReactVersion = (await mdxReactVersion.textContent())!; - // ... then assert that the versions are all the same + // Assert - The versions are all the same await expect(mdxReactDomVersion).toHaveText(actualReactVersion); await expect(mdxReactDomServerVersion).toHaveText(actualReactVersion); await expect(componentReactVersion).toHaveText(actualReactVersion); await expect(componentReactDomVersion).toHaveText(actualReactVersion); await expect(componentReactDomServerVersion).toHaveText(actualReactVersion); + + // Arrange - Navigate to autodocs + await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'docs'); + + // Arrange - Get the actual versions + const autodocsReactVersion = await root.getByTestId('react'); + const autodocsReactDomVersion = await root.getByTestId('react-dom'); + const autodocsReactDomServerVersion = await root.getByTestId('react-dom-server'); + + await expect(autodocsReactVersion).toHaveText(actualReactVersion); + await expect(autodocsReactDomVersion).toHaveText(actualReactVersion); + await expect(autodocsReactDomServerVersion).toHaveText(actualReactVersion); + + // Arrange - Navigate to story + await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'story'); + + // Arrange - Get the actual versions + const storyReactVersion = await root.getByTestId('react'); + const storyReactDomVersion = await root.getByTestId('react-dom'); + const storyReactDomServerVersion = await root.getByTestId('react-dom-server'); + + await expect(storyReactVersion).toHaveText(actualReactVersion); + await expect(storyReactDomVersion).toHaveText(actualReactVersion); + await expect(storyReactDomServerVersion).toHaveText(actualReactVersion); }); test('should have stories from multiple CSF files in autodocs', async ({ page }) => { diff --git a/code/e2e-tests/util.ts b/code/e2e-tests/util.ts index df5ca4ff59a8..f97894075f5b 100644 --- a/code/e2e-tests/util.ts +++ b/code/e2e-tests/util.ts @@ -40,7 +40,7 @@ export class SbPage { /** * Visit a story by selecting it from the sidebar. */ - async navigateToStory(title: string, name: string) { + async navigateToStory(title: string, name: string, viewMode?: 'docs' | 'story') { await this.openComponent(title); const titleId = toId(title); @@ -50,11 +50,10 @@ export class SbPage { const storyLink = this.page.locator('*', { has: this.page.locator(`> ${storyLinkId}`) }); await storyLink.click({ force: true }); - // assert url changes - const viewMode = name === 'docs' ? 'docs' : 'story'; - await this.page.waitForURL((url) => - url.search.includes(`path=/${viewMode}/${titleId}--${storyId}`) + url.search.includes( + `path=/${viewMode ?? name === 'docs' ? 'docs' : 'story'}/${titleId}--${storyId}` + ) ); const selected = await storyLink.getAttribute('data-selected'); From c75c98f0fa6560ed72766adfe5e45be08f407ba0 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 21 Mar 2024 08:47:02 +0100 Subject: [PATCH 13/69] account for version mismatch in react-dom --- .../docs/template/stories/docs2/ResolvedReact.mdx | 1 + .../template/stories/docs2/resolved-react.stories.ts | 5 ++++- code/e2e-tests/addon-docs.spec.ts | 11 ++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx index fcbb82da0c68..e044838df97d 100644 --- a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx +++ b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx @@ -15,6 +15,7 @@ The MDX here ensures that it works in an MDX file. - See the [autodocs](/docs/addons-docs-docs2-resolvedreact--docs) for how it resolves in MDX. - See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story. +**Note: There appears to be a bug in the _production_ build of `react-dom`, where it reports version `18.2.0-next-9e3b772b8-20220608` while in fact version `18.2.0` is installed.** ## In MDX diff --git a/code/addons/docs/template/stories/docs2/resolved-react.stories.ts b/code/addons/docs/template/stories/docs2/resolved-react.stories.ts index ec7f54a5e884..466e966a0ce6 100644 --- a/code/addons/docs/template/stories/docs2/resolved-react.stories.ts +++ b/code/addons/docs/template/stories/docs2/resolved-react.stories.ts @@ -11,6 +11,8 @@ import { version as reactDomServerVersion } from 'react-dom/server'; * * - See the [MDX docs](/docs/addons-docs-docs2-resolvedreact--mdx) for how it resolves in MDX. * - See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story. + * + * **Note: There appears to be a bug in the _production_ build of `react-dom`, where it reports version `18.2.0-next-9e3b772b8-20220608` while in fact version `18.2.0` is installed.** */ export default { title: 'Docs2/ResolvedReact', @@ -51,7 +53,8 @@ export const Story = { ).textContent; step('Expect React packages to all resolve to the same version', () => { - expect(actualReactVersion).toBe(actualReactDomVersion); + // react-dom has a bug in its production build, reporting version 18.2.0-next-9e3b772b8-20220608 even though version 18.2.0 is installed. + expect(actualReactDomVersion.startsWith(actualReactDomVersion)).toBeTruthy(); expect(actualReactVersion).toBe(actualReactDomServerVersion); }); }, diff --git a/code/e2e-tests/addon-docs.spec.ts b/code/e2e-tests/addon-docs.spec.ts index c89cc011215e..ecb0cdf52686 100644 --- a/code/e2e-tests/addon-docs.spec.ts +++ b/code/e2e-tests/addon-docs.spec.ts @@ -209,15 +209,16 @@ test.describe('addon-docs', () => { const componentReactDomVersion = await root.getByTestId('component-react-dom'); const componentReactDomServerVersion = await root.getByTestId('component-react-dom-server'); - // Assert - Tthe versions are in the expected range + // Assert - The versions are in the expected range await expect(mdxReactVersion).toHaveText(expectedReactVersionRange); const actualReactVersion = (await mdxReactVersion.textContent())!; // Assert - The versions are all the same - await expect(mdxReactDomVersion).toHaveText(actualReactVersion); + // react-dom has a bug in its production build, reporting version 18.2.0-next-9e3b772b8-20220608 even though version 18.2.0 is installed. + await expect(mdxReactDomVersion).toHaveText(new RegExp(`^${actualReactVersion}`)); await expect(mdxReactDomServerVersion).toHaveText(actualReactVersion); await expect(componentReactVersion).toHaveText(actualReactVersion); - await expect(componentReactDomVersion).toHaveText(actualReactVersion); + await expect(componentReactDomVersion).toHaveText(new RegExp(`^${actualReactVersion}`)); await expect(componentReactDomServerVersion).toHaveText(actualReactVersion); // Arrange - Navigate to autodocs @@ -229,7 +230,7 @@ test.describe('addon-docs', () => { const autodocsReactDomServerVersion = await root.getByTestId('react-dom-server'); await expect(autodocsReactVersion).toHaveText(actualReactVersion); - await expect(autodocsReactDomVersion).toHaveText(actualReactVersion); + await expect(autodocsReactDomVersion).toHaveText(new RegExp(`^${actualReactVersion}`)); await expect(autodocsReactDomServerVersion).toHaveText(actualReactVersion); // Arrange - Navigate to story @@ -241,7 +242,7 @@ test.describe('addon-docs', () => { const storyReactDomServerVersion = await root.getByTestId('react-dom-server'); await expect(storyReactVersion).toHaveText(actualReactVersion); - await expect(storyReactDomVersion).toHaveText(actualReactVersion); + await expect(storyReactDomVersion).toHaveText(new RegExp(`^${actualReactVersion}`)); await expect(storyReactDomServerVersion).toHaveText(actualReactVersion); }); From 02b800d1c9534de7e66fdd150bbd91e98009b127 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 21 Mar 2024 08:50:25 +0100 Subject: [PATCH 14/69] typo --- code/addons/docs/template/stories/docs2/ResolvedReact.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx index e044838df97d..1462d732ab56 100644 --- a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx +++ b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx @@ -12,7 +12,7 @@ As long as `@storybook/addon-docs` is installed, `react` and `react-dom` should The MDX here ensures that it works in an MDX file. -- See the [autodocs](/docs/addons-docs-docs2-resolvedreact--docs) for how it resolves in MDX. +- See the [autodocs](/docs/addons-docs-docs2-resolvedreact--docs) for how it resolves in autodocs. - See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story. **Note: There appears to be a bug in the _production_ build of `react-dom`, where it reports version `18.2.0-next-9e3b772b8-20220608` while in fact version `18.2.0` is installed.** From 694540aa443f96862deb064bcd933df6619e99dc Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 21 Mar 2024 14:05:25 +0100 Subject: [PATCH 15/69] fix preact aliases --- code/addons/docs/src/preset.ts | 6 +++--- code/lib/react-dom-shim/src/preset.ts | 8 +++++++- code/renderers/preact/src/preset.ts | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/code/addons/docs/src/preset.ts b/code/addons/docs/src/preset.ts index 8f59e5e64138..31248e7af990 100644 --- a/code/addons/docs/src/preset.ts +++ b/code/addons/docs/src/preset.ts @@ -1,4 +1,4 @@ -import { dirname, join } from 'path'; +import { dirname, join, isAbsolute } from 'path'; import rehypeSlug from 'rehype-slug'; import rehypeExternalLinks from 'rehype-external-links'; @@ -147,8 +147,8 @@ export const viteFinal = async (config: any, options: Options) => { resolve: { alias: { react, - // Vite doesn't respect export maps when resolving a path, so we need to do that manually here - 'react-dom/server': `${reactDom}/server.browser.js`, + // Vite doesn't respect export maps when resolving an absolute path, so we need to do that manually here + ...(isAbsolute(reactDom) && { 'react-dom/server': `${reactDom}/server.browser.js` }), 'react-dom': reactDom, '@mdx-js/react': mdx, /** diff --git a/code/lib/react-dom-shim/src/preset.ts b/code/lib/react-dom-shim/src/preset.ts index 63b2889ba93b..e863a53262b6 100644 --- a/code/lib/react-dom-shim/src/preset.ts +++ b/code/lib/react-dom-shim/src/preset.ts @@ -1,5 +1,5 @@ import type { Options } from '@storybook/types'; -import { join, dirname } from 'path'; +import { join, dirname, isAbsolute } from 'path'; import { readFile } from 'fs/promises'; /** @@ -17,6 +17,12 @@ const getIsReactVersion18 = async (options: Options) => { const resolvedReact = await options.presets.apply<{ reactDom?: string }>('resolvedReact', {}); const reactDom = resolvedReact.reactDom || dirname(require.resolve('react-dom/package.json')); + if (!isAbsolute(reactDom)) { + // if react-dom is not resolved to a file we can't be sure if the version in package.json is correct or even if package.json exists + // this happens when react-dom is resolved to 'preact/compat' for example + return false; + } + const { version } = JSON.parse(await readFile(join(reactDom, 'package.json'), 'utf-8')); return version.startsWith('18') || version.startsWith('0.0.0'); }; diff --git a/code/renderers/preact/src/preset.ts b/code/renderers/preact/src/preset.ts index 03b11e7e6097..28e5a428af0a 100644 --- a/code/renderers/preact/src/preset.ts +++ b/code/renderers/preact/src/preset.ts @@ -13,3 +13,19 @@ export const previewAnnotations: PresetProperty<'previewAnnotations'> = async ( .concat([join(__dirname, 'entry-preview.mjs')]) .concat(docsEnabled ? [join(__dirname, 'entry-preview-docs.mjs')] : []); }; + +/** + * Alias react and react-dom to preact/compat similar to the preact vite preset + * https://github.com/preactjs/preset-vite/blob/main/src/index.ts#L238-L239 + */ +export const resolvedReact = async (existing: any) => { + try { + return { + ...existing, + react: 'preact/compat', + reactDom: 'preact/compat', + }; + } catch (e) { + return existing; + } +}; From 016f70130f7198d8e0a32e92797efe557547475c Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 21 Mar 2024 14:59:20 +0100 Subject: [PATCH 16/69] change preact stories extension to jsx --- code/renderers/preact/template/stories/{React.js => React.jsx} | 0 .../{react-compat.stories.js => react-compat.stories.jsx} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename code/renderers/preact/template/stories/{React.js => React.jsx} (100%) rename code/renderers/preact/template/stories/{react-compat.stories.js => react-compat.stories.jsx} (96%) diff --git a/code/renderers/preact/template/stories/React.js b/code/renderers/preact/template/stories/React.jsx similarity index 100% rename from code/renderers/preact/template/stories/React.js rename to code/renderers/preact/template/stories/React.jsx diff --git a/code/renderers/preact/template/stories/react-compat.stories.js b/code/renderers/preact/template/stories/react-compat.stories.jsx similarity index 96% rename from code/renderers/preact/template/stories/react-compat.stories.js rename to code/renderers/preact/template/stories/react-compat.stories.jsx index 33f1078d3154..b43a0650e748 100644 --- a/code/renderers/preact/template/stories/react-compat.stories.js +++ b/code/renderers/preact/template/stories/react-compat.stories.jsx @@ -1,4 +1,4 @@ -import { ReactFunctionalComponent, ReactClassComponent } from './React'; +import { ReactFunctionalComponent, ReactClassComponent } from './React.jsx'; export default { component: ReactFunctionalComponent, From e5a21d45ea401b7bbdfabbb47c2a5f694a69f384 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 21 Mar 2024 15:07:00 +0100 Subject: [PATCH 17/69] add preact-render-to-string to preact sandboxes --- code/lib/cli/src/sandbox-templates.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts index b28021be7049..99a867192932 100644 --- a/code/lib/cli/src/sandbox-templates.ts +++ b/code/lib/cli/src/sandbox-templates.ts @@ -423,7 +423,8 @@ const baseTemplates = { }, 'preact-vite/default-js': { name: 'Preact Latest (Vite | JavaScript)', - script: 'npm create vite --yes {{beforeDir}} -- --template preact', + script: + 'npm create vite --yes preact-server-test -- --template preact && cd preact-server-test && yarn add preact-render-to-string', expected: { framework: '@storybook/preact-vite', renderer: '@storybook/preact', @@ -433,7 +434,8 @@ const baseTemplates = { }, 'preact-vite/default-ts': { name: 'Preact Latest (Vite | TypeScript)', - script: 'npm create vite --yes {{beforeDir}} -- --template preact-ts', + script: + 'npm create vite --yes {{beforeDir}} -- --template preact-ts && yarn add preact-render-to-string', expected: { framework: '@storybook/preact-vite', renderer: '@storybook/preact', From 099671497d478dc56bb2458c8089bb56a141f94f Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 21 Mar 2024 15:07:42 +0100 Subject: [PATCH 18/69] temporarily reenable test-runner dev --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1cd268cbbe1b..c240ec99bd94 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -676,9 +676,9 @@ workflows: parameters: directory: ["react", "vue3", "nextjs", "svelte"] # TODO: reenable once we find out the source of flakyness - # - test-runner-dev: - # requires: - # - create-sandboxes + - test-runner-dev: + requires: + - create-sandboxes merged: when: equal: [merged, << pipeline.parameters.workflow >>] From ef42e9cd6adbb2029ad755b49370df2eb68095c7 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 21 Mar 2024 15:18:17 +0100 Subject: [PATCH 19/69] add parallelism --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index c240ec99bd94..ada82b37b1c6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -679,6 +679,7 @@ workflows: - test-runner-dev: requires: - create-sandboxes + parallelism: 8 merged: when: equal: [merged, << pipeline.parameters.workflow >>] From 439cc6a2c41a4bb43186efc4a4d37588b37ae181 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 21 Mar 2024 15:42:39 +0100 Subject: [PATCH 20/69] disable test-runner-dev again --- .circleci/config.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ada82b37b1c6..1cd268cbbe1b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -676,10 +676,9 @@ workflows: parameters: directory: ["react", "vue3", "nextjs", "svelte"] # TODO: reenable once we find out the source of flakyness - - test-runner-dev: - requires: - - create-sandboxes - parallelism: 8 + # - test-runner-dev: + # requires: + # - create-sandboxes merged: when: equal: [merged, << pipeline.parameters.workflow >>] From d3ad0591ab35ac41a43492d7ed331d1b7944ffa1 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 20 Mar 2024 09:34:00 +0100 Subject: [PATCH 21/69] Add table.readonly to argType typing --- code/ui/blocks/src/components/ArgsTable/types.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/ui/blocks/src/components/ArgsTable/types.ts b/code/ui/blocks/src/components/ArgsTable/types.ts index a8f3dd1d453e..ec8fdb6a2eb1 100644 --- a/code/ui/blocks/src/components/ArgsTable/types.ts +++ b/code/ui/blocks/src/components/ArgsTable/types.ts @@ -41,6 +41,10 @@ export interface ArgType { description?: string; defaultValue?: any; if?: Conditional; + table?: { + readonly?: boolean; + [key: string]: any; + }; [key: string]: any; } From 2f66985e2e16cd588a5e4a27b3ab1635eb1acaf9 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 20 Mar 2024 09:34:19 +0100 Subject: [PATCH 22/69] Support readonly mode for Boolean input --- .../blocks/src/controls/Boolean.stories.tsx | 35 +++++++++++++++---- code/ui/blocks/src/controls/Boolean.tsx | 21 +++++++++-- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/code/ui/blocks/src/controls/Boolean.stories.tsx b/code/ui/blocks/src/controls/Boolean.stories.tsx index 8f7c043701c6..4629f2cc3644 100644 --- a/code/ui/blocks/src/controls/Boolean.stories.tsx +++ b/code/ui/blocks/src/controls/Boolean.stories.tsx @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { within, fireEvent, waitFor, expect } from '@storybook/test'; +import { within, fireEvent, waitFor, expect, fn } from '@storybook/test'; import { addons } from '@storybook/preview-api'; import { RESET_STORY_ARGS, STORY_ARGS_UPDATED } from '@storybook/core-events'; import { BooleanControl } from './Boolean'; @@ -14,31 +14,36 @@ const meta = { info: 'This is info for the Boolean control stories', jsx: { useBooleanShorthandSyntax: false }, }, -} as Meta; + args: { + onChange: fn(), + }, +} satisfies Meta; export default meta; -export const True: StoryObj = { +type Story = StoryObj; + +export const True: Story = { args: { value: true, name: 'True', }, }; -export const False: StoryObj = { +export const False: Story = { args: { value: false, name: 'False', }, }; -export const Undefined: StoryObj = { +export const Undefined: Story = { args: { value: undefined, name: 'Undefined', }, }; -export const Toggling: StoryObj = { +export const Toggling: Story = { args: { value: undefined, name: 'Toggling', @@ -78,7 +83,7 @@ export const Toggling: StoryObj = { }, }; -export const TogglingInDocs: StoryObj = { +export const TogglingInDocs: Story = { ...Toggling, args: { name: 'Toggling In Docs', @@ -89,3 +94,19 @@ export const TogglingInDocs: StoryObj = { }, }, }; + +export const Readonly: Story = { + args: { + name: 'readonly', + value: true, + argType: { table: { readonly: true } }, + }, +}; + +export const ReadonlyAndUndefined: Story = { + args: { + name: 'readonly-and-undefined', + value: undefined, + argType: { table: { readonly: true } }, + }, +}; diff --git a/code/ui/blocks/src/controls/Boolean.tsx b/code/ui/blocks/src/controls/Boolean.tsx index 7045d214b3c3..d8a9ee13456b 100644 --- a/code/ui/blocks/src/controls/Boolean.tsx +++ b/code/ui/blocks/src/controls/Boolean.tsx @@ -19,6 +19,13 @@ const Label = styled.label(({ theme }) => ({ background: theme.boolean.background, borderRadius: '3em', padding: 1, + '&[aria-disabled="true"]': { + opacity: 0.5, + + input: { + cursor: 'not-allowed', + }, + }, input: { appearance: 'none', @@ -98,8 +105,16 @@ export type BooleanProps = ControlProps & BooleanConfig; * * ``` */ -export const BooleanControl: FC = ({ name, value, onChange, onBlur, onFocus }) => { +export const BooleanControl: FC = ({ + name, + value, + onChange, + onBlur, + onFocus, + argType, +}) => { const onSetFalse = useCallback(() => onChange(false), [onChange]); + const readonly = argType?.table?.readonly; if (value === undefined) { return ( @@ -117,13 +133,14 @@ export const BooleanControl: FC = ({ name, value, onChange, onBlur const parsedValue = typeof value === 'string' ? parse(value) : value; return ( -