Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
95e7638
Update ./docs/versions/next.json for v10.3.0-alpha.0
storybook-bot Jan 21, 2026
912784a
Merge pull request #33315 from storybookjs/valentin/fix-vitest-mocker…
valentinpalkovic Jan 22, 2026
9dd8d5f
Merge pull request #33603 from storybookjs/shilman/add-cli-init-telem…
shilman Jan 23, 2026
94ed900
Write changelog for 10.2.1 [skip ci]
storybook-bot Jan 26, 2026
c003cb1
debugging CI problems
ndelangen Jan 26, 2026
f001002
debugging CI problems
ndelangen Jan 26, 2026
0977032
debugging CI problems
ndelangen Jan 26, 2026
03d0299
debugging CI problems
ndelangen Jan 26, 2026
a570e59
Merge pull request #33620 from storybookjs/version-patch-from-10.2.0
valentinpalkovic Jan 27, 2026
acf2b44
Bump version from "10.2.0" to "10.2.1" [skip ci]
storybook-bot Jan 27, 2026
285866d
Update ./docs/versions/next.json for v10.3.0-alpha.1
storybook-bot Jan 28, 2026
d9288e2
Merge pull request #33675 from storybookjs/valentin/implement-agent-d…
valentinpalkovic Jan 28, 2026
e8ebfd0
Merge pull request #33696 from storybookjs/kasper/docs-csf-factories-…
kylegach Jan 28, 2026
8fe8050
Merge pull request #33705 from storybookjs/kasper/refs-401-loginurl
kasperpeulen Jan 29, 2026
02dd879
Merge pull request #33708 from storybookjs/valentin/addon-vitest-prev…
valentinpalkovic Jan 29, 2026
4ae4460
Merge pull request #33694 from storybookjs/valentin/addon-vitest-supp…
valentinpalkovic Jan 29, 2026
389cecf
Merge pull request #33682 from storybookjs/valentin/fix-package-bench…
valentinpalkovic Jan 28, 2026
aeba4bf
Merge pull request #33683 from storybookjs/valentin/fix-test-flake
valentinpalkovic Jan 28, 2026
8c841e6
Merge pull request #33693 from storybookjs/valentin/addon-vitest-requ…
valentinpalkovic Jan 28, 2026
bde74ae
Write changelog for 10.2.2 [skip ci]
storybook-bot Jan 30, 2026
e77def3
Merge pull request #33688 from storybookjs/version-patch-from-10.2.1
valentinpalkovic Jan 30, 2026
e367333
Bump version from "10.2.1" to "10.2.2" [skip ci]
storybook-bot Jan 30, 2026
4ef05ef
Merge pull request #33647 from storybookjs/fix-iframe-href
ghengeveld Jan 26, 2026
841eb65
Merge pull request #33340 from tanujbhaud/fix/windows-paths-addon-vit…
valentinpalkovic Jan 30, 2026
98cc4b5
Write changelog for 10.2.3 [skip ci]
storybook-bot Jan 30, 2026
89d2e0f
Merge pull request #33716 from storybookjs/version-patch-from-10.2.2
valentinpalkovic Jan 30, 2026
d959d6c
Bump version from "10.2.2" to "10.2.3" [skip ci]
storybook-bot Jan 30, 2026
70ac263
Update ./docs/versions/next.json for v10.3.0-alpha.2
storybook-bot Jan 30, 2026
8ead8f8
Merge pull request #33714 from storybookjs/kasper/fix-codemod-windows
valentinpalkovic Jan 30, 2026
fe31daf
Merge pull request #33648 from storybookjs/kasper/csf-factories-non-i…
kasperpeulen Jan 28, 2026
c400893
Merge pull request #33666 from storybookjs/fix-zod-meta-false-positive
kasperpeulen Jan 28, 2026
92ce460
Merge pull request #33645 from storybookjs/fix-csf-import-comments
kasperpeulen Jan 28, 2026
ee7ef00
Merge pull request #33646 from storybookjs/kasper/fix-csf-factories-c…
kasperpeulen Jan 28, 2026
1f194b1
Merge pull request #33673 from storybookjs/fix-csf-factory-preview-no…
kasperpeulen Jan 28, 2026
8d21731
Merge pull request #33419 from pallaprolus/fix/30390-nextjs-link-context
valentinpalkovic Jan 30, 2026
c947cc8
Merge pull request #33697 from yatishgoel/fix/33689-zoom-button-activ…
valentinpalkovic Jan 30, 2026
9d9bceb
Merge pull request #33687 from storybookjs/kasper/docs-csf-next-gener…
valentinpalkovic Feb 2, 2026
c25df87
Write changelog for 10.2.4 [skip ci]
storybook-bot Feb 2, 2026
78489c2
Merge pull request #33739 from storybookjs/version-patch-from-10.2.3
valentinpalkovic Feb 2, 2026
8e2b782
Bump version from "10.2.3" to "10.2.4" [skip ci]
storybook-bot Feb 2, 2026
2dadfd5
Merge pull request #33740 from storybookjs/valentin/ensure-consistent…
valentinpalkovic Feb 2, 2026
14a9134
Merge pull request #33726 from theRuslan/fix-docs-loglevels
valentinpalkovic Feb 2, 2026
e979a25
Merge pull request #33717 from storybookjs/copilot/fix-cache-invalida…
valentinpalkovic Feb 3, 2026
9c9d3eb
Write changelog for 10.2.5 [skip ci]
storybook-bot Feb 3, 2026
05d356b
Update ./docs/versions/next.json for v10.3.0-alpha.3
storybook-bot Feb 3, 2026
65beae2
Merge pull request #33751 from storybookjs/version-patch-from-10.2.4
valentinpalkovic Feb 4, 2026
1053c2a
Bump version from "10.2.4" to "10.2.5" [skip ci]
storybook-bot Feb 4, 2026
5d7d985
Merge branch 'latest-release'
storybook-bot Feb 4, 2026
439af85
Update ./docs/versions/next.json for v10.3.0-alpha.4
storybook-bot Feb 4, 2026
2f8d01d
Merge pull request #33686 from JSMike/33548-fix-base-path
valentinpalkovic Feb 3, 2026
cae3d07
Merge pull request #33755 from storybookjs/valentin/support-vitest-co…
valentinpalkovic Feb 4, 2026
babcf85
Merge pull request #33712 from storybookjs/valentin/addon-vitest-skip…
valentinpalkovic Jan 30, 2026
69d8d3b
Write changelog for 10.2.6 [skip ci]
storybook-bot Feb 4, 2026
9b895ec
Merge pull request #33718 from storybookjs/valentin/bundle-addon-vite…
valentinpalkovic Feb 4, 2026
40ef0ea
Fix tests
valentinpalkovic Feb 4, 2026
d09e7f8
Merge pull request #33764 from storybookjs/version-patch-from-10.2.5
valentinpalkovic Feb 4, 2026
cc0d1f9
Bump version from "10.2.5" to "10.2.6" [skip ci]
storybook-bot Feb 4, 2026
e7d1d84
Merge pull request #33651 from storybookjs/fix-scale-1
ghengeveld Jan 27, 2026
3802165
Merge pull request #33284 from ia319/bug/33281-dynamic-title-select
valentinpalkovic Feb 4, 2026
17fcaa9
Merge pull request #33723 from yatishgoel/fix/csf-factories-cross-fil…
valentinpalkovic Feb 5, 2026
711e245
Merge pull request #33776 from LouisLau-art/fix/loglevel-flag-works
valentinpalkovic Feb 5, 2026
a075e07
Write changelog for 10.2.7 [skip ci]
storybook-bot Feb 5, 2026
2f7fcfb
Merge pull request #33775 from storybookjs/version-patch-from-10.2.6
valentinpalkovic Feb 5, 2026
8d687ec
Bump version from "10.2.6" to "10.2.7" [skip ci]
storybook-bot Feb 5, 2026
1c96212
Merge pull request #33783 from storybookjs/copilot/add-expo-telemetry…
valentinpalkovic Feb 6, 2026
0ca7278
Merge pull request #33766 from storybookjs/norbert/share-channel-events
ndelangen Feb 6, 2026
78f274b
Merge pull request #33773 from storybookjs/valentin/add-exit-telemetry
valentinpalkovic Feb 6, 2026
d9652ff
Merge pull request #33787 from storybookjs/valentin/fix-event-view-un…
valentinpalkovic Feb 9, 2026
7c2a587
Write changelog for 10.2.8 [skip ci]
storybook-bot Feb 9, 2026
a36426a
Merge pull request #33786 from storybookjs/version-patch-from-10.2.7
valentinpalkovic Feb 9, 2026
719b6ca
Bump version from "10.2.7" to "10.2.8" [skip ci]
storybook-bot Feb 9, 2026
e3021c7
Update ./docs/versions/next.json for v10.3.0-alpha.5
storybook-bot Feb 11, 2026
46e5dc7
Merge pull request #33792 from DukeDeSouth/fix/vite-inject-mocker-rel…
valentinpalkovic Feb 9, 2026
eb607d3
Merge pull request #33810 from storybookjs/valentin/fix-sec-issue
valentinpalkovic Feb 11, 2026
ca176a0
Merge pull request #31251 from yatishgoel/fix/nextjs15-link-component…
valentinpalkovic Feb 11, 2026
b119439
Merge pull request #33814 from storybookjs/valentin/improve-config-fi…
valentinpalkovic Feb 12, 2026
f3ccdd9
Write changelog for 10.2.9 [skip ci]
storybook-bot Feb 12, 2026
ec2587d
Update ./docs/versions/next.json for v10.3.0-alpha.6
storybook-bot Feb 16, 2026
d58e069
Merge pull request #33824 from storybookjs/version-patch-from-10.2.8
valentinpalkovic Feb 17, 2026
4cdde82
Bump version from "10.2.8" to "10.2.9" [skip ci]
storybook-bot Feb 17, 2026
c4c587e
Merge remote-tracking branch 'origin/latest-release'
valentinpalkovic Feb 17, 2026
e22f6a0
fix(checklist): respect disableTelemetry config in initializeChecklist
mixelburg Apr 1, 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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,66 @@
## 10.2.9

