Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
9000830
Add parameter typings for addon-pseudo-state
mrginglymus Sep 3, 2025
ddf8cd2
Add rudimentary type tests
mrginglymus Sep 8, 2025
e073b37
Set up type testing correctly
mrginglymus Sep 15, 2025
6da28d9
docs: Fix typo in comment
Sidnioulz Oct 5, 2025
bb70672
Merge branch 'next' into pseudo-params
Sidnioulz Oct 6, 2025
b592c3b
Merge branch 'next' into pseudo-params
mrginglymus Oct 7, 2025
a74fda7
Add reference to react renderer typings
mrginglymus Oct 7, 2025
c6d0823
Merge branch 'next' into pseudo-params
Sidnioulz Oct 13, 2025
a488781
perf(cli): switch over to modern-tar
ayuhito Oct 17, 2025
d37b8bd
Avoid `es-toolkit/compat` imports as they cannot be effectively shaken
mrginglymus Oct 21, 2025
c37b231
chore: bump modern-tar
ayuhito Oct 22, 2025
9dcbc85
Merge branch 'next' into perf/modern-tar
ndelangen Oct 22, 2025
f746660
Include `@storybook/addon-docs/blocks` in optimizeDeps
mrginglymus Oct 22, 2025
0588761
Dedupe aria-query and @testing-library/dom
mrginglymus Oct 23, 2025
79e9835
Don't use semver lib for trivial version parsing
mrginglymus Oct 23, 2025
bd49265
Merge branch 'next' into one-aria-query-to-rule-them-all
kasperpeulen Oct 23, 2025
3f2ef59
Merge branch 'next' into perf/modern-tar
ndelangen Oct 24, 2025
6f2a421
Merge branch 'next' into perf/modern-tar
ndelangen Oct 24, 2025
23c27f6
Merge branch 'next' into one-aria-query-to-rule-them-all
yannbf Oct 24, 2025
684b1f0
Merge branch 'next' into optimize-startup
yannbf Oct 24, 2025
92e7ff4
Merge branch 'next' into no-semver-react
yannbf Oct 24, 2025
8f489b1
Merge branch 'next' into es-toolkit-ohno
yannbf Oct 24, 2025
ffd220e
fix nextjs steps hanging
yannbf Oct 24, 2025
df97183
Merge pull request #32828 from storybookjs/yann/fix-nextjs-hanging
yannbf Oct 24, 2025
dbf7c18
Update CHANGELOG.md for v9.1.15 [skip ci]
storybook-bot Oct 24, 2025
093c50b
Replace es-toolkit compat imports with non-compat
mrginglymus Oct 25, 2025
d423bc4
Apply fixes/suggestions
mrginglymus Oct 25, 2025
a423349
Merge pull request #32763 from ayuhito/perf/modern-tar
ndelangen Oct 26, 2025
9c22793
Merge branch 'next' into no-es-toolkit-compat
ndelangen Oct 26, 2025
88f92e0
Merge branch 'next' into es-toolkit-ohno
ndelangen Oct 26, 2025
95d7c4d
Merge branch 'next' into optimize-startup
ndelangen Oct 26, 2025
575ad04
Merge branch 'next' into no-semver-react
ndelangen Oct 26, 2025
521ff29
Merge branch 'next' into one-aria-query-to-rule-them-all
ndelangen Oct 26, 2025
f1801f6
Update Button component snapshots to reflect recent rendering changes
ndelangen Oct 26, 2025
dd82ecf
Merge pull request #32840 from storybookjs/norbert/fix-snapshot-svelte
ndelangen Oct 26, 2025
ffbd4ff
Merge branch 'next' into pr/mrginglymus/32787
ndelangen Oct 26, 2025
a057075
fix linting
ndelangen Oct 26, 2025
ca35a93
Merge branch 'next' into no-semver-react
ndelangen Oct 26, 2025
d4414b7
Merge branch 'next' into optimize-startup
ndelangen Oct 26, 2025
1615b5f
Merge branch 'next' into no-es-toolkit-compat
ndelangen Oct 26, 2025
5e75e42
Merge branch 'next' into one-aria-query-to-rule-them-all
ndelangen Oct 26, 2025
97a246f
Merge pull request #32787 from mrginglymus/es-toolkit-ohno
ndelangen Oct 26, 2025
950fdaa
Merge pull request #32801 from mrginglymus/one-aria-query-to-rule-the…
ndelangen Oct 26, 2025
7949b77
Merge branch 'next' into optimize-startup
ndelangen Oct 26, 2025
2fe97e5
Merge pull request #32802 from mrginglymus/no-semver-react
ndelangen Oct 26, 2025
f6ae955
Merge branch 'next' into pseudo-params
ndelangen Oct 26, 2025
800be77
Merge branch 'next' into pr/mrginglymus/32837
ndelangen Oct 26, 2025
8f8f324
Merge pull request #32384 from mrginglymus/pseudo-params
ndelangen Oct 26, 2025
597c4fd
Merge pull request #32798 from mrginglymus/optimize-startup
ndelangen Oct 26, 2025
d13459e
Merge pull request #32837 from mrginglymus/no-es-toolkit-compat
ndelangen Oct 26, 2025
b5f41bf
Write changelog for 10.0.0-rc.2 [skip ci]
storybook-bot Oct 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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!
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -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!
Expand Down
2 changes: 1 addition & 1 deletion code/.storybook/manager.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { startCase } from 'es-toolkit/compat';
import { startCase } from 'es-toolkit/string';
import { addons } from 'storybook/manager-api';

