mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-09 00:19:13 +08:00
Merge branch 'next' into cli/improve-sb-add-messages
This commit is contained in:
commit
253623a47a
@ -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',
|
||||
],
|
||||
|
@ -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(),
|
||||
})
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
6
code/addons/backgrounds/src/defaults.ts
Normal file
6
code/addons/backgrounds/src/defaults.ts
Normal 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' },
|
||||
};
|
@ -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>,
|
||||
};
|
||||
|
||||
|
@ -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"
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "vitest",
|
||||
"name": "addon-test",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "library",
|
||||
"targets": {
|
9
code/addons/test/src/index.ts
Normal file
9
code/addons/test/src/index.ts
Normal 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;
|
||||
}
|
@ -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) {
|
@ -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()';
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
: {};
|
||||
|
@ -42,5 +42,3 @@ export const iconsMap: Record<Viewport['type'], React.ReactNode> = {
|
||||
tablet: <TabletIcon />,
|
||||
other: <Fragment />,
|
||||
};
|
||||
|
||||
export const emptyViewportMap: ViewportMap = {};
|
||||
|
@ -1,2 +0,0 @@
|
||||
// make it work with --isolatedModules
|
||||
export default {};
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -0,0 +1,3 @@
|
||||
import vitePluginStorybookNextJs from 'vite-plugin-storybook-nextjs';
|
||||
|
||||
export const storybookNextJsPlugin = vitePluginStorybookNextJs;
|
@ -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"
|
||||
},
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -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',
|
||||
|
@ -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)) {
|
||||
|
@ -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'],
|
||||
},
|
||||
|
@ -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:*",
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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}`,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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') {
|
||||
|
Loading…
x
Reference in New Issue
Block a user