Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
7fe0822
UI: Improve status handling in sidebar nodes
yannbf Nov 6, 2025
0de2d7d
Merge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 12, 2025
97df7c7
Merge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 13, 2025
ae1c72f
Merge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 15, 2025
225c329
Docs: Add migration guide for test-runner -> Vitest addon
kylegach Nov 17, 2025
9bbf3ff
MMerge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 17, 2025
9de849f
Address review comments
kylegach Nov 17, 2025
f55b402
Merge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 18, 2025
97c5b0b
Merge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 18, 2025
cbdfe24
Merge branch 'next' into docs-test-runner-migration
kylegach Nov 18, 2025
0354718
React: Add isPackage flag to component imports for better package ide…
kasperpeulen Nov 19, 2025
a3b196a
Update code/renderers/react/src/componentManifest/getComponentImports.ts
kasperpeulen Nov 19, 2025
41112e7
improve logic
kasperpeulen Nov 19, 2025
dee069b
Fix tests
kasperpeulen Nov 19, 2025
449a022
Update code/renderers/react/src/componentManifest/getComponentImports.ts
kasperpeulen Nov 19, 2025
3d2ce4a
Update tests
kasperpeulen Nov 19, 2025
f6174c8
Merge remote-tracking branch 'origin/kasper/next' into kasper/next
kasperpeulen Nov 19, 2025
e57fe90
Merge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 20, 2025
80b3272
Merge branch 'yann/improve-sidebar-context-menu-statuses' of github.c…
yannbf Nov 20, 2025
04978f0
fix e2e tests
yannbf Nov 20, 2025
44c467a
Apply suggestions from code review
kylegach Nov 21, 2025
8008a2d
Merge branch 'next' into docs-test-runner-migration
kylegach Nov 21, 2025
d4dc9a6
Address feedback
kylegach Nov 21, 2025
a05c8ab
Ignore example entries when checking index
ghengeveld Nov 22, 2025
795cd67
Improve button.stories snippet
ghengeveld Nov 22, 2025
eef6f26
Implement availability check for Vitest addon
ghengeveld Nov 22, 2025
3d07b50
Extend addon-vitest availability check with supported frameworks
ghengeveld Nov 24, 2025
c6db888
Rename constant
ghengeveld Nov 24, 2025
d3324b3
Move constant to a separate file to avoid importing Node.js stuff int…
ghengeveld Nov 24, 2025
7c94f80
Merge branch 'next' into checklistData-improvements
ghengeveld Nov 24, 2025
81563f7
Fix STORYBOOK_FRAMEWORK, STORYBOOK_RENDERER and STORYBOOK_BUILDER var…
ghengeveld Nov 24, 2025
eac7ebc
Use enum value and remove unnecessary guard
ghengeveld Nov 24, 2025
9a552e6
Merge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 24, 2025
f202400
Merge branch 'next' into yann/improve-sidebar-context-menu-statuses
yannbf Nov 24, 2025
170566a
Fix
yannbf Nov 24, 2025
87d93a5
Merge branch 'yann/improve-sidebar-context-menu-statuses' of github.c…
yannbf Nov 24, 2025
0e5f1c5
CLI: Update clack
valentinpalkovic Nov 24, 2025
9f09c7e
CLI: Update package manager proxies and CLI utils; refine main config…
valentinpalkovic Nov 24, 2025
c10be02
Fix story data, avoid dealing with conditional checklist item
ghengeveld Nov 24, 2025
43bac1c
Angular: Migrate from RxJS to async/await in command builders and run…
valentinpalkovic Nov 24, 2025
739b657
Remove getCoercedStorybookVersion and clean up related code
valentinpalkovic Nov 24, 2025
bfd4d07
Merge branch 'next' into valentin/fix-storybook-version-evaluation
valentinpalkovic Nov 24, 2025
74a4036
Merge branch 'next' into docs-test-runner-migration
kylegach Nov 24, 2025
fe334bf
Merge pull request #33129 from storybookjs/checklistData-improvements
ghengeveld Nov 24, 2025
38d9dec
Merge pull request #33061 from storybookjs/docs-test-runner-migration
kylegach Nov 24, 2025
33b47ad
Collapse checklist items by default
ghengeveld Nov 25, 2025
9751b81
Refactor Storybook version handling: rename version to versionSpecifi…
valentinpalkovic Nov 25, 2025
ed50d99
Enhance logging for Storybook build and start processes
valentinpalkovic Nov 25, 2025
4b1a651
Update code/lib/cli-storybook/src/automigrate/helpers/mainConfigFile.ts
valentinpalkovic Nov 25, 2025
1a860fd
Merge pull request #32965 from storybookjs/yann/improve-sidebar-conte…
yannbf Nov 25, 2025
42b6c68
Simplify getModulePackageJSON usage
valentinpalkovic Nov 25, 2025
e84b50c
Fix
kasperpeulen Nov 25, 2025
809c130
Merge pull request #33090 from storybookjs/kasper/next
kasperpeulen Nov 25, 2025
4dcfdc4
Update PNPMProxy to use primaryPackageJson.operationDir for packageJs…
valentinpalkovic Nov 25, 2025
4ba9f38
Merge pull request #33156 from storybookjs/valentin/show-compodoc-pro…
valentinpalkovic Nov 25, 2025
33ca730
CLI: Change task message from stop to cancel for project detection
valentinpalkovic Nov 25, 2025
9524438
CLI: Change spinner message from stop to error and update success mes…
valentinpalkovic Nov 25, 2025
6712284
Merge branch 'next' into collapse-checklist-items-by-default
ghengeveld Nov 25, 2025
358240c
Merge pull request #33141 from storybookjs/valentin/fix-storybook-ver…
valentinpalkovic Nov 25, 2025
c905dbb
Merge branch 'next' into collapse-checklist-items-by-default
ghengeveld Nov 25, 2025
9876f85
Revert
valentinpalkovic Nov 25, 2025
6e66a2e
Merge pull request #33160 from storybookjs/collapse-checklist-items-b…
ghengeveld Nov 25, 2025
e02f7e6
CLI: Use spinner.stop for success and reserve spinner.cancel for abor…
valentinpalkovic Nov 25, 2025
7a40d76
Remove Agents.md
valentinpalkovic Nov 25, 2025
392b378
CLI: Add stop method to spinner instance and update task execution to…
valentinpalkovic Nov 25, 2025
1e80e8d
Refactor logger imports in spinner and taskLog functions
valentinpalkovic Nov 25, 2025
8e7a331
CLI: Update task and spinner methods to use stop for project detectio…
valentinpalkovic Nov 25, 2025
a3d8244
Merge pull request #33151 from storybookjs/valentin/update-clack
valentinpalkovic Nov 25, 2025
d49e25f
Write changelog for 10.1.0-beta.4 [skip ci]
storybook-bot Nov 25, 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
10 changes: 10 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 10.1.0-beta.4