addons.setConfig({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
2 changes: 1 addition & 1 deletion code/addons/docs/src/blocks/controls/Color.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
2 changes: 1 addition & 1 deletion code/addons/docs/src/blocks/controls/Object.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
7 changes: 6 additions & 1 deletion code/addons/docs/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
2 changes: 0 additions & 2 deletions code/addons/pseudo-states/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,3 @@ export const PSEUDO_STATES = {
link: 'link',
target: 'target',
} as const;

export type PseudoState = keyof typeof PSEUDO_STATES;
5 changes: 4 additions & 1 deletion code/addons/pseudo-states/src/index.ts
Original file line number Diff line number Diff line change
@@ -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<PseudoTypes>(addonAnnotations);
10 changes: 1 addition & 9 deletions code/addons/pseudo-states/src/preview/withPseudoState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Element>();

Expand Down
47 changes: 47 additions & 0 deletions code/addons/pseudo-states/src/types.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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
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 }>();
});
});
24 changes: 24 additions & 0 deletions code/addons/pseudo-states/src/types.ts
Original file line number Diff line number Diff line change
@@ -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;
}
6 changes: 5 additions & 1 deletion code/addons/pseudo-states/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { vitestCommonConfig } from '../../vitest.workspace';
export default mergeConfig(
vitestCommonConfig,
defineConfig({
// Add custom config here
test: {
typecheck: {
enabled: true,
},
},
})
);
4 changes: 2 additions & 2 deletions code/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -232,7 +231,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",
Expand Down Expand Up @@ -290,6 +289,7 @@
"leven": "^4.0.0",
"memfs": "^4.11.1",
"memoizerific": "^1.11.3",
"modern-tar": "^0.5.5",
"nanoid": "^4.0.2",
"npmlog": "^7.0.0",
"open": "^10.2.0",
Expand Down
19 changes: 15 additions & 4 deletions code/core/src/cli/dirs.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<Uint8Array>),
createGunzip(),
unpackTar(tempDirectory)
);

return join(tempDirectory, 'package');
};
Expand Down
7 changes: 4 additions & 3 deletions code/core/src/core-server/utils/stories-json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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', { spy: true });
vi.mock('storybook/internal/node-logger');

vi.mock('../utils/constants', () => {
Expand Down Expand Up @@ -575,7 +575,8 @@ describe('useStoriesJson', () => {

it('debounces invalidation events', async () => {
vi.mocked(debounce).mockImplementation(
(await vi.importActual<typeof import('es-toolkit/compat')>('es-toolkit/compat')).debounce
(await vi.importActual<typeof import('es-toolkit/function')>('es-toolkit/function'))
.debounce
);

const mockServerChannel = { emit: vi.fn() } as any as ServerChannel;
Expand Down
4 changes: 2 additions & 2 deletions code/core/src/core-server/utils/stories-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/manager/components/sidebar/useLastViewed.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
2 changes: 1 addition & 1 deletion code/lib/codemod/src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
6 changes: 3 additions & 3 deletions code/lib/create-storybook/src/scaffold-new-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ const SUPPORTED_PROJECTS: Record<string, SupportedProject> = {
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': {
Expand Down
4 changes: 3 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -282,5 +283,6 @@
"Dependency Upgrades"
]
]
}
},
"deferredNextVersion": "10.0.0-rc.2"
}
2 changes: 0 additions & 2 deletions code/renderers/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Loading
Loading