Skip to content

Commit e266b17

Browse files
authored
Merge pull request #29590 from storybookjs/version-patch-from-8.4.2
Release: Patch 8.4.3
2 parents d5fa671 + c946bc1 commit e266b17

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1061
-301
lines changed

.circleci/config.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -920,30 +920,30 @@ workflows:
920920
requires:
921921
- build
922922
- create-sandboxes:
923-
parallelism: 38
923+
parallelism: 37
924924
requires:
925925
- build
926926
# - smoke-test-sandboxes: # disabled for now
927927
# requires:
928928
# - create-sandboxes
929929
- build-sandboxes:
930-
parallelism: 38
930+
parallelism: 37
931931
requires:
932932
- create-sandboxes
933933
- chromatic-sandboxes:
934-
parallelism: 35
934+
parallelism: 34
935935
requires:
936936
- build-sandboxes
937937
- e2e-production:
938-
parallelism: 33
938+
parallelism: 32
939939
requires:
940940
- build-sandboxes
941941
- e2e-dev:
942942
parallelism: 2
943943
requires:
944944
- create-sandboxes
945945
- test-runner-production:
946-
parallelism: 33
946+
parallelism: 32
947947
requires:
948948
- build-sandboxes
949949
- vitest-integration:

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 8.4.3
2+
3+
- Addon Test: Optimize internal dependencies - [#29595](https://github.com/storybookjs/storybook/pull/29595), thanks @yannbf!
4+
- Next.js: Add support for Next 15 - [#29587](https://github.com/storybookjs/storybook/pull/29587), thanks @yannbf!
5+
16
## 8.4.2
27

38
- Addon Test: Fix post-install logic for Next.js Vite framework support - [#29524](https://github.com/storybookjs/storybook/pull/29524), thanks @valentinpalkovic!

code/addons/test/src/vitest-plugin/index.ts

+10
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ export const storybookTest = (options?: UserOptions): Plugin => {
131131
config.test.server.deps.inline.push('@storybook/experimental-addon-test');
132132
}
133133

134+
config.optimizeDeps ??= {};
135+
config.optimizeDeps = {
136+
...config.optimizeDeps,
137+
include: [
138+
...(config.optimizeDeps.include ?? []),
139+
'react-dom/test-utils',
140+
'@storybook/experimental-addon-test/**',
141+
],
142+
};
143+
134144
if (frameworkName?.includes('vue3')) {
135145
config.define ??= {};
136146
config.define.__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ = 'false';

code/core/src/manager/components/sidebar/TestingModule.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,10 @@ const DynamicInfo = ({ state }: { state: TestProviders[keyof TestProviders] }) =
175175
const Title = state.title;
176176
return (
177177
<Info>
178-
<TitleWrapper crashed={state.crashed}>
178+
<TitleWrapper crashed={state.crashed} id="testing-module-title">
179179
<Title {...state} />
180180
</TitleWrapper>
181-
<DescriptionWrapper>
181+
<DescriptionWrapper id="testing-module-description">
182182
<Description {...state} />
183183
</DescriptionWrapper>
184184
</Info>
@@ -244,7 +244,7 @@ export const TestingModule = ({
244244
>
245245
<Content ref={contentRef}>
246246
{testProviders.map((state) => (
247-
<TestProvider key={state.id}>
247+
<TestProvider key={state.id} data-module-id={state.id}>
248248
<DynamicInfo state={state} />
249249
<Actions>
250250
{state.watchable && (

code/e2e-tests/addon-docs.spec.ts

+5
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ test.describe('addon-docs', () => {
189189
});
190190

191191
test('should resolve react to the correct version', async ({ page }) => {
192+
test.skip(
193+
templateName?.includes('nextjs'),
194+
'TODO: remove this once sandboxes are synced (SOON!!)'
195+
);
192196
// Arrange - Navigate to MDX docs
193197
const sbPage = new SbPage(page, expect);
194198
await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'mdx', 'docs');
@@ -201,6 +205,7 @@ test.describe('addon-docs', () => {
201205
} else if (templateName.includes('react16')) {
202206
expectedReactVersionRange = /^16/;
203207
} else if (
208+
templateName.includes('nextjs/default-ts') ||
204209
templateName.includes('nextjs/prerelease') ||
205210
templateName.includes('react-vite/prerelease') ||
206211
templateName.includes('react-webpack/prerelease')

code/e2e-tests/framework-nextjs.spec.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ test.describe('Next.js', () => {
5353
test.beforeEach(async ({ page }) => {
5454
sbPage = new SbPage(page, expect);
5555

56-
await sbPage.navigateToStory(
57-
'stories/frameworks/nextjs-nextjs-default-ts/Navigation',
58-
'default'
59-
);
56+
await sbPage.navigateToStory('stories/frameworks/nextjs/Navigation', 'default');
6057
root = sbPage.previewRoot();
6158
});
6259

@@ -88,7 +85,7 @@ test.describe('Next.js', () => {
8885
test.beforeEach(async ({ page }) => {
8986
sbPage = new SbPage(page, expect);
9087

91-
await sbPage.navigateToStory('stories/frameworks/nextjs-nextjs-default-ts/Router', 'default');
88+
await sbPage.navigateToStory('stories/frameworks/nextjs/Router', 'default');
9289
root = sbPage.previewRoot();
9390
});
9491

code/frameworks/nextjs/package.json

+8-2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
"import": "./dist/compatibility/redirect-status-code.compat.mjs",
5858
"require": "./dist/compatibility/redirect-status-code.compat.js"
5959
},
60+
"./dist/compatibility/draft-mode.compat": {
61+
"types": "./dist/compatibility/draft-mode.compat.d.ts",
62+
"import": "./dist/compatibility/draft-mode.compat.mjs",
63+
"require": "./dist/compatibility/draft-mode.compat.js"
64+
},
6065
"./export-mocks": {
6166
"types": "./dist/export-mocks/index.d.ts",
6267
"import": "./dist/export-mocks/index.mjs",
@@ -171,12 +176,12 @@
171176
"@types/babel__preset-env": "^7",
172177
"@types/loader-utils": "^2.0.5",
173178
"@types/react-refresh": "^0",
174-
"next": "^14.1.0",
179+
"next": "^15.0.3",
175180
"typescript": "^5.3.2",
176181
"webpack": "^5.65.0"
177182
},
178183
"peerDependencies": {
179-
"next": "^13.5.0 || ^14.0.0",
184+
"next": "^13.5.0 || ^14.0.0 || ^15.0.0",
180185
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
181186
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
182187
"storybook": "workspace:^",
@@ -212,6 +217,7 @@
212217
"./src/export-mocks/navigation/index.ts",
213218
"./src/compatibility/segment.compat.ts",
214219
"./src/compatibility/redirect-status-code.compat.ts",
220+
"./src/compatibility/draft-mode.compat.ts",
215221
"./src/next-image-loader-stub.ts",
216222
"./src/images/decorator.tsx",
217223
"./src/images/next-legacy-image.tsx",
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
import type { Configuration as WebpackConfig } from 'webpack';
22

3+
import { configureCompatibilityAliases } from '../compatibility/compatibility-map';
4+
import { configureNextExportMocks } from '../export-mocks/webpack';
5+
36
export const configureAliases = (baseConfig: WebpackConfig): void => {
7+
configureNextExportMocks(baseConfig);
8+
configureCompatibilityAliases(baseConfig);
9+
410
baseConfig.resolve = {
511
...(baseConfig.resolve ?? {}),
612
alias: {
713
...(baseConfig.resolve?.alias ?? {}),
814
'@opentelemetry/api': 'next/dist/compiled/@opentelemetry/api',
915
},
1016
};
17+
18+
// remove warnings regarding compatibility paths
19+
baseConfig.ignoreWarnings = [
20+
...(baseConfig.ignoreWarnings ?? []),
21+
(warning) =>
22+
warning.message.includes("export 'draftMode'") &&
23+
warning.message.includes('next/dist/server/request/headers'),
24+
];
1125
};

code/frameworks/nextjs/src/compatibility/compatibility-map.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import semver from 'semver';
22
import type { Configuration as WebpackConfig } from 'webpack';
33

4-
import { addScopedAlias, getNextjsVersion } from '../utils';
4+
import { addScopedAlias, getNextjsVersion, setAlias } from '../utils';
55

6-
const mapping: Record<string, Record<string, string>> = {
6+
const mapping: Record<string, Record<string, string | boolean>> = {
77
'<14.1.0': {
88
// https://github.com/vercel/next.js/blob/v14.1.0/packages/next/src/shared/lib/segment.ts
99
'next/dist/shared/lib/segment': '@storybook/nextjs/dist/compatibility/segment.compat',
@@ -13,6 +13,11 @@ const mapping: Record<string, Record<string, string>> = {
1313
'next/dist/client/components/redirect-status-code':
1414
'@storybook/nextjs/dist/compatibility/redirect-status-code.compat',
1515
},
16+
'<15.0.0': {
17+
'next/dist/server/request/headers': 'next/dist/client/components/headers',
18+
// this path only exists from Next 15 onwards
19+
'next/dist/server/request/draft-mode': '@storybook/nextjs/dist/compatibility/draft-mode.compat',
20+
},
1621
};
1722

1823
export const getCompatibilityAliases = () => {
@@ -32,6 +37,10 @@ export const configureCompatibilityAliases = (baseConfig: WebpackConfig): void =
3237
const aliases = getCompatibilityAliases();
3338

3439
Object.entries(aliases).forEach(([name, alias]) => {
35-
addScopedAlias(baseConfig, name, alias);
40+
if (typeof alias === 'string') {
41+
addScopedAlias(baseConfig, name, alias);
42+
} else {
43+
setAlias(baseConfig, name, alias);
44+
}
3645
});
3746
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Compatibility for Next 14
2+
export { draftMode } from 'next/dist/client/components/headers';
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { fn } from '@storybook/test';
22

3-
import * as originalHeaders from 'next/dist/client/components/headers';
3+
// This export won't exist in Next.js 14 but it's safe because we ignore it in Webpack when applicable
4+
import { draftMode as originalDraftMode } from 'next/dist/server/request/draft-mode';
5+
import * as headers from 'next/dist/server/request/headers';
46

57
// re-exports of the actual module
6-
export * from 'next/dist/client/components/headers';
8+
export * from 'next/dist/server/request/headers';
79

810
// mock utilities/overrides (as of Next v14.2.0)
911
export { headers } from './headers';
1012
export { cookies } from './cookies';
1113

1214
// passthrough mocks - keep original implementation but allow for spying
13-
const draftMode = fn(originalHeaders.draftMode).mockName('draftMode');
15+
const draftMode = fn(originalDraftMode ?? (headers as any).draftMode).mockName('draftMode');
1416
export { draftMode };

code/frameworks/nextjs/src/export-mocks/webpack.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ export const getPackageAliases = ({ useESM = false }: { useESM?: boolean } = {})
2323
const packageLocation = dirname(require.resolve('@storybook/nextjs/package.json'));
2424

2525
const getFullPath = (path: string) =>
26-
join(packageLocation, path.replace('@storybook/nextjs', ''));
26+
path.startsWith('next') ? path : join(packageLocation, path.replace('@storybook/nextjs', ''));
2727

2828
const aliases = Object.fromEntries(
2929
Object.entries(mapping).map(([originalPath, aliasedPath]) => [
3030
originalPath,
3131
// Use paths for both next/xyz and @storybook/nextjs/xyz imports
3232
// to make sure they all serve the MJS/CJS version of the file
33-
getFullPath(`${aliasedPath}.${extension}`),
33+
typeof aliasedPath === 'string' ? getFullPath(`${aliasedPath}.${extension}`) : aliasedPath,
3434
])
3535
);
3636

code/frameworks/nextjs/src/preset.ts

-2
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,6 @@ export const webpackFinal: StorybookConfig['webpackFinal'] = async (baseConfig,
162162
configureStyledJsx(baseConfig);
163163
configureNodePolyfills(baseConfig);
164164
configureAliases(baseConfig);
165-
configureCompatibilityAliases(baseConfig);
166-
configureNextExportMocks(baseConfig);
167165

168166
if (isDevelopment) {
169167
configureFastRefresh(baseConfig);

code/frameworks/nextjs/src/routing/app-router-provider.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ import {
1818
PathnameContext,
1919
SearchParamsContext,
2020
} from 'next/dist/shared/lib/hooks-client-context.shared-runtime';
21-
import { type Params } from 'next/dist/shared/lib/router/utils/route-matcher';
2221
import { PAGE_SEGMENT_KEY } from 'next/dist/shared/lib/segment';
2322

2423
import type { RouteParams } from './types';
2524

25+
// Using an inline type so we can support Next 14 and lower
26+
// from https://github.com/vercel/next.js/blob/v15.0.3/packages/next/src/server/request/params.ts#L25
27+
type Params = Record<string, string | Array<string> | undefined>;
28+
2629
type AppRouterProviderProps = {
2730
routeParams: RouteParams;
2831
};

code/frameworks/nextjs/template/stories/DynamicImport.stories.jsx renamed to code/frameworks/nextjs/template/stories/DynamicImport.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React, { Suspense } from 'react';
22

3+
import type { Meta, StoryObj } from '@storybook/react';
4+
35
import dynamic from 'next/dynamic';
46

57
const DynamicComponent = dynamic(() => import('./dynamic-component'), {
@@ -16,6 +18,6 @@ function Component() {
1618

1719
export default {
1820
component: Component,
19-
};
21+
} as Meta<typeof Component>;
2022

21-
export const Default = {};
23+
export const Default: StoryObj<typeof Component> = {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { Meta, StoryObj } from '@storybook/react';
2+
3+
import Font from './Font';
4+
5+
export default {
6+
component: Font,
7+
} as Meta<typeof Font>;
8+
9+
type Story = StoryObj<typeof Font>;
10+
11+
export const WithClassName: Story = {
12+
args: {
13+
variant: 'className',
14+
},
15+
};
16+
17+
export const WithStyle: Story = {
18+
args: {
19+
variant: 'style',
20+
},
21+
};
22+
23+
export const WithVariable: Story = {
24+
args: {
25+
variant: 'variable',
26+
},
27+
};

code/frameworks/nextjs/template/stories_nextjs-default-js/Font.jsx renamed to code/frameworks/nextjs/template/stories/Font.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable react/prop-types */
21
import React from 'react';
32

43
import { Rubik_Puddles } from 'next/font/google';
@@ -15,7 +14,7 @@ export const localRubikStorm = localFont({
1514
variable: '--font-rubik-storm',
1615
});
1716

18-
export default function Font({ variant }) {
17+
export default function Font({ variant }: { variant: 'className' | 'style' | 'variable' }) {
1918
switch (variant) {
2019
case 'className':
2120
return (

code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx renamed to code/frameworks/nextjs/template/stories/Head.stories.tsx

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22

3+
import type { Meta, StoryObj } from '@storybook/react';
34
import { expect, waitFor } from '@storybook/test';
45

56
import Head from 'next/head';
@@ -21,14 +22,14 @@ function Component() {
2122

2223
export default {
2324
component: Component,
24-
};
25+
} as Meta<typeof Component>;
2526

26-
export const Default = {
27+
export const Default: StoryObj<typeof Component> = {
2728
play: async () => {
2829
await waitFor(() => expect(document.title).toEqual('Next.js Head Title'));
2930
await expect(document.querySelectorAll('meta[property="og:title"]')).toHaveLength(1);
30-
await expect(document.querySelector('meta[property="og:title"]').content).toEqual(
31-
'My new title'
32-
);
31+
await expect(
32+
(document.querySelector('meta[property="og:title"]') as HTMLMetaElement)?.content
33+
).toEqual('My new title');
3334
},
3435
};

0 commit comments

Comments
 (0)