From 90008304018963980f1bd0b3a93d5b5d82186048 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Wed, 3 Sep 2025 11:28:44 +0100 Subject: [PATCH 01/18] Add parameter typings for addon-pseudo-state --- code/addons/pseudo-states/src/constants.ts | 2 -- code/addons/pseudo-states/src/index.ts | 5 +++- .../src/preview/withPseudoState.ts | 10 +------- code/addons/pseudo-states/src/types.ts | 24 +++++++++++++++++++ 4 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 code/addons/pseudo-states/src/types.ts diff --git a/code/addons/pseudo-states/src/constants.ts b/code/addons/pseudo-states/src/constants.ts index a01ae9a77340..6e169a007102 100644 --- a/code/addons/pseudo-states/src/constants.ts +++ b/code/addons/pseudo-states/src/constants.ts @@ -41,5 +41,3 @@ export const PSEUDO_STATES = { link: 'link', target: 'target', } as const; - -export type PseudoState = keyof typeof PSEUDO_STATES; diff --git a/code/addons/pseudo-states/src/index.ts b/code/addons/pseudo-states/src/index.ts index 40fcb0b5511a..b91e16697407 100644 --- a/code/addons/pseudo-states/src/index.ts +++ b/code/addons/pseudo-states/src/index.ts @@ -1,7 +1,10 @@ import { definePreviewAddon } from 'storybook/internal/csf'; import * as addonAnnotations from './preview'; +import type { PseudoTypes } from './types'; export { PARAM_KEY } from './constants'; -export default () => definePreviewAddon(addonAnnotations); +export type { PseudoTypes } from './types'; + +export default () => definePreviewAddon(addonAnnotations); diff --git a/code/addons/pseudo-states/src/preview/withPseudoState.ts b/code/addons/pseudo-states/src/preview/withPseudoState.ts index 75492b5684d3..25d8c8a92d97 100644 --- a/code/addons/pseudo-states/src/preview/withPseudoState.ts +++ b/code/addons/pseudo-states/src/preview/withPseudoState.ts @@ -12,18 +12,10 @@ import type { DecoratorFunction } from 'storybook/internal/types'; import { addons, useEffect, useMemo, useRef } from 'storybook/preview-api'; -import type { PseudoState } from '../constants'; import { PSEUDO_STATES } from '../constants'; +import type { PseudoParameter, PseudoState, PseudoStateConfig } from '../types'; import { rewriteStyleSheet } from './rewriteStyleSheet'; -type PseudoStateConfig = { - [P in PseudoState]?: boolean | string | string[]; -}; - -export interface PseudoParameter extends PseudoStateConfig { - rootSelector?: string; -} - const channel = addons.getChannel(); const shadowHosts = new Set(); diff --git a/code/addons/pseudo-states/src/types.ts b/code/addons/pseudo-states/src/types.ts new file mode 100644 index 000000000000..3215f44105a2 --- /dev/null +++ b/code/addons/pseudo-states/src/types.ts @@ -0,0 +1,24 @@ +import type { PSEUDO_STATES } from './constants'; + +export type PseudoState = keyof typeof PSEUDO_STATES; + +export type PseudoStateConfig = { + [P in PseudoState]?: boolean | string | string[]; +}; + +export interface PseudoParameter extends PseudoStateConfig { + rootSelector?: string; +} + +export interface PseudoParameters { + /** + * Pseudo state configuration + * + * @see https://storybook.js.org/addons/storybook-addon-pseudo-states + */ + pseudo?: PseudoParameter; +} + +export interface PseudoTypes { + parameters: PseudoParameters; +} From ddf8cd2d6491f34e3131d21f0b456ca28aa66eec Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Mon, 8 Sep 2025 15:03:22 +0100 Subject: [PATCH 02/18] Add rudimentary type tests --- code/addons/pseudo-states/src/types.test.ts | 40 +++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 code/addons/pseudo-states/src/types.test.ts diff --git a/code/addons/pseudo-states/src/types.test.ts b/code/addons/pseudo-states/src/types.test.ts new file mode 100644 index 000000000000..f01ef709ceed --- /dev/null +++ b/code/addons/pseudo-states/src/types.test.ts @@ -0,0 +1,40 @@ +import { describe, it } from 'vitest'; + +import { definePreview } from 'storybook/internal/csf'; + +describe('addon parameters', () => { + // Skip this tests - it's for the type checker only, and the preview import doesn't work in a non-DOM environment + it.skip('are injected to csf factory', async () => { + // Late import to prevent error referencing `Element` + const pseudoAddon = await import('.'); + + // Define preview with psuedo addon + const preview = definePreview({ addons: [pseudoAddon.default()] }); + + preview.meta({ + parameters: { + pseudo: { + // @ts-expect-error focus should be bool/string + focus: 2, + }, + }, + }); + preview.meta({ + parameters: { + pseudo: { + // @ts-expect-error this pseudo state doesn't exist + madeUpKey: true, + }, + }, + }); + // And now for something completely different - valid config + preview.meta({ + parameters: { + pseudo: { + rootSelector: 'body', + focus: true, + }, + }, + }); + }); +}); From e073b37ae4bf5b1f5e5f0fdb87d764024c275583 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Mon, 15 Sep 2025 11:12:15 +0100 Subject: [PATCH 03/18] Set up type testing correctly --- code/addons/pseudo-states/src/types.test-d.ts | 46 +++++++++++++++++++ code/addons/pseudo-states/src/types.test.ts | 40 ---------------- code/addons/pseudo-states/vitest.config.ts | 6 ++- 3 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 code/addons/pseudo-states/src/types.test-d.ts delete mode 100644 code/addons/pseudo-states/src/types.test.ts diff --git a/code/addons/pseudo-states/src/types.test-d.ts b/code/addons/pseudo-states/src/types.test-d.ts new file mode 100644 index 000000000000..dcf7d5d0edcd --- /dev/null +++ b/code/addons/pseudo-states/src/types.test-d.ts @@ -0,0 +1,46 @@ +import { describe, expectTypeOf, it } from 'vitest'; + +import { definePreview } from 'storybook/internal/csf'; + +import pseudoAddon from '.'; + +describe('addon parameters are injected to csf factory', () => { + // Define preview with psuedo addon + const preview = definePreview({ addons: [pseudoAddon()] }); + + it('with invalid value', () => { + const meta = preview.meta({ + parameters: { + pseudo: { + // @ts-expect-error focus should be bool/string + focus: 2, + }, + }, + }); + expectTypeOf(meta.input.parameters!.pseudo).not.toExtend<{ focus: number }>(); + }); + + it('with invalid key', () => { + const meta = preview.meta({ + parameters: { + pseudo: { + // @ts-expect-error this pseudo state doesn't exist + madeUpKey: true, + }, + }, + }); + expectTypeOf(meta.input.parameters!.pseudo).not.toExtend<{ madeUpKey: boolean }>(); + }); + + it('with valid config', () => { + const meta = preview.meta({ + parameters: { + pseudo: { + rootSelector: 'body', + focus: true, + }, + }, + }); + expectTypeOf(meta.input.parameters!.pseudo!).toExtend<{ focus: boolean }>(); + }); +}); diff --git a/code/addons/pseudo-states/src/types.test.ts b/code/addons/pseudo-states/src/types.test.ts deleted file mode 100644 index f01ef709ceed..000000000000 --- a/code/addons/pseudo-states/src/types.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { describe, it } from 'vitest'; - -import { definePreview } from 'storybook/internal/csf'; - -describe('addon parameters', () => { - // Skip this tests - it's for the type checker only, and the preview import doesn't work in a non-DOM environment - it.skip('are injected to csf factory', async () => { - // Late import to prevent error referencing `Element` - const pseudoAddon = await import('.'); - - // Define preview with psuedo addon - const preview = definePreview({ addons: [pseudoAddon.default()] }); - - preview.meta({ - parameters: { - pseudo: { - // @ts-expect-error focus should be bool/string - focus: 2, - }, - }, - }); - preview.meta({ - parameters: { - pseudo: { - // @ts-expect-error this pseudo state doesn't exist - madeUpKey: true, - }, - }, - }); - // And now for something completely different - valid config - preview.meta({ - parameters: { - pseudo: { - rootSelector: 'body', - focus: true, - }, - }, - }); - }); -}); diff --git a/code/addons/pseudo-states/vitest.config.ts b/code/addons/pseudo-states/vitest.config.ts index 7420176b2e46..5347797a6664 100644 --- a/code/addons/pseudo-states/vitest.config.ts +++ b/code/addons/pseudo-states/vitest.config.ts @@ -5,6 +5,10 @@ import { vitestCommonConfig } from '../../vitest.workspace'; export default mergeConfig( vitestCommonConfig, defineConfig({ - // Add custom config here + test: { + typecheck: { + enabled: true, + }, + }, }) ); From 6da28d928da69c4842edccea777f6a3a4f5f18ce Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Sun, 5 Oct 2025 15:20:25 +0200 Subject: [PATCH 04/18] docs: Fix typo in comment --- code/addons/pseudo-states/src/types.test-d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/addons/pseudo-states/src/types.test-d.ts b/code/addons/pseudo-states/src/types.test-d.ts index dcf7d5d0edcd..1db04a947b45 100644 --- a/code/addons/pseudo-states/src/types.test-d.ts +++ b/code/addons/pseudo-states/src/types.test-d.ts @@ -5,7 +5,7 @@ import { definePreview } from 'storybook/internal/csf'; import pseudoAddon from '.'; describe('addon parameters are injected to csf factory', () => { - // Define preview with psuedo addon + // Define preview with pseudo addon const preview = definePreview({ addons: [pseudoAddon()] }); it('with invalid value', () => { From a74fda7cb863de49c58d47f14f98d47ea52480db Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Tue, 7 Oct 2025 20:50:18 +0100 Subject: [PATCH 05/18] Add reference to react renderer typings --- code/addons/pseudo-states/src/types.test-d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/code/addons/pseudo-states/src/types.test-d.ts b/code/addons/pseudo-states/src/types.test-d.ts index 1db04a947b45..871f32492adc 100644 --- a/code/addons/pseudo-states/src/types.test-d.ts +++ b/code/addons/pseudo-states/src/types.test-d.ts @@ -3,6 +3,7 @@ import { describe, expectTypeOf, it } from 'vitest'; import { definePreview } from 'storybook/internal/csf'; import pseudoAddon from '.'; +import '../../../renderers/react/src/typings'; describe('addon parameters are injected to csf factory', () => { // Define preview with pseudo addon From a4887819f786f1bd7ed5973787e39029c3198903 Mon Sep 17 00:00:00 2001 From: ayuhito Date: Fri, 17 Oct 2025 12:56:35 +0900 Subject: [PATCH 06/18] perf(cli): switch over to modern-tar --- code/core/package.json | 2 +- code/core/src/cli/dirs.ts | 19 ++++- code/yarn.lock | 154 +++----------------------------------- 3 files changed, 28 insertions(+), 147 deletions(-) diff --git a/code/core/package.json b/code/core/package.json index 16d531f3650c..f8a546e925ef 100644 --- a/code/core/package.json +++ b/code/core/package.json @@ -223,7 +223,6 @@ "@emotion/styled": "^11.14.0", "@fal-works/esbuild-plugin-global-externals": "^2.1.2", "@happy-dom/global-registrator": "^18.0.1", - "@ndelangen/get-tarball": "^3.0.7", "@ngard/tiny-isequal": "^1.1.0", "@polka/compression": "^1.0.0-next.28", "@radix-ui/react-dialog": "^1.1.2", @@ -290,6 +289,7 @@ "leven": "^4.0.0", "memfs": "^4.11.1", "memoizerific": "^1.11.3", + "modern-tar": "^0.5.4", "nanoid": "^4.0.2", "npmlog": "^7.0.0", "open": "^10.2.0", diff --git a/code/core/src/cli/dirs.ts b/code/core/src/cli/dirs.ts index c855125e566e..3529582b63be 100644 --- a/code/core/src/cli/dirs.ts +++ b/code/core/src/cli/dirs.ts @@ -1,11 +1,15 @@ import { join } from 'node:path'; +import { Readable } from 'node:stream'; +import { pipeline } from 'node:stream/promises'; +import type { ReadableStream } from 'node:stream/web'; +import { createGunzip } from 'node:zlib'; import { temporaryDirectory, versions } from 'storybook/internal/common'; import type { JsPackageManager } from 'storybook/internal/common'; import type { SupportedFrameworks, SupportedRenderers } from 'storybook/internal/types'; -import downloadTarballDefault from '@ndelangen/get-tarball'; import getNpmTarballUrlDefault from 'get-npm-tarball-url'; +import { unpackTar } from 'modern-tar/fs'; import invariant from 'tiny-invariant'; import { resolvePackageDir } from '../shared/utils/module'; @@ -21,15 +25,22 @@ const resolveUsingBranchInstall = async (packageManager: JsPackageManager, reque // an artifact of esbuild + type=commonjs + exportmap // @ts-expect-error (default export) const getNpmTarballUrl = getNpmTarballUrlDefault.default || getNpmTarballUrlDefault; - // @ts-expect-error (default export) - const downloadTarball = downloadTarballDefault.default || downloadTarballDefault; const url = getNpmTarballUrl(request, version, { registry: await packageManager.getRegistryURL(), }); + const response = await fetch(url); + if (!response.ok || !response.body) { + throw new Error(`Failed to download tarball from ${url}`); + } + // this unzips the tarball into the temp directory - await downloadTarball({ url, dir: tempDirectory }); + await pipeline( + Readable.fromWeb(response.body as ReadableStream), + createGunzip(), + unpackTar(tempDirectory) + ); return join(tempDirectory, 'package'); }; diff --git a/code/yarn.lock b/code/yarn.lock index fbc0b812a177..e8349596396f 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -4043,17 +4043,6 @@ __metadata: languageName: node linkType: hard -"@ndelangen/get-tarball@npm:^3.0.7": - version: 3.0.9 - resolution: "@ndelangen/get-tarball@npm:3.0.9" - dependencies: - gunzip-maybe: "npm:^1.4.2" - pump: "npm:^3.0.0" - tar-fs: "npm:^2.1.1" - checksum: 10c0/d66e76c6c990745d691c85d1dfa7f3dfd181405bb52c295baf4d1838b847d40c686e24602ea0ab1cdeb14d409db59f6bb9e2f96f56fe53da275da9cccf778e27 - languageName: node - linkType: hard - "@neoconfetti/react@npm:^1.0.0": version: 1.0.0 resolution: "@neoconfetti/react@npm:1.0.0" @@ -10737,15 +10726,6 @@ __metadata: languageName: node linkType: hard -"browserify-zlib@npm:^0.1.4": - version: 0.1.4 - resolution: "browserify-zlib@npm:0.1.4" - dependencies: - pako: "npm:~0.2.0" - checksum: 10c0/0cde7ca5d33d43125649330fd75c056397e53731956a2593c4a2529f4e609a8e6abdb2b8e1921683abf5645375b92cfb2a21baa42fe3c9fc3e2556d32043af93 - languageName: node - linkType: hard - "browserify-zlib@npm:^0.2.0": version: 0.2.0 resolution: "browserify-zlib@npm:0.2.0" @@ -11146,13 +11126,6 @@ __metadata: languageName: node linkType: hard -"chownr@npm:^1.1.1": - version: 1.1.4 - resolution: "chownr@npm:1.1.4" - checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db - languageName: node - linkType: hard - "chownr@npm:^3.0.0": version: 3.0.0 resolution: "chownr@npm:3.0.0" @@ -12865,18 +12838,6 @@ __metadata: languageName: node linkType: hard -"duplexify@npm:^3.5.0, duplexify@npm:^3.6.0": - version: 3.7.1 - resolution: "duplexify@npm:3.7.1" - dependencies: - end-of-stream: "npm:^1.0.0" - inherits: "npm:^2.0.1" - readable-stream: "npm:^2.0.0" - stream-shift: "npm:^1.0.0" - checksum: 10c0/59d1440c1b4e3a4db35ae96933392703ce83518db1828d06b9b6322920d6cbbf0b7159e88be120385fe459e77f1eb0c7622f26e9ec1f47c9ff05c2b35747dbd3 - languageName: node - linkType: hard - "duplexify@npm:^4.0.0, duplexify@npm:^4.1.1": version: 4.1.3 resolution: "duplexify@npm:4.1.3" @@ -13180,7 +13141,7 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": +"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.5 resolution: "end-of-stream@npm:1.4.5" dependencies: @@ -15833,22 +15794,6 @@ __metadata: languageName: node linkType: hard -"gunzip-maybe@npm:^1.4.2": - version: 1.4.2 - resolution: "gunzip-maybe@npm:1.4.2" - dependencies: - browserify-zlib: "npm:^0.1.4" - is-deflate: "npm:^1.0.0" - is-gzip: "npm:^1.0.0" - peek-stream: "npm:^1.1.0" - pumpify: "npm:^1.3.3" - through2: "npm:^2.0.3" - bin: - gunzip-maybe: bin.js - checksum: 10c0/42798a8061759885c2084e1804e51313d14f2dc9cf6c137e222953ec802f914e592d6f9dbf6ad67f4e78eb036e86db017d9c7c93bb23e90cd5ae09326296ed77 - languageName: node - linkType: hard - "handle-thing@npm:^2.0.0": version: 2.0.1 resolution: "handle-thing@npm:2.0.1" @@ -16938,13 +16883,6 @@ __metadata: languageName: node linkType: hard -"is-deflate@npm:^1.0.0": - version: 1.0.0 - resolution: "is-deflate@npm:1.0.0" - checksum: 10c0/35f7ffcbef3549dd8a4d8df5dc09b4f4656a0fc88326e8b5201cda54114a9c2d8efb689d87c16f3f35c95bd71dcf13dc790d62b7504745b42c53ab4b40238f5a - languageName: node - linkType: hard - "is-docker@npm:^2.0.0, is-docker@npm:^2.1.1": version: 2.2.1 resolution: "is-docker@npm:2.2.1" @@ -17033,13 +16971,6 @@ __metadata: languageName: node linkType: hard -"is-gzip@npm:^1.0.0": - version: 1.0.0 - resolution: "is-gzip@npm:1.0.0" - checksum: 10c0/cbc1db080c636a6fb0f7346e3076f8276a29a9d8b52ae67c1971a8131c43f308e98ed227d1a6f49970e6c6ebabee0568e60aed7a3579dd4e1817cddf2faaf9b7 - languageName: node - linkType: hard - "is-hexadecimal@npm:^1.0.0": version: 1.0.4 resolution: "is-hexadecimal@npm:1.0.4" @@ -19605,13 +19536,6 @@ __metadata: languageName: node linkType: hard -"mkdirp-classic@npm:^0.5.2": - version: 0.5.3 - resolution: "mkdirp-classic@npm:0.5.3" - checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168 - languageName: node - linkType: hard - "mkdirp@npm:^0.5.0, mkdirp@npm:^0.5.1": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" @@ -19649,6 +19573,13 @@ __metadata: languageName: node linkType: hard +"modern-tar@npm:^0.5.4": + version: 0.5.4 + resolution: "modern-tar@npm:0.5.4" + checksum: 10c0/f784ba0edd341bb3b5990c6acd8b5a793036365d513bf239c0ea5818be835f1fe43a4aea20972db047eeab89b61c02cacad721b69b5a13a402dcbd07905b7c7f + languageName: node + linkType: hard + "module-alias@npm:^2.2.3": version: 2.2.3 resolution: "module-alias@npm:2.2.3" @@ -20780,13 +20711,6 @@ __metadata: languageName: node linkType: hard -"pako@npm:~0.2.0": - version: 0.2.9 - resolution: "pako@npm:0.2.9" - checksum: 10c0/79c1806ebcf325b60ae599e4d7227c2e346d7b829dc20f5cf24cef07c934079dc3a61c5b3c8278a2f7a190c4a613e343ea11e5302dbe252efd11712df4b6b041 - languageName: node - linkType: hard - "pako@npm:~1.0.5": version: 1.0.11 resolution: "pako@npm:1.0.11" @@ -21115,17 +21039,6 @@ __metadata: languageName: node linkType: hard -"peek-stream@npm:^1.1.0": - version: 1.1.3 - resolution: "peek-stream@npm:1.1.3" - dependencies: - buffer-from: "npm:^1.0.0" - duplexify: "npm:^3.5.0" - through2: "npm:^2.0.3" - checksum: 10c0/3c35d1951b8640036f93b1b5628a90f849e49ca4f2e6aba393ff4978413931d9c491c83f71a92f878d5ea4c670af0bba04dfcfb79b310ead22601db7c1420e36 - languageName: node - linkType: hard - "perfect-debounce@npm:^2.0.0": version: 2.0.0 resolution: "perfect-debounce@npm:2.0.0" @@ -22011,16 +21924,6 @@ __metadata: languageName: node linkType: hard -"pump@npm:^2.0.0": - version: 2.0.1 - resolution: "pump@npm:2.0.1" - dependencies: - end-of-stream: "npm:^1.1.0" - once: "npm:^1.3.1" - checksum: 10c0/f1fe8960f44d145f8617ea4c67de05392da4557052980314c8f85081aee26953bdcab64afad58a2b1df0e8ff7203e3710e848cbe81a01027978edc6e264db355 - languageName: node - linkType: hard - "pump@npm:^3.0.0": version: 3.0.3 resolution: "pump@npm:3.0.3" @@ -22031,17 +21934,6 @@ __metadata: languageName: node linkType: hard -"pumpify@npm:^1.3.3": - version: 1.5.1 - resolution: "pumpify@npm:1.5.1" - dependencies: - duplexify: "npm:^3.6.0" - inherits: "npm:^2.0.3" - pump: "npm:^2.0.0" - checksum: 10c0/0bcabf9e3dbf2d0cc1f9b84ac80d3c75386111caf8963bfd98817a1e2192000ac0ccc804ca6ccd5b2b8430fdb71347b20fb2f014fe3d41adbacb1b502a841c45 - languageName: node - linkType: hard - "punycode@npm:^1.4.1": version: 1.4.1 resolution: "punycode@npm:1.4.1" @@ -22551,7 +22443,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.0.1, readable-stream@npm:^2.3.8": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -24469,7 +24361,6 @@ __metadata: "@emotion/styled": "npm:^11.14.0" "@fal-works/esbuild-plugin-global-externals": "npm:^2.1.2" "@happy-dom/global-registrator": "npm:^18.0.1" - "@ndelangen/get-tarball": "npm:^3.0.7" "@ngard/tiny-isequal": "npm:^1.1.0" "@polka/compression": "npm:^1.0.0-next.28" "@radix-ui/react-dialog": "npm:^1.1.2" @@ -24543,6 +24434,7 @@ __metadata: leven: "npm:^4.0.0" memfs: "npm:^4.11.1" memoizerific: "npm:^1.11.3" + modern-tar: "npm:^0.5.4" nanoid: "npm:^4.0.2" npmlog: "npm:^7.0.0" open: "npm:^10.2.0" @@ -24629,7 +24521,7 @@ __metadata: languageName: node linkType: hard -"stream-shift@npm:^1.0.0, stream-shift@npm:^1.0.2": +"stream-shift@npm:^1.0.2": version: 1.0.3 resolution: "stream-shift@npm:1.0.3" checksum: 10c0/939cd1051ca750d240a0625b106a2b988c45fb5a3be0cebe9a9858cb01bc1955e8c7b9fac17a9462976bea4a7b704e317c5c2200c70f0ca715a3363b9aa4fd3b @@ -25109,19 +25001,7 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:^2.1.1": - version: 2.1.4 - resolution: "tar-fs@npm:2.1.4" - dependencies: - chownr: "npm:^1.1.1" - mkdirp-classic: "npm:^0.5.2" - pump: "npm:^3.0.0" - tar-stream: "npm:^2.1.4" - checksum: 10c0/decb25acdc6839182c06ec83cba6136205bda1db984e120c8ffd0d80182bc5baa1d916f9b6c5c663ea3f9975b4dd49e3c6bb7b1707cbcdaba4e76042f43ec84c - languageName: node - linkType: hard - -"tar-stream@npm:^2.1.4, tar-stream@npm:~2.2.0": +"tar-stream@npm:~2.2.0": version: 2.2.0 resolution: "tar-stream@npm:2.2.0" dependencies: @@ -25272,16 +25152,6 @@ __metadata: languageName: node linkType: hard -"through2@npm:^2.0.3": - version: 2.0.5 - resolution: "through2@npm:2.0.5" - dependencies: - readable-stream: "npm:~2.3.6" - xtend: "npm:~4.0.1" - checksum: 10c0/cbfe5b57943fa12b4f8c043658c2a00476216d79c014895cef1ac7a1d9a8b31f6b438d0e53eecbb81054b93128324a82ecd59ec1a4f91f01f7ac113dcb14eade - languageName: node - linkType: hard - "thunky@npm:^1.0.2": version: 1.1.0 resolution: "thunky@npm:1.1.0" From d37b8bd077b7741ad18f131526db2409690715dc Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Tue, 21 Oct 2025 20:24:56 +0100 Subject: [PATCH 07/18] Avoid `es-toolkit/compat` imports as they cannot be effectively shaken --- .../docs/src/blocks/components/ArgsTable/ArgValue.tsx | 2 +- .../docs/src/blocks/components/ArgsTable/ArgsTable.tsx | 2 +- code/addons/docs/src/blocks/controls/Color.tsx | 2 +- code/addons/docs/src/blocks/controls/Object.tsx | 2 +- code/core/src/core-server/utils/stories-json.test.ts | 6 +++--- code/core/src/core-server/utils/stories-json.ts | 2 +- code/core/src/manager/components/sidebar/useLastViewed.ts | 2 +- .../src/docs/lib/defaultValues/createFromRawDefaultProp.ts | 4 +++- 8 files changed, 12 insertions(+), 10 deletions(-) diff --git a/code/addons/docs/src/blocks/components/ArgsTable/ArgValue.tsx b/code/addons/docs/src/blocks/components/ArgsTable/ArgValue.tsx index 7532e7bbd262..f61140e3754a 100644 --- a/code/addons/docs/src/blocks/components/ArgsTable/ArgValue.tsx +++ b/code/addons/docs/src/blocks/components/ArgsTable/ArgValue.tsx @@ -5,7 +5,7 @@ import { SyntaxHighlighter, WithTooltipPure, codeCommon } from 'storybook/intern import { ChevronSmallDownIcon, ChevronSmallUpIcon } from '@storybook/icons'; -import { uniq } from 'es-toolkit/compat'; +import uniq from 'es-toolkit/compat/uniq'; import memoize from 'memoizerific'; import { styled } from 'storybook/theming'; diff --git a/code/addons/docs/src/blocks/components/ArgsTable/ArgsTable.tsx b/code/addons/docs/src/blocks/components/ArgsTable/ArgsTable.tsx index acb832016b49..c61c14bdb96a 100644 --- a/code/addons/docs/src/blocks/components/ArgsTable/ArgsTable.tsx +++ b/code/addons/docs/src/blocks/components/ArgsTable/ArgsTable.tsx @@ -7,7 +7,7 @@ import { includeConditionalArg } from 'storybook/internal/csf'; import { DocumentIcon, UndoIcon } from '@storybook/icons'; -import { pickBy } from 'es-toolkit/compat'; +import pickBy from 'es-toolkit/compat/pickBy'; import { transparentize } from 'polished'; import { styled } from 'storybook/theming'; diff --git a/code/addons/docs/src/blocks/controls/Color.tsx b/code/addons/docs/src/blocks/controls/Color.tsx index bd485c377eaf..938c9a7a10f6 100644 --- a/code/addons/docs/src/blocks/controls/Color.tsx +++ b/code/addons/docs/src/blocks/controls/Color.tsx @@ -6,7 +6,7 @@ import { Form, TooltipNote, WithTooltip } from 'storybook/internal/components'; import { MarkupIcon } from '@storybook/icons'; import convert from 'color-convert'; -import { debounce } from 'es-toolkit/compat'; +import debounce from 'es-toolkit/compat/debounce'; import { HexColorPicker, HslaStringColorPicker, RgbaStringColorPicker } from 'react-colorful'; import { styled } from 'storybook/theming'; diff --git a/code/addons/docs/src/blocks/controls/Object.tsx b/code/addons/docs/src/blocks/controls/Object.tsx index 27f82b34815c..e84093591cf3 100644 --- a/code/addons/docs/src/blocks/controls/Object.tsx +++ b/code/addons/docs/src/blocks/controls/Object.tsx @@ -5,7 +5,7 @@ import { Button, Form, IconButton } from 'storybook/internal/components'; import { AddIcon, EyeCloseIcon, EyeIcon, SubtractIcon } from '@storybook/icons'; -import { cloneDeep } from 'es-toolkit/compat'; +import cloneDeep from 'es-toolkit/compat/cloneDeep'; import { type Theme, styled, useTheme } from 'storybook/theming'; import { getControlId, getControlSetterButtonId } from './helpers'; diff --git a/code/core/src/core-server/utils/stories-json.test.ts b/code/core/src/core-server/utils/stories-json.test.ts index 725f6de19aa1..eaa8b1ed0dd3 100644 --- a/code/core/src/core-server/utils/stories-json.test.ts +++ b/code/core/src/core-server/utils/stories-json.test.ts @@ -5,7 +5,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { normalizeStoriesEntry } from 'storybook/internal/common'; import { STORY_INDEX_INVALIDATED } from 'storybook/internal/core-events'; -import { debounce } from 'es-toolkit/compat'; +import debounce from 'es-toolkit/compat/debounce'; import type { Polka, Request, Response } from 'polka'; import Watchpack from 'watchpack'; @@ -16,7 +16,7 @@ import type { ServerChannel } from './get-server-channel'; import { DEBOUNCE, useStoriesJson } from './stories-json'; vi.mock('watchpack'); -vi.mock('es-toolkit/compat'); +vi.mock('es-toolkit/compat/debounce'); vi.mock('storybook/internal/node-logger'); vi.mock('../utils/constants', () => { @@ -575,7 +575,7 @@ describe('useStoriesJson', () => { it('debounces invalidation events', async () => { vi.mocked(debounce).mockImplementation( - (await vi.importActual('es-toolkit/compat')).debounce + (await vi.importActual('es-toolkit/compat/debounce')).default ); const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; diff --git a/code/core/src/core-server/utils/stories-json.ts b/code/core/src/core-server/utils/stories-json.ts index 029e935f77f7..9d96f779bab7 100644 --- a/code/core/src/core-server/utils/stories-json.ts +++ b/code/core/src/core-server/utils/stories-json.ts @@ -4,7 +4,7 @@ import { basename } from 'node:path'; import { STORY_INDEX_INVALIDATED } from 'storybook/internal/core-events'; import type { NormalizedStoriesSpecifier, StoryIndex } from 'storybook/internal/types'; -import { debounce } from 'es-toolkit/compat'; +import debounce from 'es-toolkit/compat/debounce'; import type { Polka } from 'polka'; import type { StoryIndexGenerator } from './StoryIndexGenerator'; diff --git a/code/core/src/manager/components/sidebar/useLastViewed.ts b/code/core/src/manager/components/sidebar/useLastViewed.ts index 48aa8e10cf12..b8810171c64a 100644 --- a/code/core/src/manager/components/sidebar/useLastViewed.ts +++ b/code/core/src/manager/components/sidebar/useLastViewed.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'; -import { debounce } from 'es-toolkit/compat'; +import debounce from 'es-toolkit/compat/debounce'; import store from 'store2'; import type { Selection, StoryRef } from './types'; diff --git a/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts b/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts index 9b4322d78699..6119ff7cade7 100644 --- a/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts +++ b/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts @@ -5,7 +5,9 @@ import { isTooLongForDefaultValueSummary, } from 'storybook/internal/docs-tools'; -import { isFunction, isPlainObject, isString } from 'es-toolkit/compat'; +import isFunction from 'es-toolkit/compat/isFunction'; +import isString from 'es-toolkit/compat/isString'; +import isPlainObject from 'es-toolkit/compat/isPlainObject'; import type reactElementToJSXStringType from 'react-element-to-jsx-string'; // @ts-expect-error (this is needed, because our bundling prefers the `browser` field, but that yields CJS) import reactElementToJSXStringRaw from 'react-element-to-jsx-string/dist/esm/index.js'; From c37b231fd9b5635333c876130277acc983bf719a Mon Sep 17 00:00:00 2001 From: ayuhito Date: Wed, 22 Oct 2025 16:17:05 +0900 Subject: [PATCH 08/18] chore: bump modern-tar --- code/core/package.json | 2 +- code/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/core/package.json b/code/core/package.json index f8a546e925ef..4b7f0cf951ad 100644 --- a/code/core/package.json +++ b/code/core/package.json @@ -289,7 +289,7 @@ "leven": "^4.0.0", "memfs": "^4.11.1", "memoizerific": "^1.11.3", - "modern-tar": "^0.5.4", + "modern-tar": "^0.5.5", "nanoid": "^4.0.2", "npmlog": "^7.0.0", "open": "^10.2.0", diff --git a/code/yarn.lock b/code/yarn.lock index e8349596396f..ff89de196303 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -19573,10 +19573,10 @@ __metadata: languageName: node linkType: hard -"modern-tar@npm:^0.5.4": - version: 0.5.4 - resolution: "modern-tar@npm:0.5.4" - checksum: 10c0/f784ba0edd341bb3b5990c6acd8b5a793036365d513bf239c0ea5818be835f1fe43a4aea20972db047eeab89b61c02cacad721b69b5a13a402dcbd07905b7c7f +"modern-tar@npm:^0.5.5": + version: 0.5.5 + resolution: "modern-tar@npm:0.5.5" + checksum: 10c0/e34b60e735941c53a9786cf0d9c6835e24af24860dc848c1fb8a8e2f477421d6bff19ae6d68361a2955ea8a83692ed098b3e946342670b9ff6cc8ea6f30ca6e8 languageName: node linkType: hard @@ -24434,7 +24434,7 @@ __metadata: leven: "npm:^4.0.0" memfs: "npm:^4.11.1" memoizerific: "npm:^1.11.3" - modern-tar: "npm:^0.5.4" + modern-tar: "npm:^0.5.5" nanoid: "npm:^4.0.2" npmlog: "npm:^7.0.0" open: "npm:^10.2.0" From f7466600b35f68dff2c2385780c597b2f78c7f56 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Wed, 22 Oct 2025 21:18:37 +0100 Subject: [PATCH 09/18] Include `@storybook/addon-docs/blocks` in optimizeDeps --- code/addons/docs/src/preset.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/addons/docs/src/preset.ts b/code/addons/docs/src/preset.ts index 094a8cdec95b..28316ad5580d 100644 --- a/code/addons/docs/src/preset.ts +++ b/code/addons/docs/src/preset.ts @@ -204,6 +204,11 @@ export const resolvedReact = async (existing: any) => ({ mdx: existing?.mdx ?? fileURLToPath(import.meta.resolve('@mdx-js/react')), }); -const optimizeViteDeps = ['@mdx-js/react', '@storybook/addon-docs', 'markdown-to-jsx']; +const optimizeViteDeps = [ + '@mdx-js/react', + '@storybook/addon-docs', + '@storybook/addon-docs/blocks', + 'markdown-to-jsx', +]; export { webpackX as webpack, docsX as docs, optimizeViteDeps }; From 058876125df8a120b3a89b0e7f7d22bf2da7eb8d Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Thu, 23 Oct 2025 09:05:18 +0100 Subject: [PATCH 10/18] Dedupe aria-query and @testing-library/dom --- code/core/package.json | 2 +- code/package.json | 1 + code/yarn.lock | 33 ++++----------------------------- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/code/core/package.json b/code/core/package.json index 895b342d9b64..3140288cc7f4 100644 --- a/code/core/package.json +++ b/code/core/package.json @@ -232,7 +232,7 @@ "@rolldown/pluginutils": "1.0.0-beta.18", "@storybook/docs-mdx": "4.0.0-next.1", "@tanstack/react-virtual": "^3.3.0", - "@testing-library/dom": "10.4.0", + "@testing-library/dom": "^10.4.1", "@testing-library/react": "^14.0.0", "@types/cross-spawn": "^6.0.6", "@types/detect-port": "^1.3.0", diff --git a/code/package.json b/code/package.json index e4002eef5189..cd106ba3b8bb 100644 --- a/code/package.json +++ b/code/package.json @@ -96,6 +96,7 @@ "@types/node": "^22.0.0", "@types/react": "^18.0.0", "@vitest/expect@npm:3.2.4": "patch:@vitest/expect@npm%3A3.2.4#~/.yarn/patches/@vitest-expect-npm-3.2.4-97c526d5cc.patch", + "aria-query@5.3.0": "^5.3.0", "esbuild": "^0.25.3", "playwright": "1.52.0", "playwright-core": "1.52.0", diff --git a/code/yarn.lock b/code/yarn.lock index 38ca6d66fcc7..1f82f3abc603 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -7208,23 +7208,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:10.4.0": - version: 10.4.0 - resolution: "@testing-library/dom@npm:10.4.0" - dependencies: - "@babel/code-frame": "npm:^7.10.4" - "@babel/runtime": "npm:^7.12.5" - "@types/aria-query": "npm:^5.0.1" - aria-query: "npm:5.3.0" - chalk: "npm:^4.1.0" - dom-accessibility-api: "npm:^0.5.9" - lz-string: "npm:^1.5.0" - pretty-format: "npm:^27.0.2" - checksum: 10c0/0352487720ecd433400671e773df0b84b8268fb3fe8e527cdfd7c11b1365b398b4e0eddba6e7e0c85e8d615f48257753283fccec41f6b986fd6c85f15eb5f84f - languageName: node - linkType: hard - -"@testing-library/dom@npm:9.x.x || 10.x.x, @testing-library/dom@npm:^10.4.0": +"@testing-library/dom@npm:9.x.x || 10.x.x, @testing-library/dom@npm:^10.4.0, @testing-library/dom@npm:^10.4.1": version: 10.4.1 resolution: "@testing-library/dom@npm:10.4.1" dependencies: @@ -9601,16 +9585,7 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.3.0": - version: 5.3.0 - resolution: "aria-query@npm:5.3.0" - dependencies: - dequal: "npm:^2.0.3" - checksum: 10c0/2bff0d4eba5852a9dd578ecf47eaef0e82cc52569b48469b0aac2db5145db0b17b7a58d9e01237706d1e14b7a1b0ac9b78e9c97027ad97679dd8f91b85da1469 - languageName: node - linkType: hard - -"aria-query@npm:^5.0.0, aria-query@npm:^5.3.1, aria-query@npm:^5.3.2": +"aria-query@npm:^5.0.0, aria-query@npm:^5.3.0, aria-query@npm:^5.3.1, aria-query@npm:^5.3.2": version: 5.3.2 resolution: "aria-query@npm:5.3.2" checksum: 10c0/003c7e3e2cff5540bf7a7893775fc614de82b0c5dde8ae823d47b7a28a9d4da1f7ed85f340bdb93d5649caa927755f0e31ecc7ab63edfdfc00c8ef07e505e03e @@ -12474,7 +12449,7 @@ __metadata: languageName: node linkType: hard -"dequal@npm:^2.0.0, dequal@npm:^2.0.2, dequal@npm:^2.0.3": +"dequal@npm:^2.0.0, dequal@npm:^2.0.2": version: 2.0.3 resolution: "dequal@npm:2.0.3" checksum: 10c0/f98860cdf58b64991ae10205137c0e97d384c3a4edc7f807603887b7c4b850af1224a33d88012009f150861cbee4fa2d322c4cc04b9313bee312e47f6ecaa888 @@ -24463,7 +24438,7 @@ __metadata: "@storybook/global": "npm:^5.0.0" "@storybook/icons": "npm:^1.6.0" "@tanstack/react-virtual": "npm:^3.3.0" - "@testing-library/dom": "npm:10.4.0" + "@testing-library/dom": "npm:^10.4.1" "@testing-library/jest-dom": "npm:^6.6.3" "@testing-library/react": "npm:^14.0.0" "@testing-library/user-event": "npm:^14.6.1" From 79e98357357b6f89db83625e0b81b23c901838e9 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Thu, 23 Oct 2025 09:38:27 +0100 Subject: [PATCH 11/18] Don't use semver lib for trivial version parsing --- code/renderers/react/package.json | 2 -- code/renderers/react/src/entry-preview.tsx | 8 +++++--- code/yarn.lock | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index 465323e7f141..35302f086c7a 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -61,7 +61,6 @@ "@types/escodegen": "^0.0.6", "@types/estree": "^1.0.6", "@types/node": "^22.0.0", - "@types/semver": "^7.3.4", "acorn": "^7.4.1", "acorn-jsx": "^5.3.1", "acorn-walk": "^7.2.0", @@ -73,7 +72,6 @@ "prop-types": "^15.7.2", "react-element-to-jsx-string": "npm:@7rulnik/react-element-to-jsx-string@15.0.1", "require-from-string": "^2.0.2", - "semver": "^7.3.7", "ts-dedent": "^2.0.0", "type-fest": "~2.19" }, diff --git a/code/renderers/react/src/entry-preview.tsx b/code/renderers/react/src/entry-preview.tsx index b6f2928c1c8b..9c09399a0821 100644 --- a/code/renderers/react/src/entry-preview.tsx +++ b/code/renderers/react/src/entry-preview.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { global } from '@storybook/global'; -import semver from 'semver'; import { configure } from 'storybook/test'; import { getAct, getReactActEnvironment, setReactActEnvironment } from './act-compat'; @@ -19,8 +18,11 @@ export const decorators: Decorator[] = [ return story(); } - const major = semver.major(React.version); - const minor = semver.minor(React.version); + const [major, minor] = React.version.split('.').map((part) => parseInt(part, 10)); + + if (!Number.isInteger(major) || !Number.isInteger(minor)) { + throw new Error('Unable to parse React version'); + } if (major < 18 || (major === 18 && minor < 3)) { throw new Error('React Server Components require React >= 18.3'); } diff --git a/code/yarn.lock b/code/yarn.lock index 38ca6d66fcc7..882fc1696619 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6820,7 +6820,6 @@ __metadata: "@types/escodegen": "npm:^0.0.6" "@types/estree": "npm:^1.0.6" "@types/node": "npm:^22.0.0" - "@types/semver": "npm:^7.3.4" acorn: "npm:^7.4.1" acorn-jsx: "npm:^5.3.1" acorn-walk: "npm:^7.2.0" @@ -6832,7 +6831,6 @@ __metadata: prop-types: "npm:^15.7.2" react-element-to-jsx-string: "npm:@7rulnik/react-element-to-jsx-string@15.0.1" require-from-string: "npm:^2.0.2" - semver: "npm:^7.3.7" ts-dedent: "npm:^2.0.0" type-fest: "npm:~2.19" peerDependencies: From ffd220e2fdf6a16db95d8c1dc24c92033f132d76 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Fri, 24 Oct 2025 16:59:07 +0200 Subject: [PATCH 12/18] fix nextjs steps hanging --- code/lib/create-storybook/src/scaffold-new-project.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/lib/create-storybook/src/scaffold-new-project.ts b/code/lib/create-storybook/src/scaffold-new-project.ts index 70b5c11ab441..bba45c83e278 100644 --- a/code/lib/create-storybook/src/scaffold-new-project.ts +++ b/code/lib/create-storybook/src/scaffold-new-project.ts @@ -46,10 +46,10 @@ const SUPPORTED_PROJECTS: Record = { language: 'TS', }, createScript: { - npm: 'npm create next-app . -- --turbopack --typescript --use-npm --eslint --tailwind --no-app --import-alias="@/*" --src-dir', + npm: 'npm create next-app . -- --turbopack --typescript --use-npm --eslint --tailwind --no-app --import-alias="@/*" --src-dir --no-react-compiler', // yarn doesn't support version ranges, so we have to use npx - yarn: 'npx create-next-app . --turbopack --typescript --use-yarn --eslint --tailwind --no-app --import-alias="@/*" --src-dir', - pnpm: 'pnpm create next-app . --turbopack --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir', + yarn: 'npx create-next-app . --turbopack --typescript --use-yarn --eslint --tailwind --no-app --import-alias="@/*" --src-dir --no-react-compiler', + pnpm: 'pnpm create next-app . --turbopack --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir --no-react-compiler', }, }, 'vue-vite-ts': { From dbf7c18ce4a329127028784c61b6f0526f295458 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:46:50 +0000 Subject: [PATCH 13/18] Update CHANGELOG.md for v9.1.15 [skip ci] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67dd4be250e6..a2b083c7f424 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 9.1.15 + +- Core: Add `preview-first-load` telemetry - [#32770](https://github.com/storybookjs/storybook/pull/32770), thanks @shilman! +- Dependencies: Update `vite-plugin-storybook-nextjs` - [#32821](https://github.com/storybookjs/storybook/pull/32821), thanks @ndelangen! + ## 9.1.14 - NextJS: Add NextJS 16 support - [#32791](https://github.com/storybookjs/storybook/pull/32791), thanks @yannbf and @ndelangen! From 093c50b9b6dd520683e7407be17e777196eca290 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Sat, 25 Oct 2025 11:54:02 +0100 Subject: [PATCH 14/18] Replace es-toolkit compat imports with non-compat --- code/.storybook/manager.tsx | 2 +- .../docs/src/blocks/components/ArgsTable/ArgValue.tsx | 2 +- .../docs/src/blocks/components/ArgsTable/ArgsTable.tsx | 2 +- code/addons/docs/src/blocks/controls/Color.tsx | 2 +- code/addons/docs/src/blocks/controls/Object.tsx | 2 +- code/core/src/core-server/utils/stories-json.test.ts | 7 ++++--- code/core/src/core-server/utils/stories-json.ts | 2 +- code/core/src/manager/components/sidebar/useLastViewed.ts | 2 +- code/lib/codemod/src/lib/utils.ts | 2 +- .../src/docs/lib/defaultValues/createFromRawDefaultProp.ts | 2 +- .../react/template/stories/js-argtypes.stories.jsx | 2 +- .../react/template/stories/ts-argtypes.stories.tsx | 2 +- scripts/utils/options.ts | 2 +- 13 files changed, 16 insertions(+), 15 deletions(-) diff --git a/code/.storybook/manager.tsx b/code/.storybook/manager.tsx index 8c8deec2daae..f7a31bd2bd06 100644 --- a/code/.storybook/manager.tsx +++ b/code/.storybook/manager.tsx @@ -1,4 +1,4 @@ -import { startCase } from 'es-toolkit/compat'; +import { startCase } from 'es-toolkit/string'; import { addons } from 'storybook/manager-api'; addons.setConfig({ diff --git a/code/addons/docs/src/blocks/components/ArgsTable/ArgValue.tsx b/code/addons/docs/src/blocks/components/ArgsTable/ArgValue.tsx index 7532e7bbd262..a469eccfd32e 100644 --- a/code/addons/docs/src/blocks/components/ArgsTable/ArgValue.tsx +++ b/code/addons/docs/src/blocks/components/ArgsTable/ArgValue.tsx @@ -5,7 +5,7 @@ import { SyntaxHighlighter, WithTooltipPure, codeCommon } from 'storybook/intern import { ChevronSmallDownIcon, ChevronSmallUpIcon } from '@storybook/icons'; -import { uniq } from 'es-toolkit/compat'; +import { uniq } from 'es-toolkit/array'; import memoize from 'memoizerific'; import { styled } from 'storybook/theming'; diff --git a/code/addons/docs/src/blocks/components/ArgsTable/ArgsTable.tsx b/code/addons/docs/src/blocks/components/ArgsTable/ArgsTable.tsx index acb832016b49..4693a3f2ac3a 100644 --- a/code/addons/docs/src/blocks/components/ArgsTable/ArgsTable.tsx +++ b/code/addons/docs/src/blocks/components/ArgsTable/ArgsTable.tsx @@ -7,7 +7,7 @@ import { includeConditionalArg } from 'storybook/internal/csf'; import { DocumentIcon, UndoIcon } from '@storybook/icons'; -import { pickBy } from 'es-toolkit/compat'; +import { pickBy } from 'es-toolkit/object'; import { transparentize } from 'polished'; import { styled } from 'storybook/theming'; diff --git a/code/addons/docs/src/blocks/controls/Color.tsx b/code/addons/docs/src/blocks/controls/Color.tsx index bd485c377eaf..578acfb90e75 100644 --- a/code/addons/docs/src/blocks/controls/Color.tsx +++ b/code/addons/docs/src/blocks/controls/Color.tsx @@ -6,7 +6,7 @@ import { Form, TooltipNote, WithTooltip } from 'storybook/internal/components'; import { MarkupIcon } from '@storybook/icons'; import convert from 'color-convert'; -import { debounce } from 'es-toolkit/compat'; +import { debounce } from 'es-toolkit/function'; import { HexColorPicker, HslaStringColorPicker, RgbaStringColorPicker } from 'react-colorful'; import { styled } from 'storybook/theming'; diff --git a/code/addons/docs/src/blocks/controls/Object.tsx b/code/addons/docs/src/blocks/controls/Object.tsx index 27f82b34815c..e98ab0ed6639 100644 --- a/code/addons/docs/src/blocks/controls/Object.tsx +++ b/code/addons/docs/src/blocks/controls/Object.tsx @@ -5,7 +5,7 @@ import { Button, Form, IconButton } from 'storybook/internal/components'; import { AddIcon, EyeCloseIcon, EyeIcon, SubtractIcon } from '@storybook/icons'; -import { cloneDeep } from 'es-toolkit/compat'; +import { cloneDeep } from 'es-toolkit/object'; import { type Theme, styled, useTheme } from 'storybook/theming'; import { getControlId, getControlSetterButtonId } from './helpers'; diff --git a/code/core/src/core-server/utils/stories-json.test.ts b/code/core/src/core-server/utils/stories-json.test.ts index 725f6de19aa1..e3b97669cd85 100644 --- a/code/core/src/core-server/utils/stories-json.test.ts +++ b/code/core/src/core-server/utils/stories-json.test.ts @@ -5,7 +5,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { normalizeStoriesEntry } from 'storybook/internal/common'; import { STORY_INDEX_INVALIDATED } from 'storybook/internal/core-events'; -import { debounce } from 'es-toolkit/compat'; +import { debounce } from 'es-toolkit/function'; import type { Polka, Request, Response } from 'polka'; import Watchpack from 'watchpack'; @@ -16,7 +16,7 @@ import type { ServerChannel } from './get-server-channel'; import { DEBOUNCE, useStoriesJson } from './stories-json'; vi.mock('watchpack'); -vi.mock('es-toolkit/compat'); +vi.mock('es-toolkit/function'); vi.mock('storybook/internal/node-logger'); vi.mock('../utils/constants', () => { @@ -575,7 +575,8 @@ describe('useStoriesJson', () => { it('debounces invalidation events', async () => { vi.mocked(debounce).mockImplementation( - (await vi.importActual('es-toolkit/compat')).debounce + (await vi.importActual('es-toolkit/function')) + .debounce ); const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; diff --git a/code/core/src/core-server/utils/stories-json.ts b/code/core/src/core-server/utils/stories-json.ts index 029e935f77f7..1200eca7c3c2 100644 --- a/code/core/src/core-server/utils/stories-json.ts +++ b/code/core/src/core-server/utils/stories-json.ts @@ -4,7 +4,7 @@ import { basename } from 'node:path'; import { STORY_INDEX_INVALIDATED } from 'storybook/internal/core-events'; import type { NormalizedStoriesSpecifier, StoryIndex } from 'storybook/internal/types'; -import { debounce } from 'es-toolkit/compat'; +import { debounce } from 'es-toolkit/function'; import type { Polka } from 'polka'; import type { StoryIndexGenerator } from './StoryIndexGenerator'; diff --git a/code/core/src/manager/components/sidebar/useLastViewed.ts b/code/core/src/manager/components/sidebar/useLastViewed.ts index 48aa8e10cf12..d64840ee5add 100644 --- a/code/core/src/manager/components/sidebar/useLastViewed.ts +++ b/code/core/src/manager/components/sidebar/useLastViewed.ts @@ -1,6 +1,6 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'; -import { debounce } from 'es-toolkit/compat'; +import { debounce } from 'es-toolkit/function'; import store from 'store2'; import type { Selection, StoryRef } from './types'; diff --git a/code/lib/codemod/src/lib/utils.ts b/code/lib/codemod/src/lib/utils.ts index 4d0415f7a0a9..f88a3007e23b 100644 --- a/code/lib/codemod/src/lib/utils.ts +++ b/code/lib/codemod/src/lib/utils.ts @@ -1,4 +1,4 @@ -import { camelCase, upperFirst } from 'es-toolkit/compat'; +import { camelCase, upperFirst } from 'es-toolkit/string'; export const sanitizeName = (name: string) => { let key = upperFirst(camelCase(name)) as string; diff --git a/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts b/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts index 9b4322d78699..ead66465d810 100644 --- a/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts +++ b/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts @@ -5,7 +5,7 @@ import { isTooLongForDefaultValueSummary, } from 'storybook/internal/docs-tools'; -import { isFunction, isPlainObject, isString } from 'es-toolkit/compat'; +import { isFunction, isPlainObject, isString } from 'es-toolkit/predicate'; import type reactElementToJSXStringType from 'react-element-to-jsx-string'; // @ts-expect-error (this is needed, because our bundling prefers the `browser` field, but that yields CJS) import reactElementToJSXStringRaw from 'react-element-to-jsx-string/dist/esm/index.js'; diff --git a/code/renderers/react/template/stories/js-argtypes.stories.jsx b/code/renderers/react/template/stories/js-argtypes.stories.jsx index 3ec1276f9ad1..553cda81a820 100644 --- a/code/renderers/react/template/stories/js-argtypes.stories.jsx +++ b/code/renderers/react/template/stories/js-argtypes.stories.jsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { PureArgsTable as ArgsTable } from '@storybook/addon-docs/blocks'; -import { mapValues } from 'es-toolkit/compat'; +import { mapValues } from 'es-toolkit/object'; import PropTypes from 'prop-types'; import { inferControls } from 'storybook/preview-api'; import { ThemeProvider, convert, themes } from 'storybook/theming'; diff --git a/code/renderers/react/template/stories/ts-argtypes.stories.tsx b/code/renderers/react/template/stories/ts-argtypes.stories.tsx index 30f940f97b18..c262c053180d 100644 --- a/code/renderers/react/template/stories/ts-argtypes.stories.tsx +++ b/code/renderers/react/template/stories/ts-argtypes.stories.tsx @@ -6,7 +6,7 @@ import type { StoryObj } from '@storybook/react'; import { PureArgsTable as ArgsTable } from '@storybook/addon-docs/blocks'; -import { mapValues } from 'es-toolkit/compat'; +import { mapValues } from 'es-toolkit/object'; import { inferControls } from 'storybook/preview-api'; import { ThemeProvider, convert, themes } from 'storybook/theming'; diff --git a/scripts/utils/options.ts b/scripts/utils/options.ts index 9ac63cca5b08..3b1b139228fd 100644 --- a/scripts/utils/options.ts +++ b/scripts/utils/options.ts @@ -1,6 +1,6 @@ /** Use commander and prompts to gather a list of options for a script */ import { type Command, type Option as CommanderOption, program } from 'commander'; -import { kebabCase } from 'es-toolkit/compat'; +import { kebabCase } from 'es-toolkit/string'; import picocolors from 'picocolors'; import prompts from 'prompts'; import type { Falsy, PrevCaller, PromptObject, PromptType } from 'prompts'; From d423bc487f5756f61e25b9127fb31240ab5c8f00 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Sat, 25 Oct 2025 12:30:09 +0100 Subject: [PATCH 15/18] Apply fixes/suggestions --- code/core/src/core-server/utils/stories-json.test.ts | 2 +- code/core/src/core-server/utils/stories-json.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/core/src/core-server/utils/stories-json.test.ts b/code/core/src/core-server/utils/stories-json.test.ts index e3b97669cd85..c75e9d92f83a 100644 --- a/code/core/src/core-server/utils/stories-json.test.ts +++ b/code/core/src/core-server/utils/stories-json.test.ts @@ -16,7 +16,7 @@ import type { ServerChannel } from './get-server-channel'; import { DEBOUNCE, useStoriesJson } from './stories-json'; vi.mock('watchpack'); -vi.mock('es-toolkit/function'); +vi.mock('es-toolkit/function', { spy: true }); vi.mock('storybook/internal/node-logger'); vi.mock('../utils/constants', () => { diff --git a/code/core/src/core-server/utils/stories-json.ts b/code/core/src/core-server/utils/stories-json.ts index 1200eca7c3c2..cdc2d5a8432d 100644 --- a/code/core/src/core-server/utils/stories-json.ts +++ b/code/core/src/core-server/utils/stories-json.ts @@ -40,7 +40,7 @@ export function useStoriesJson({ normalizedStories: NormalizedStoriesSpecifier[]; }) { const maybeInvalidate = debounce(() => serverChannel.emit(STORY_INDEX_INVALIDATED), DEBOUNCE, { - leading: true, + edges: ['leading', 'trailing'], }); watchStorySpecifiers(normalizedStories, { workingDir }, async (specifier, path, removed) => { const generator = await initializedStoryIndexGenerator; From f1801f693c723914c09526911fc0c4027e746f4b Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sun, 26 Oct 2025 11:12:37 +0100 Subject: [PATCH 16/18] Update Button component snapshots to reflect recent rendering changes --- .../stories/__snapshots__/Button.test.ts.snap | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test-storybooks/portable-stories-kitchen-sink/svelte/stories/__snapshots__/Button.test.ts.snap b/test-storybooks/portable-stories-kitchen-sink/svelte/stories/__snapshots__/Button.test.ts.snap index 4fb950f42dab..2a3dcb2b4c71 100644 --- a/test-storybooks/portable-stories-kitchen-sink/svelte/stories/__snapshots__/Button.test.ts.snap +++ b/test-storybooks/portable-stories-kitchen-sink/svelte/stories/__snapshots__/Button.test.ts.snap @@ -15,9 +15,11 @@ exports[`Renders CSF2Secondary story 1`] = ` + + `; @@ -48,9 +50,11 @@ exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = ` + + `; @@ -70,9 +74,11 @@ exports[`Renders CSF3Button story 1`] = ` + + `; @@ -101,9 +107,11 @@ exports[`Renders CSF3ButtonWithRender story 1`] = ` + + `; @@ -118,9 +126,11 @@ exports[`Renders CSF3InputFieldFilled story 1`] = ` + + `; @@ -140,9 +150,11 @@ exports[`Renders CSF3Primary story 1`] = ` + + `; @@ -167,9 +179,11 @@ exports[`Renders LoaderStory story 1`] = ` + + `; @@ -200,9 +214,11 @@ exports[`Renders NewStory story 1`] = ` + + `; From a0570758605cf95d34254f95a03e4d6b8f9c54e9 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Sun, 26 Oct 2025 11:20:34 +0100 Subject: [PATCH 17/18] fix linting --- code/core/src/core-server/utils/stories-json.test.ts | 6 +++++- .../src/docs/lib/defaultValues/createFromRawDefaultProp.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/core/src/core-server/utils/stories-json.test.ts b/code/core/src/core-server/utils/stories-json.test.ts index eaa8b1ed0dd3..9d7acd17b945 100644 --- a/code/core/src/core-server/utils/stories-json.test.ts +++ b/code/core/src/core-server/utils/stories-json.test.ts @@ -575,7 +575,11 @@ describe('useStoriesJson', () => { it('debounces invalidation events', async () => { vi.mocked(debounce).mockImplementation( - (await vi.importActual('es-toolkit/compat/debounce')).default + ( + await vi.importActual( + 'es-toolkit/compat/debounce' + ) + ).default ); const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; diff --git a/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts b/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts index 6119ff7cade7..cccc2390138e 100644 --- a/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts +++ b/code/renderers/react/src/docs/lib/defaultValues/createFromRawDefaultProp.ts @@ -6,8 +6,8 @@ import { } from 'storybook/internal/docs-tools'; import isFunction from 'es-toolkit/compat/isFunction'; -import isString from 'es-toolkit/compat/isString'; import isPlainObject from 'es-toolkit/compat/isPlainObject'; +import isString from 'es-toolkit/compat/isString'; import type reactElementToJSXStringType from 'react-element-to-jsx-string'; // @ts-expect-error (this is needed, because our bundling prefers the `browser` field, but that yields CJS) import reactElementToJSXStringRaw from 'react-element-to-jsx-string/dist/esm/index.js'; From b5f41bf8ba9c90db521d64f6499778e06a026819 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Sun, 26 Oct 2025 11:30:04 +0000 Subject: [PATCH 18/18] Write changelog for 10.0.0-rc.2 [skip ci] --- CHANGELOG.prerelease.md | 11 +++++++++++ code/package.json | 3 ++- docs/versions/next.json | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index 3155fd133ee7..c54934ed4126 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,14 @@ +## 10.0.0-rc.2 + +- CLI: Fix Nextjs project creation in empty directories - [#32828](https://github.com/storybookjs/storybook/pull/32828), thanks @yannbf! +- CLI: Switch over to modern-tar - [#32763](https://github.com/storybookjs/storybook/pull/32763), thanks @ayuhito! +- Core: Add parameter typings for addon-pseudo-state - [#32384](https://github.com/storybookjs/storybook/pull/32384), thanks @mrginglymus! +- Core: Dedupe aria-query and @testing-library/dom packages - [#32801](https://github.com/storybookjs/storybook/pull/32801), thanks @mrginglymus! +- Core: Improve es-toolkit usage for better tree-shaking - [#32787](https://github.com/storybookjs/storybook/pull/32787), thanks @mrginglymus! +- Core: Replace es-toolkit compat imports with non-compat - [#32837](https://github.com/storybookjs/storybook/pull/32837), thanks @mrginglymus! +- React: Simplify version detection - [#32802](https://github.com/storybookjs/storybook/pull/32802), thanks @mrginglymus! +- Vite: Optimize @storybook/addon-docs/blocks dependency - [#32798](https://github.com/storybookjs/storybook/pull/32798), thanks @mrginglymus! + ## 10.0.0-rc.1 - Addon-Vitest: Support Vitest 4 - [#32819](https://github.com/storybookjs/storybook/pull/32819), thanks @yannbf! diff --git a/code/package.json b/code/package.json index ac5490861adf..e65b4b271c9a 100644 --- a/code/package.json +++ b/code/package.json @@ -283,5 +283,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "10.0.0-rc.2" } diff --git a/docs/versions/next.json b/docs/versions/next.json index 48ae770832bd..0b6e09de90dc 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"10.0.0-rc.1","info":{"plain":"- Addon-Vitest: Support Vitest 4 - [#32819](https://github.com/storybookjs/storybook/pull/32819), thanks @yannbf!\n- CSF: Fix `play-fn` tag for methods - [#32695](https://github.com/storybookjs/storybook/pull/32695), thanks @shilman!\n- Core: Add `preview-first-load` telemetry - [#32770](https://github.com/storybookjs/storybook/pull/32770), thanks @shilman!\n- Dependencies: Update `vite-plugin-storybook-nextjs` - [#32821](https://github.com/storybookjs/storybook/pull/32821), thanks @ndelangen!\n- Maintenance: Fix bundle size bloat caused by `SyntaxHighlighter` (`createElement`) - [#32800](https://github.com/storybookjs/storybook/pull/32800), thanks @mrginglymus!\n- Nextjs: Add Next v16 support - [#32791](https://github.com/storybookjs/storybook/pull/32791), thanks @yannbf!\n- UI: Improve syntax-highlighter bundling - [#32776](https://github.com/storybookjs/storybook/pull/32776), thanks @mrginglymus!"}} \ No newline at end of file +{"version":"10.0.0-rc.2","info":{"plain":"- CLI: Fix Nextjs project creation in empty directories - [#32828](https://github.com/storybookjs/storybook/pull/32828), thanks @yannbf!\n- CLI: Switch over to modern-tar - [#32763](https://github.com/storybookjs/storybook/pull/32763), thanks @ayuhito!\n- Core: Add parameter typings for addon-pseudo-state - [#32384](https://github.com/storybookjs/storybook/pull/32384), thanks @mrginglymus!\n- Core: Dedupe aria-query and @testing-library/dom packages - [#32801](https://github.com/storybookjs/storybook/pull/32801), thanks @mrginglymus!\n- Core: Improve es-toolkit usage for better tree-shaking - [#32787](https://github.com/storybookjs/storybook/pull/32787), thanks @mrginglymus!\n- Core: Replace es-toolkit compat imports with non-compat - [#32837](https://github.com/storybookjs/storybook/pull/32837), thanks @mrginglymus!\n- React: Simplify version detection - [#32802](https://github.com/storybookjs/storybook/pull/32802), thanks @mrginglymus!\n- Vite: Optimize @storybook/addon-docs/blocks dependency - [#32798](https://github.com/storybookjs/storybook/pull/32798), thanks @mrginglymus!"}} \ No newline at end of file