- Angular: Migrate from RxJS to async/await in command builders and run Compodoc utility as spinner - [#33156](https://github.com/storybookjs/storybook/pull/33156), thanks @valentinpalkovic!
- CLI: Fix 'beforeVersion' evaluation for Storybook package - [#33141](https://github.com/storybookjs/storybook/pull/33141), thanks @valentinpalkovic!
- CLI: Update clack - [#33151](https://github.com/storybookjs/storybook/pull/33151), thanks @valentinpalkovic!
- Checklist: Data improvements - [#33129](https://github.com/storybookjs/storybook/pull/33129), thanks @ghengeveld!
- Guide: Collapse checklist items by default - [#33160](https://github.com/storybookjs/storybook/pull/33160), thanks @ghengeveld!
- React: Add isPackage flag to component imports for better package identification - [#33090](https://github.com/storybookjs/storybook/pull/33090), thanks @kasperpeulen!
- UI: Improve status handling in sidebar nodes - [#32965](https://github.com/storybookjs/storybook/pull/32965), thanks @yannbf!

## 10.1.0-beta.3

- A11y: Make search clear button keyboard accessible - [#32590](https://github.com/storybookjs/storybook/pull/32590), thanks @ritoban23!
Expand Down
5 changes: 2 additions & 3 deletions code/addons/vitest/src/manager.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';

import { Addon_TypesEnum } from 'storybook/internal/types';
import { Addon_TypesEnum, SupportedBuilder } from 'storybook/internal/types';

import {
a11yStatusStore,
Expand All @@ -23,8 +23,7 @@ import {
import { useTestProvider } from './use-test-provider-state';

addons.register(ADDON_ID, (api) => {
const storybookBuilder = (globalThis as any).STORYBOOK_BUILDER || '';
if (storybookBuilder.includes('vite')) {
if (globalThis.STORYBOOK_BUILDER === SupportedBuilder.VITE) {
const openPanel = (panelId: string) => {
api.setSelectedPanel(panelId);
api.togglePanel(true);
Expand Down
2 changes: 1 addition & 1 deletion code/addons/vitest/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
declare const BROWSER_CONFIG: object;
declare var STORYBOOK_BUILDER: string | undefined;
declare var STORYBOOK_BUILDER: import('storybook/internal/types').SupportedBuilder | undefined;

interface ImportMetaEnv {
__STORYBOOK_URL__?: string;
Expand Down
2 changes: 1 addition & 1 deletion code/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@
"@babel/parser": "^7.26.9",
"@babel/traverse": "^7.26.9",
"@babel/types": "^7.26.8",
"@clack/prompts": "1.0.0-alpha.6",
"@clack/prompts": "1.0.0-alpha.7",
"@devtools-ds/object-inspector": "^1.1.2",
"@discoveryjs/json-ext": "^0.5.3",
"@emotion/cache": "^11.14.0",
Expand Down
49 changes: 0 additions & 49 deletions code/core/src/builder-manager/utils/framework.test.ts

This file was deleted.

70 changes: 19 additions & 51 deletions code/core/src/builder-manager/utils/framework.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,27 @@
import { sep } from 'node:path';

import { extractRenderer, getFrameworkName } from 'storybook/internal/common';
import type { Options } from 'storybook/internal/types';

interface PropertyObject {
name: string;
options?: Record<string, any>;
}

type Property = string | PropertyObject | undefined;

export const pluckNameFromConfigProperty = (property: Property) => {
if (!property) {
return undefined;
}

return typeof property === 'string' ? property : property.name;
};

// For replacing Windows backslashes with forward slashes
const normalizePath = (packagePath: string) => packagePath.replaceAll(sep, '/');

export const pluckStorybookPackageFromPath = (packagePath: string) =>
normalizePath(packagePath).match(/(@storybook\/.*)$/)?.[1];

export const pluckThirdPartyPackageFromPath = (packagePath: string) =>
normalizePath(packagePath).split('node_modules/')[1] ?? packagePath;
import {
extractFrameworkPackageName,
frameworkPackages,
frameworkToRenderer,
getFrameworkName,
} from 'storybook/internal/common';
import { type Options, SupportedBuilder } from 'storybook/internal/types';

export const buildFrameworkGlobalsFromOptions = async (options: Options) => {
const globals: Record<string, any> = {};
const globals: Record<string, string | undefined> = {};

const { builder } = await options.presets.apply('core');
const builderConfig = (await options.presets.apply('core')).builder;
const builderName = typeof builderConfig === 'string' ? builderConfig : builderConfig?.name;
const builder = Object.values(SupportedBuilder).find((builder) => builderName?.includes(builder));

const frameworkName = await getFrameworkName(options);
const rendererName = await extractRenderer(frameworkName);

if (rendererName) {
globals.STORYBOOK_RENDERER = rendererName ?? undefined;
}

const resolvedPreviewBuilder = pluckNameFromConfigProperty(builder);
if (resolvedPreviewBuilder) {
globals.STORYBOOK_BUILDER =
pluckStorybookPackageFromPath(resolvedPreviewBuilder) ??
pluckThirdPartyPackageFromPath(resolvedPreviewBuilder);
}

const framework = pluckNameFromConfigProperty(await options.presets.apply('framework'));
if (framework) {
globals.STORYBOOK_FRAMEWORK = framework;
}

if (options.networkAddress) {
globals.STORYBOOK_NETWORK_ADDRESS = options.networkAddress;
}
const frameworkPackageName = extractFrameworkPackageName(frameworkName);
const framework = frameworkPackages[frameworkPackageName];
const renderer = frameworkToRenderer[framework];

globals.STORYBOOK_BUILDER = builder;
globals.STORYBOOK_FRAMEWORK = framework;
globals.STORYBOOK_RENDERER = renderer;
globals.STORYBOOK_NETWORK_ADDRESS = options.networkAddress;

return globals;
};
13 changes: 13 additions & 0 deletions code/core/src/cli/AddonVitestService.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SupportedFramework } from '../types';

export const SUPPORTED_FRAMEWORKS: readonly SupportedFramework[] = [
SupportedFramework.HTML_VITE,
SupportedFramework.NEXTJS_VITE,
SupportedFramework.PREACT_VITE,
SupportedFramework.REACT_NATIVE_WEB_VITE,
SupportedFramework.REACT_VITE,
SupportedFramework.SVELTE_VITE,
SupportedFramework.SVELTEKIT,
SupportedFramework.VUE3_VITE,
SupportedFramework.WEB_COMPONENTS_VITE,
];
16 changes: 3 additions & 13 deletions code/core/src/cli/AddonVitestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import * as find from 'empathic/find';
import { coerce, minVersion, satisfies, validRange } from 'semver';
import { dedent } from 'ts-dedent';

import { SupportedBuilder, SupportedFramework } from '../types';
import { SupportedBuilder, type SupportedFramework } from '../types';
import { SUPPORTED_FRAMEWORKS } from './AddonVitestService.constants';

type Result = {
compatible: boolean;
Expand All @@ -38,17 +39,6 @@ export interface AddonVitestCompatibilityOptions {
export class AddonVitestService {
constructor(private readonly packageManager: JsPackageManager) {}

readonly supportedFrameworks: SupportedFramework[] = [
SupportedFramework.HTML_VITE,
SupportedFramework.NEXTJS_VITE,
SupportedFramework.PREACT_VITE,
SupportedFramework.REACT_NATIVE_WEB_VITE,
SupportedFramework.REACT_VITE,
SupportedFramework.SVELTE_VITE,
SupportedFramework.SVELTEKIT,
SupportedFramework.VUE3_VITE,
SupportedFramework.WEB_COMPONENTS_VITE,
];
/**
* Collect all dependencies needed for @storybook/addon-vitest
*
Expand Down Expand Up @@ -196,7 +186,7 @@ export class AddonVitestService {
}

// Check renderer/framework support
const isFrameworkSupported = this.supportedFrameworks.some(
const isFrameworkSupported = SUPPORTED_FRAMEWORKS.some(
(framework) => options.framework === framework
);

Expand Down
5 changes: 4 additions & 1 deletion code/core/src/common/js-package-manager/BUNProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ export class BUNProxy extends JsPackageManager {

public async getModulePackageJSON(packageName: string): Promise<PackageJson | null> {
const wantedPath = join('node_modules', packageName, 'package.json');
const packageJsonPath = find.up(wantedPath, { cwd: this.cwd, last: getProjectRoot() });
const packageJsonPath = find.up(wantedPath, {
cwd: this.primaryPackageJson.operationDir,
last: getProjectRoot(),
});

if (!packageJsonPath) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export abstract class JsPackageManager {
abstract getRunCommand(command: string): string;

/** Get the package.json file for a given module. */
abstract getModulePackageJSON(packageName: string): Promise<PackageJson | null>;
abstract getModulePackageJSON(packageName: string, cwd?: string): Promise<PackageJson | null>;

isStorybookInMonorepo() {
const turboJsonPath = find.up(`turbo.json`, { last: getProjectRoot() });
Expand Down
5 changes: 4 additions & 1 deletion code/core/src/common/js-package-manager/NPMProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ export class NPMProxy extends JsPackageManager {

async getModulePackageJSON(packageName: string): Promise<PackageJson | null> {
const wantedPath = join('node_modules', packageName, 'package.json');
const packageJsonPath = find.up(wantedPath, { cwd: this.cwd, last: getProjectRoot() });
const packageJsonPath = find.up(wantedPath, {
cwd: this.primaryPackageJson.operationDir,
last: getProjectRoot(),
});

if (!packageJsonPath) {
return null;
Expand Down
5 changes: 4 additions & 1 deletion code/core/src/common/js-package-manager/PNPMProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,10 @@ export class PNPMProxy extends JsPackageManager {
}

const wantedPath = join('node_modules', packageName, 'package.json');
const packageJsonPath = find.up(wantedPath, { cwd: this.cwd, last: getProjectRoot() });
const packageJsonPath = find.up(wantedPath, {
cwd: this.primaryPackageJson.operationDir,
last: getProjectRoot(),
});

if (!packageJsonPath) {
return null;
Expand Down
5 changes: 4 additions & 1 deletion code/core/src/common/js-package-manager/Yarn1Proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ export class Yarn1Proxy extends JsPackageManager {

public async getModulePackageJSON(packageName: string): Promise<PackageJson | null> {
const wantedPath = join('node_modules', packageName, 'package.json');
const packageJsonPath = find.up(wantedPath, { cwd: this.cwd, last: getProjectRoot() });
const packageJsonPath = find.up(wantedPath, {
cwd: this.primaryPackageJson.operationDir,
last: getProjectRoot(),
});

if (!packageJsonPath) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/common/js-package-manager/Yarn2Proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class Yarn2Proxy extends JsPackageManager {
// TODO: Remove pnp compatibility code in SB11
async getModulePackageJSON(packageName: string): Promise<PackageJson | null> {
const pnpapiPath = find.any(['.pnp.js', '.pnp.cjs'], {
cwd: this.cwd,
cwd: this.primaryPackageJson.operationDir,
last: getProjectRoot(),
});

Expand Down
20 changes: 0 additions & 20 deletions code/core/src/common/utils/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import uniqueString from 'unique-string';
import type { JsPackageManager } from '../js-package-manager';
import satelliteAddons from '../satellite-addons';
import storybookPackagesVersions from '../versions';
import { rendererPackages } from './get-storybook-info';

const tempDir = () => realpath(os.tmpdir());

Expand Down Expand Up @@ -67,25 +66,6 @@ export function parseList(str: string): string[] {
.filter((item) => item.length > 0);
}

/**
* Given a package manager, returns the coerced version of Storybook. It tries to find renderer
* packages in the project and returns the coerced version of the first one found. Example: If
*
* @storybook/react version 8.0.0-alpha.14 is installed, it returns the coerced version 8.0.0
*/
export async function getCoercedStorybookVersion(packageManager: JsPackageManager) {
const packages = (
await Promise.all(
Object.keys(rendererPackages).map(async (pkg) => ({
name: pkg,
version: (await packageManager.getModulePackageJSON(pkg))?.version ?? null,
}))
)
).filter(({ version }) => !!version);

return packages[0]?.version || storybookPackagesVersions.storybook;
}

export function getEnvConfig(program: Record<string, any>, configEnv: Record<string, any>): void {
Object.keys(configEnv).forEach((fieldName) => {
const envVarName = configEnv[fieldName];
Expand Down
6 changes: 3 additions & 3 deletions code/core/src/common/utils/get-storybook-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,12 @@ export const getStorybookInfo = async (
const frameworkValue = mainConfig.framework;
const frameworkField = typeof frameworkValue === 'string' ? frameworkValue : frameworkValue?.name;
const addons = getAddonNames(mainConfig);
const version = getStorybookVersionSpecifier(configDir);
const versionSpecifier = getStorybookVersionSpecifier(configDir);

if (!frameworkField) {
return {
...configInfo,
version,
versionSpecifier,
addons,
mainConfig,
mainConfigPath: configInfo.mainConfigPath ?? undefined,
Expand Down Expand Up @@ -183,7 +183,7 @@ export const getStorybookInfo = async (
addons,
mainConfig,
framework,
version,
versionSpecifier,
renderer: renderer ?? undefined,
builder: builder ?? undefined,
frameworkPackage,
Expand Down
6 changes: 3 additions & 3 deletions code/core/src/manager-api/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ declare var REFS: any;
declare var VERSIONCHECK: any;
declare var LOGLEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent' | undefined;
declare var STORYBOOK_ADDON_STATE: Record<string, any>;
declare var STORYBOOK_RENDERER: string | undefined;
declare var STORYBOOK_BUILDER: string | undefined;
declare var STORYBOOK_FRAMEWORK: string | undefined;
declare var STORYBOOK_FRAMEWORK: import('storybook/internal/types').SupportedFramework | undefined;
declare var STORYBOOK_RENDERER: import('storybook/internal/types').SupportedRenderer | undefined;
declare var STORYBOOK_BUILDER: import('storybook/internal/types').SupportedBuilder | undefined;
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const meta = preview.meta({
...initialState.items,
controls: { status: 'accepted' },
renderComponent: { status: 'done' },
installVitest: { status: 'done' },
moreComponents: { status: 'skipped' },
moreStories: { status: 'skipped' },
},
Expand All @@ -57,6 +58,7 @@ const play: PlayFunction = async ({ step }) => {
...initialState.items,
controls: { status: 'accepted' },
renderComponent: { status: 'done' },
installVitest: { status: 'done' },
viewports: { status: 'done' },
moreComponents: { status: 'skipped' },
moreStories: { status: 'skipped' },
Expand All @@ -73,10 +75,11 @@ const play: PlayFunction = async ({ step }) => {
...initialState.items,
controls: { status: 'accepted' },
renderComponent: { status: 'done' },
installVitest: { status: 'done' },
viewports: { status: 'done' },
moreComponents: { status: 'skipped' },
moreStories: { status: 'skipped' },
installVitest: { status: 'skipped' },
writeInteractions: { status: 'skipped' },
},
});
});
Expand Down
Loading
Loading