Merge branch 'next' into cli/improve-sb-add-messages

This commit is contained in:
Gert Hengeveld 2024-09-02 17:40:59 +02:00
commit 253623a47a
51 changed files with 184 additions and 112 deletions

View File

@ -91,7 +91,7 @@ const config: StorybookConfig = {
'@storybook/addon-interactions',
'@storybook/addon-storysource',
'@storybook/addon-designs',
'@storybook/experimental-addon-vitest',
'@storybook/experimental-addon-test',
'@storybook/addon-a11y',
'@chromatic-com/storybook',
],

View File

@ -21,7 +21,7 @@ export default mergeConfig(
vitestCommonConfig,
defineProject({
plugins: [
import('@storybook/experimental-addon-vitest/plugin').then(({ storybookTest }) =>
import('@storybook/experimental-addon-test/vite-plugin').then(({ storybookTest }) =>
storybookTest({
configDir: process.cwd(),
})

View File

@ -6,18 +6,17 @@ import { useGlobals, useParameter } from 'storybook/internal/manager-api';
import { CircleIcon, GridIcon, PhotoIcon, RefreshIcon } from '@storybook/icons';
import { PARAM_KEY as KEY } from '../constants';
import { DEFAULT_BACKGROUNDS } from '../defaults';
import type { Background, BackgroundMap, Config, GlobalStateUpdate } from '../types';
type Link = Parameters<typeof TooltipLinkList>['0']['links'][0];
const emptyBackgroundMap: BackgroundMap = {};
export const BackgroundTool = memo(function BackgroundSelector() {
const config = useParameter<Config>(KEY);
const [globals, updateGlobals, storyGlobals] = useGlobals();
const [isTooltipVisible, setIsTooltipVisible] = useState(false);
const { options = emptyBackgroundMap, disable = true } = config || {};
const { options = DEFAULT_BACKGROUNDS, disable = true } = config || {};
if (disable) {
return null;
}

View File

@ -6,6 +6,7 @@ import type {
} from 'storybook/internal/types';
import { PARAM_KEY as KEY } from './constants';
import { DEFAULT_BACKGROUNDS } from './defaults';
import type { Config, GridConfig } from './types';
import { addBackgroundStyle, addGridStyle, clearStyles, isReduceMotionEnabled } from './utils';
@ -25,7 +26,11 @@ export const withBackgroundAndGrid = (
context: StoryContext<Renderer>
) => {
const { globals, parameters, viewMode, id } = context;
const { options = {}, disable, grid = defaultGrid } = (parameters[KEY] || {}) as Config;
const {
options = DEFAULT_BACKGROUNDS,
disable,
grid = defaultGrid,
} = (parameters[KEY] || {}) as Config;
const data = globals[KEY] || {};
const backgroundName: string | undefined = data.value;

View File

@ -0,0 +1,6 @@
import type { BackgroundMap } from './types';
export const DEFAULT_BACKGROUNDS: BackgroundMap = {
light: { name: 'light', value: '#F8F8F8' },
dark: { name: 'dark', value: '#333' },
};

View File

@ -2,6 +2,7 @@ import type { Addon_DecoratorFunction } from 'storybook/internal/types';
import { PARAM_KEY as KEY } from './constants';
import { withBackgroundAndGrid } from './decorator';
import { DEFAULT_BACKGROUNDS } from './defaults';
import { withBackground } from './legacy/withBackgroundLegacy';
import { withGrid } from './legacy/withGridLegacy';
import type { Config, GlobalState } from './types';
@ -18,20 +19,10 @@ export const parameters = {
cellAmount: 5,
},
disable: false,
...(FEATURES?.backgroundsStoryGlobals
? {
options: {
light: { name: 'light', value: '#F8F8F8' },
dark: { name: 'dark', value: '#333' },
},
}
: {
// TODO: remove in 9.0
values: [
{ name: 'light', value: '#F8F8F8' },
{ name: 'dark', value: '#333333' },
],
}),
// TODO: remove in 9.0
...(!FEATURES?.backgroundsStoryGlobals && {
values: Object.values(DEFAULT_BACKGROUNDS),
}),
} satisfies Partial<Config>,
};

View File

@ -1,10 +1,10 @@
{
"name": "@storybook/experimental-addon-vitest",
"name": "@storybook/experimental-addon-test",
"version": "8.3.0-beta.1",
"description": "Integrate Vitest with Storybook",
"keywords": [
"storybook-addons",
"addon-vitest",
"addon-test",
"vitest",
"testing"
],
@ -29,7 +29,7 @@
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./plugin": {
"./vite-plugin": {
"types": "./dist/plugin/index.d.ts",
"import": "./dist/plugin/index.js",
"require": "./dist/plugin/index.cjs"

View File

@ -1,5 +1,5 @@
{
"name": "vitest",
"name": "addon-test",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"targets": {

View File

@ -0,0 +1,9 @@
import type { storybookTest as storybookTestImport } from './plugin';
// make it work with --isolatedModules
export default {};
// @ts-expect-error - this is a hack to make the module's sub-path augmentable
declare module '@storybook/experimental-addon-test/vite-plugin' {
export const storybookTest: typeof storybookTestImport;
}

View File

@ -113,7 +113,7 @@ export const storybookTest = (options?: UserOptions): Plugin => {
if (typeof config.test.setupFiles === 'string') {
config.test.setupFiles = [config.test.setupFiles];
}
config.test.setupFiles.push('@storybook/experimental-addon-vitest/internal/setup-file');
config.test.setupFiles.push('@storybook/experimental-addon-test/internal/setup-file');
// when a Storybook script is provided, we spawn Storybook for the user when in watch mode
if (finalOptions.storybookScript) {
@ -121,14 +121,14 @@ export const storybookTest = (options?: UserOptions): Plugin => {
if (typeof config.test.globalSetup === 'string') {
config.test.globalSetup = [config.test.globalSetup];
}
config.test.globalSetup.push('@storybook/experimental-addon-vitest/internal/global-setup');
config.test.globalSetup.push('@storybook/experimental-addon-test/internal/global-setup');
}
config.test.server ??= {};
config.test.server.deps ??= {};
config.test.server.deps.inline ??= [];
if (Array.isArray(config.test.server.deps.inline)) {
config.test.server.deps.inline.push('@storybook/experimental-addon-vitest');
config.test.server.deps.inline.push('@storybook/experimental-addon-test');
}
},
async transform(code, id) {

View File

@ -159,10 +159,17 @@ export default async function postInstall(options: PostinstallOptions) {
dedent`
It looks like you're using Next.js.
I'll add the ${colors.pink.bold(`vite-plugin-storybook-nextjs`)} plugin so you can use it with Vitest.
I'll add ${colors.pink.bold(`@storybook/experimental-nextjs-vite/vite-plugin`)} so you can use it with Vitest.
`
);
dependencies.push('vite-plugin-storybook-nextjs');
try {
const storybookVersion = await packageManager.getInstalledVersion('storybook');
dependencies.push(`@storybook/experimental-nextjs-vite@^${storybookVersion}`);
} catch (e) {
console.error(
'Failed to install @storybook/experimental-nextjs-vite. Please install it manually'
);
}
}
logger.line(1);
@ -240,7 +247,7 @@ export default async function postInstall(options: PostinstallOptions) {
browserWorkspaceFile,
dedent`
import { defineWorkspace } from 'vitest/config';
import { storybookTest } from '@storybook/experimental-addon-vitest/plugin';
import { storybookTest } from '@storybook/experimental-addon-test/vite-plugin';
${vitestInfo.frameworkPluginImport ? vitestInfo.frameworkPluginImport + '\n' : ''}
// More info at: https://storybook.js.org/docs/writing-tests/test-runner-with-vitest
@ -249,7 +256,7 @@ export default async function postInstall(options: PostinstallOptions) {
{
extends: '${viteConfig ? relative(dirname(browserWorkspaceFile), viteConfig) : ''}',
plugins: [
storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall : ''}
storybookTest(),${vitestInfo.frameworkPluginCall ? '\n ' + vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall : ''}
],
test: {
name: 'storybook',
@ -277,13 +284,13 @@ export default async function postInstall(options: PostinstallOptions) {
'vitest.config.ts',
dedent`
import { defineConfig } from "vitest/config";
import { storybookTest } from "@storybook/experimental-addon-vitest/plugin";
import { storybookTest } from "@storybook/experimental-addon-test/vite-plugin";
${vitestInfo.frameworkPluginImport ? vitestInfo.frameworkPluginImport + '\n' : ''}
// More info at: https://storybook.js.org/docs/writing-tests/test-runner-with-vitest
export default defineConfig({
plugins: [
storybookTest(),${vitestInfo.frameworkPluginCall ? '\n' + vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall : ''}
storybookTest(),${vitestInfo.frameworkPluginCall ? '\n ' + vitestInfo.frameworkPluginDocs + vitestInfo.frameworkPluginCall : ''}
],
test: {
browser: {
@ -318,19 +325,21 @@ const getVitestPluginInfo = (framework: string) => {
let frameworkPluginDocs = '';
if (framework === '@storybook/nextjs') {
frameworkPluginImport = "import vitePluginNext from 'vite-plugin-storybook-nextjs'";
frameworkPluginCall = 'vitePluginNext()';
frameworkPluginImport =
"import { storybookNextJsPlugin } from '@storybook/experimental-nextjs-vite/vite-plugin'";
frameworkPluginCall = 'storybookNextJsPlugin()';
frameworkPluginDocs =
'// More info at: https://github.com/storybookjs/vite-plugin-storybook-nextjs\n';
'// More info at: https://github.com/storybookjs/vite-plugin-storybook-nextjs\n ';
}
if (framework === '@storybook/sveltekit') {
frameworkPluginImport = "import { storybookSveltekitPlugin } from '@storybook/sveltekit/vite'";
frameworkPluginImport =
"import { storybookSveltekitPlugin } from '@storybook/sveltekit/vite-plugin'";
frameworkPluginCall = 'storybookSveltekitPlugin()';
}
if (framework === '@storybook/vue3-vite') {
frameworkPluginImport = "import { storybookVuePlugin } from '@storybook/vue3-vite/vite'";
frameworkPluginImport = "import { storybookVuePlugin } from '@storybook/vue3-vite/vite-plugin'";
frameworkPluginCall = 'storybookVuePlugin()';
}

View File

@ -7,15 +7,15 @@ import { Global } from 'storybook/internal/theming';
import { GrowIcon, RefreshIcon, TransferIcon } from '@storybook/icons';
import { PARAM_KEY as KEY } from '../constants';
import { MINIMAL_VIEWPORTS } from '../defaults';
import { responsiveViewport } from '../responsiveViewport';
import { registerShortcuts } from '../shortcuts';
import type { Config, GlobalState, GlobalStateUpdate, Viewport, ViewportMap } from '../types';
import type { Config, GlobalStateUpdate, Viewport, ViewportMap } from '../types';
import {
ActiveViewportLabel,
ActiveViewportSize,
IconButtonLabel,
IconButtonWithLabel,
emptyViewportMap,
iconsMap,
} from '../utils';
@ -39,7 +39,7 @@ export const ViewportTool: FC<{ api: API }> = ({ api }) => {
const [globals, updateGlobals, storyGlobals] = useGlobals();
const [isTooltipVisible, setIsTooltipVisible] = useState(false);
const { options = emptyViewportMap, disable } = config || {};
const { options = MINIMAL_VIEWPORTS, disable } = config || {};
const data = globals?.[KEY] || {};
const viewportName: string = data.value;
const isRotated: boolean = data.isRotated;

View File

@ -10,11 +10,3 @@ const modern: Record<string, GlobalState> = {
const legacy = { viewport: 'reset', viewportRotated: false };
export const initialGlobals = FEATURES?.viewportStoryGlobals ? modern : legacy;
export const parameters = FEATURES?.viewportStoryGlobals
? {
[KEY]: {
options: MINIMAL_VIEWPORTS,
},
}
: {};

View File

@ -42,5 +42,3 @@ export const iconsMap: Record<Viewport['type'], React.ReactNode> = {
tablet: <TabletIcon />,
other: <Fragment />,
};
export const emptyViewportMap: ViewportMap = {};

View File

@ -1,2 +0,0 @@
// make it work with --isolatedModules
export default {};

View File

@ -15,10 +15,10 @@ export default {
'@storybook/addon-onboarding': '8.3.0-beta.1',
'@storybook/addon-outline': '8.3.0-beta.1',
'@storybook/addon-storysource': '8.3.0-beta.1',
'@storybook/experimental-addon-test': '8.3.0-beta.1',
'@storybook/addon-themes': '8.3.0-beta.1',
'@storybook/addon-toolbars': '8.3.0-beta.1',
'@storybook/addon-viewport': '8.3.0-beta.1',
'@storybook/experimental-addon-vitest': '8.3.0-beta.1',
'@storybook/builder-vite': '8.3.0-beta.1',
'@storybook/builder-webpack5': '8.3.0-beta.1',
'@storybook/core': '8.3.0-beta.1',

View File

@ -73,7 +73,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
component: Button,
title: "automatic/calculated/title"
@ -102,7 +102,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
title: "automatic/calculated/title",
component: Button
@ -132,7 +132,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const meta = {
component: Button,
title: "automatic/calculated/title"
@ -163,7 +163,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const meta = {
title: "automatic/calculated/title",
component: Button
@ -195,7 +195,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
component: Button,
title: "automatic/calculated/title"
@ -229,7 +229,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
title: "automatic/calculated/title"
};
@ -264,7 +264,7 @@ describe('transformer', () => {
const result = await transform({ code });
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
title: "automatic/calculated/title"
};
@ -299,7 +299,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
title: "automatic/calculated/title",
component: Button,
@ -356,7 +356,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
title: "automatic/calculated/title"
};
@ -387,7 +387,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
title: "automatic/calculated/title"
};
@ -416,7 +416,7 @@ describe('transformer', () => {
expect(result.code).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const _meta = {
title: "automatic/calculated/title"
};
@ -449,7 +449,7 @@ describe('transformer', () => {
expect(transformedCode).toMatchInlineSnapshot(`
import { test as _test, expect as _expect } from "vitest";
import { testStory as _testStory } from "@storybook/experimental-addon-vitest/internal/test-utils";
import { testStory as _testStory } from "@storybook/experimental-addon-test/internal/test-utils";
const meta = {
title: "automatic/calculated/title",
component: Button

View File

@ -260,7 +260,7 @@ export async function vitestTransform({
),
t.importDeclaration(
[t.importSpecifier(testStoryId, t.identifier('testStory'))],
t.stringLiteral('@storybook/experimental-addon-vitest/internal/test-utils')
t.stringLiteral('@storybook/experimental-addon-test/internal/test-utils')
),
];

View File

@ -53,6 +53,11 @@
"import": "./dist/export-mocks/router/index.mjs",
"require": "./dist/export-mocks/router/index.js"
},
"./vite-plugin": {
"types": "./dist/vite-plugin/index.d.ts",
"import": "./dist/vite-plugin/index.js",
"require": "./dist/vite-plugin/index.cjs"
},
"./package.json": "./package.json"
},
"main": "dist/index.js",
@ -93,21 +98,20 @@
"@storybook/builder-vite": "workspace:*",
"@storybook/react": "workspace:*",
"@storybook/test": "workspace:*",
"styled-jsx": "5.1.6"
"styled-jsx": "5.1.6",
"vite-plugin-storybook-nextjs": "^1.0.10"
},
"devDependencies": {
"@types/node": "^18.0.0",
"next": "^14.2.5",
"typescript": "^5.3.2",
"vite-plugin-storybook-nextjs": "^1.0.0"
"typescript": "^5.3.2"
},
"peerDependencies": {
"next": "^14.1.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
"storybook": "workspace:^",
"vite": "^5.0.0",
"vite-plugin-storybook-nextjs": "^1.0.8"
"vite": "^5.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@ -126,6 +130,7 @@
"bundler": {
"entries": [
"./src/index.ts",
"./src/vite-plugin/index.ts",
"./src/preset.ts",
"./src/preview.tsx",
"./src/export-mocks/cache/index.ts",

View File

@ -1,2 +1,10 @@
import type vitePluginStorybookNextJs from 'vite-plugin-storybook-nextjs';
export * from './types';
export * from './portable-stories';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
declare module '@storybook/experimental-nextjs-vite/vite-plugin' {
export const storybookNextJsPlugin: typeof vitePluginStorybookNextJs;
}

View File

@ -6,7 +6,6 @@ import type { PresetProperty } from 'storybook/internal/types';
import type { StorybookConfigVite } from '@storybook/builder-vite';
import { dirname, join } from 'path';
// @ts-expect-error - tsconfig settings have to be moduleResolution=Bundler and module=Preserve
import vitePluginStorybookNextjs from 'vite-plugin-storybook-nextjs';
import type { FrameworkOptions } from './types';

View File

@ -0,0 +1,3 @@
import vitePluginStorybookNextJs from 'vite-plugin-storybook-nextjs';
export const storybookNextJsPlugin = vitePluginStorybookNextJs;

View File

@ -36,10 +36,10 @@
"types": "./dist/preset.d.ts",
"require": "./dist/preset.js"
},
"./vite": {
"types": "./dist/vite.d.ts",
"require": "./dist/vite.js",
"import": "./dist/vite.mjs"
"./vite-plugin": {
"types": "./dist/vite-plugin.d.ts",
"require": "./dist/vite-plugin.js",
"import": "./dist/vite-plugin.mjs"
},
"./package.json": "./package.json"
},
@ -84,7 +84,7 @@
"./src/index.ts",
"./src/preview.ts",
"./src/preset.ts",
"./src/vite.ts"
"./src/vite-plugin.ts"
],
"platform": "node"
},

View File

@ -30,10 +30,10 @@
"types": "./dist/preset.d.ts",
"require": "./dist/preset.js"
},
"./vite": {
"types": "./dist/vite.d.ts",
"require": "./dist/vite.js",
"import": "./dist/vite.mjs"
"./vite-plugin": {
"types": "./dist/vite-plugin.d.ts",
"require": "./dist/vite-plugin.js",
"import": "./dist/vite-plugin.mjs"
},
"./package.json": "./package.json"
},
@ -80,7 +80,7 @@
"entries": [
"./src/index.ts",
"./src/preset.ts",
"./src/vite.ts"
"./src/vite-plugin.ts"
],
"platform": "node"
},

View File

@ -1,10 +1,13 @@
import { describe, expect, test, vi } from 'vitest';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import { add, getVersionSpecifier } from './add';
const MockedConfig = vi.hoisted(() => {
return {
appendValueToArray: vi.fn(),
getFieldNode: vi.fn(),
valueToNode: vi.fn(),
appendNodeToArray: vi.fn(),
};
});
const MockedPackageManager = vi.hoisted(() => {
@ -20,6 +23,12 @@ const MockedPostInstall = vi.hoisted(() => {
postinstallAddon: vi.fn(),
};
});
const MockWrapRequireUtils = vi.hoisted(() => {
return {
getRequireWrapperName: vi.fn(),
wrapValueWithRequireWrapper: vi.fn(),
};
});
const MockedConsole = {
log: vi.fn(),
warn: vi.fn(),
@ -35,6 +44,9 @@ vi.mock('storybook/internal/csf-tools', () => {
vi.mock('./postinstallAddon', () => {
return MockedPostInstall;
});
vi.mock('./automigrate/fixes/wrap-require-utils', () => {
return MockWrapRequireUtils;
});
vi.mock('storybook/internal/common', () => {
return {
getStorybookInfo: vi.fn(() => ({ mainConfig: {}, configDir: '' })),
@ -103,6 +115,35 @@ describe('add', () => {
});
describe('add (extra)', () => {
beforeEach(() => {
vi.clearAllMocks();
});
test('should not add a "wrap require" to the addon when not needed', async () => {
MockedConfig.getFieldNode.mockReturnValue({});
MockWrapRequireUtils.getRequireWrapperName.mockReturnValue(null);
await add(
'@storybook/addon-docs',
{ packageManager: 'npm', skipPostinstall: true },
MockedConsole
);
expect(MockWrapRequireUtils.wrapValueWithRequireWrapper).not.toHaveBeenCalled();
expect(MockedConfig.appendValueToArray).toHaveBeenCalled();
expect(MockedConfig.appendNodeToArray).not.toHaveBeenCalled();
});
test('should add a "wrap require" to the addon when applicable', async () => {
MockedConfig.getFieldNode.mockReturnValue({});
MockWrapRequireUtils.getRequireWrapperName.mockReturnValue('require');
await add(
'@storybook/addon-docs',
{ packageManager: 'npm', skipPostinstall: true },
MockedConsole
);
expect(MockWrapRequireUtils.wrapValueWithRequireWrapper).toHaveBeenCalled();
expect(MockedConfig.appendValueToArray).not.toHaveBeenCalled();
expect(MockedConfig.appendNodeToArray).toHaveBeenCalled();
});
test('not warning when installing the correct version of storybook', async () => {
await add(
'@storybook/addon-docs',

View File

@ -13,6 +13,10 @@ import { readConfig, writeConfig } from 'storybook/internal/csf-tools';
import SemVer from 'semver';
import { dedent } from 'ts-dedent';
import {
getRequireWrapperName,
wrapValueWithRequireWrapper,
} from './automigrate/fixes/wrap-require-utils';
import { postinstallAddon } from './postinstallAddon';
export interface PostinstallOptions {
@ -136,8 +140,17 @@ export async function add(
logger.log(`Installing ${addonWithVersion}`);
await packageManager.addDependencies({ installAsDevDependencies: true }, [addonWithVersion]);
logger.log(`Adding '${addon}' to the addons field in ${mainConfig}.`);
main.appendValueToArray(['addons'], addonName);
logger.log(`Adding '${addon}' to the "addons" field in ${mainConfig}`);
const mainConfigAddons = main.getFieldNode(['addons']);
if (mainConfigAddons && getRequireWrapperName(main) !== null) {
const addonNode = main.valueToNode(addonName);
main.appendNodeToArray(['addons'], addonNode as any);
wrapValueWithRequireWrapper(main, addonNode as any);
} else {
main.appendValueToArray(['addons'], addonName);
}
await writeConfig(main);
if (!skipPostinstall && isCoreAddon(addonName)) {

View File

@ -216,12 +216,7 @@ const baseTemplates = {
framework: '@storybook/experimental-nextjs-vite',
features: { experimentalRSC: true },
},
extraDependencies: [
'server-only',
'vite-plugin-storybook-nextjs',
'@storybook/experimental-nextjs-vite',
'vite',
],
extraDependencies: ['server-only', '@storybook/experimental-nextjs-vite', 'vite'],
},
skipTasks: ['e2e-tests-dev', 'bench'],
},

View File

@ -126,7 +126,7 @@
"@storybook/csf-plugin": "workspace:*",
"@storybook/ember": "workspace:*",
"@storybook/eslint-config-storybook": "^4.0.0",
"@storybook/experimental-addon-vitest": "workspace:*",
"@storybook/experimental-addon-test": "workspace:*",
"@storybook/global": "^5.0.0",
"@storybook/html": "workspace:*",
"@storybook/html-vite": "workspace:*",

View File

@ -6126,9 +6126,9 @@ __metadata:
languageName: node
linkType: hard
"@storybook/experimental-addon-vitest@workspace:*, @storybook/experimental-addon-vitest@workspace:addons/vitest":
"@storybook/experimental-addon-test@workspace:*, @storybook/experimental-addon-test@workspace:addons/test":
version: 0.0.0-use.local
resolution: "@storybook/experimental-addon-vitest@workspace:addons/vitest"
resolution: "@storybook/experimental-addon-test@workspace:addons/test"
dependencies:
"@storybook/csf": "npm:^0.1.11"
"@types/semver": "npm:^7"
@ -6158,14 +6158,13 @@ __metadata:
sharp: "npm:^0.33.3"
styled-jsx: "npm:5.1.6"
typescript: "npm:^5.3.2"
vite-plugin-storybook-nextjs: "npm:^1.0.0"
vite-plugin-storybook-nextjs: "npm:^1.0.10"
peerDependencies:
next: ^14.1.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
storybook: "workspace:^"
vite: ^5.0.0
vite-plugin-storybook-nextjs: ^1.0.8
dependenciesMeta:
sharp:
optional: true
@ -6723,7 +6722,7 @@ __metadata:
"@storybook/csf-plugin": "workspace:*"
"@storybook/ember": "workspace:*"
"@storybook/eslint-config-storybook": "npm:^4.0.0"
"@storybook/experimental-addon-vitest": "workspace:*"
"@storybook/experimental-addon-test": "workspace:*"
"@storybook/global": "npm:^5.0.0"
"@storybook/html": "workspace:*"
"@storybook/html-vite": "workspace:*"
@ -28427,9 +28426,9 @@ __metadata:
languageName: node
linkType: hard
"vite-plugin-storybook-nextjs@npm:^1.0.0":
version: 1.0.0
resolution: "vite-plugin-storybook-nextjs@npm:1.0.0"
"vite-plugin-storybook-nextjs@npm:^1.0.10":
version: 1.0.10
resolution: "vite-plugin-storybook-nextjs@npm:1.0.10"
dependencies:
"@next/env": "npm:^14.2.5"
image-size: "npm:^1.1.1"
@ -28439,13 +28438,13 @@ __metadata:
ts-dedent: "npm:^2.2.0"
peerDependencies:
"@storybook/test": ^8.3.0-alpha.3
next: ^14.2.5
next: ^14.1.0
storybook: ^8.3.0-alpha.3
vite: ^5.0.0
dependenciesMeta:
sharp:
optional: true
checksum: 10c0/6ca17326e0387044d7bfa4373e6ccb64e8bb5bec1f19898ba9b8338c7817d8bea0fb01169adfb623f652fded5e6f59170129f7c8c4d4c3c54ca3764727e5a195
checksum: 10c0/e0e373ef94e1761b871b2cc846c205a846901d93c7e61f9d9ee3c69740681e42e6403a7d61109c59f2d98d5829476c3e6d4e9d5a329c4bd51e758b763fa8ea9e
languageName: node
linkType: hard

View File

@ -28,7 +28,7 @@ sidebar:
<If renderer="react">
<Callout variant="warning">
**Using `Next.js`?** You can test your Next.js stories with Vitest by installing and setting up the [`vite-plugin-storybook-nextjs`](https://github.com/storybookjs/vite-plugin-storybook-nextjs) package.
**Using `Next.js`?** You can test your Next.js stories with Vitest by installing and setting up the `@storybook/experimental-nextjs-vite` which re-exports [vite-plugin-storybook-nextjs](https://github.com/storybookjs/vite-plugin-storybook-nextjs) package.
</Callout>
</If>

View File

@ -369,17 +369,19 @@ const getVitestPluginInfo = (details: TemplateDetails) => {
const isSveltekit = framework.includes('sveltekit');
if (isNextjs) {
frameworkPluginImport = "import vitePluginNext from 'vite-plugin-storybook-nextjs'";
frameworkPluginCall = 'vitePluginNext()';
frameworkPluginImport =
"import { storybookNextJsPlugin } from '@storybook/experimental-nextjs-vite/vite-plugin'";
frameworkPluginCall = 'storybookNextJsPlugin()';
}
if (isSveltekit) {
frameworkPluginImport = "import { storybookSveltekitPlugin } from '@storybook/sveltekit/vite'";
frameworkPluginImport =
"import { storybookSveltekitPlugin } from '@storybook/sveltekit/vite-plugin'";
frameworkPluginCall = 'storybookSveltekitPlugin()';
}
if (framework === '@storybook/vue3-vite') {
frameworkPluginImport = "import { storybookVuePlugin } from '@storybook/vue3-vite/vite'";
frameworkPluginImport = "import { storybookVuePlugin } from '@storybook/vue3-vite/vite-plugin'";
frameworkPluginCall = 'storybookVuePlugin()';
}
@ -435,7 +437,7 @@ export async function setupVitest(details: TemplateDetails, options: PassedOptio
join(sandboxDir, 'vitest.workspace.ts'),
dedent`
import { defineWorkspace, defaultExclude } from "vitest/config";
import { storybookTest } from "@storybook/experimental-addon-vitest/plugin";
import { storybookTest } from "@storybook/experimental-addon-test/vite-plugin";
${frameworkPluginImport}
export default defineWorkspace([
@ -513,7 +515,7 @@ export async function setupVitest(details: TemplateDetails, options: PassedOptio
const vitestAddonPath = relative(sandboxDir, join(CODE_DIRECTORY, 'addons', 'vitest'));
packageJson.resolutions = {
...packageJson.resolutions,
'@storybook/experimental-addon-vitest': `file:${vitestAddonPath}`,
'@storybook/experimental-addon-test': `file:${vitestAddonPath}`,
};
}

View File

@ -94,11 +94,11 @@ export const sandbox: Task = {
'vitest',
'playwright',
'@vitest/browser',
'@storybook/experimental-addon-vitest'
'@storybook/experimental-addon-test'
);
if (details.template.expected.framework.includes('nextjs')) {
extraDeps.push('vite-plugin-storybook-nextjs', 'jsdom');
extraDeps.push('@storybook/experimental-nextjs-vite', 'jsdom');
}
// if (details.template.expected.renderer === '@storybook/svelte') {