Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
c9d07af
Update ./docs/versions/next.json for v10.4.0-alpha.3
storybook-bot Mar 23, 2026
14febc1
Merge pull request #34212 from storybookjs/norbert/dts-sequential-gen…
yannbf Mar 23, 2026
5bc8686
Merge pull request #34281 from storybookjs/fix-stackblitz-websocket
ghengeveld Mar 23, 2026
4ce1648
Merge pull request #34274 from chida09/fix/34270-builder-vite-hash-co…
valentinpalkovic Mar 25, 2026
bf06f9a
Merge pull request #34203 from mixelburg/fix/a11y-context-clear-timeo…
valentinpalkovic Mar 26, 2026
756f6e3
Merge pull request #34335 from beeswhacks/upgrade-vite-plugin-react-d…
valentinpalkovic Mar 26, 2026
ff9d121
Merge pull request #34316 from storybookjs/jeppe/fix-error-reports-on…
JReinhold Mar 27, 2026
7ad88e9
Merge pull request #33841 from storybookjs/kasper/docs-rdt-monorepo-faq
kylegach Mar 27, 2026
4fb52a2
Merge pull request #34393 from mixelburg/fix/docgen-resolver-tsx-fall…
valentinpalkovic Mar 30, 2026
4eb227b
Build: Move prettier to oxfmt
huang-julien Mar 19, 2026
21d37fd
Merge pull request #34224 from storybookjs/chore/removeprettierrc
kasperpeulen Mar 20, 2026
f997746
Merge pull request #34273 from storybookjs/fix/recast_windows_lf_crlf
yannbf Mar 23, 2026
60e8c15
Write changelog for 10.3.4 [skip ci]
storybook-bot Mar 31, 2026
a1ca843
Merge pull request #34361 from storybookjs/valentin/fix-csf4-vitest-i…
valentinpalkovic Mar 27, 2026
7a820b1
Merge pull request #34245 from storybookjs/chore/root_oxfmt
huang-julien Mar 24, 2026
729b118
Merge pull request #34306 from storybookjs/nx/fmt
huang-julien Mar 24, 2026
18f4fd9
Dedupe lock file
valentinpalkovic Mar 31, 2026
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
6 changes: 3 additions & 3 deletions .github/workflows/fork-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: check
run: yarn task --task check

prettier:
formatting:
name: Core Formatting
if: github.repository_owner != 'storybookjs'
runs-on: ubuntu-latest
Expand All @@ -39,8 +39,8 @@ jobs:
with:
install-code-deps: true

- name: prettier
run: cd code && yarn lint:prettier --check .
- name: oxfmt
run: cd code && yarn lint:fmt

test:
strategy:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:

runs-on: ubuntu-latest
env:
ALL_TASKS: compile,check,knip,test,pretty-docs,lint,sandbox,build,e2e-tests,e2e-tests-dev,test-runner,vitest-integration,check-sandbox,e2e-ui,jest,vitest,playwright-ct,cypress
ALL_TASKS: compile,check,knip,test,lint,fmt,sandbox,build,e2e-tests,e2e-tests-dev,test-runner,vitest-integration,check-sandbox,e2e-ui,jest,vitest,playwright-ct,cypress
steps:
- uses: actions/checkout@v4
with:
Expand Down
4 changes: 0 additions & 4 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
if [ -z "$SKIP_STORYBOOK_GIT_HOOKS" ]; then
cd code
yarn lint-staged

cd ../scripts
yarn lint-staged
fi
11 changes: 11 additions & 0 deletions .lintstagedrc.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { detectAgent } from 'std-env';

const fmtCmd = detectAgent().name ? 'oxfmt' : 'oxfmt --check';