- Addon-Vitest: Improve config file detection in monorepos - [#33814](https://github.com/storybookjs/storybook/pull/33814), thanks @valentinpalkovic!
- Builder-Vite: Update dependencies react-vite framework - [#33810](https://github.com/storybookjs/storybook/pull/33810), thanks @valentinpalkovic!
- Builder-Vite: Use relative path for mocker entry in production builds - [#33792](https://github.com/storybookjs/storybook/pull/33792), thanks @DukeDeSouth!
- Next.js: Fix Link component override in appDirectory configuration - [#31251](https://github.com/storybookjs/storybook/pull/31251), thanks @yatishgoel!

## 10.2.8

- Telemetry: Add Expo metaframework - [#33783](https://github.com/storybookjs/storybook/pull/33783), thanks @copilot-swe-agent!
- Telemetry: Add init exit event - [#33773](https://github.com/storybookjs/storybook/pull/33773), thanks @valentinpalkovic!
- Telemetry: Add share events - [#33766](https://github.com/storybookjs/storybook/pull/33766), thanks @ndelangen!
- Test: Update event creation logic in user-event package - [#33787](https://github.com/storybookjs/storybook/pull/33787), thanks @valentinpalkovic!

## 10.2.7

- CSF: Fix cross-file story imports in csf-factories codemod - [#33723](https://github.com/storybookjs/storybook/pull/33723), thanks @yatishgoel!
- Core: Fix rendering of View Transitions in Firefox - [#33651](https://github.com/storybookjs/storybook/pull/33651), thanks @ghengeveld!
- Globals: Repair dynamicTitle: false for user-defined tools - [#33284](https://github.com/storybookjs/storybook/pull/33284), thanks @ia319!
- Logger: Honor --loglevel for npmlog output - [#33776](https://github.com/storybookjs/storybook/pull/33776), thanks @LouisLau-art!

## 10.2.6

- Addon-Vitest: Skip postinstall setup when configured - [#33712](https://github.com/storybookjs/storybook/pull/33712), thanks @valentinpalkovic!
- Addon-Vitest: Support vite/vitest config with deferred export - [#33755](https://github.com/storybookjs/storybook/pull/33755), thanks @valentinpalkovic!
- CLI: Support addon-vitest setup when --skip-install is passed - [#33718](https://github.com/storybookjs/storybook/pull/33718), thanks @valentinpalkovic!
- Manager: Update logic to use base path instead of full pathname - [#33686](https://github.com/storybookjs/storybook/pull/33686), thanks @JSMike!

## 10.2.5

- Angular: fix --loglevel options in docs and descriptions - [#33726](https://github.com/storybookjs/storybook/pull/33726), thanks @theRuslan!
- Builder-Vite: Add plugin to enforce Storybook's output directory in Vite build configuration - [#33740](https://github.com/storybookjs/storybook/pull/33740), thanks @valentinpalkovic!
- Core: Invalidate cache on Storybook version upgrade - [#33717](https://github.com/storybookjs/storybook/pull/33717), thanks @copilot-swe-agent!

## 10.2.4

- CSF-Factories: Fix codemod for preview files without exports - [#33673](https://github.com/storybookjs/storybook/pull/33673), thanks @kasperpeulen!
- CSF: Fix false positive detection of Zod v4 .meta() as CSF Factory - [#33666](https://github.com/storybookjs/storybook/pull/33666), thanks @kasperpeulen!
- CSFFactories: Add non-interactive mode and --glob flag - [#33648](https://github.com/storybookjs/storybook/pull/33648), thanks @kasperpeulen!
- CSFFactories: Preserve leading comments when adding imports - [#33645](https://github.com/storybookjs/storybook/pull/33645), thanks @kasperpeulen!
- Codemod: Fix csf-2-to-3 failing due to quoted filenames - [#33646](https://github.com/storybookjs/storybook/pull/33646), thanks @kasperpeulen!
- Codemod: Fix glob pattern handling on Windows - [#33714](https://github.com/storybookjs/storybook/pull/33714), thanks @kasperpeulen!
- Manager: Remove deprecated `active` prop warning in ZoomButton - [#33697](https://github.com/storybookjs/storybook/pull/33697), thanks @yatishgoel!
- Next.js: Alias AppRouterContext to shared runtime to fix Link navigation - [#33419](https://github.com/storybookjs/storybook/pull/33419), thanks @pallaprolus!

## 10.2.3

- Addon-Vitest: Normalize Windows paths in addon-vitest automigration - [#33340](https://github.com/storybookjs/storybook/pull/33340), thanks @tanujbhaud!
- Core: Fix `previewHref` when current path does not end with a slash - [#33647](https://github.com/storybookjs/storybook/pull/33647), thanks @ghengeveld!

## 10.2.2

- Addon Vitest: Support simple vite.config without defineConfig helper - [#33694](https://github.com/storybookjs/storybook/pull/33694), thanks @valentinpalkovic!
- Addon-Vitest: Append Storybook project to existing test.projects array without double nesting - [#33708](https://github.com/storybookjs/storybook/pull/33708), thanks @valentinpalkovic!
- Addon-Vitest: Update Vitest plugin configuration to disable requireAssertions for expect - [#33693](https://github.com/storybookjs/storybook/pull/33693), thanks @valentinpalkovic!
- Composition: Handle 401 responses with loginUrl from Chromatic - [#33705](https://github.com/storybookjs/storybook/pull/33705), thanks @kasperpeulen!
- Telemetry: Add agent detection - [#33675](https://github.com/storybookjs/storybook/pull/33675), thanks @valentinpalkovic!

## 10.2.1

- Builder-Webpack5: Fix @vitest/mocker resolution issue - [#33315](https://github.com/storybookjs/storybook/pull/33315), thanks @valentinpalkovic!
- CLI: Add init telemetry for CLI integrations - [#33603](https://github.com/storybookjs/storybook/pull/33603), thanks @shilman!

## 10.2.0

> Improved UI and story authoring ergonomics
Expand Down
5 changes: 2 additions & 3 deletions code/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,9 @@ module.exports = {
'import-x/no-named-as-default-member': 'warn',
'react/destructuring-assignment': 'warn',

// This warns about importing interfaces and types in a normal import, it's arguably better to import with the `type` prefix separate from the runtime imports,
// I leave this as a warning right now because we haven't really decided yet, and the codebase is riddled with errors if I set to 'error'.
// Our codebase is mostly TypeScript, and typescript will warn when imports are not found.
// It IS set to 'error' for JS files.
'import-x/named': 'warn',
'import-x/named': 'off',
Comment on lines +163 to +165

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

In eslint-plugin-import-x (or eslint-plugin-import equivalent), does the named rule catch invalid named imports that TypeScript may miss (especially when importing from untyped JS/CJS modules)? Please provide current docs/recommendations.

💡 Result:

Yes, the import-x/named rule in eslint-plugin-import-x (and the equivalent import/named in eslint-plugin-import) catches invalid named imports from untyped JS/CJS modules that TypeScript may miss. The rule statically analyzes the targeted module file to verify that named imports match actual named exports declared there, regardless of TypeScript typing. Key points from official docs: - It verifies "named imports are part of the set of named exports in the referenced module" by inspecting the file contents {1, high}. - For untyped JS/CJS modules (especially node_modules), it checks package.json for jsnext:main (deprecated) or module fields to find the ES module entry, then analyzes exports {1, high}. - Modules can be ignored via import-x/ignore setting (defaults include node_modules), but when not ignored, it analyzes them {1, high}. - Note: "A module path that is ignored or not unambiguously an ES module will not be reported" {1, high}. CJS modules with module.exports may not be treated as ES modules, potentially skipping analysis, but pure JS ES modules or those with module field are checked. - In TypeScript configs (flat/typescript, typescript), the rule is disabled (🚫) because TypeScript handles named import validation via types, but it can be manually enabled and works with eslint-import-resolver-typescript for path resolution {1,3,4,5, high}. TypeScript itself may miss runtime exports in untyped JS if no .d.ts declares them exhaustively. Current recommendations (2026): - Use eslint-plugin-import-x with flat/recommended or recommended configs where named is enabled by default {3,4,5, high}. - For TS projects, extend plugin:import-x/typescript + resolver, but enable import-x/named explicitly if you want checks on untyped JS {4,16, high}. - Pair with eslint-import-resolver-typescript to properly resolve paths and prefer @types but fall back to JS analysis {16, high}.

Citations:


🏁 Script executed:

cat -n code/.eslintrc.js | sed -n '150,180p'

Repository: storybookjs/storybook

Length of output: 1433


🏁 Script executed:

rg -A 5 -B 5 "import-x/named" code/.eslintrc.js

Repository: storybookjs/storybook

Length of output: 413


🏁 Script executed:

rg -n "^\s*rules:\s*{" code/.eslintrc.js | head -20

Repository: storybookjs/storybook

Length of output: 156


🏁 Script executed:

rg -n "rules:" code/.eslintrc.js | head -20

Repository: storybookjs/storybook

Length of output: 379


🏁 Script executed:

sed -n '16,68p' code/.eslintrc.js

Repository: storybookjs/storybook

Length of output: 2247


Clarify the misleading comment about JS file configuration

Lines 163–164: The comment states "It IS set to 'error' for JS files," but this ESLint config has no explicit import-x/named rule for JS files. The rule is only mentioned here, where it's disabled for TypeScript files. Revise the comment to accurately reflect what the config does—disable the check for TypeScript (where TypeScript validates named imports) while relying on plugin defaults for JS files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/.eslintrc.js` around lines 163 - 165, Update the misleading comment
above the 'import-x/named' rule to state that the rule is disabled for
TypeScript files because the TypeScript compiler handles named-import
validation, and that JS behavior will follow plugin/default settings (i.e.,
there is no explicit 'error' setting for JS here); reference the
'import-x/named' entry so reviewers know which rule the comment describes and
ensure the revised comment clearly distinguishes TypeScript vs JS handling.

},
},
{
Expand Down
2 changes: 1 addition & 1 deletion code/addons/a11y/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
"version": "10.2.0",
"version": "10.2.9",
"description": "Storybook Addon A11y: Test UI component compliance with WCAG web accessibility standards",
"keywords": [
"a11y",
Expand Down
10 changes: 7 additions & 3 deletions code/addons/a11y/src/postinstall.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { JsPackageManagerFactory } from 'storybook/internal/common';
import { JsPackageManagerFactory, versions } from 'storybook/internal/common';

import type { PostinstallOptions } from '../../../lib/cli-storybook/src/add';

export default async function postinstall(options: PostinstallOptions) {
const args = ['storybook', 'automigrate', 'addon-a11y-addon-test'];
const args = [
options.skipInstall ? `storybook@${versions.storybook}` : `storybook`,
'automigrate',
'addon-a11y-addon-test',
];

args.push('--loglevel', 'silent');
args.push('--skip-doctor');
Expand All @@ -25,5 +29,5 @@ export default async function postinstall(options: PostinstallOptions) {
configDir: options.configDir,
});

await jsPackageManager.runPackageCommand({ args });
await jsPackageManager.runPackageCommand({ args, useRemotePkg: !!options.skipInstall });
}
2 changes: 1 addition & 1 deletion code/addons/docs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-docs",
"version": "10.2.0",
"version": "10.2.9",
"description": "Storybook Docs: Document UI components automatically with stories and MDX",
"keywords": [
"docs",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/links/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-links",
"version": "10.2.0",
"version": "10.2.9",
"description": "Storybook Links: Link stories together to build demos and prototypes with your UI components",
"keywords": [
"storybook",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/onboarding/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-onboarding",
"version": "10.2.0",
"version": "10.2.9",
"description": "Storybook Onboarding: Help new users learn how to write stories",
"keywords": [
"storybook",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/pseudo-states/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "storybook-addon-pseudo-states",
"version": "10.2.0",
"version": "10.2.9",
"description": "Storybook Pseudo-states addon: Manipulate CSS pseudo states",
"keywords": [
"storybook",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/themes/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-themes",
"version": "10.2.0",
"version": "10.2.9",
"description": "Storybook Themes addon: Switch between themes from the toolbar",
"keywords": [
"css",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/vitest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-vitest",
"version": "10.2.0",
"version": "10.2.9",
"description": "Storybook Vitest addon: Blazing fast component testing using stories",
"keywords": [
"storybook",
Expand Down
55 changes: 45 additions & 10 deletions code/addons/vitest/src/node/vitest-manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { existsSync } from 'node:fs';
import { existsSync, readFileSync } from 'node:fs';

import type {
CoverageOptions,
Expand All @@ -13,7 +13,8 @@ import { Tag } from 'storybook/internal/core-server';
import type { StoryId, StoryIndex, StoryIndexEntry } from 'storybook/internal/types';

import * as find from 'empathic/find';
import path, { dirname, join, normalize } from 'pathe';
import * as walk from 'empathic/walk';
import path, { dirname, join, normalize, resolve } from 'pathe';
// eslint-disable-next-line depend/ban-dependencies
import slash from 'slash';

Expand Down Expand Up @@ -75,19 +76,53 @@ export class VitestManager {
: { enabled: false }
) as CoverageOptions;

const vitestWorkspaceConfig = find.any(
[
...VITEST_WORKSPACE_FILE_EXTENSION.map((ext) => `vitest.workspace.${ext}`),
...VITEST_CONFIG_FILE_EXTENSIONS.map((ext) => `vitest.config.${ext}`),
],
{ last: getProjectRoot() }
);
// In monorepos, the Storybook configDir (e.g. packages/web-app/.storybook) identifies
// the sub-package. We start the Vitest config search from its parent (the package root)
// and traverse upward to the project root, so configs in both sub-packages and the
// monorepo root are found. Without this, find.any defaults to process.cwd() which may
// be the monorepo root and would miss sub-package configs entirely.
const configDir = this.testManager.storybookOptions.configDir;
const packageRoot = configDir ? dirname(resolve(configDir)) : undefined;

const configFiles = [
...VITEST_WORKSPACE_FILE_EXTENSION.map((ext) => `vitest.workspace.${ext}`),
...VITEST_CONFIG_FILE_EXTENSIONS.flatMap((ext) => [
`vitest.config.${ext}`,
`vite.config.${ext}`,
]),
];

const potentialConfigFileLocations = walk.up(packageRoot || process.cwd(), {
last: getProjectRoot(),
});

let vitestWorkspaceConfig: string | undefined;
let firstVitestConfig: string | undefined;

for (const location of potentialConfigFileLocations) {
for (const file of configFiles) {
const maybe = find.any([file], { cwd: location, last: getProjectRoot() });
if (maybe && existsSync(maybe)) {
firstVitestConfig ??= maybe;
const content = readFileSync(maybe, 'utf8');
if (content.includes('storybookTest') || content.includes('@storybook/addon-vitest')) {
vitestWorkspaceConfig = dirname(maybe);
break;
}
}
}
if (vitestWorkspaceConfig) {
break;
}
}

const projectName = 'storybook:' + process.env.STORYBOOK_CONFIG_DIR;

const vitestConfigFallbackLocation = firstVitestConfig || packageRoot || process.cwd();

try {
this.vitest = await createVitest('test', {
root: vitestWorkspaceConfig ? dirname(vitestWorkspaceConfig) : process.cwd(),
root: vitestWorkspaceConfig ?? vitestConfigFallbackLocation,
watch: true,
passWithNoTests: false,
project: [projectName],
Expand Down
49 changes: 49 additions & 0 deletions code/addons/vitest/src/postinstall.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { describe, expect, it } from 'vitest';

import { isConfigAlreadySetup } from './postinstall';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Missing file extension on relative import.

As per coding guidelines, TypeScript files should use explicit file extensions for relative imports.

🔧 Suggested fix
-import { isConfigAlreadySetup } from './postinstall';
+import { isConfigAlreadySetup } from './postinstall.ts';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { isConfigAlreadySetup } from './postinstall';
import { isConfigAlreadySetup } from './postinstall.ts';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/addons/vitest/src/postinstall.test.ts` at line 3, The import in
postinstall.test.ts uses a relative path without an explicit extension; update
the import statement that references isConfigAlreadySetup so it includes the
TypeScript extension (change './postinstall' to './postinstall.ts') to comply
with the TypeScript explicit-extension guideline and ensure module resolution
for the isConfigAlreadySetup import works correctly.


describe('postinstall helpers', () => {
it('detects a fully configured Vitest config with addon plugin', () => {
const config = `
import { defineConfig } from 'vitest/config';
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';

export default defineConfig({
test: {
projects: [
{
extends: true,
plugins: [storybookTest({ configDir: '.storybook' })],
test: {
setupFiles: ['./.storybook/vitest.setup.ts'],
},
},
],
},
});
`;

expect(isConfigAlreadySetup('/project/vitest.config.ts', config)).toBe(true);
});

it('returns false when storybookTest plugin is not used', () => {
const config = `
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
projects: [
{
extends: true,
test: {
setupFiles: ['./.storybook/vitest.setup.ts'],
},
},
],
},
});
`;

expect(isConfigAlreadySetup('/project/vitest.config.ts', config)).toBe(false);
});
});
Loading