export default {
'code/**/*.{js,jsx,mjs,ts,tsx,html,json}': [fmtCmd, 'yarn --cwd code lint:js:cmd'],
'scripts/**/*.{html,js,json,jsx,mjs,ts,tsx}': ['yarn --cwd scripts lint:js:cmd'],
'docs/_snippets/**/*.{js,jsx,mjs,ts,tsx,html,json}': [fmtCmd],
'**/*.ejs': ['yarn --cwd scripts exec ejslint'],
'**/package.json': ['yarn --cwd scripts lint:package'],
};
1 change: 0 additions & 1 deletion .nx/workflows/distribution-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ assignment-rules:
- compile
- check
- lint
- pretty-docs
- knip
run-on:
- agent: linux-js
Expand Down
68 changes: 68 additions & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"printWidth": 100,
"tabWidth": 2,
"bracketSpacing": true,
"trailingComma": "es5",
"singleQuote": true,
"arrowParens": "always",
"sortPackageJson": false,
"ignorePatterns": [
"*.bundle.js",
"*.js.map",
".yarn",
".vscode",
".nx/cache",
".nx/workspace-data",
"dist",
"build",
"bench",
"coverage",
"node_modules",
"storybook-static",
"built-storybooks",
"ember-output",
"code/core/assets",
"code/core/report",
"code/core/src/core-server/presets/common-manager.ts",
"code/core/src/core-server/utils/__search-files-tests__",
"code/core/src/core-server/utils/__mockdata__/src/Empty.stories.ts",
"code/lib/codemod/src/transforms/__testfixtures__",
"code/frameworks/angular/template/**",
"code/lib/eslint-plugin",
".prettierrc",
"test-storybooks",
"*.yml",
"*.yaml",
"*.md",
"*.mdx",
"!docs/_snippets/**"
],
"overrides": [
{
"files": ["docs/_snippets/**"],
"options": {
"trailingComma": "all"
}
},
{
"files": ["*.md", "*.mdx"],
"options": {
"importOrderSeparation": false,
"importOrderSortSpecifiers": false
}
},
{
"files": ["*.component.html"],
"options": {
"parser": "angular"
}
},
{
"files": ["**/frameworks/angular/src/**/*.ts", "**/frameworks/angular/template/**/*.ts"],
"options": {
"parser": "babel-ts"
}
}
]
}
2 changes: 1 addition & 1 deletion .serena/memories/project_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Current version: 10.2.x (as of March 2026)
- **Monorepo Tool**: NX (with `--no-cloud` flag required to avoid NX Cloud login issues)
- **Test Runner**: Vitest (primary), Playwright (E2E)
- **Linting**: ESLint 8
- **Formatting**: Prettier 3.7+
- **Formatting**: Oxfmt
- **Bundlers**: Vite 7, Webpack 5, esbuild
- **UI Libraries**: React 18, react-aria (use specific submodules, not root imports)
- **Build System**: Custom build via `jiti ./scripts/build/build-package.ts`
Expand Down
5 changes: 3 additions & 2 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"unifiedjs.vscode-mdx",
"yzhang.markdown-all-in-one"
"yzhang.markdown-all-in-one",
"oxc.oxc-vscode"
]
}
}
42 changes: 21 additions & 21 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
{
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.formatOnSave": true
},
"[javascriptreact]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.formatOnSave": true
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"[javascript][javascriptreact][typescript][typescriptreact][json][jsonc]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
"source.fixAll.eslint": "explicit",
"source.fixAll.oxc": "explicit"
},
"editor.formatOnSave": true,
"editor.tabSize": 2,
"eslint.format.enable": true,
"eslint.options": {
"cache": true,
"cacheLocation": ".cache/eslint",
"extensions": [".js", ".jsx", ".mjs", ".json", ".ts", ".tsx"]
"extensions": [
".js",
".jsx",
".mjs",
".json",
".ts",
".tsx"
]
},
"eslint.useESLintClass": true,
"eslint.validate": [
Expand All @@ -35,14 +30,17 @@
"typescript",
"typescriptreact"
],
"eslint.workingDirectories": ["./code", "./scripts"],
"eslint.workingDirectories": [
"./code",
"./scripts"
],
"files.associations": {
"*.js": "javascriptreact"
"*.js": "javascriptreact",
".oxfmtrc.json": "json"
},
"javascript.preferences.importModuleSpecifier": "relative",
"javascript.preferences.quoteStyle": "single",
"js/ts.implicitProjectConfig.target": "ESNext",
"prettier.ignorePath": "./code/.prettierignore",
"storyExplorer.storybookConfigDir": "./code/.storybook",
"typescript.format.enable": false,
"typescript.preferences.importModuleSpecifier": "relative",
Expand All @@ -52,4 +50,6 @@
"typescript.tsdk": "./typescript/lib",
"vitest.workspaceConfig": "./code/vitest.workspace.ts",
"vitest.rootConfig": "./code/vitest.workspace.ts",
}
"oxc.fmt.configPath": ".oxfmtrc.json",
"oxc.enable.oxlint": false,
}
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ When writing tests:

After changing files:

1. Format with `yarn prettier --write <file>`
1. Format with `cd code && oxfmt`
2. Lint with `yarn --cwd code lint:js:cmd <file-relative-to-code-folder> --fix` or `cd code && yarn lint:js:cmd <file-relative-to-code-folder>`
3. Run relevant tests before submitting a PR

Expand All @@ -243,6 +243,8 @@ Use Storybook loggers instead of raw `console.*` in normal code paths:
- Server-side: `storybook/internal/node-logger`
- Client-side: `storybook/internal/client-logger`

The pre-commit hook automatically detects AI agents (via `std-env`) and switches from check-only to write mode, so formatting is auto-fixed when agents commit.

Avoid `console.log`, `console.warn`, and `console.error` unless the file is isolated enough that importing the logger is not reasonable.

## Troubleshooting
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## 10.3.4

- Addon-a11y: Clear status transition timer on unmount to prevent test flake - [#34203](https://github.com/storybookjs/storybook/pull/34203), thanks @mixelburg!
- Bug: Skip re-processing already transformed config files for CSF factories - [#34273](https://github.com/storybookjs/storybook/pull/34273), thanks @huang-julien!
- Builder-Vite: Use djb2 hash to prevent variable name collisions in builder-vite - [#34274](https://github.com/storybookjs/storybook/pull/34274), thanks @chida09!
- CLI: Prompt for init crash reports - [#34316](https://github.com/storybookjs/storybook/pull/34316), thanks @JReinhold!
- CSF4: Fix duplicate preview loading issue in Vitest - [#34361](https://github.com/storybookjs/storybook/pull/34361), thanks @valentinpalkovic!
- Core: Fix WebSocket connection for StackBlitz/WebContainers - [#34281](https://github.com/storybookjs/storybook/pull/34281), thanks @ghengeveld!
- React-Docgen: Try .tsx fallback when resolving .js ESM imports in docgen resolvers - [#34393](https://github.com/storybookjs/storybook/pull/34393), thanks @mixelburg!
- React-Vite: Upgrade @joshwooding/vite-plugin-react-docgen-typescript to 0.7.0 - [#34335](https://github.com/storybookjs/storybook/pull/34335), thanks @beeswhacks!

## 10.3.3

- Addon-Vitest: Streamline vite(st) config detection across init and postinstall - [#34193](https://github.com/storybookjs/storybook/pull/34193), thanks @valentinpalkovic!
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Here's a highlight of notable directories and files:
│ ├── package.json
│ ├── playwright.config.ts
│ ├── presets # Preset packages
│ ├── prettier.config.mjs
│ ├── .oxfmtrc.json
│ ├── renderers # Storybook renderers for different frameworks
│ ├── sandbox # Sandboxes for Bug Reproductions or experimentation
│ ├── tsconfig.json
Expand Down Expand Up @@ -117,7 +117,7 @@ Here's a highlight of notable directories and files:
│ └── writing-tests
├── node_modules
├── package.json # Root of the yarn monorepo
├── prettier.config.mjs
├── .oxfmtrc.json
├── scripts # Build and Helper Scripts
├── test-storybooks
│ ├── ember-cli
Expand Down
16 changes: 0 additions & 16 deletions code/.prettierignore

This file was deleted.

31 changes: 28 additions & 3 deletions code/addons/a11y/src/components/A11yContext.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import type { FC, PropsWithChildren } from 'react';
import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import React, {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
useState,
} from 'react';

import {
STORY_CHANGED,
Expand Down Expand Up @@ -140,9 +148,22 @@ export const A11yContextProvider: FC<PropsWithChildren> = (props) => {
}, [setState, storyId]);

const handleToggleHighlight = useCallback(() => {
setState((prev) => ({ ...prev, ui: { ...prev.ui, highlighted: !prev.ui.highlighted } }));
setState((prev) => ({
...prev,
ui: { ...prev.ui, highlighted: !prev.ui.highlighted },
}));
}, [setState]);

const statusTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

useEffect(() => {
return () => {
if (statusTimerRef.current !== null) {
clearTimeout(statusTimerRef.current);
}
};
}, []);

const [selectedItems, setSelectedItems] = useState<Map<string, string>>(() => {
const initialValue = new Map();
// Check if the a11ySelection param is a valid format before parsing it
Expand Down Expand Up @@ -202,7 +223,11 @@ export const A11yContextProvider: FC<PropsWithChildren> = (props) => {
if (storyId === id) {
setState((prev) => ({ ...prev, status: 'ran', results: axeResults }));

setTimeout(() => {
if (statusTimerRef.current !== null) {
clearTimeout(statusTimerRef.current);
}
statusTimerRef.current = setTimeout(() => {
statusTimerRef.current = null;
setState((prev) => {
if (prev.status === 'ran') {
return { ...prev, status: 'ready' };
Expand Down
2 changes: 1 addition & 1 deletion code/addons/docs/docs/frameworks/WEB_COMPONENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
```js
import { setCustomElementsManifest } from '@storybook/web-components';
import customElements from '../custom-elements.json';

setCustomElementsManifest(customElements);
```

Expand Down
8 changes: 1 addition & 7 deletions code/addons/vitest/src/vitest-plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,22 +303,16 @@ export const storybookTest = async (options?: UserOptions): Promise<Plugin[]> =>
finalOptions.includeStories = includeStories;
const projectId = oneWayHash(finalOptions.configDir);

const previewOrConfigFile = loadPreviewOrConfigFile({ configDir: finalOptions.configDir });
const previewConfig = previewOrConfigFile ? await readConfig(previewOrConfigFile) : undefined;
const isCSF4 = previewConfig ? isCsfFactoryPreview(previewConfig) : false;

const areProjectAnnotationRequired = await requiresProjectAnnotations(
nonMutableInputConfig.test,
finalOptions,
isCSF4
finalOptions
);

const internalSetupFiles = (
[
'@storybook/addon-vitest/internal/setup-file',
areProjectAnnotationRequired &&
'@storybook/addon-vitest/internal/setup-file-with-project-annotations',
isCSF4 && previewOrConfigFile,
].filter(Boolean) as string[]
).map((filePath) => fileURLToPath(import.meta.resolve(filePath)));

Expand Down
5 changes: 1 addition & 4 deletions code/addons/vitest/src/vitest-plugin/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ const logBoxOnce = (message: string) => {

export async function requiresProjectAnnotations(
testConfig: ViteUserConfig['test'] | undefined,
finalOptions: InternalOptions,
isCSF4: boolean
finalOptions: InternalOptions
) {
const setupFiles = Array.isArray(testConfig?.setupFiles)
? testConfig.setupFiles
Expand Down Expand Up @@ -58,8 +57,6 @@ export async function requiresProjectAnnotations(
You can safely remove the "setProjectAnnotations" call from your setup file, or remove the file entirely if you don't have custom code there.
`);

return false;
} else if (isCSF4) {
return false;
}

Expand Down
Loading
Loading