Date: Wed, 10 Apr 2024 11:07:58 +0200
Subject: [PATCH 072/380] improve tests
---
.../NextHeader.stories.tsx | 26 ++++++++++++++++---
.../stories_nextjs-default-ts/NextHeader.tsx | 2 +-
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.stories.tsx
index fe7c8ed9f34a..4ef5a3d7466b 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.stories.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.stories.tsx
@@ -19,10 +19,28 @@ export const Default: Story = {
});
headers().set('timezone', 'Central European Summer Time');
},
- play: async ({ canvasElement }) => {
+ play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
- const submitButton = await canvas.findByRole('button');
- await userEvent.click(submitButton);
- expect(headers().get('cookie')).toContain('user-id=encrypted-id');
+ const headersMock = headers();
+ const cookiesMock = cookies();
+ await step('Cookie and header store apis are called upon rendering', async () => {
+ await expect(cookiesMock.getAll).toHaveBeenCalled();
+ await expect(headersMock.entries).toHaveBeenCalled();
+ });
+
+ await step('Upon clicking on submit, the user-id cookie is set', async () => {
+ const submitButton = await canvas.findByRole('button');
+ await userEvent.click(submitButton);
+
+ await expect(cookiesMock.set).toHaveBeenCalledWith('user-id', 'encrypted-id');
+ });
+
+ await step('The user-id cookie is available in cookie and header stores', async () => {
+ await expect(headersMock.get('cookie')).toContain('user-id=encrypted-id');
+ await expect(cookiesMock.get('user-id')).toEqual({
+ name: 'user-id',
+ value: 'encrypted-id',
+ });
+ });
},
};
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.tsx
index bb70c020699c..b93c9611c774 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.tsx
@@ -22,7 +22,7 @@ export default async function Component() {
})}
Headers:
- {Array.from(headers()).map(([name, value]: [string, string]) => {
+ {Array.from(headers().entries()).map(([name, value]: [string, string]) => {
return (
Name: {name}
From 34ca025f5b897fc6f3c5b8a568de7fae6220a8cc Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Wed, 10 Apr 2024 11:09:49 +0200
Subject: [PATCH 073/380] Change entrypoint to `@storybook/nextjs/headers.mock`
---
code/frameworks/nextjs/package.json | 4 ++--
code/frameworks/nextjs/src/headers/cookies.ts | 2 +-
code/frameworks/nextjs/src/headers/webpack.ts | 2 +-
code/frameworks/nextjs/src/preview.tsx | 2 +-
.../template/stories_nextjs-default-ts/NextHeader.stories.tsx | 2 +-
.../portable-stories-kitchen-sink/nextjs/jest.config.js | 2 +-
.../nextjs/stories/NextHeader.stories.tsx | 2 +-
7 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json
index 83f28e8756e3..e30984136eae 100644
--- a/code/frameworks/nextjs/package.json
+++ b/code/frameworks/nextjs/package.json
@@ -47,7 +47,7 @@
"require": "./dist/next-image-loader-stub.js",
"import": "./dist/next-image-loader-stub.mjs"
},
- "./headers": {
+ "./headers.mock": {
"types": "./dist/headers/index.d.ts",
"require": "./dist/headers/index.js",
"import": "./dist/headers/index.mjs"
@@ -65,7 +65,7 @@
"dist/image-context": [
"dist/image-context.d.ts"
],
- "headers": [
+ "headers.mock": [
"dist/headers/index.d.ts"
]
}
diff --git a/code/frameworks/nextjs/src/headers/cookies.ts b/code/frameworks/nextjs/src/headers/cookies.ts
index d7c9524ac43f..13bc7779d3ef 100644
--- a/code/frameworks/nextjs/src/headers/cookies.ts
+++ b/code/frameworks/nextjs/src/headers/cookies.ts
@@ -11,7 +11,7 @@ import {
// is the only way to achieve it actually being a singleton
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore we must ignore types here as during compilation they are not generated yet
-import { headers, type HeadersStore } from '@storybook/nextjs/headers';
+import { headers, type HeadersStore } from '@storybook/nextjs/headers.mock';
const stringifyCookies = (map: Map) => {
return Array.from(map)
diff --git a/code/frameworks/nextjs/src/headers/webpack.ts b/code/frameworks/nextjs/src/headers/webpack.ts
index 9e78fc459cac..fceb5049f6d2 100644
--- a/code/frameworks/nextjs/src/headers/webpack.ts
+++ b/code/frameworks/nextjs/src/headers/webpack.ts
@@ -13,6 +13,6 @@ export const configureNextHeaders = (baseConfig: WebpackConfig): void => {
resolve.alias = {
...resolve.alias,
'next/headers': headersPath,
- '@storybook/nextjs/headers': headersPath,
+ '@storybook/nextjs/headers.mock': headersPath,
};
};
diff --git a/code/frameworks/nextjs/src/preview.tsx b/code/frameworks/nextjs/src/preview.tsx
index 0bb931dbd85e..7fb164d1f0de 100644
--- a/code/frameworks/nextjs/src/preview.tsx
+++ b/code/frameworks/nextjs/src/preview.tsx
@@ -10,7 +10,7 @@ import { HeadManagerDecorator } from './head-manager/decorator';
// is the only way to achieve it actually being a singleton
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore we must ignore types here as during compilation they are not generated yet
-import { cookies, headers } from '@storybook/nextjs/headers';
+import { cookies, headers } from '@storybook/nextjs/headers.mock';
function addNextHeadCount() {
const meta = document.createElement('meta');
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.stories.tsx
index 4ef5a3d7466b..d8abfe11bdd1 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.stories.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/NextHeader.stories.tsx
@@ -2,7 +2,7 @@ import NextHeader from './NextHeader';
import type { Meta } from '@storybook/react';
import type { StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';
-import { cookies, headers } from '@storybook/nextjs/headers';
+import { cookies, headers } from '@storybook/nextjs/headers.mock';
export default {
component: NextHeader,
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/jest.config.js b/test-storybooks/portable-stories-kitchen-sink/nextjs/jest.config.js
index 1869752aaa5d..deb85e5a4b0e 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/jest.config.js
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/jest.config.js
@@ -13,7 +13,7 @@ const customJestConfig = {
setupFilesAfterEnv: ['./jest.setup.ts'],
// TODO add docs about this: alias next/headers to @storybook/nextjs/headers
moduleNameMapper: {
- '^next/headers$': '@storybook/nextjs/headers',
+ '^next/headers$': '@storybook/nextjs/headers.mock',
},
};
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/NextHeader.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/NextHeader.stories.tsx
index d6b0cf7f922b..edbe082ef0f0 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/NextHeader.stories.tsx
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/NextHeader.stories.tsx
@@ -1,7 +1,7 @@
import type { Meta } from '@storybook/react';
import type { StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';
-import { cookies, headers } from '@storybook/nextjs/headers';
+import { cookies, headers } from '@storybook/nextjs/headers.mock';
import NextHeader from './NextHeader';
export default {
From 5c20e9514414e465eb7bd68903b00cc4266d5b4f Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Wed, 10 Apr 2024 11:12:21 +0200
Subject: [PATCH 074/380] update portable stories test
---
.../nextjs/stories/NextHeader.stories.tsx | 26 +++-
.../nextjs/yarn.lock | 144 +++++++++---------
2 files changed, 94 insertions(+), 76 deletions(-)
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/NextHeader.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/NextHeader.stories.tsx
index edbe082ef0f0..1c75f64375ea 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/NextHeader.stories.tsx
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/NextHeader.stories.tsx
@@ -19,10 +19,28 @@ export const Default: Story = {
});
headers().set('timezone', 'Central European Summer Time');
},
- play: async ({ canvasElement }) => {
+ play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
- const submitButton = await canvas.findByRole('button');
- await userEvent.click(submitButton);
- expect(headers().get('cookie')).toContain('user-id=encrypted-id');
+ const headersMock = headers();
+ const cookiesMock = cookies();
+ await step('Cookie and header store apis are called upon rendering', async () => {
+ await expect(cookiesMock.getAll).toHaveBeenCalled();
+ await expect(headersMock.entries).toHaveBeenCalled();
+ });
+
+ await step('Upon clicking on submit, the user-id cookie is set', async () => {
+ const submitButton = await canvas.findByRole('button');
+ await userEvent.click(submitButton);
+
+ await expect(cookiesMock.set).toHaveBeenCalledWith('user-id', 'encrypted-id');
+ });
+
+ await step('The user-id cookie is available in cookie and header stores', async () => {
+ await expect(headersMock.get('cookie')).toContain('user-id=encrypted-id');
+ await expect(cookiesMock.get('user-id')).toEqual({
+ name: 'user-id',
+ value: 'encrypted-id',
+ });
+ });
},
};
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
index b67bf0e79b9a..7b54b424d5b9 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
@@ -2379,7 +2379,7 @@ __metadata:
"@storybook/addon-actions@file:../../../code/addons/actions::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-actions@file:../../../code/addons/actions#../../../code/addons/actions::hash=65179b&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-actions@file:../../../code/addons/actions#../../../code/addons/actions::hash=99649f&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-events": "workspace:*"
"@storybook/global": "npm:^5.0.0"
@@ -2387,18 +2387,18 @@ __metadata:
dequal: "npm:^2.0.2"
polished: "npm:^4.2.2"
uuid: "npm:^9.0.0"
- checksum: 10/9ed534d56ffd4ae256837a80af482961a5881624cb85eb46983e913497bbdcd8c441deac96ea76bf99eb1f7b0fb523b60a7eec4059a78eadf00e92aa6bf977b3
+ checksum: 10/79a14c7a74591e404e5ec22c2b6c9eaa03dd48bf3316470dd2642e3c70abd7c90b168fd350e729b617967c7d759df2ef0107534d218d1138b12e737c8a3e888e
languageName: node
linkType: hard
"@storybook/addon-backgrounds@file:../../../code/addons/backgrounds::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-backgrounds@file:../../../code/addons/backgrounds#../../../code/addons/backgrounds::hash=026986&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-backgrounds@file:../../../code/addons/backgrounds#../../../code/addons/backgrounds::hash=bbac2f&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
memoizerific: "npm:^1.11.3"
ts-dedent: "npm:^2.0.0"
- checksum: 10/99d407bf5df62a7e85233e5a484ec0801ed309c3b910af79c65bbcceabeb1a7e8619c89178ada8ea20c1dae9196d559dbd75905732fe6a181374bf8c8d305993
+ checksum: 10/aaae35c1f570d788cded175bad9b07ce9826023fa320e6d276c62678953d07cfe98f636005d7ce0456d0b5df699e16377317edcfdb7d304d3b05cc4d1683bb72
languageName: node
linkType: hard
@@ -2419,7 +2419,7 @@ __metadata:
"@storybook/addon-docs@file:../../../code/addons/docs::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-docs@file:../../../code/addons/docs#../../../code/addons/docs::hash=58d358&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-docs@file:../../../code/addons/docs#../../../code/addons/docs::hash=c90446&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/core": "npm:^7.12.3"
"@mdx-js/react": "npm:^3.0.0"
@@ -2441,13 +2441,13 @@ __metadata:
rehype-external-links: "npm:^3.0.0"
rehype-slug: "npm:^6.0.0"
ts-dedent: "npm:^2.0.0"
- checksum: 10/e794088e3f6cdad1c5ea178ab7d07db27da5729bbb380bee957a46d185f19125ad91519d56d2a3d68b7d60afd9e31a9a72edb2f24f5ba68866a531a25e97ef35
+ checksum: 10/6cb03b37a894e2a563a67bcc1179194a7e48f202ed438763cce7b6255697fd6dd192607076dad6503d7be4a1d094daf9d18daf50b8aebae71ededfe020f151f1
languageName: node
linkType: hard
"@storybook/addon-essentials@file:../../../code/addons/essentials::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-essentials@file:../../../code/addons/essentials#../../../code/addons/essentials::hash=5092fe&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-essentials@file:../../../code/addons/essentials#../../../code/addons/essentials::hash=584ec5&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/addon-actions": "workspace:*"
"@storybook/addon-backgrounds": "workspace:*"
@@ -2463,22 +2463,22 @@ __metadata:
"@storybook/node-logger": "workspace:*"
"@storybook/preview-api": "workspace:*"
ts-dedent: "npm:^2.0.0"
- checksum: 10/6e482c766038f53305099b1cad8195bb546bb2b18a701b2f85491e9c5393e39e715b6505672ffb36616d5ae5baa9f06d16dd6f4a86d3faa31ee550d045a4bc57
+ checksum: 10/986829238ed66c8818ab27995effd47614c4182aa326e70de645d38babf58f2cab76c7a2f1825a34cecab07ca78ca2bb5e69938da2dec3bb9837905f7e43ec9b
languageName: node
linkType: hard
"@storybook/addon-highlight@file:../../../code/addons/highlight::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-highlight@file:../../../code/addons/highlight#../../../code/addons/highlight::hash=a69c2f&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-highlight@file:../../../code/addons/highlight#../../../code/addons/highlight::hash=291b82&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
- checksum: 10/e61e168997b91f2ab729f02de3e186a26c697c0851d188d7ece1ec145fcd84c7fea3cd3fac3608269bb4944c9b4e13436493f65ddf8c0a808e30bb5ece70d9f3
+ checksum: 10/ecf6c7aecffb3b61cd08468d9a8f0f67b191ff8c4d9df0022b077f3e0cb6a42b109a8d844745c14a62ae740131708c606b3b5e359fbf5921559b0e02a85cc686
languageName: node
linkType: hard
"@storybook/addon-interactions@file:../../../code/addons/interactions::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-interactions@file:../../../code/addons/interactions#../../../code/addons/interactions::hash=3e90ca&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-interactions@file:../../../code/addons/interactions#../../../code/addons/interactions::hash=e7e04a&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
"@storybook/instrumenter": "workspace:*"
@@ -2486,43 +2486,43 @@ __metadata:
"@storybook/types": "workspace:*"
polished: "npm:^4.2.2"
ts-dedent: "npm:^2.2.0"
- checksum: 10/18c21704ebc20d55fe75e735f89e8c5926b6fe3a44e7025de16d666cf3c6435e9fc19ada8dc3714f4406ce1f3b3117120610c7c8bcfefb86c913a6bbf14f668a
+ checksum: 10/c66d7db9c1356903d444211962054b0a692a56f7ed5debcaa1f2e40fd57575975b8de86c2fb3be3a140e69cdc8f36b25f81be6e2ca55fb4facf826694d8be65f
languageName: node
linkType: hard
"@storybook/addon-measure@file:../../../code/addons/measure::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-measure@file:../../../code/addons/measure#../../../code/addons/measure::hash=086736&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-measure@file:../../../code/addons/measure#../../../code/addons/measure::hash=43b2ca&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
tiny-invariant: "npm:^1.3.1"
- checksum: 10/3f9a7ddab76235f46cfaa96386074964a311908344e5a4617025dcbab610742e48672b8f236a0d4a5c254273ae4b959ef9114bf31e22ebfcae085c17309c2f47
+ checksum: 10/ce880ee3acae8c6a5994a5905724040f1cb9b7a1c1654c6ab6dfec0f61298db78afc78309aa966eecf1dbdc2e59f48cb2108c7514305ca701eeb19262477bfc8
languageName: node
linkType: hard
"@storybook/addon-outline@file:../../../code/addons/outline::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-outline@file:../../../code/addons/outline#../../../code/addons/outline::hash=c2049c&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-outline@file:../../../code/addons/outline#../../../code/addons/outline::hash=772f7e&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
ts-dedent: "npm:^2.0.0"
- checksum: 10/6935af0b38fdb46c5bee74c22a170b2f10ffcbff14ee039ddc8488f3b6eb1c2d3f11c35c9761eaa8ddfafe3fecaef3ace12a5a30610fc4d1c9a5b161d7fbba53
+ checksum: 10/17d761b1298d08adc15d65dfb3efb91440cc73e6828ab7ee290703e36f9c2756546a99220119c15d03697c5ac2b71ccdd7b98fba4ebb87faab9caf9ba053dbdc
languageName: node
linkType: hard
"@storybook/addon-toolbars@file:../../../code/addons/toolbars::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-toolbars@file:../../../code/addons/toolbars#../../../code/addons/toolbars::hash=7413c4&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/a428f3c5b3530cd56c81c83a7e05c2f364a75a7e358dbd9f082eb1b88b875a5e721db0cb7050f1ac48117ed0d4b95a8b35e07e8f3e4b17e6cdd0076a4d959bc7
+ resolution: "@storybook/addon-toolbars@file:../../../code/addons/toolbars#../../../code/addons/toolbars::hash=ce7192&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/fd28942b5da079e25cd778e7b134b34e07289044553622b1a1636e7e2da5075ddf16f66934619eb7ba3514d98425102365ea8dd8cebbf17fec4bb6849ef38ec5
languageName: node
linkType: hard
"@storybook/addon-viewport@file:../../../code/addons/viewport::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-viewport@file:../../../code/addons/viewport#../../../code/addons/viewport::hash=57d9d2&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-viewport@file:../../../code/addons/viewport#../../../code/addons/viewport::hash=1fd57e&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
memoizerific: "npm:^1.11.3"
- checksum: 10/752aa713b8b924944dbf1b3b904dd31e4508651ef9b8437dc3a60444890f760a7f76fcbbe80037c0f8e790e31a37d062aa6aa27182c1cd0784eba000745a44f2
+ checksum: 10/00e25bcdc41c2ac49405c62004b0946ca24f73ee7d65678ea25ddd222ac44e44ed6716ab6c66d6743b8dd4bb89123cce0edd4bafb14883257cb133f3a8a4198a
languageName: node
linkType: hard
@@ -2568,7 +2568,7 @@ __metadata:
"@storybook/builder-manager@file:../../../code/builders/builder-manager::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/builder-manager@file:../../../code/builders/builder-manager#../../../code/builders/builder-manager::hash=727c53&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/builder-manager@file:../../../code/builders/builder-manager#../../../code/builders/builder-manager::hash=875996&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@fal-works/esbuild-plugin-global-externals": "npm:^2.1.2"
"@storybook/core-common": "workspace:*"
@@ -2584,13 +2584,13 @@ __metadata:
fs-extra: "npm:^11.1.0"
process: "npm:^0.11.10"
util: "npm:^0.12.4"
- checksum: 10/1e3f751ec4dd12ca12d8a3190fb104644041cd08fb4c1548567105dabea9c20af0d25e19333e9c9da51225e0dd5159c2d2614cb3ac78b6f6b2e06c866f543eaf
+ checksum: 10/b776c568ef58940649b06b746b4002b221b88b0c9c4d56bb136b8997cfa88f77e3a05954c59c815ca2ecf19285607e2ef717198f42c11dac2235ed6b01a07c9d
languageName: node
linkType: hard
"@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5#../../../code/builders/builder-webpack5::hash=ad9e5e&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5#../../../code/builders/builder-webpack5::hash=983659&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2629,20 +2629,20 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/1dbbad195f6f0cb506b0b693c825c494f1a88cd71ca7784b06e0410f080468cac67d35adff1bc6f785b3f7d55cfe8e794684df01b4f440799955f0e787d8963a
+ checksum: 10/f84f41cd8ac80376ba603f4bb58da565f2b0e95ed37593279d85c4e5573de64633f10b7c6f2bd399f6d40057f1c97934760b969326520250f6de5efd07ac967b
languageName: node
linkType: hard
"@storybook/channels@file:../../../code/lib/channels::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/channels@file:../../../code/lib/channels#../../../code/lib/channels::hash=78c3de&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/channels@file:../../../code/lib/channels#../../../code/lib/channels::hash=3a33a2&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/core-events": "workspace:*"
"@storybook/global": "npm:^5.0.0"
telejson: "npm:^7.2.0"
tiny-invariant: "npm:^1.3.1"
- checksum: 10/d161eff9c0218c7a6628e44dceed5299b253f997fc36fd344a428937b901a3f0755a067240394636ca0e33611848cfc4b43e07a259f4232a7ea3c409418da5fc
+ checksum: 10/cda1b155f07fdac919a29e5a5287ae33ef4b3ed9c5c9816c29e17e3aa0dd788dc59da8775c40341ebcbd426ecf4f9ab629949dfe945834f48db7ca6053c062f1
languageName: node
linkType: hard
@@ -2695,16 +2695,16 @@ __metadata:
"@storybook/client-logger@file:../../../code/lib/client-logger::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/client-logger@file:../../../code/lib/client-logger#../../../code/lib/client-logger::hash=54f3a6&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/client-logger@file:../../../code/lib/client-logger#../../../code/lib/client-logger::hash=f3ac76&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
- checksum: 10/234fc62dd3bbf8350049d6b149d035eae31b804dd6b8ef175c84ac7bc7ef32943976197a204f4d059952d47de3b97c56a8d2238f0bebcd10e29665b112ba0e1f
+ checksum: 10/00b5cfade208483f5ec85c8aa59cabf402502a4cf1d9c3ee24a311a396e65ce97f0a3d4356aac9f413c8d84c9804ccb07aaeda6f3d553799e6e036960f4a2fbe
languageName: node
linkType: hard
"@storybook/codemod@file:../../../code/lib/codemod::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/codemod@file:../../../code/lib/codemod#../../../code/lib/codemod::hash=a56758&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/codemod@file:../../../code/lib/codemod#../../../code/lib/codemod::hash=13e51b&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/core": "npm:^7.23.2"
"@babel/preset-env": "npm:^7.23.2"
@@ -2721,13 +2721,13 @@ __metadata:
prettier: "npm:^3.1.1"
recast: "npm:^0.23.5"
tiny-invariant: "npm:^1.3.1"
- checksum: 10/281ccf2a77c876f5c76629a2d40c19c90d5c5244acb1bb0480e8317c79a1d71e52cae72d542368b0b3192f8775b8dc380141d0ba8ecfc3677970ac43de5eab4f
+ checksum: 10/5cfc52e72455178e503ff226dd3fa1a0917e7f14a86f58b914aa5971f5288e45b68246b0d550169a9af941d5bdb2293c160831de4c466894ddabb609092dbace
languageName: node
linkType: hard
"@storybook/components@file:../../../code/ui/components::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/components@file:../../../code/ui/components#../../../code/ui/components::hash=df917d&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/components@file:../../../code/ui/components#../../../code/ui/components::hash=2c348b&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@radix-ui/react-slot": "npm:^1.0.2"
"@storybook/client-logger": "workspace:*"
@@ -2741,7 +2741,7 @@ __metadata:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
- checksum: 10/70d228121e8d87efe766d01665df20448f310c0413edf80d7496ad887e876c7d24bae7786c89a0746d2b1fced8d89f1c7d5a20d52d39bbeee0de269512232b0c
+ checksum: 10/5ca7607bebb485e1dbb5c26f5dc3482e661d1646381be3ae26284c1e82cb0e2de51e05f5c4272ebe4d5fa6536aecb8dcd46e3da871aad90ba67a2e7e8987d278
languageName: node
linkType: hard
@@ -2783,16 +2783,16 @@ __metadata:
"@storybook/core-events@file:../../../code/lib/core-events::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-events@file:../../../code/lib/core-events#../../../code/lib/core-events::hash=00e230&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-events@file:../../../code/lib/core-events#../../../code/lib/core-events::hash=840150&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
ts-dedent: "npm:^2.0.0"
- checksum: 10/04b637e0c32d0cf6b8b7f13a9c3366ae2f8d1881ac1e0024cb2d02cf4f38052a2655676c67876644c81fd4c351ebbf138afb6873d2449d3b8bcbecf4596b22b5
+ checksum: 10/ccfa4397af9c114f401ac87d232f66c0cb37e7ee104647b36dd34e7bf598ff7e3a22fb18a6fb9d1529cef35f053056e34fa3f7626e62c5e133d31bd58fd6b5cb
languageName: node
linkType: hard
"@storybook/core-server@file:../../../code/lib/core-server::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-server@file:../../../code/lib/core-server#../../../code/lib/core-server::hash=6e21ef&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-server@file:../../../code/lib/core-server#../../../code/lib/core-server::hash=2c034c&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@aw-web-design/x-default-browser": "npm:1.4.126"
"@babel/core": "npm:^7.23.9"
@@ -2837,36 +2837,36 @@ __metadata:
util-deprecate: "npm:^1.0.2"
watchpack: "npm:^2.2.0"
ws: "npm:^8.2.3"
- checksum: 10/052920abcb3352dc422ed230cda74a60996475600ce4bf23e0566dfeb25d2b5b86e7d84a19a47240b518a067bd74dec1bfae7674d68b3c59099c0ebd16e588d7
+ checksum: 10/83c58dfa24e67e8ea10107858e723eebe3ebafa17580fbe9526022e02d1ba2467ef5e75ba3b303436c470a7151f183ad2d781b4cef1201a73cdf8f10d317cc57
languageName: node
linkType: hard
"@storybook/core-webpack@file:../../../code/lib/core-webpack::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-webpack@file:../../../code/lib/core-webpack#../../../code/lib/core-webpack::hash=a48486&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-webpack@file:../../../code/lib/core-webpack#../../../code/lib/core-webpack::hash=d17dda&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-common": "workspace:*"
"@storybook/node-logger": "workspace:*"
"@storybook/types": "workspace:*"
"@types/node": "npm:^18.0.0"
ts-dedent: "npm:^2.0.0"
- checksum: 10/f605ac68389a0ea374291444486bf82be36f01bf75ff1756bbc0d7de2a836095a695a072cdc14fbd941d4f49745cc775e3e02b29b9ed42065902e2fdd8091835
+ checksum: 10/2e56db38374ec96f01c00c0fa4c8a9090c1db1d56c8c611a93d1a0c60769aa6a2c751ed29fa6c3a3a7adbf99d457287908e8e01ee1848ab6c59f6837934d81bf
languageName: node
linkType: hard
"@storybook/csf-plugin@file:../../../code/lib/csf-plugin::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/csf-plugin@file:../../../code/lib/csf-plugin#../../../code/lib/csf-plugin::hash=786030&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/csf-plugin@file:../../../code/lib/csf-plugin#../../../code/lib/csf-plugin::hash=5ec6ec&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/csf-tools": "workspace:*"
unplugin: "npm:^1.3.1"
- checksum: 10/76d71cc728d93f09e0869a052b131c8b2d2307355c09c4396706e61b948c63fe7991110e8a1e6eb91f7802fe2030b53070292067adf2496f8924326f36c760f8
+ checksum: 10/592fd4a3cc9af877bce352c7ad61aaf442b2b65dfcb9f27cbd3d6f29d48649f1c3d001fb68d4abdea376b57c277f25ccd25f41e6d6d23780ae4e498daaf37014
languageName: node
linkType: hard
"@storybook/csf-tools@file:../../../code/lib/csf-tools::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/csf-tools@file:../../../code/lib/csf-tools#../../../code/lib/csf-tools::hash=edd208&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/csf-tools@file:../../../code/lib/csf-tools#../../../code/lib/csf-tools::hash=69584a&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/generator": "npm:^7.23.0"
"@babel/parser": "npm:^7.23.0"
@@ -2877,7 +2877,7 @@ __metadata:
fs-extra: "npm:^11.1.0"
recast: "npm:^0.23.5"
ts-dedent: "npm:^2.0.0"
- checksum: 10/d0205249b09db44b07382c14308e54bf527cf4f872a7ce5769486fb2099455fad045c7098c4faf133f8cf43c94fdc082f91c9165856fe6d98993553213f2a6f3
+ checksum: 10/7fce79866ace04b9a2bc78a66a03e27e6e770b4279e1b40c08634bce01eb57be22f5f192f73c6a65cc959c8910f63a3d35e31a71fe3ac821aea095722e324710
languageName: node
linkType: hard
@@ -2908,7 +2908,7 @@ __metadata:
"@storybook/docs-tools@file:../../../code/lib/docs-tools::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/docs-tools@file:../../../code/lib/docs-tools#../../../code/lib/docs-tools::hash=40a697&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/docs-tools@file:../../../code/lib/docs-tools#../../../code/lib/docs-tools::hash=4be280&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-common": "workspace:*"
"@storybook/preview-api": "workspace:*"
@@ -2917,7 +2917,7 @@ __metadata:
assert: "npm:^2.1.0"
doctrine: "npm:^3.0.0"
lodash: "npm:^4.17.21"
- checksum: 10/5b0d4e375559fa833a2d206469993635b41a134d7ec2c20b5dcac7c5919c598134148ed10848773ce294e7a82af472090d790a09d207022627da1a6220972437
+ checksum: 10/121355441e903b87a0b9e590eca45a9b355af949148da6d23434f59b2aa753f00e0ffb8bc625d4ca91cf01e5e9782caceb561537d62729a2b2e240b6e640a0f4
languageName: node
linkType: hard
@@ -2940,7 +2940,7 @@ __metadata:
"@storybook/instrumenter@file:../../../code/lib/instrumenter::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/instrumenter@file:../../../code/lib/instrumenter#../../../code/lib/instrumenter::hash=9f8861&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/instrumenter@file:../../../code/lib/instrumenter#../../../code/lib/instrumenter::hash=ffe9d7&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2949,13 +2949,13 @@ __metadata:
"@storybook/preview-api": "workspace:*"
"@vitest/utils": "npm:^1.3.1"
util: "npm:^0.12.4"
- checksum: 10/5328defaee67eb906c05673839abbf388cca0ddb2e66f1eb5fad6c8bca89a8b9df122d5e1b2ab409670f245e37744c3433e1c92c49ad9116fa981c80feac51b3
+ checksum: 10/84948fcfafe05e5934117e6c514a1788f9d146d28f749c11313e5f65c60f3f20be0e659e97f14a6b5ce405b01afa4941571f644a9cb88d8b3a956c2c79413723
languageName: node
linkType: hard
"@storybook/manager-api@file:../../../code/lib/manager-api::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/manager-api@file:../../../code/lib/manager-api#../../../code/lib/manager-api::hash=73f66e&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/manager-api@file:../../../code/lib/manager-api#../../../code/lib/manager-api::hash=3e3312&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2972,20 +2972,20 @@ __metadata:
store2: "npm:^2.14.2"
telejson: "npm:^7.2.0"
ts-dedent: "npm:^2.0.0"
- checksum: 10/16915e26260d957b65691178ffc5b57550b2750e6be44407885673e2df4f4e532cb513844405179e6cba0ae22e0f6d76811c741c0d4ff424703e4e78339c03c1
+ checksum: 10/dcc92a7797ccf0f986ef2eb9077884799e4cc92603ca52a69071b4943ca149fd17d771c64bd1fd474c8287b4bda5385c7b24bada7acc9f7413deac152ec32157
languageName: node
linkType: hard
"@storybook/manager@file:../../../code/ui/manager::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/manager@file:../../../code/ui/manager#../../../code/ui/manager::hash=ca1cc8&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/b99169a99791cda6a1eb5e34a00aff80433a8d8a2af0766035da5eca4a6f36be2dc885ed8f2ca4955aa913dcd80b7a3d0641cd5f0dabd2f5e91d2f87fa5fc7bd
+ resolution: "@storybook/manager@file:../../../code/ui/manager#../../../code/ui/manager::hash=257346&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/cdfcb34cdfaa7b7fbd388c54f2ecc85e0b4276ba1d915cc4b36dfcdd9ab8c5391815ae502089aa77e5dad8e51a064f86771969f20e9d10b5b14973d8e4e80a8b
languageName: node
linkType: hard
"@storybook/nextjs@file:../../../code/frameworks/nextjs::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/nextjs@file:../../../code/frameworks/nextjs#../../../code/frameworks/nextjs::hash=449323&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/nextjs@file:../../../code/frameworks/nextjs#../../../code/frameworks/nextjs::hash=a5b14e&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/core": "npm:^7.23.2"
"@babel/plugin-syntax-bigint": "npm:^7.8.3"
@@ -3043,20 +3043,20 @@ __metadata:
optional: true
webpack:
optional: true
- checksum: 10/cca75d58487e2dcba461dc15fb913f2ec60afa0fddbd0038eba3983f5286fa6555ab4c00e94b6eb1048fad85656a88fb7e5fd6534ec0907c3c46049ace5551dc
+ checksum: 10/86d287d5088a26adabce7b6ca5e56eebedf44df95bd07b1085253e095bea2d1d54898eed384ff7ca75866b00ffa36dd0a0c8f252edc1b4feb48725b6ca2ca851
languageName: node
linkType: hard
"@storybook/node-logger@file:../../../code/lib/node-logger::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/node-logger@file:../../../code/lib/node-logger#../../../code/lib/node-logger::hash=0d0b98&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/a3370020de702f0645ebe90da5e61d2a5d04bf719f6cda3b4c09e2b3f377c49a3d2c922175d2909d00fae0b7ef9453ac6f7ffee14399bd18ae3a6f9783736504
+ resolution: "@storybook/node-logger@file:../../../code/lib/node-logger#../../../code/lib/node-logger::hash=0d5379&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/ba3b49b55a325ec5d885898e5cd61370c19ad27a54315025c315bb08b6a09a64cfd3097748225be1f4b07aad42245a239ac9ba6e957c854ebb48718a43e5c215
languageName: node
linkType: hard
"@storybook/preset-react-webpack@file:../../../code/presets/react-webpack::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preset-react-webpack@file:../../../code/presets/react-webpack#../../../code/presets/react-webpack::hash=72b9b2&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/preset-react-webpack@file:../../../code/presets/react-webpack#../../../code/presets/react-webpack::hash=3c5b01&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-webpack": "workspace:*"
"@storybook/docs-tools": "workspace:*"
@@ -3079,13 +3079,13 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/f0304ce896fb0dc5d0aa170b82a567daccf7d2f45425da0c8ed9136d6f4ec0acd544474e37933145c639bd706e6846f8ec6d766a04b6a92cb00420f9fb498865
+ checksum: 10/3baffd6ce4e642f852c370ccd4ae8098a5e730f4493ce43c8414f0b44e59c8bc8a99d9975cf5149b655f1808e54d274754044f45983b9f1be7c9a28f00931ac2
languageName: node
linkType: hard
"@storybook/preview-api@file:../../../code/lib/preview-api::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preview-api@file:../../../code/lib/preview-api#../../../code/lib/preview-api::hash=8ed046&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/preview-api@file:../../../code/lib/preview-api#../../../code/lib/preview-api::hash=2e825a&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -3101,14 +3101,14 @@ __metadata:
tiny-invariant: "npm:^1.3.1"
ts-dedent: "npm:^2.0.0"
util-deprecate: "npm:^1.0.2"
- checksum: 10/d5a6dc59d0cf9660869c7059567ffe09e1d590835aa781a5a94fc109ae67ae961f82db05a5e983b209e76a595ef3b9669f25897a174701fbcd2846a321ddd8e6
+ checksum: 10/8cb6df33b082d43c40daa182241aef50e583fc3c45d954730df0fbf305645926b2904b5177661a7a6294969014bda8c647f24960afd6114333e7c4bb00caa869
languageName: node
linkType: hard
"@storybook/preview@file:../../../code/lib/preview::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preview@file:../../../code/lib/preview#../../../code/lib/preview::hash=1b46c6&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/6f32462ffef399955e23eda2f74ab4de1187eb9f81490207002fd36cb1801ad7f34cc7a86de10613f0a971c0dad8d7b9790b593fed87b994257b87a5874c7db2
+ resolution: "@storybook/preview@file:../../../code/lib/preview#../../../code/lib/preview::hash=dccd68&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/834521c05fe7496e5d411dd9dc8cd3d2e3902bd101fcfe9e1caa2bace894fb6698d035fd190072a3cf2e294c86324315f30732c16bc30f75a1307feab53c16d1
languageName: node
linkType: hard
@@ -3132,17 +3132,17 @@ __metadata:
"@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim#../../../code/lib/react-dom-shim::hash=cb4d21&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim#../../../code/lib/react-dom-shim::hash=062b74&locator=portable-stories-nextjs%40workspace%3A."
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
- checksum: 10/fd2ab770da0b3450f92cad74f068d297cba56d51730987c2e9a866a01b3507335d913ba705e0c39bd53050f6de3415a6fb5fe32e25f01c246df05de76c888d01
+ checksum: 10/ba63271a1f2d663cd53354798c490d306787b8033586a1062175b89fe4409759cbc959aa34dad12ff8f9bf2e9c141a391784eda81f23cbc9d13495128c9e1611
languageName: node
linkType: hard
"@storybook/react@file:../../../code/renderers/react::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/react@file:../../../code/renderers/react#../../../code/renderers/react::hash=feef2f&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/react@file:../../../code/renderers/react#../../../code/renderers/react::hash=f60a6b&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/docs-tools": "workspace:*"
@@ -3172,24 +3172,24 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/c302a3188a07344a4ed6ff1d5e563eecba774f766433ee6c00a8db0817002cd228d2163247e8a7f0e77930aeb654ccaca2d4240f34aec578de6e1914c1d5ad3f
+ checksum: 10/aa5c6739bfda7f26dcf2155cc61cc02c7387046fd3f1ef0029fa851b56024e5c81e69ef11c7a3f167bf66715161586abc2e29bbcdd5e3ea4ff9f0a34bbdac095
languageName: node
linkType: hard
"@storybook/router@file:../../../code/lib/router::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/router@file:../../../code/lib/router#../../../code/lib/router::hash=12e846&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/router@file:../../../code/lib/router#../../../code/lib/router::hash=f3d914&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
memoizerific: "npm:^1.11.3"
qs: "npm:^6.10.0"
- checksum: 10/211a8eb4828a583ef4b882860a8eebdc9d20e79b576e46f2a53f9b87cfda6c6d95de53344cfdb767bdf64c465f55b70ffe7b2e85a800443ea8867f937bd6f452
+ checksum: 10/ae4218eb5cb26c1fd31b334a5431a228a4fd6f30bff1e4feb68c188317ceece7b91510c0c98c4a2d4fe419baebb2da21ea03d65dfe5123257befdb8ad9e0770c
languageName: node
linkType: hard
"@storybook/telemetry@file:../../../code/lib/telemetry::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/telemetry@file:../../../code/lib/telemetry#../../../code/lib/telemetry::hash=23a3d9&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/telemetry@file:../../../code/lib/telemetry#../../../code/lib/telemetry::hash=ef1a5d&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/core-common": "workspace:*"
@@ -3199,13 +3199,13 @@ __metadata:
fetch-retry: "npm:^5.0.2"
fs-extra: "npm:^11.1.0"
read-pkg-up: "npm:^7.0.1"
- checksum: 10/609dd2f7509d5b8611fead6e310e485dbd0ee4ad9c02d75c7cd66be068fbecb77e2f95f8b7879c01b2767b1e566031e9eae5c616ce36fab23df92d7d6d5f05fc
+ checksum: 10/b4d3d4aa974ea59a259584466abf9dc7ca07b926833e8e4cd53e43bd47a37ead871f2f4458cc2f8d3c9776e41b3daac9a1fe3363d210190b4d45585de86453f7
languageName: node
linkType: hard
"@storybook/test@file:../../../code/lib/test::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/test@file:../../../code/lib/test#../../../code/lib/test::hash=b5fbc8&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/test@file:../../../code/lib/test#../../../code/lib/test::hash=cd3c93&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/core-events": "workspace:*"
@@ -3218,13 +3218,13 @@ __metadata:
"@vitest/spy": "npm:^1.3.1"
chai: "npm:^4.4.1"
util: "npm:^0.12.4"
- checksum: 10/47a026e105e8e42c6942b48d87bf8d96310a8507da9a2f6f923aa3dbb45a75846d59779d2e69b66a3fddbfe355de1e00dd49f8753b4b04939cc755127149f4b8
+ checksum: 10/783d04972494921194bbf60ba366dd62c81340257671acdb2693156dc64c709c64a51efc5fcf528c5a43d11167b2193d4582d24e5012e86407b64fbeda4c1c66
languageName: node
linkType: hard
"@storybook/theming@file:../../../code/lib/theming::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/theming@file:../../../code/lib/theming#../../../code/lib/theming::hash=cf2697&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/theming@file:../../../code/lib/theming#../../../code/lib/theming::hash=9cc340&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1"
"@storybook/client-logger": "workspace:*"
@@ -3238,7 +3238,7 @@ __metadata:
optional: true
react-dom:
optional: true
- checksum: 10/c87b12f79a54319df221805988e5da6955265e1a76f67daba34c401959ca0d12c77b19a53c5ed824782979b09f19eec774e68f6d9bd126e0d0640d8197a2d381
+ checksum: 10/e64850170fec111310877caa5a994ad53c9e072f324d0871d98e34f7d30688dadd7b24914441b3c50f3e9dc3f80909c60fa292e61f7fe6b257a6e19521a6c8e1
languageName: node
linkType: hard
From d9a4ab1c2c7c9f6c7248ad25f5047557996e3db8 Mon Sep 17 00:00:00 2001
From: Kasper Peulen
Date: Wed, 10 Apr 2024 11:18:12 +0200
Subject: [PATCH 075/380] Use beforeEach in test
---
.../actions/template/stories/spies.stories.ts | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/code/addons/actions/template/stories/spies.stories.ts b/code/addons/actions/template/stories/spies.stories.ts
index 824494bda1c9..9749cfb3e492 100644
--- a/code/addons/actions/template/stories/spies.stories.ts
+++ b/code/addons/actions/template/stories/spies.stories.ts
@@ -1,24 +1,24 @@
import { global as globalThis } from '@storybook/global';
import { spyOn } from '@storybook/test';
-export default {
+const meta = {
component: globalThis.Components.Button,
- loaders() {
+ beforeEach() {
spyOn(console, 'log').mockName('console.log');
- },
- args: {
- label: 'Button',
- },
- parameters: {
- chromatic: { disable: true },
+ console.log('first');
},
};
+export default meta;
+
export const ShowSpyOnInActions = {
+ beforeEach() {
+ console.log('second');
+ },
args: {
+ label: 'Button',
onClick: () => {
- console.log('first');
- console.log('second');
+ console.log('third');
},
},
};
From 4d452f3b80714ee810c0a9c537cd69a5f5e0bbce Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Wed, 10 Apr 2024 11:46:34 +0200
Subject: [PATCH 076/380] fix inner class context
---
code/frameworks/nextjs/src/headers/headers.ts | 61 +++++++++++--------
1 file changed, 35 insertions(+), 26 deletions(-)
diff --git a/code/frameworks/nextjs/src/headers/headers.ts b/code/frameworks/nextjs/src/headers/headers.ts
index 46f30fe0c171..b71bece89695 100644
--- a/code/frameworks/nextjs/src/headers/headers.ts
+++ b/code/frameworks/nextjs/src/headers/headers.ts
@@ -8,9 +8,12 @@ import type { HeadersAdapter } from 'next/dist/server/web/spec-extension/adapter
export class HeadersStore extends Headers implements HeadersAdapter {
private headers: IncomingHttpHeaders = {};
- /** @internal */
+ /** Used to restore the mocks. Called internally by @storybook/nextjs
+ * to ensure that the mocks are restored between stories.
+ * @internal
+ * */
mockRestore = () => {
- this.forEach((key) => this.delete(key));
+ this.forEach((key: string) => this.delete(key));
};
/**
@@ -64,33 +67,39 @@ export class HeadersStore extends Headers implements HeadersAdapter {
}
).mockName('headers().forEach');
- public entries = fn(function* (this: HeadersStore): IterableIterator<[string, string]> {
- for (const key of Object.keys(this.headers)) {
- const name = key.toLowerCase();
- // We assert here that this is a string because we got it from the
- // Object.keys() call above.
- const value = this.get(name) as string;
+ public entries = fn(
+ function* (this: HeadersStore): IterableIterator<[string, string]> {
+ for (const key of Object.keys(this.headers)) {
+ const name = key.toLowerCase();
+ // We assert here that this is a string because we got it from the
+ // Object.keys() call above.
+ const value = this.get(name) as string;
- yield [name, value];
- }
- }).mockName('headers().entries');
-
- public keys = fn(function* (this: HeadersStore): IterableIterator {
- for (const key of Object.keys(this.headers)) {
- const name = key.toLowerCase();
- yield name;
- }
- }).mockName('headers().keys');
+ yield [name, value];
+ }
+ }.bind(this)
+ ).mockName('headers().entries');
+
+ public keys = fn(
+ function* (this: HeadersStore): IterableIterator {
+ for (const key of Object.keys(this.headers)) {
+ const name = key.toLowerCase();
+ yield name;
+ }
+ }.bind(this)
+ ).mockName('headers().keys');
- public values = fn(function* (this: HeadersStore): IterableIterator {
- for (const key of Object.keys(this.headers)) {
- // We assert here that this is a string because we got it from the
- // Object.keys() call above.
- const value = this.get(key) as string;
+ public values = fn(
+ function* (this: HeadersStore): IterableIterator {
+ for (const key of Object.keys(this.headers)) {
+ // We assert here that this is a string because we got it from the
+ // Object.keys() call above.
+ const value = this.get(key) as string;
- yield value;
- }
- }).mockName('headers().values');
+ yield value;
+ }
+ }.bind(this)
+ ).mockName('headers().values');
public [Symbol.iterator](): IterableIterator<[string, string]> {
return this.entries();
From fbb33d122bc277cb9a90ffa364bf2a59055eb1eb Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Wed, 10 Apr 2024 11:49:12 +0200
Subject: [PATCH 077/380] Refactor cookies.ts to add internal documentation for
mockRestore method
---
code/frameworks/nextjs/src/headers/cookies.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/code/frameworks/nextjs/src/headers/cookies.ts b/code/frameworks/nextjs/src/headers/cookies.ts
index 13bc7779d3ef..6466ad439c55 100644
--- a/code/frameworks/nextjs/src/headers/cookies.ts
+++ b/code/frameworks/nextjs/src/headers/cookies.ts
@@ -41,7 +41,10 @@ class CookieStore implements RequestCookies {
return this._parsed[Symbol.iterator]();
}
- /** @internal */
+ /** Used to restore the mocks. Called internally by @storybook/nextjs
+ * to ensure that the mocks are restored between stories.
+ * @internal
+ * */
mockRestore = () => {
this.clear();
this._headers.mockRestore();
From 7db928e22c47a008d5481a86c4ea9c2d614ddd9a Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Mon, 8 Apr 2024 17:54:06 +0200
Subject: [PATCH 078/380] NextJS: Spy next/router and next/navigation useRouter
hooks
---
code/frameworks/nextjs/package.json | 7 +-
.../nextjs/src/routing/decorator.tsx | 7 +-
.../{ => navigation}/app-router-provider.tsx | 29 +-----
.../nextjs/src/routing/navigation/index.ts | 47 ++++++++++
.../src/routing/page-router-provider.tsx | 69 --------------
.../nextjs/src/routing/router/index.ts | 82 ++++++++++++++++
.../routing/router/page-router-provider.tsx | 34 +++++++
.../Router.stories.jsx | 23 ++++-
.../Navigation.stories.tsx | 23 ++++-
.../Router.stories.tsx | 93 +++++++++++++++++++
code/yarn.lock | 1 -
11 files changed, 310 insertions(+), 105 deletions(-)
rename code/frameworks/nextjs/src/routing/{ => navigation}/app-router-provider.tsx (70%)
create mode 100644 code/frameworks/nextjs/src/routing/navigation/index.ts
delete mode 100644 code/frameworks/nextjs/src/routing/page-router-provider.tsx
create mode 100644 code/frameworks/nextjs/src/routing/router/index.ts
create mode 100644 code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
create mode 100644 code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json
index e30984136eae..ad48325066c4 100644
--- a/code/frameworks/nextjs/package.json
+++ b/code/frameworks/nextjs/package.json
@@ -52,6 +52,8 @@
"require": "./dist/headers/index.js",
"import": "./dist/headers/index.mjs"
},
+ "./router": "./dist/routing/router/index.mjs",
+ "./navigation": "./dist/routing/navigation/index.mjs",
"./package.json": "./package.json"
},
"main": "dist/index.js",
@@ -97,7 +99,6 @@
"@babel/preset-typescript": "^7.23.2",
"@babel/runtime": "^7.23.2",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
- "@storybook/addon-actions": "workspace:*",
"@storybook/builder-webpack5": "workspace:*",
"@storybook/core-common": "workspace:*",
"@storybook/core-events": "workspace:*",
@@ -168,6 +169,8 @@
"./src/preset.ts",
"./src/headers/index.ts",
"./src/preview.tsx",
+ "./src/routing/router/index.ts",
+ "./src/routing/navigation/index.ts",
"./src/next-image-loader-stub.ts",
"./src/images/decorator.tsx",
"./src/images/next-legacy-image.tsx",
@@ -184,4 +187,4 @@
"platform": "node"
},
"gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae17"
-}
+}
\ No newline at end of file
diff --git a/code/frameworks/nextjs/src/routing/decorator.tsx b/code/frameworks/nextjs/src/routing/decorator.tsx
index 939c3ed0114b..d45f61b69c14 100644
--- a/code/frameworks/nextjs/src/routing/decorator.tsx
+++ b/code/frameworks/nextjs/src/routing/decorator.tsx
@@ -1,8 +1,7 @@
import * as React from 'react';
import type { Addon_StoryContext } from '@storybook/types';
-import { action } from '@storybook/addon-actions';
-import { AppRouterProvider } from './app-router-provider';
-import { PageRouterProvider } from './page-router-provider';
+import { AppRouterProvider } from './navigation/app-router-provider';
+import { PageRouterProvider } from './router/page-router-provider';
import type { RouteParams, NextAppDirectory } from './types';
const defaultRouterParams: RouteParams = {
@@ -23,7 +22,6 @@ export const RouterDecorator = (
}
return (
(...args: any[]) => void;
routeParams: RouteParams;
};
@@ -28,7 +28,6 @@ const getParallelRoutes = (segmentsList: Array): FlightRouterState => {
export const AppRouterProvider: React.FC> = ({
children,
- action,
routeParams,
}) => {
const { pathname, query, segments = [], ...restRouteParams } = routeParams;
@@ -55,29 +54,7 @@ export const AppRouterProvider: React.FC
- {
- action('nextNavigation.refresh')();
- },
- ...restRouteParams,
- }}
- >
+
{
+ if (!navigationAPI) {
+ const navigationActions = {
+ push: fn().mockName('nextNavigation.push'),
+ replace: fn().mockName('nextNavigation.replace'),
+ forward: fn().mockName('nextNavigation.forward'),
+ back: fn().mockName('nextNavigation.back'),
+ prefetch: fn().mockName('nextNavigation.prefetch'),
+ refresh: fn().mockName('nextNavigation.refresh'),
+ };
+
+ if (overrides) {
+ Object.keys(navigationActions).forEach((key) => {
+ if (key in overrides) {
+ (navigationActions as any)[key] = fn((...args: any[]) => {
+ return (overrides as any)[key](...args);
+ }).mockName(`nextNavigation.${key}`);
+ }
+ });
+ }
+
+ navigationAPI = navigationActions;
+ }
+
+ return navigationAPI;
+};
+
+export const useRouter = () => {
+ if (!navigationAPI) {
+ // TODO: improve error message
+ throw new Error('The router mock was not created yet. This is probably a bug.');
+ }
+
+ return navigationAPI;
+};
diff --git a/code/frameworks/nextjs/src/routing/page-router-provider.tsx b/code/frameworks/nextjs/src/routing/page-router-provider.tsx
deleted file mode 100644
index 066e7f32b3fd..000000000000
--- a/code/frameworks/nextjs/src/routing/page-router-provider.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import type { Globals } from '@storybook/csf';
-import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime';
-import type { PropsWithChildren } from 'react';
-import React from 'react';
-import type { RouteParams } from './types';
-
-type PageRouterProviderProps = {
- action: (name: string) => (...args: any[]) => void;
- routeParams: RouteParams;
- globals: Globals;
-};
-
-export const PageRouterProvider: React.FC> = ({
- children,
- action,
- routeParams,
- globals,
-}) => (
-
- {children}
-
-);
diff --git a/code/frameworks/nextjs/src/routing/router/index.ts b/code/frameworks/nextjs/src/routing/router/index.ts
new file mode 100644
index 000000000000..7c0253147385
--- /dev/null
+++ b/code/frameworks/nextjs/src/routing/router/index.ts
@@ -0,0 +1,82 @@
+import type { Mock } from '@storybook/test';
+import { fn } from '@storybook/test';
+import type { NextRouter } from 'next/router';
+
+let routerAPI: {
+ push: Mock;
+ replace: Mock;
+ reload: Mock;
+ back: Mock;
+ forward: Mock;
+ prefetch: Mock;
+ beforePopState: Mock;
+ events: {
+ on: Mock;
+ off: Mock;
+ emit: Mock;
+ };
+};
+
+export const createRouter = ({ overrides }: { overrides?: Partial }) => {
+ if (!routerAPI) {
+ const routerActions: Partial = {
+ push: fn((..._args: any[]) => {
+ return Promise.resolve(true);
+ }).mockName('nextRouter.push'),
+ replace: fn((..._args: any[]) => {
+ return Promise.resolve(true);
+ }).mockName('nextRouter.replace'),
+ reload: fn((..._args: any[]) => {}).mockName('nextRouter.reload'),
+ back: fn((..._args: any[]) => {}).mockName('nextRouter.back'),
+ forward: fn(() => {}).mockName('nextRouter.forward'),
+ prefetch: fn((..._args: any[]) => {
+ return Promise.resolve();
+ }).mockName('nextRouter.prefetch'),
+ beforePopState: fn((..._args: any[]) => {}).mockName('nextRouter.beforePopState'),
+ };
+
+ const routerEvents: Partial = {
+ events: {
+ on: fn((..._args: any[]) => {}).mockName('nextRouter.events.on'),
+ off: fn((..._args: any[]) => {}).mockName('nextRouter.events.off'),
+ emit: fn((..._args: any[]) => {}).mockName('nextRouter.events.emit'),
+ },
+ };
+
+ if (overrides) {
+ Object.keys(routerActions).forEach((key) => {
+ if (key in overrides) {
+ (routerActions as any)[key] = fn((...args: any[]) => {
+ return (overrides as any)[key](...args);
+ }).mockName(`nextRouter.${key}`);
+ }
+ });
+ }
+
+ if (overrides?.events) {
+ Object.keys(routerEvents.events!).forEach((key) => {
+ if (key in routerEvents.events!) {
+ (routerEvents.events as any)[key] = fn((...args: any[]) => {
+ return (overrides.events as any)[key](...args);
+ }).mockName(`nextRouter.events.${key}`);
+ }
+ });
+ }
+
+ routerAPI = {
+ ...routerActions,
+ // @ts-expect-error TODO improve typings
+ events: routerEvents.events,
+ };
+ }
+
+ return routerAPI;
+};
+
+export const useRouter = () => {
+ if (!routerAPI) {
+ throw new Error('Router not created yet');
+ }
+
+ return routerAPI;
+};
diff --git a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
new file mode 100644
index 000000000000..99dcf4924ba3
--- /dev/null
+++ b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
@@ -0,0 +1,34 @@
+import type { Globals } from '@storybook/csf';
+import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime';
+import type { PropsWithChildren } from 'react';
+import React from 'react';
+import type { RouteParams } from '../types';
+import { createRouter } from './index';
+
+type PageRouterProviderProps = {
+ routeParams: RouteParams;
+ globals: Globals;
+};
+
+export const PageRouterProvider: React.FC> = ({
+ children,
+ routeParams,
+ globals,
+}) => (
+
+ {children}
+
+);
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx
index 2ea7511a2f4e..ceee12ad3666 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx
@@ -1,3 +1,5 @@
+import { expect, within, userEvent } from '@storybook/test';
+import { useRouter as useRouterMock } from '@storybook/nextjs/router';
import { useRouter } from 'next/router';
import React from 'react';
@@ -61,9 +63,28 @@ export default {
query: {
foo: 'bar',
},
+ prefetch: () => {
+ console.log('custom prefetch');
+ },
},
},
},
};
-export const Default = {};
+export const Default = {
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+
+ await step('Asserts whether forward hook is called', async () => {
+ const forwardBtn = await canvas.findByText('Go forward');
+ await userEvent.click(forwardBtn);
+ await expect(useRouterMock().forward).toHaveBeenCalled();
+ });
+
+ await step('Asserts whether custom prefetch hook is called', async () => {
+ const prefetchBtn = await canvas.findByText('Prefetch');
+ await userEvent.click(prefetchBtn);
+ await expect(useRouterMock().prefetch).toHaveBeenCalledWith('/prefetched-html');
+ });
+ },
+};
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
index 6287d5ae2a73..79520290c716 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
@@ -2,6 +2,8 @@
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { expect, userEvent, within } from '@storybook/test';
+import { useRouter as useRouterMock } from '@storybook/nextjs/navigation';
function Component() {
const router = useRouter();
@@ -73,9 +75,28 @@ export default {
query: {
foo: 'bar',
},
+ prefetch: () => {
+ console.log('custom prefetch');
+ },
},
},
},
} as Meta;
-export const Default: StoryObj = {};
+export const Default: StoryObj = {
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+
+ await step('Asserts whether forward hook is called', async () => {
+ const forwardBtn = await canvas.findByText('Go forward');
+ await userEvent.click(forwardBtn);
+ await expect(useRouterMock().forward).toHaveBeenCalled();
+ });
+
+ await step('Asserts whether custom prefetch hook is called', async () => {
+ const prefetchBtn = await canvas.findByText('Prefetch');
+ await userEvent.click(prefetchBtn);
+ await expect(useRouterMock().prefetch).toHaveBeenCalledWith('/prefetched-html');
+ });
+ },
+};
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
new file mode 100644
index 000000000000..0319e17efa02
--- /dev/null
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
@@ -0,0 +1,93 @@
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import { expect, within, userEvent } from '@storybook/test';
+import { useRouter as useRouterMock } from '@storybook/nextjs/router';
+import { useRouter } from 'next/router';
+
+function Component() {
+ const router = useRouter();
+ const searchParams = router.query;
+
+ const routerActions = [
+ {
+ cb: () => router.back(),
+ name: 'Go back',
+ },
+ {
+ cb: () => router.forward(),
+ name: 'Go forward',
+ },
+ {
+ cb: () => router.prefetch('/prefetched-html'),
+ name: 'Prefetch',
+ },
+ {
+ // @ts-expect-error (old API)
+ cb: () => router.push('/push-html', { forceOptimisticNavigation: true }),
+ name: 'Push HTML',
+ },
+ {
+ // @ts-expect-error (old API)
+ cb: () => router.replace('/replaced-html', { forceOptimisticNavigation: true }),
+ name: 'Replace',
+ },
+ ];
+
+ return (
+
+
pathname: {router.pathname}
+
+ searchparams:{' '}
+
+ {Object.entries(searchParams).map(([key, value]) => (
+
+ {key}: {value}
+
+ ))}
+
+
+ {routerActions.map(({ cb, name }) => (
+
+
+ {name}
+
+
+ ))}
+
+ );
+}
+
+export default {
+ component: Component,
+ parameters: {
+ nextjs: {
+ router: {
+ pathname: '/hello',
+ query: {
+ foo: 'bar',
+ },
+ prefetch: () => {
+ console.log('custom prefetch');
+ },
+ },
+ },
+ },
+} as Meta;
+
+export const Default: StoryObj = {
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+
+ await step('Asserts whether forward hook is called', async () => {
+ const forwardBtn = await canvas.findByText('Go forward');
+ await userEvent.click(forwardBtn);
+ await expect(useRouterMock().forward).toHaveBeenCalled();
+ });
+
+ await step('Asserts whether custom prefetch hook is called', async () => {
+ const prefetchBtn = await canvas.findByText('Prefetch');
+ await userEvent.click(prefetchBtn);
+ await expect(useRouterMock().prefetch).toHaveBeenCalledWith('/prefetched-html');
+ });
+ },
+};
diff --git a/code/yarn.lock b/code/yarn.lock
index aa1315007109..a0839ce820a0 100644
--- a/code/yarn.lock
+++ b/code/yarn.lock
@@ -5940,7 +5940,6 @@ __metadata:
"@babel/runtime": "npm:^7.23.2"
"@babel/types": "npm:^7.23.0"
"@pmmmwh/react-refresh-webpack-plugin": "npm:^0.5.11"
- "@storybook/addon-actions": "workspace:*"
"@storybook/builder-webpack5": "workspace:*"
"@storybook/core-common": "workspace:*"
"@storybook/core-events": "workspace:*"
From 501301a4072734e9e610da70bc86d26f553ac0e6 Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Tue, 9 Apr 2024 11:13:37 +0200
Subject: [PATCH 079/380] fix default Router mock export, add improvements
---
.../nextjs/src/routing/navigation/index.ts | 8 +--
.../nextjs/src/routing/router/index.ts | 49 +++++++++++++------
.../routing/router/page-router-provider.tsx | 12 +----
.../Router.stories.tsx | 10 +++-
.../core-events/src/errors/preview-errors.ts | 17 +++++++
5 files changed, 67 insertions(+), 29 deletions(-)
diff --git a/code/frameworks/nextjs/src/routing/navigation/index.ts b/code/frameworks/nextjs/src/routing/navigation/index.ts
index 3c9a84f4df92..23e34cb0c190 100644
--- a/code/frameworks/nextjs/src/routing/navigation/index.ts
+++ b/code/frameworks/nextjs/src/routing/navigation/index.ts
@@ -1,5 +1,6 @@
import type { Mock } from '@storybook/test';
import { fn } from '@storybook/test';
+import { NextjsRouterMocksNotAvailable } from '@storybook/core-events/preview-errors';
let navigationAPI: {
push: Mock;
@@ -10,7 +11,7 @@ let navigationAPI: {
refresh: Mock;
};
-export const createNavigation = ({ overrides }: { overrides?: any }) => {
+export const createNavigation = (overrides: any) => {
if (!navigationAPI) {
const navigationActions = {
push: fn().mockName('nextNavigation.push'),
@@ -39,8 +40,9 @@ export const createNavigation = ({ overrides }: { overrides?: any }) => {
export const useRouter = () => {
if (!navigationAPI) {
- // TODO: improve error message
- throw new Error('The router mock was not created yet. This is probably a bug.');
+ throw new NextjsRouterMocksNotAvailable({
+ importType: 'next/navigation',
+ });
}
return navigationAPI;
diff --git a/code/frameworks/nextjs/src/routing/router/index.ts b/code/frameworks/nextjs/src/routing/router/index.ts
index 7c0253147385..5332c4111d74 100644
--- a/code/frameworks/nextjs/src/routing/router/index.ts
+++ b/code/frameworks/nextjs/src/routing/router/index.ts
@@ -1,6 +1,20 @@
import type { Mock } from '@storybook/test';
import { fn } from '@storybook/test';
+import { NextjsRouterMocksNotAvailable } from '@storybook/core-events/preview-errors';
import type { NextRouter } from 'next/router';
+import singletonRouter from 'next/router';
+
+const defaultRouterState = {
+ route: '/',
+ asPath: '/',
+ basePath: '/',
+ pathname: '/',
+ query: {},
+ isFallback: false,
+ isLocaleDomain: false,
+ isReady: true,
+ isPreview: false,
+};
let routerAPI: {
push: Mock;
@@ -15,9 +29,9 @@ let routerAPI: {
off: Mock;
emit: Mock;
};
-};
+} & typeof defaultRouterState;
-export const createRouter = ({ overrides }: { overrides?: Partial }) => {
+export const createRouter = (overrides?: Partial) => {
if (!routerAPI) {
const routerActions: Partial = {
push: fn((..._args: any[]) => {
@@ -35,12 +49,10 @@ export const createRouter = ({ overrides }: { overrides?: Partial })
beforePopState: fn((..._args: any[]) => {}).mockName('nextRouter.beforePopState'),
};
- const routerEvents: Partial = {
- events: {
- on: fn((..._args: any[]) => {}).mockName('nextRouter.events.on'),
- off: fn((..._args: any[]) => {}).mockName('nextRouter.events.off'),
- emit: fn((..._args: any[]) => {}).mockName('nextRouter.events.emit'),
- },
+ const routerEvents: NextRouter['events'] = {
+ on: fn((..._args: any[]) => {}).mockName('nextRouter.events.on'),
+ off: fn((..._args: any[]) => {}).mockName('nextRouter.events.off'),
+ emit: fn((..._args: any[]) => {}).mockName('nextRouter.events.emit'),
};
if (overrides) {
@@ -54,9 +66,9 @@ export const createRouter = ({ overrides }: { overrides?: Partial })
}
if (overrides?.events) {
- Object.keys(routerEvents.events!).forEach((key) => {
- if (key in routerEvents.events!) {
- (routerEvents.events as any)[key] = fn((...args: any[]) => {
+ Object.keys(routerEvents).forEach((key) => {
+ if (key in routerEvents) {
+ (routerEvents as any)[key] = fn((...args: any[]) => {
return (overrides.events as any)[key](...args);
}).mockName(`nextRouter.events.${key}`);
}
@@ -64,18 +76,27 @@ export const createRouter = ({ overrides }: { overrides?: Partial })
}
routerAPI = {
+ ...defaultRouterState,
+ ...overrides,
...routerActions,
// @ts-expect-error TODO improve typings
- events: routerEvents.events,
+ events: routerEvents,
};
+
+ // overwrite the singleton router from next/router
+ singletonRouter.router = routerAPI as any;
+ singletonRouter.readyCallbacks.forEach((cb) => cb());
+ singletonRouter.readyCallbacks = [];
}
- return routerAPI;
+ return routerAPI as unknown as NextRouter;
};
export const useRouter = () => {
if (!routerAPI) {
- throw new Error('Router not created yet');
+ throw new NextjsRouterMocksNotAvailable({
+ importType: 'next/router',
+ });
}
return routerAPI;
diff --git a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
index 99dcf4924ba3..abd948d0d9dd 100644
--- a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
+++ b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
@@ -16,18 +16,10 @@ export const PageRouterProvider: React.FC (
{children}
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
index 0319e17efa02..ea524e55f9b8 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
@@ -77,17 +77,23 @@ export default {
export const Default: StoryObj = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
+ const routerMock = useRouterMock();
+
+ await step('Router property overrides should be available', async () => {
+ await expect(routerMock.pathname).toBe('/hello');
+ await expect(routerMock.query).toEqual({ foo: 'bar' });
+ });
await step('Asserts whether forward hook is called', async () => {
const forwardBtn = await canvas.findByText('Go forward');
await userEvent.click(forwardBtn);
- await expect(useRouterMock().forward).toHaveBeenCalled();
+ await expect(routerMock.forward).toHaveBeenCalled();
});
await step('Asserts whether custom prefetch hook is called', async () => {
const prefetchBtn = await canvas.findByText('Prefetch');
await userEvent.click(prefetchBtn);
- await expect(useRouterMock().prefetch).toHaveBeenCalledWith('/prefetched-html');
+ await expect(routerMock.prefetch).toHaveBeenCalledWith('/prefetched-html');
});
},
};
diff --git a/code/lib/core-events/src/errors/preview-errors.ts b/code/lib/core-events/src/errors/preview-errors.ts
index fb33c42688b3..0872718a03c1 100644
--- a/code/lib/core-events/src/errors/preview-errors.ts
+++ b/code/lib/core-events/src/errors/preview-errors.ts
@@ -27,6 +27,7 @@ export enum Category {
RENDERER_VUE = 'RENDERER_VUE',
RENDERER_VUE3 = 'RENDERER_VUE3',
RENDERER_WEB_COMPONENTS = 'RENDERER_WEB-COMPONENTS',
+ FRAMEWORK_NEXTJS = 'FRAMEWORK_NEXTJS',
}
export class MissingStoryAfterHmrError extends StorybookError {
@@ -235,3 +236,19 @@ export class StoryStoreAccessedBeforeInitializationError extends StorybookError
remove access to the store entirely`;
}
}
+
+export class NextjsRouterMocksNotAvailable extends StorybookError {
+ readonly category = Category.FRAMEWORK_NEXTJS;
+
+ readonly code = 1;
+
+ constructor(public data: { importType: string }) {
+ super();
+ }
+
+ template() {
+ return dedent`
+ Tried to access router mocks from ${this.data.importType} but they were not created yet. You might be running code in an unsupported environment.
+ `;
+ }
+}
From a6de166b3620d294a93dcd72b3b3bcd9ae496c0a Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Tue, 9 Apr 2024 11:17:30 +0200
Subject: [PATCH 080/380] add portable stories tests
---
code/frameworks/nextjs/package.json | 12 ++++++--
.../Navigation.stories.tsx | 5 ++--
.../nextjs/stories/Navigation.stories.tsx | 24 ++++++++++++++-
.../nextjs/stories/Router.stories.tsx | 30 +++++++++++++++++--
.../nextjs/stories/portable-stories.test.tsx | 2 +-
.../nextjs/yarn.lock | 1 -
6 files changed, 64 insertions(+), 10 deletions(-)
diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json
index ad48325066c4..24a235df9501 100644
--- a/code/frameworks/nextjs/package.json
+++ b/code/frameworks/nextjs/package.json
@@ -52,8 +52,16 @@
"require": "./dist/headers/index.js",
"import": "./dist/headers/index.mjs"
},
- "./router": "./dist/routing/router/index.mjs",
- "./navigation": "./dist/routing/navigation/index.mjs",
+ "./router": {
+ "types": "./dist/routing/router/index.d.ts",
+ "require": "./dist/routing/router/index.js",
+ "import": "./dist/routing/router/index.mjs"
+ },
+ "./navigation": {
+ "types": "./dist/routing/navigation/index.d.ts",
+ "require": "./dist/routing/navigation/index.js",
+ "import": "./dist/routing/navigation/index.mjs"
+ },
"./package.json": "./package.json"
},
"main": "dist/index.js",
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
index 79520290c716..1049d345c6d4 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
@@ -86,17 +86,18 @@ export default {
export const Default: StoryObj = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
+ const routerMock = useRouterMock();
await step('Asserts whether forward hook is called', async () => {
const forwardBtn = await canvas.findByText('Go forward');
await userEvent.click(forwardBtn);
- await expect(useRouterMock().forward).toHaveBeenCalled();
+ await expect(routerMock.forward).toHaveBeenCalled();
});
await step('Asserts whether custom prefetch hook is called', async () => {
const prefetchBtn = await canvas.findByText('Prefetch');
await userEvent.click(prefetchBtn);
- await expect(useRouterMock().prefetch).toHaveBeenCalledWith('/prefetched-html');
+ await expect(routerMock.prefetch).toHaveBeenCalledWith('/prefetched-html');
});
},
};
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Navigation.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Navigation.stories.tsx
index 6287d5ae2a73..1049d345c6d4 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Navigation.stories.tsx
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Navigation.stories.tsx
@@ -2,6 +2,8 @@
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { expect, userEvent, within } from '@storybook/test';
+import { useRouter as useRouterMock } from '@storybook/nextjs/navigation';
function Component() {
const router = useRouter();
@@ -73,9 +75,29 @@ export default {
query: {
foo: 'bar',
},
+ prefetch: () => {
+ console.log('custom prefetch');
+ },
},
},
},
} as Meta;
-export const Default: StoryObj = {};
+export const Default: StoryObj = {
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+ const routerMock = useRouterMock();
+
+ await step('Asserts whether forward hook is called', async () => {
+ const forwardBtn = await canvas.findByText('Go forward');
+ await userEvent.click(forwardBtn);
+ await expect(routerMock.forward).toHaveBeenCalled();
+ });
+
+ await step('Asserts whether custom prefetch hook is called', async () => {
+ const prefetchBtn = await canvas.findByText('Prefetch');
+ await userEvent.click(prefetchBtn);
+ await expect(routerMock.prefetch).toHaveBeenCalledWith('/prefetched-html');
+ });
+ },
+};
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
index 2ea7511a2f4e..0319e17efa02 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
@@ -1,5 +1,8 @@
-import { useRouter } from 'next/router';
import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import { expect, within, userEvent } from '@storybook/test';
+import { useRouter as useRouterMock } from '@storybook/nextjs/router';
+import { useRouter } from 'next/router';
function Component() {
const router = useRouter();
@@ -19,10 +22,12 @@ function Component() {
name: 'Prefetch',
},
{
+ // @ts-expect-error (old API)
cb: () => router.push('/push-html', { forceOptimisticNavigation: true }),
name: 'Push HTML',
},
{
+ // @ts-expect-error (old API)
cb: () => router.replace('/replaced-html', { forceOptimisticNavigation: true }),
name: 'Replace',
},
@@ -61,9 +66,28 @@ export default {
query: {
foo: 'bar',
},
+ prefetch: () => {
+ console.log('custom prefetch');
+ },
},
},
},
-};
+} as Meta;
-export const Default = {};
+export const Default: StoryObj = {
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+
+ await step('Asserts whether forward hook is called', async () => {
+ const forwardBtn = await canvas.findByText('Go forward');
+ await userEvent.click(forwardBtn);
+ await expect(useRouterMock().forward).toHaveBeenCalled();
+ });
+
+ await step('Asserts whether custom prefetch hook is called', async () => {
+ const prefetchBtn = await canvas.findByText('Prefetch');
+ await userEvent.click(prefetchBtn);
+ await expect(useRouterMock().prefetch).toHaveBeenCalledWith('/prefetched-html');
+ });
+ },
+};
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/portable-stories.test.tsx b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/portable-stories.test.tsx
index d6789edde932..79684dc595e0 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/portable-stories.test.tsx
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/portable-stories.test.tsx
@@ -29,7 +29,7 @@ const runTests = (name: string, storiesModule: any) => {
})
}
-// // example with composeStory, returns a single story composed with args/decorators
+// example with composeStory, returns a single story composed with args/decorators
describe('renders', () => {
runTests('nextHeaderStories', nextHeaderStories);
runTests('navigationStories', navigationStories);
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
index 7b54b424d5b9..46d9fd1b8d40 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
@@ -3001,7 +3001,6 @@ __metadata:
"@babel/preset-typescript": "npm:^7.23.2"
"@babel/runtime": "npm:^7.23.2"
"@pmmmwh/react-refresh-webpack-plugin": "npm:^0.5.11"
- "@storybook/addon-actions": "workspace:*"
"@storybook/builder-webpack5": "workspace:*"
"@storybook/core-common": "workspace:*"
"@storybook/core-events": "workspace:*"
From 6037744e0729357e0012f99a8673e507c640bbc9 Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Tue, 9 Apr 2024 12:27:37 +0200
Subject: [PATCH 081/380] set up mocks in loaders instead of decorators
---
code/frameworks/nextjs/src/preview.tsx | 14 ++++++++++-
.../nextjs/src/routing/decorator.tsx | 10 ++------
.../navigation/app-router-provider.tsx | 6 ++---
.../nextjs/src/routing/router/index.ts | 2 +-
.../routing/router/page-router-provider.tsx | 24 +++----------------
.../Router.stories.tsx | 16 +++++++++----
.../core-events/src/errors/preview-errors.ts | 2 +-
.../nextjs/stories/Router.stories.tsx | 20 +++++++++++++---
8 files changed, 52 insertions(+), 42 deletions(-)
diff --git a/code/frameworks/nextjs/src/preview.tsx b/code/frameworks/nextjs/src/preview.tsx
index 7fb164d1f0de..7dbfb344861b 100644
--- a/code/frameworks/nextjs/src/preview.tsx
+++ b/code/frameworks/nextjs/src/preview.tsx
@@ -11,6 +11,8 @@ import { HeadManagerDecorator } from './head-manager/decorator';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore we must ignore types here as during compilation they are not generated yet
import { cookies, headers } from '@storybook/nextjs/headers.mock';
+import { createRouter } from './routing/router';
+import { createNavigation } from './routing/navigation';
function addNextHeadCount() {
const meta = document.createElement('meta');
@@ -28,9 +30,19 @@ export const decorators: Addon_DecoratorFunction[] = [
HeadManagerDecorator,
];
-export const loaders: Addon_LoaderFunction = async () => {
+export const loaders: Addon_LoaderFunction = async ({ globals, parameters }) => {
cookies().mockRestore();
headers().mockRestore();
+
+ const { router, appDirectory } = parameters.nextjs ?? {};
+ if (appDirectory) {
+ createNavigation(router);
+ } else {
+ createRouter({
+ locale: globals.locale,
+ ...router,
+ });
+ }
};
export const parameters = {
diff --git a/code/frameworks/nextjs/src/routing/decorator.tsx b/code/frameworks/nextjs/src/routing/decorator.tsx
index d45f61b69c14..4edd87812b3f 100644
--- a/code/frameworks/nextjs/src/routing/decorator.tsx
+++ b/code/frameworks/nextjs/src/routing/decorator.tsx
@@ -11,7 +11,7 @@ const defaultRouterParams: RouteParams = {
export const RouterDecorator = (
Story: React.FC,
- { globals, parameters }: Addon_StoryContext
+ { parameters }: Addon_StoryContext
): React.ReactNode => {
const nextAppDirectory =
(parameters.nextjs?.appDirectory as NextAppDirectory | undefined) ?? false;
@@ -33,13 +33,7 @@ export const RouterDecorator = (
}
return (
-
+
);
diff --git a/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx b/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
index d4fcd1501676..efd122bae7c3 100644
--- a/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
+++ b/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
@@ -10,7 +10,7 @@ import {
} from 'next/dist/shared/lib/hooks-client-context.shared-runtime';
import type { FlightRouterState } from 'next/dist/server/app-render/types';
import type { RouteParams } from '../types';
-import { createNavigation } from './index';
+import { useRouter } from './index';
type AppRouterProviderProps = {
routeParams: RouteParams;
@@ -30,7 +30,7 @@ export const AppRouterProvider: React.FC {
- const { pathname, query, segments = [], ...restRouteParams } = routeParams;
+ const { pathname, query, segments = [] } = routeParams;
const tree: FlightRouterState = [pathname, { children: getParallelRoutes([...segments]) }];
@@ -54,7 +54,7 @@ export const AppRouterProvider: React.FC
-
+
) => {
+export const createRouter = (overrides: Partial) => {
if (!routerAPI) {
const routerActions: Partial = {
push: fn((..._args: any[]) => {
diff --git a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
index abd948d0d9dd..b56dd5f97e9c 100644
--- a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
+++ b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
@@ -1,26 +1,8 @@
-import type { Globals } from '@storybook/csf';
import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime';
import type { PropsWithChildren } from 'react';
import React from 'react';
-import type { RouteParams } from '../types';
-import { createRouter } from './index';
+import { useRouter } from './index';
-type PageRouterProviderProps = {
- routeParams: RouteParams;
- globals: Globals;
-};
-
-export const PageRouterProvider: React.FC> = ({
- children,
- routeParams,
- globals,
-}) => (
-
- {children}
-
+export const PageRouterProvider: React.FC = ({ children }) => (
+ {children}
);
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
index ea524e55f9b8..7f3a60a787f0 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { expect, within, userEvent } from '@storybook/test';
import { useRouter as useRouterMock } from '@storybook/nextjs/router';
-import { useRouter } from 'next/router';
+import Router, { useRouter } from 'next/router';
function Component() {
const router = useRouter();
@@ -79,11 +79,19 @@ export const Default: StoryObj = {
const canvas = within(canvasElement);
const routerMock = useRouterMock();
- await step('Router property overrides should be available', async () => {
- await expect(routerMock.pathname).toBe('/hello');
- await expect(routerMock.query).toEqual({ foo: 'bar' });
+ await step('Router property overrides should be available in useRouter fn', async () => {
+ await expect(Router.pathname).toBe('/hello');
+ await expect(Router.query).toEqual({ foo: 'bar' });
});
+ await step(
+ 'Router property overrides should be available in default export from next/router',
+ async () => {
+ await expect(Router.pathname).toBe('/hello');
+ await expect(Router.query).toEqual({ foo: 'bar' });
+ }
+ );
+
await step('Asserts whether forward hook is called', async () => {
const forwardBtn = await canvas.findByText('Go forward');
await userEvent.click(forwardBtn);
diff --git a/code/lib/core-events/src/errors/preview-errors.ts b/code/lib/core-events/src/errors/preview-errors.ts
index 0872718a03c1..5821e6444509 100644
--- a/code/lib/core-events/src/errors/preview-errors.ts
+++ b/code/lib/core-events/src/errors/preview-errors.ts
@@ -248,7 +248,7 @@ export class NextjsRouterMocksNotAvailable extends StorybookError {
template() {
return dedent`
- Tried to access router mocks from ${this.data.importType} but they were not created yet. You might be running code in an unsupported environment.
+ Tried to access router mocks from "${this.data.importType}" but they were not created yet. You might be running code in an unsupported environment.
`;
}
}
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
index 0319e17efa02..7f3a60a787f0 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { expect, within, userEvent } from '@storybook/test';
import { useRouter as useRouterMock } from '@storybook/nextjs/router';
-import { useRouter } from 'next/router';
+import Router, { useRouter } from 'next/router';
function Component() {
const router = useRouter();
@@ -77,17 +77,31 @@ export default {
export const Default: StoryObj = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
+ const routerMock = useRouterMock();
+
+ await step('Router property overrides should be available in useRouter fn', async () => {
+ await expect(Router.pathname).toBe('/hello');
+ await expect(Router.query).toEqual({ foo: 'bar' });
+ });
+
+ await step(
+ 'Router property overrides should be available in default export from next/router',
+ async () => {
+ await expect(Router.pathname).toBe('/hello');
+ await expect(Router.query).toEqual({ foo: 'bar' });
+ }
+ );
await step('Asserts whether forward hook is called', async () => {
const forwardBtn = await canvas.findByText('Go forward');
await userEvent.click(forwardBtn);
- await expect(useRouterMock().forward).toHaveBeenCalled();
+ await expect(routerMock.forward).toHaveBeenCalled();
});
await step('Asserts whether custom prefetch hook is called', async () => {
const prefetchBtn = await canvas.findByText('Prefetch');
await userEvent.click(prefetchBtn);
- await expect(useRouterMock().prefetch).toHaveBeenCalledWith('/prefetched-html');
+ await expect(routerMock.prefetch).toHaveBeenCalledWith('/prefetched-html');
});
},
};
From d229729d5bb2281dfc9f5fbe9daa476512b4c4a8 Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Tue, 9 Apr 2024 14:24:19 +0200
Subject: [PATCH 082/380] Update imports to use @storybook/nextjs/router and
@storybook/nextjs/navigation in nextjs package.json and source files
---
code/frameworks/nextjs/package.json | 6 ++++++
code/frameworks/nextjs/src/preview.tsx | 4 ++--
.../nextjs/src/routing/navigation/app-router-provider.tsx | 5 ++++-
.../nextjs/src/routing/router/page-router-provider.tsx | 5 ++++-
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json
index 24a235df9501..b2c0f1d13fe5 100644
--- a/code/frameworks/nextjs/package.json
+++ b/code/frameworks/nextjs/package.json
@@ -77,6 +77,12 @@
],
"headers.mock": [
"dist/headers/index.d.ts"
+ ],
+ "router": [
+ "dist/routing/router/index.d.ts"
+ ],
+ "navigation": [
+ "dist/routing/navigation/index.d.ts"
]
}
},
diff --git a/code/frameworks/nextjs/src/preview.tsx b/code/frameworks/nextjs/src/preview.tsx
index 7dbfb344861b..32380e899684 100644
--- a/code/frameworks/nextjs/src/preview.tsx
+++ b/code/frameworks/nextjs/src/preview.tsx
@@ -11,8 +11,8 @@ import { HeadManagerDecorator } from './head-manager/decorator';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore we must ignore types here as during compilation they are not generated yet
import { cookies, headers } from '@storybook/nextjs/headers.mock';
-import { createRouter } from './routing/router';
-import { createNavigation } from './routing/navigation';
+import { createRouter } from '@storybook/nextjs/router';
+import { createNavigation } from '@storybook/nextjs/navigation';
function addNextHeadCount() {
const meta = document.createElement('meta');
diff --git a/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx b/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
index efd122bae7c3..e34759453be2 100644
--- a/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
+++ b/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
@@ -10,7 +10,10 @@ import {
} from 'next/dist/shared/lib/hooks-client-context.shared-runtime';
import type { FlightRouterState } from 'next/dist/server/app-render/types';
import type { RouteParams } from '../types';
-import { useRouter } from './index';
+// We need this import to be a singleton, and because it's used in multiple entrypoints
+// both in ESM and CJS, importing it via the package name instead of having a local import
+// is the only way to achieve it actually being a singleton
+import { useRouter } from '@storybook/nextjs/navigation';
type AppRouterProviderProps = {
routeParams: RouteParams;
diff --git a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
index b56dd5f97e9c..90554245d5f1 100644
--- a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
+++ b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
@@ -1,7 +1,10 @@
import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime';
import type { PropsWithChildren } from 'react';
import React from 'react';
-import { useRouter } from './index';
+// We need this import to be a singleton, and because it's used in multiple entrypoints
+// both in ESM and CJS, importing it via the package name instead of having a local import
+// is the only way to achieve it actually being a singleton
+import { useRouter } from '@storybook/nextjs/router';
export const PageRouterProvider: React.FC = ({ children }) => (
{children}
From 4515e78c1d6968a2aac08e498b110c59b7adff98 Mon Sep 17 00:00:00 2001
From: Norbert de Langen
Date: Tue, 2 Apr 2024 10:09:26 +0200
Subject: [PATCH 083/380] add events
---
code/lib/core-events/src/index.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/code/lib/core-events/src/index.ts b/code/lib/core-events/src/index.ts
index 82978a994d07..f9ad1e4a7d9f 100644
--- a/code/lib/core-events/src/index.ts
+++ b/code/lib/core-events/src/index.ts
@@ -75,6 +75,8 @@ enum events {
TELEMETRY_ERROR = 'telemetryError',
FILE_COMPONENT_SEARCH = 'fileComponentSearch',
FILE_COMPONENT_SEARCH_RESULT = 'fileComponentSearchResult',
+ SAVE_STORY_REQUEST = 'saveStoryRequest',
+ SAVE_STORY_RESULT = 'saveStoryResult',
}
// Enables: `import Events from ...`
From 22b79632b84dce79700eca7188d28916832dfc83 Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Wed, 10 Apr 2024 13:01:45 +0200
Subject: [PATCH 084/380] fix singleton logic
---
.../nextjs/src/routing/navigation/index.ts | 38 ++++---
.../nextjs/src/routing/router/index.ts | 100 +++++++++---------
2 files changed, 67 insertions(+), 71 deletions(-)
diff --git a/code/frameworks/nextjs/src/routing/navigation/index.ts b/code/frameworks/nextjs/src/routing/navigation/index.ts
index 23e34cb0c190..804492c34d26 100644
--- a/code/frameworks/nextjs/src/routing/navigation/index.ts
+++ b/code/frameworks/nextjs/src/routing/navigation/index.ts
@@ -12,29 +12,27 @@ let navigationAPI: {
};
export const createNavigation = (overrides: any) => {
- if (!navigationAPI) {
- const navigationActions = {
- push: fn().mockName('nextNavigation.push'),
- replace: fn().mockName('nextNavigation.replace'),
- forward: fn().mockName('nextNavigation.forward'),
- back: fn().mockName('nextNavigation.back'),
- prefetch: fn().mockName('nextNavigation.prefetch'),
- refresh: fn().mockName('nextNavigation.refresh'),
- };
-
- if (overrides) {
- Object.keys(navigationActions).forEach((key) => {
- if (key in overrides) {
- (navigationActions as any)[key] = fn((...args: any[]) => {
- return (overrides as any)[key](...args);
- }).mockName(`nextNavigation.${key}`);
- }
- });
- }
+ const navigationActions = {
+ push: fn().mockName('nextNavigation.push'),
+ replace: fn().mockName('nextNavigation.replace'),
+ forward: fn().mockName('nextNavigation.forward'),
+ back: fn().mockName('nextNavigation.back'),
+ prefetch: fn().mockName('nextNavigation.prefetch'),
+ refresh: fn().mockName('nextNavigation.refresh'),
+ };
- navigationAPI = navigationActions;
+ if (overrides) {
+ Object.keys(navigationActions).forEach((key) => {
+ if (key in overrides) {
+ (navigationActions as any)[key] = fn((...args: any[]) => {
+ return (overrides as any)[key](...args);
+ }).mockName(`nextNavigation.${key}`);
+ }
+ });
}
+ navigationAPI = navigationActions;
+
return navigationAPI;
};
diff --git a/code/frameworks/nextjs/src/routing/router/index.ts b/code/frameworks/nextjs/src/routing/router/index.ts
index 587ab08a4791..120063353e84 100644
--- a/code/frameworks/nextjs/src/routing/router/index.ts
+++ b/code/frameworks/nextjs/src/routing/router/index.ts
@@ -32,62 +32,60 @@ let routerAPI: {
} & typeof defaultRouterState;
export const createRouter = (overrides: Partial) => {
- if (!routerAPI) {
- const routerActions: Partial = {
- push: fn((..._args: any[]) => {
- return Promise.resolve(true);
- }).mockName('nextRouter.push'),
- replace: fn((..._args: any[]) => {
- return Promise.resolve(true);
- }).mockName('nextRouter.replace'),
- reload: fn((..._args: any[]) => {}).mockName('nextRouter.reload'),
- back: fn((..._args: any[]) => {}).mockName('nextRouter.back'),
- forward: fn(() => {}).mockName('nextRouter.forward'),
- prefetch: fn((..._args: any[]) => {
- return Promise.resolve();
- }).mockName('nextRouter.prefetch'),
- beforePopState: fn((..._args: any[]) => {}).mockName('nextRouter.beforePopState'),
- };
+ const routerActions: Partial = {
+ push: fn((..._args: any[]) => {
+ return Promise.resolve(true);
+ }).mockName('nextRouter.push'),
+ replace: fn((..._args: any[]) => {
+ return Promise.resolve(true);
+ }).mockName('nextRouter.replace'),
+ reload: fn((..._args: any[]) => {}).mockName('nextRouter.reload'),
+ back: fn((..._args: any[]) => {}).mockName('nextRouter.back'),
+ forward: fn(() => {}).mockName('nextRouter.forward'),
+ prefetch: fn((..._args: any[]) => {
+ return Promise.resolve();
+ }).mockName('nextRouter.prefetch'),
+ beforePopState: fn((..._args: any[]) => {}).mockName('nextRouter.beforePopState'),
+ };
- const routerEvents: NextRouter['events'] = {
- on: fn((..._args: any[]) => {}).mockName('nextRouter.events.on'),
- off: fn((..._args: any[]) => {}).mockName('nextRouter.events.off'),
- emit: fn((..._args: any[]) => {}).mockName('nextRouter.events.emit'),
- };
+ const routerEvents: NextRouter['events'] = {
+ on: fn((..._args: any[]) => {}).mockName('nextRouter.events.on'),
+ off: fn((..._args: any[]) => {}).mockName('nextRouter.events.off'),
+ emit: fn((..._args: any[]) => {}).mockName('nextRouter.events.emit'),
+ };
- if (overrides) {
- Object.keys(routerActions).forEach((key) => {
- if (key in overrides) {
- (routerActions as any)[key] = fn((...args: any[]) => {
- return (overrides as any)[key](...args);
- }).mockName(`nextRouter.${key}`);
- }
- });
- }
+ if (overrides) {
+ Object.keys(routerActions).forEach((key) => {
+ if (key in overrides) {
+ (routerActions as any)[key] = fn((...args: any[]) => {
+ return (overrides as any)[key](...args);
+ }).mockName(`nextRouter.${key}`);
+ }
+ });
+ }
- if (overrides?.events) {
- Object.keys(routerEvents).forEach((key) => {
- if (key in routerEvents) {
- (routerEvents as any)[key] = fn((...args: any[]) => {
- return (overrides.events as any)[key](...args);
- }).mockName(`nextRouter.events.${key}`);
- }
- });
- }
+ if (overrides?.events) {
+ Object.keys(routerEvents).forEach((key) => {
+ if (key in routerEvents) {
+ (routerEvents as any)[key] = fn((...args: any[]) => {
+ return (overrides.events as any)[key](...args);
+ }).mockName(`nextRouter.events.${key}`);
+ }
+ });
+ }
- routerAPI = {
- ...defaultRouterState,
- ...overrides,
- ...routerActions,
- // @ts-expect-error TODO improve typings
- events: routerEvents,
- };
+ routerAPI = {
+ ...defaultRouterState,
+ ...overrides,
+ ...routerActions,
+ // @ts-expect-error TODO improve typings
+ events: routerEvents,
+ };
- // overwrite the singleton router from next/router
- singletonRouter.router = routerAPI as any;
- singletonRouter.readyCallbacks.forEach((cb) => cb());
- singletonRouter.readyCallbacks = [];
- }
+ // overwrite the singleton router from next/router
+ singletonRouter.router = routerAPI as any;
+ singletonRouter.readyCallbacks.forEach((cb) => cb());
+ singletonRouter.readyCallbacks = [];
return routerAPI as unknown as NextRouter;
};
From ace01fd9b68fc1e71a6d6180392a8484d102fd64 Mon Sep 17 00:00:00 2001
From: Yann Braga
Date: Wed, 10 Apr 2024 13:04:42 +0200
Subject: [PATCH 085/380] Update imports to use @storybook/nextjs/router.mock
and @storybook/nextjs/navigation.mock
---
code/frameworks/nextjs/package.json | 10 +-
code/frameworks/nextjs/src/preview.tsx | 8 +-
.../navigation/app-router-provider.tsx | 6 +-
.../nextjs/src/routing/navigation/index.ts | 21 +--
.../nextjs/src/routing/router/index.ts | 31 +++--
.../routing/router/page-router-provider.tsx | 6 +-
.../Router.stories.jsx | 25 +++-
.../Navigation.stories.tsx | 4 +-
.../Router.stories.tsx | 5 +-
.../nextjs/stories/Navigation.stories.tsx | 4 +-
.../nextjs/stories/Router.stories.tsx | 5 +-
.../portable-stories.test.tsx.snap | 4 +
.../nextjs/yarn.lock | 126 +++++++++---------
13 files changed, 146 insertions(+), 109 deletions(-)
diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json
index b2c0f1d13fe5..a9cac9d5a6ec 100644
--- a/code/frameworks/nextjs/package.json
+++ b/code/frameworks/nextjs/package.json
@@ -52,12 +52,12 @@
"require": "./dist/headers/index.js",
"import": "./dist/headers/index.mjs"
},
- "./router": {
+ "./router.mock": {
"types": "./dist/routing/router/index.d.ts",
"require": "./dist/routing/router/index.js",
"import": "./dist/routing/router/index.mjs"
},
- "./navigation": {
+ "./navigation.mock": {
"types": "./dist/routing/navigation/index.d.ts",
"require": "./dist/routing/navigation/index.js",
"import": "./dist/routing/navigation/index.mjs"
@@ -78,10 +78,10 @@
"headers.mock": [
"dist/headers/index.d.ts"
],
- "router": [
+ "router.mock": [
"dist/routing/router/index.d.ts"
],
- "navigation": [
+ "navigation.mock": [
"dist/routing/navigation/index.d.ts"
]
}
@@ -201,4 +201,4 @@
"platform": "node"
},
"gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae17"
-}
\ No newline at end of file
+}
diff --git a/code/frameworks/nextjs/src/preview.tsx b/code/frameworks/nextjs/src/preview.tsx
index 32380e899684..e65e76bf4854 100644
--- a/code/frameworks/nextjs/src/preview.tsx
+++ b/code/frameworks/nextjs/src/preview.tsx
@@ -11,8 +11,12 @@ import { HeadManagerDecorator } from './head-manager/decorator';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore we must ignore types here as during compilation they are not generated yet
import { cookies, headers } from '@storybook/nextjs/headers.mock';
-import { createRouter } from '@storybook/nextjs/router';
-import { createNavigation } from '@storybook/nextjs/navigation';
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore we must ignore types here as during compilation they are not generated yet
+import { createRouter } from '@storybook/nextjs/router.mock';
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore we must ignore types here as during compilation they are not generated yet
+import { createNavigation } from '@storybook/nextjs/navigation.mock';
function addNextHeadCount() {
const meta = document.createElement('meta');
diff --git a/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx b/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
index e34759453be2..7e26b54e050f 100644
--- a/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
+++ b/code/frameworks/nextjs/src/routing/navigation/app-router-provider.tsx
@@ -13,7 +13,9 @@ import type { RouteParams } from '../types';
// We need this import to be a singleton, and because it's used in multiple entrypoints
// both in ESM and CJS, importing it via the package name instead of having a local import
// is the only way to achieve it actually being a singleton
-import { useRouter } from '@storybook/nextjs/navigation';
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore we must ignore types here as during compilation they are not generated yet
+import { getRouter } from '@storybook/nextjs/navigation.mock';
type AppRouterProviderProps = {
routeParams: RouteParams;
@@ -57,7 +59,7 @@ export const AppRouterProvider: React.FC
-
+
{
const navigationActions = {
- push: fn().mockName('nextNavigation.push'),
- replace: fn().mockName('nextNavigation.replace'),
- forward: fn().mockName('nextNavigation.forward'),
- back: fn().mockName('nextNavigation.back'),
- prefetch: fn().mockName('nextNavigation.prefetch'),
- refresh: fn().mockName('nextNavigation.refresh'),
+ push: fn().mockName('useRouter().push'),
+ replace: fn().mockName('useRouter().replace'),
+ forward: fn().mockName('useRouter().forward'),
+ back: fn().mockName('useRouter().back'),
+ prefetch: fn().mockName('useRouter().prefetch'),
+ refresh: fn().mockName('useRouter().refresh'),
};
if (overrides) {
@@ -26,7 +31,7 @@ export const createNavigation = (overrides: any) => {
if (key in overrides) {
(navigationActions as any)[key] = fn((...args: any[]) => {
return (overrides as any)[key](...args);
- }).mockName(`nextNavigation.${key}`);
+ }).mockName(`useRouter().${key}`);
}
});
}
@@ -36,7 +41,7 @@ export const createNavigation = (overrides: any) => {
return navigationAPI;
};
-export const useRouter = () => {
+export const getRouter = () => {
if (!navigationAPI) {
throw new NextjsRouterMocksNotAvailable({
importType: 'next/navigation',
diff --git a/code/frameworks/nextjs/src/routing/router/index.ts b/code/frameworks/nextjs/src/routing/router/index.ts
index 120063353e84..922ccca2e5a4 100644
--- a/code/frameworks/nextjs/src/routing/router/index.ts
+++ b/code/frameworks/nextjs/src/routing/router/index.ts
@@ -31,27 +31,32 @@ let routerAPI: {
};
} & typeof defaultRouterState;
+/**
+ * Creates a next/router router API mock. Used internally.
+ * @ignore
+ * @internal
+ * */
export const createRouter = (overrides: Partial) => {
const routerActions: Partial = {
push: fn((..._args: any[]) => {
return Promise.resolve(true);
- }).mockName('nextRouter.push'),
+ }).mockName('useRouter().push'),
replace: fn((..._args: any[]) => {
return Promise.resolve(true);
- }).mockName('nextRouter.replace'),
- reload: fn((..._args: any[]) => {}).mockName('nextRouter.reload'),
- back: fn((..._args: any[]) => {}).mockName('nextRouter.back'),
- forward: fn(() => {}).mockName('nextRouter.forward'),
+ }).mockName('useRouter().replace'),
+ reload: fn((..._args: any[]) => {}).mockName('useRouter().reload'),
+ back: fn((..._args: any[]) => {}).mockName('useRouter().back'),
+ forward: fn(() => {}).mockName('useRouter().forward'),
prefetch: fn((..._args: any[]) => {
return Promise.resolve();
- }).mockName('nextRouter.prefetch'),
- beforePopState: fn((..._args: any[]) => {}).mockName('nextRouter.beforePopState'),
+ }).mockName('useRouter().prefetch'),
+ beforePopState: fn((..._args: any[]) => {}).mockName('useRouter().beforePopState'),
};
const routerEvents: NextRouter['events'] = {
- on: fn((..._args: any[]) => {}).mockName('nextRouter.events.on'),
- off: fn((..._args: any[]) => {}).mockName('nextRouter.events.off'),
- emit: fn((..._args: any[]) => {}).mockName('nextRouter.events.emit'),
+ on: fn((..._args: any[]) => {}).mockName('useRouter().events.on'),
+ off: fn((..._args: any[]) => {}).mockName('useRouter().events.off'),
+ emit: fn((..._args: any[]) => {}).mockName('useRouter().events.emit'),
};
if (overrides) {
@@ -59,7 +64,7 @@ export const createRouter = (overrides: Partial) => {
if (key in overrides) {
(routerActions as any)[key] = fn((...args: any[]) => {
return (overrides as any)[key](...args);
- }).mockName(`nextRouter.${key}`);
+ }).mockName(`useRouter().${key}`);
}
});
}
@@ -69,7 +74,7 @@ export const createRouter = (overrides: Partial) => {
if (key in routerEvents) {
(routerEvents as any)[key] = fn((...args: any[]) => {
return (overrides.events as any)[key](...args);
- }).mockName(`nextRouter.events.${key}`);
+ }).mockName(`useRouter().events.${key}`);
}
});
}
@@ -90,7 +95,7 @@ export const createRouter = (overrides: Partial) => {
return routerAPI as unknown as NextRouter;
};
-export const useRouter = () => {
+export const getRouter = () => {
if (!routerAPI) {
throw new NextjsRouterMocksNotAvailable({
importType: 'next/router',
diff --git a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
index 90554245d5f1..e536a16db547 100644
--- a/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
+++ b/code/frameworks/nextjs/src/routing/router/page-router-provider.tsx
@@ -4,8 +4,10 @@ import React from 'react';
// We need this import to be a singleton, and because it's used in multiple entrypoints
// both in ESM and CJS, importing it via the package name instead of having a local import
// is the only way to achieve it actually being a singleton
-import { useRouter } from '@storybook/nextjs/router';
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore we must ignore types here as during compilation they are not generated yet
+import { getRouter } from '@storybook/nextjs/router.mock';
export const PageRouterProvider: React.FC = ({ children }) => (
- {children}
+ {children}
);
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx
index ceee12ad3666..9813958be952 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-js/Router.stories.jsx
@@ -1,7 +1,7 @@
-import { expect, within, userEvent } from '@storybook/test';
-import { useRouter as useRouterMock } from '@storybook/nextjs/router';
-import { useRouter } from 'next/router';
import React from 'react';
+import { expect, within, userEvent } from '@storybook/test';
+import { getRouter } from '@storybook/nextjs/router.mock';
+import Router, { useRouter } from 'next/router';
function Component() {
const router = useRouter();
@@ -32,6 +32,7 @@ function Component() {
return (
+
Router pathname: {Router.pathname}
pathname: {router.pathname}
searchparams:{' '}
@@ -74,17 +75,31 @@ export default {
export const Default = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
+ const routerMock = getRouter();
+
+ await step('Router property overrides should be available in useRouter fn', async () => {
+ await expect(Router.pathname).toBe('/hello');
+ await expect(Router.query).toEqual({ foo: 'bar' });
+ });
+
+ await step(
+ 'Router property overrides should be available in default export from next/router',
+ async () => {
+ await expect(Router.pathname).toBe('/hello');
+ await expect(Router.query).toEqual({ foo: 'bar' });
+ }
+ );
await step('Asserts whether forward hook is called', async () => {
const forwardBtn = await canvas.findByText('Go forward');
await userEvent.click(forwardBtn);
- await expect(useRouterMock().forward).toHaveBeenCalled();
+ await expect(routerMock.forward).toHaveBeenCalled();
});
await step('Asserts whether custom prefetch hook is called', async () => {
const prefetchBtn = await canvas.findByText('Prefetch');
await userEvent.click(prefetchBtn);
- await expect(useRouterMock().prefetch).toHaveBeenCalledWith('/prefetched-html');
+ await expect(routerMock.prefetch).toHaveBeenCalledWith('/prefetched-html');
});
},
};
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
index 1049d345c6d4..c477cb785c58 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Navigation.stories.tsx
@@ -3,7 +3,7 @@ import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';
-import { useRouter as useRouterMock } from '@storybook/nextjs/navigation';
+import { getRouter } from '@storybook/nextjs/navigation.mock';
function Component() {
const router = useRouter();
@@ -86,7 +86,7 @@ export default {
export const Default: StoryObj
= {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
- const routerMock = useRouterMock();
+ const routerMock = getRouter();
await step('Asserts whether forward hook is called', async () => {
const forwardBtn = await canvas.findByText('Go forward');
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
index 7f3a60a787f0..f5a840241fb4 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-ts/Router.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { expect, within, userEvent } from '@storybook/test';
-import { useRouter as useRouterMock } from '@storybook/nextjs/router';
+import { getRouter } from '@storybook/nextjs/router.mock';
import Router, { useRouter } from 'next/router';
function Component() {
@@ -35,6 +35,7 @@ function Component() {
return (
+
Router pathname: {Router.pathname}
pathname: {router.pathname}
searchparams:{' '}
@@ -77,7 +78,7 @@ export default {
export const Default: StoryObj
= {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
- const routerMock = useRouterMock();
+ const routerMock = getRouter();
await step('Router property overrides should be available in useRouter fn', async () => {
await expect(Router.pathname).toBe('/hello');
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Navigation.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Navigation.stories.tsx
index 1049d345c6d4..c477cb785c58 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Navigation.stories.tsx
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Navigation.stories.tsx
@@ -3,7 +3,7 @@ import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';
-import { useRouter as useRouterMock } from '@storybook/nextjs/navigation';
+import { getRouter } from '@storybook/nextjs/navigation.mock';
function Component() {
const router = useRouter();
@@ -86,7 +86,7 @@ export default {
export const Default: StoryObj = {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
- const routerMock = useRouterMock();
+ const routerMock = getRouter();
await step('Asserts whether forward hook is called', async () => {
const forwardBtn = await canvas.findByText('Go forward');
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
index 7f3a60a787f0..f5a840241fb4 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/Router.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { expect, within, userEvent } from '@storybook/test';
-import { useRouter as useRouterMock } from '@storybook/nextjs/router';
+import { getRouter } from '@storybook/nextjs/router.mock';
import Router, { useRouter } from 'next/router';
function Component() {
@@ -35,6 +35,7 @@ function Component() {
return (
+
Router pathname: {Router.pathname}
pathname: {router.pathname}
searchparams:{' '}
@@ -77,7 +78,7 @@ export default {
export const Default: StoryObj
= {
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
- const routerMock = useRouterMock();
+ const routerMock = getRouter();
await step('Router property overrides should be available in useRouter fn', async () => {
await expect(Router.pathname).toBe('/hello');
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/__snapshots__/portable-stories.test.tsx.snap b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/__snapshots__/portable-stories.test.tsx.snap
index 7f5212f2f6a3..2b8af2b9cd59 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/__snapshots__/portable-stories.test.tsx.snap
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/stories/__snapshots__/portable-stories.test.tsx.snap
@@ -832,6 +832,10 @@ exports[`renders routerStories stories renders Default 1`] = `
Global Decorator
+
+ Router pathname:
+ /hello
+
pathname:
/hello
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
index 46d9fd1b8d40..1846f8c034a2 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
@@ -2379,7 +2379,7 @@ __metadata:
"@storybook/addon-actions@file:../../../code/addons/actions::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-actions@file:../../../code/addons/actions#../../../code/addons/actions::hash=99649f&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-actions@file:../../../code/addons/actions#../../../code/addons/actions::hash=a58e61&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-events": "workspace:*"
"@storybook/global": "npm:^5.0.0"
@@ -2387,7 +2387,7 @@ __metadata:
dequal: "npm:^2.0.2"
polished: "npm:^4.2.2"
uuid: "npm:^9.0.0"
- checksum: 10/79a14c7a74591e404e5ec22c2b6c9eaa03dd48bf3316470dd2642e3c70abd7c90b168fd350e729b617967c7d759df2ef0107534d218d1138b12e737c8a3e888e
+ checksum: 10/448ef050488c32b161113c707a9bd3e4eb734f7a23f350d7cb05dd30927785c19b0eb1b2f01f8f5f7106e8f46dcc2cfc9496a089dee818754dc83ae5403d8ee6
languageName: node
linkType: hard
@@ -2403,17 +2403,13 @@ __metadata:
linkType: hard
"@storybook/addon-controls@file:../../../code/addons/controls::locator=portable-stories-nextjs%40workspace%3A.":
- version: 8.1.0-alpha.5
- resolution: "@storybook/addon-controls@file:../../../code/addons/controls#../../../code/addons/controls::hash=358687&locator=portable-stories-nextjs%40workspace%3A."
+ version: 8.1.0-alpha.6
+ resolution: "@storybook/addon-controls@file:../../../code/addons/controls#../../../code/addons/controls::hash=b28ca0&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/blocks": "workspace:*"
- "@storybook/core-common": "workspace:*"
- cjs-module-lexer: "npm:^1.2.3"
- es-module-lexer: "npm:^1.5.0"
- globby: "npm:^14.0.1"
lodash: "npm:^4.17.21"
ts-dedent: "npm:^2.0.0"
- checksum: 10/feb098e18f942562769dfdfb4afc70655f67f11e6d14acf8e3ca4cfe9a22e09e89ede9f17be6ff1c07a56bed8a6fa1961fa044137a3e7a34471345bcccd091f2
+ checksum: 10/f68a13e40bda392c1abc4cee2f2294fe98f11e8b34af8213532ae14027327efbafb3c9a8d75d300a3c58fb8d036a09f349e60cd064dd8dbde504add2945bab6b
languageName: node
linkType: hard
@@ -2478,7 +2474,7 @@ __metadata:
"@storybook/addon-interactions@file:../../../code/addons/interactions::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-interactions@file:../../../code/addons/interactions#../../../code/addons/interactions::hash=e7e04a&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-interactions@file:../../../code/addons/interactions#../../../code/addons/interactions::hash=43a156&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
"@storybook/instrumenter": "workspace:*"
@@ -2486,7 +2482,7 @@ __metadata:
"@storybook/types": "workspace:*"
polished: "npm:^4.2.2"
ts-dedent: "npm:^2.2.0"
- checksum: 10/c66d7db9c1356903d444211962054b0a692a56f7ed5debcaa1f2e40fd57575975b8de86c2fb3be3a140e69cdc8f36b25f81be6e2ca55fb4facf826694d8be65f
+ checksum: 10/7ab50dfb5ccfde231d5ebde1e695512c5bb3706e5fe9bc580fbf23d5298ac7685e9648fbbc5f65605779954dc2f04ac1ce799e47b387d7eaaff5c9d7e8485602
languageName: node
linkType: hard
@@ -2590,7 +2586,7 @@ __metadata:
"@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5#../../../code/builders/builder-webpack5::hash=983659&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5#../../../code/builders/builder-webpack5::hash=c0c586&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2629,26 +2625,26 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/f84f41cd8ac80376ba603f4bb58da565f2b0e95ed37593279d85c4e5573de64633f10b7c6f2bd399f6d40057f1c97934760b969326520250f6de5efd07ac967b
+ checksum: 10/f4fe0264184b91d9a96baf2d35fc7c7c212b516901650c852f61c2aec2e6b7d81f6828b7ca7ce34f1623bab5cd838936d5877d982df0fa75cab577af78ce79ef
languageName: node
linkType: hard
"@storybook/channels@file:../../../code/lib/channels::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/channels@file:../../../code/lib/channels#../../../code/lib/channels::hash=3a33a2&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/channels@file:../../../code/lib/channels#../../../code/lib/channels::hash=413c8e&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/core-events": "workspace:*"
"@storybook/global": "npm:^5.0.0"
telejson: "npm:^7.2.0"
tiny-invariant: "npm:^1.3.1"
- checksum: 10/cda1b155f07fdac919a29e5a5287ae33ef4b3ed9c5c9816c29e17e3aa0dd788dc59da8775c40341ebcbd426ecf4f9ab629949dfe945834f48db7ca6053c062f1
+ checksum: 10/6091e0ca5a19b46589877a6a17cac725ef863a8cdf61d812261673e16227490f8b80fcf26daa8924dbcaad434c91118ac399f3a610c7eec5ed094e7b0dfd0947
languageName: node
linkType: hard
"@storybook/cli@file:../../../code/lib/cli::locator=portable-stories-nextjs%40workspace%3A.":
- version: 8.1.0-alpha.5
- resolution: "@storybook/cli@file:../../../code/lib/cli#../../../code/lib/cli::hash=49e395&locator=portable-stories-nextjs%40workspace%3A."
+ version: 8.1.0-alpha.6
+ resolution: "@storybook/cli@file:../../../code/lib/cli#../../../code/lib/cli::hash=2914c7&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/core": "npm:^7.23.0"
"@babel/types": "npm:^7.23.0"
@@ -2689,16 +2685,16 @@ __metadata:
bin:
getstorybook: ./bin/index.js
sb: ./bin/index.js
- checksum: 10/37be78e7b11cfb9d712f9b948e3017665fcee970e1b3a4806f3f8307ea9db7e39f4b12fa919086a53efbe4e24a5e6196b2daafb958c11145e9e5d224fa70af55
+ checksum: 10/6c967c34ef47687aa6ccbc70d82f22e375be79af1bf5eec3e1163c7774b65fda69a414c0aa712039062a9f184bc84d70e7fcf713712c28d4a121cc3848a32600
languageName: node
linkType: hard
"@storybook/client-logger@file:../../../code/lib/client-logger::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/client-logger@file:../../../code/lib/client-logger#../../../code/lib/client-logger::hash=f3ac76&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/client-logger@file:../../../code/lib/client-logger#../../../code/lib/client-logger::hash=6408e1&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
- checksum: 10/00b5cfade208483f5ec85c8aa59cabf402502a4cf1d9c3ee24a311a396e65ce97f0a3d4356aac9f413c8d84c9804ccb07aaeda6f3d553799e6e036960f4a2fbe
+ checksum: 10/ff3312279cf1bcaa3fcf91149951e4b7b6cba79ddbb0f80e488126a38bf1f7ceab4ad43cf40324b5ec9c3a8a786695042bc7cd47a0ae0a4835f06dddc5fb214e
languageName: node
linkType: hard
@@ -2727,7 +2723,7 @@ __metadata:
"@storybook/components@file:../../../code/ui/components::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/components@file:../../../code/ui/components#../../../code/ui/components::hash=2c348b&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/components@file:../../../code/ui/components#../../../code/ui/components::hash=636348&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@radix-ui/react-slot": "npm:^1.0.2"
"@storybook/client-logger": "workspace:*"
@@ -2741,13 +2737,13 @@ __metadata:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
- checksum: 10/5ca7607bebb485e1dbb5c26f5dc3482e661d1646381be3ae26284c1e82cb0e2de51e05f5c4272ebe4d5fa6536aecb8dcd46e3da871aad90ba67a2e7e8987d278
+ checksum: 10/02326f8b50631922d80cf64163abf4e723c5a1fd78c1ae1b276c95ff7992c0a826736badf1b7222038d83775b2937ef60de426aab7a6d5262a7b1152f5825abc
languageName: node
linkType: hard
"@storybook/core-common@file:../../../code/lib/core-common::locator=portable-stories-nextjs%40workspace%3A.":
- version: 8.1.0-alpha.5
- resolution: "@storybook/core-common@file:../../../code/lib/core-common#../../../code/lib/core-common::hash=55d292&locator=portable-stories-nextjs%40workspace%3A."
+ version: 8.1.0-alpha.6
+ resolution: "@storybook/core-common@file:../../../code/lib/core-common#../../../code/lib/core-common::hash=26f1e6&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-events": "workspace:*"
"@storybook/csf-tools": "workspace:*"
@@ -2777,22 +2773,22 @@ __metadata:
tiny-invariant: "npm:^1.3.1"
ts-dedent: "npm:^2.0.0"
util: "npm:^0.12.4"
- checksum: 10/e9308c3683651e2c925823e4bee0f91156ba544b0dc72ee6291810e7bd2e17690bce3f426c10d942fd5e18eb545589e5a3347cd02eb6ecceb058dad7a56bb775
+ checksum: 10/7b692d71f9d170253ad376d67d364d351eff3d6f9b21fcf2471aefbf78fe4fdfb61a24f444630ad0bcbe3d560b92350271087e03f7e040cedbbfbb142ef0bc7b
languageName: node
linkType: hard
"@storybook/core-events@file:../../../code/lib/core-events::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-events@file:../../../code/lib/core-events#../../../code/lib/core-events::hash=840150&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-events@file:../../../code/lib/core-events#../../../code/lib/core-events::hash=3d1227&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
ts-dedent: "npm:^2.0.0"
- checksum: 10/ccfa4397af9c114f401ac87d232f66c0cb37e7ee104647b36dd34e7bf598ff7e3a22fb18a6fb9d1529cef35f053056e34fa3f7626e62c5e133d31bd58fd6b5cb
+ checksum: 10/9ecdadbfc30f79f4ef930595681e39197e8545d32308b9e9a1829f3f67047521d44c66664386f6be62a75019abe67e5b37d08bd9ced83eeee28c0602f8bed5fa
languageName: node
linkType: hard
"@storybook/core-server@file:../../../code/lib/core-server::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-server@file:../../../code/lib/core-server#../../../code/lib/core-server::hash=2c034c&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-server@file:../../../code/lib/core-server#../../../code/lib/core-server::hash=e5bcbd&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@aw-web-design/x-default-browser": "npm:1.4.126"
"@babel/core": "npm:^7.23.9"
@@ -2817,9 +2813,11 @@ __metadata:
"@types/semver": "npm:^7.3.4"
better-opn: "npm:^3.0.2"
chalk: "npm:^4.1.0"
+ cjs-module-lexer: "npm:^1.2.3"
cli-table3: "npm:^0.6.1"
compression: "npm:^1.7.4"
detect-port: "npm:^1.3.0"
+ es-module-lexer: "npm:^1.5.0"
express: "npm:^4.17.3"
fs-extra: "npm:^11.1.0"
globby: "npm:^14.0.1"
@@ -2837,20 +2835,20 @@ __metadata:
util-deprecate: "npm:^1.0.2"
watchpack: "npm:^2.2.0"
ws: "npm:^8.2.3"
- checksum: 10/83c58dfa24e67e8ea10107858e723eebe3ebafa17580fbe9526022e02d1ba2467ef5e75ba3b303436c470a7151f183ad2d781b4cef1201a73cdf8f10d317cc57
+ checksum: 10/1f4f9495d5d3158613966a1b84f8fb19d8fcee6d05f06c885d27315cf8416fe36b18c898d577ff2a5ad72157d7f7e63171d9b49bf0191cdc45519f224e5c5ad7
languageName: node
linkType: hard
"@storybook/core-webpack@file:../../../code/lib/core-webpack::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-webpack@file:../../../code/lib/core-webpack#../../../code/lib/core-webpack::hash=d17dda&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-webpack@file:../../../code/lib/core-webpack#../../../code/lib/core-webpack::hash=1c6e9a&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-common": "workspace:*"
"@storybook/node-logger": "workspace:*"
"@storybook/types": "workspace:*"
"@types/node": "npm:^18.0.0"
ts-dedent: "npm:^2.0.0"
- checksum: 10/2e56db38374ec96f01c00c0fa4c8a9090c1db1d56c8c611a93d1a0c60769aa6a2c751ed29fa6c3a3a7adbf99d457287908e8e01ee1848ab6c59f6837934d81bf
+ checksum: 10/af79e1e751158c7d47475736c052cf1fd6535fbaa131168141a06eef2ed5f178165771dba4e4995a567d5d180d4af33a4e75c573153ec39a838901cbb16aa4c1
languageName: node
linkType: hard
@@ -2866,7 +2864,7 @@ __metadata:
"@storybook/csf-tools@file:../../../code/lib/csf-tools::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/csf-tools@file:../../../code/lib/csf-tools#../../../code/lib/csf-tools::hash=69584a&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/csf-tools@file:../../../code/lib/csf-tools#../../../code/lib/csf-tools::hash=703916&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/generator": "npm:^7.23.0"
"@babel/parser": "npm:^7.23.0"
@@ -2877,7 +2875,7 @@ __metadata:
fs-extra: "npm:^11.1.0"
recast: "npm:^0.23.5"
ts-dedent: "npm:^2.0.0"
- checksum: 10/7fce79866ace04b9a2bc78a66a03e27e6e770b4279e1b40c08634bce01eb57be22f5f192f73c6a65cc959c8910f63a3d35e31a71fe3ac821aea095722e324710
+ checksum: 10/b597a467657223667710c73bcdd8d85e481a7c088e816539dd9513f2a42cb825e1d3fdd5461772d969201d2f6901280c30a9712d8711b7e12661a01d692f6871
languageName: node
linkType: hard
@@ -2908,7 +2906,7 @@ __metadata:
"@storybook/docs-tools@file:../../../code/lib/docs-tools::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/docs-tools@file:../../../code/lib/docs-tools#../../../code/lib/docs-tools::hash=4be280&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/docs-tools@file:../../../code/lib/docs-tools#../../../code/lib/docs-tools::hash=0f1a92&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-common": "workspace:*"
"@storybook/preview-api": "workspace:*"
@@ -2917,7 +2915,7 @@ __metadata:
assert: "npm:^2.1.0"
doctrine: "npm:^3.0.0"
lodash: "npm:^4.17.21"
- checksum: 10/121355441e903b87a0b9e590eca45a9b355af949148da6d23434f59b2aa753f00e0ffb8bc625d4ca91cf01e5e9782caceb561537d62729a2b2e240b6e640a0f4
+ checksum: 10/6efb67c748bf9616313844cc482a31b49834d7b94767a544b7a5ed9a2e2d28c3d8a945162040b09f39af3f36c5288c00a83a67166c5d6a91b38875b8ff039acd
languageName: node
linkType: hard
@@ -2940,7 +2938,7 @@ __metadata:
"@storybook/instrumenter@file:../../../code/lib/instrumenter::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/instrumenter@file:../../../code/lib/instrumenter#../../../code/lib/instrumenter::hash=ffe9d7&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/instrumenter@file:../../../code/lib/instrumenter#../../../code/lib/instrumenter::hash=da2c8f&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2949,13 +2947,13 @@ __metadata:
"@storybook/preview-api": "workspace:*"
"@vitest/utils": "npm:^1.3.1"
util: "npm:^0.12.4"
- checksum: 10/84948fcfafe05e5934117e6c514a1788f9d146d28f749c11313e5f65c60f3f20be0e659e97f14a6b5ce405b01afa4941571f644a9cb88d8b3a956c2c79413723
+ checksum: 10/a55b3615eee655ef969641128c408ad5a6f3a0196af135e4ea1aa9289b9a2c98d84b34c3a57a25ca8cf6e619faad5fe6440232097fb99ecf7fc0341395a8ce16
languageName: node
linkType: hard
"@storybook/manager-api@file:../../../code/lib/manager-api::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/manager-api@file:../../../code/lib/manager-api#../../../code/lib/manager-api::hash=3e3312&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/manager-api@file:../../../code/lib/manager-api#../../../code/lib/manager-api::hash=4ab1f3&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2972,20 +2970,20 @@ __metadata:
store2: "npm:^2.14.2"
telejson: "npm:^7.2.0"
ts-dedent: "npm:^2.0.0"
- checksum: 10/dcc92a7797ccf0f986ef2eb9077884799e4cc92603ca52a69071b4943ca149fd17d771c64bd1fd474c8287b4bda5385c7b24bada7acc9f7413deac152ec32157
+ checksum: 10/ef8fe488bd220f3b895d26895e5a55a9bc110ee799f062f06d3c32dfa5ccd834c04074d96d8d4dc8c41336e322b2d3a4e0f93dc518442b22a9b36ddbfc92f990
languageName: node
linkType: hard
"@storybook/manager@file:../../../code/ui/manager::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/manager@file:../../../code/ui/manager#../../../code/ui/manager::hash=257346&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/cdfcb34cdfaa7b7fbd388c54f2ecc85e0b4276ba1d915cc4b36dfcdd9ab8c5391815ae502089aa77e5dad8e51a064f86771969f20e9d10b5b14973d8e4e80a8b
+ resolution: "@storybook/manager@file:../../../code/ui/manager#../../../code/ui/manager::hash=645d43&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/9708627cc2f3a886c53dfec9402088f6b18b40ba8f472289d08c6b25c0e2e1e71871d6a79f19e57586751b287b55506c72372d1a0fab2efa89847719bf7c50f7
languageName: node
linkType: hard
"@storybook/nextjs@file:../../../code/frameworks/nextjs::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/nextjs@file:../../../code/frameworks/nextjs#../../../code/frameworks/nextjs::hash=a5b14e&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/nextjs@file:../../../code/frameworks/nextjs#../../../code/frameworks/nextjs::hash=e17c4a&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/core": "npm:^7.23.2"
"@babel/plugin-syntax-bigint": "npm:^7.8.3"
@@ -3042,20 +3040,20 @@ __metadata:
optional: true
webpack:
optional: true
- checksum: 10/86d287d5088a26adabce7b6ca5e56eebedf44df95bd07b1085253e095bea2d1d54898eed384ff7ca75866b00ffa36dd0a0c8f252edc1b4feb48725b6ca2ca851
+ checksum: 10/c683698db1894bd29caa5bedf5f9bef0378e5e9e391b8d986144ecc95a625bc22574fab9e60d56703975a69c558baa1d6a652eabdf5760aafb1a8f23d97798d9
languageName: node
linkType: hard
"@storybook/node-logger@file:../../../code/lib/node-logger::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/node-logger@file:../../../code/lib/node-logger#../../../code/lib/node-logger::hash=0d5379&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/ba3b49b55a325ec5d885898e5cd61370c19ad27a54315025c315bb08b6a09a64cfd3097748225be1f4b07aad42245a239ac9ba6e957c854ebb48718a43e5c215
+ resolution: "@storybook/node-logger@file:../../../code/lib/node-logger#../../../code/lib/node-logger::hash=76992b&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/39a64d0cfc1ab16e4e808edc63fb9b5b76c038acb864b00d756260f9b5cf66116a758f6969dcc06daab8e69a8965fceef11c1d3cab8b524de1021b97dfd5b0e4
languageName: node
linkType: hard
"@storybook/preset-react-webpack@file:../../../code/presets/react-webpack::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preset-react-webpack@file:../../../code/presets/react-webpack#../../../code/presets/react-webpack::hash=3c5b01&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/preset-react-webpack@file:../../../code/presets/react-webpack#../../../code/presets/react-webpack::hash=f3317c&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-webpack": "workspace:*"
"@storybook/docs-tools": "workspace:*"
@@ -3078,13 +3076,13 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/3baffd6ce4e642f852c370ccd4ae8098a5e730f4493ce43c8414f0b44e59c8bc8a99d9975cf5149b655f1808e54d274754044f45983b9f1be7c9a28f00931ac2
+ checksum: 10/ee2981fac009bed8163403a304fc34ea8e6f307bd11c26dc6b9e1682e5116facfef0a1e6c59dafe179977b1f5e366912db7e6cac7530cd7074a7c2dd071bd91e
languageName: node
linkType: hard
"@storybook/preview-api@file:../../../code/lib/preview-api::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preview-api@file:../../../code/lib/preview-api#../../../code/lib/preview-api::hash=2e825a&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/preview-api@file:../../../code/lib/preview-api#../../../code/lib/preview-api::hash=8ed046&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -3100,14 +3098,14 @@ __metadata:
tiny-invariant: "npm:^1.3.1"
ts-dedent: "npm:^2.0.0"
util-deprecate: "npm:^1.0.2"
- checksum: 10/8cb6df33b082d43c40daa182241aef50e583fc3c45d954730df0fbf305645926b2904b5177661a7a6294969014bda8c647f24960afd6114333e7c4bb00caa869
+ checksum: 10/d5a6dc59d0cf9660869c7059567ffe09e1d590835aa781a5a94fc109ae67ae961f82db05a5e983b209e76a595ef3b9669f25897a174701fbcd2846a321ddd8e6
languageName: node
linkType: hard
"@storybook/preview@file:../../../code/lib/preview::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preview@file:../../../code/lib/preview#../../../code/lib/preview::hash=dccd68&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/834521c05fe7496e5d411dd9dc8cd3d2e3902bd101fcfe9e1caa2bace894fb6698d035fd190072a3cf2e294c86324315f30732c16bc30f75a1307feab53c16d1
+ resolution: "@storybook/preview@file:../../../code/lib/preview#../../../code/lib/preview::hash=364559&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/cda37fa779743c888a72cc6329ce2d2d7d0171ae2c45d5854c90cf49a834c53e8334d36d95c255254440f4e6304251789f600c64a8f7925df1dc52e76aa18277
languageName: node
linkType: hard
@@ -3131,17 +3129,17 @@ __metadata:
"@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim#../../../code/lib/react-dom-shim::hash=062b74&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim#../../../code/lib/react-dom-shim::hash=4a12a1&locator=portable-stories-nextjs%40workspace%3A."
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
- checksum: 10/ba63271a1f2d663cd53354798c490d306787b8033586a1062175b89fe4409759cbc959aa34dad12ff8f9bf2e9c141a391784eda81f23cbc9d13495128c9e1611
+ checksum: 10/1328cd24014a00ea7b07c2359c0d6af7fd7973a8635e1e42ff8f462524ad0961fccfc3200f25f86e1fdd75d151f2f50038db70e88c5fb4c9ff7a93cfa387d4dd
languageName: node
linkType: hard
"@storybook/react@file:../../../code/renderers/react::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/react@file:../../../code/renderers/react#../../../code/renderers/react::hash=f60a6b&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/react@file:../../../code/renderers/react#../../../code/renderers/react::hash=e02d2f&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/docs-tools": "workspace:*"
@@ -3171,18 +3169,18 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/aa5c6739bfda7f26dcf2155cc61cc02c7387046fd3f1ef0029fa851b56024e5c81e69ef11c7a3f167bf66715161586abc2e29bbcdd5e3ea4ff9f0a34bbdac095
+ checksum: 10/bc3d21e78b36c3fa4133532858d0b32f1686a8227096c1079c4575cc29461e32ebeb742b74671c0c43523b738ec8186a1368036d3e9406f6e4cf561a67fc2b79
languageName: node
linkType: hard
"@storybook/router@file:../../../code/lib/router::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/router@file:../../../code/lib/router#../../../code/lib/router::hash=f3d914&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/router@file:../../../code/lib/router#../../../code/lib/router::hash=2f121e&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
memoizerific: "npm:^1.11.3"
qs: "npm:^6.10.0"
- checksum: 10/ae4218eb5cb26c1fd31b334a5431a228a4fd6f30bff1e4feb68c188317ceece7b91510c0c98c4a2d4fe419baebb2da21ea03d65dfe5123257befdb8ad9e0770c
+ checksum: 10/8fcccb54ade96e59e716e74c9985633d6ff4a9e025f80e83cb1c8c61443910cb3205d2b2753f7a455544b8d39be832c456db4ecff2e58753b0fd45a0f828b6b6
languageName: node
linkType: hard
@@ -3204,7 +3202,7 @@ __metadata:
"@storybook/test@file:../../../code/lib/test::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/test@file:../../../code/lib/test#../../../code/lib/test::hash=cd3c93&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/test@file:../../../code/lib/test#../../../code/lib/test::hash=4192cc&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/core-events": "workspace:*"
@@ -3217,13 +3215,13 @@ __metadata:
"@vitest/spy": "npm:^1.3.1"
chai: "npm:^4.4.1"
util: "npm:^0.12.4"
- checksum: 10/783d04972494921194bbf60ba366dd62c81340257671acdb2693156dc64c709c64a51efc5fcf528c5a43d11167b2193d4582d24e5012e86407b64fbeda4c1c66
+ checksum: 10/ae7add4394f4c590aaac487da53f0e335051560ecd18f0e831f6e62ffb15aad2299060f58e6149bf3637dd8ed48217e7ae3bd54b58a5ea35ab8fea3982aabbc2
languageName: node
linkType: hard
"@storybook/theming@file:../../../code/lib/theming::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/theming@file:../../../code/lib/theming#../../../code/lib/theming::hash=9cc340&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/theming@file:../../../code/lib/theming#../../../code/lib/theming::hash=f968b9&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1"
"@storybook/client-logger": "workspace:*"
@@ -3237,18 +3235,18 @@ __metadata:
optional: true
react-dom:
optional: true
- checksum: 10/e64850170fec111310877caa5a994ad53c9e072f324d0871d98e34f7d30688dadd7b24914441b3c50f3e9dc3f80909c60fa292e61f7fe6b257a6e19521a6c8e1
+ checksum: 10/e603c954ca9f8a99cb82deac40c66f1fd71d170900f6c8a4e0f3157921b6b1da6c0d644519960312eefa1def67a99c50a4e4cd6c6e92fd121d99a9fcb822f6b9
languageName: node
linkType: hard
"@storybook/types@file:../../../code/lib/types::locator=portable-stories-nextjs%40workspace%3A.":
- version: 8.1.0-alpha.5
- resolution: "@storybook/types@file:../../../code/lib/types#../../../code/lib/types::hash=0524c9&locator=portable-stories-nextjs%40workspace%3A."
+ version: 8.1.0-alpha.6
+ resolution: "@storybook/types@file:../../../code/lib/types#../../../code/lib/types::hash=c292b3&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@types/express": "npm:^4.7.0"
file-system-cache: "npm:2.3.0"
- checksum: 10/b2835c9386c22e535e62263fe03ead9c43a1c9762b6524ed8a9b1954887e8853311d580caa7711d57a1eecc9ce30cd7cfd9d814a45723e8434397b7adced1871
+ checksum: 10/66db65b0e5185de6e9df7fb239b4a45beaf5e42d1f558ae465346b850f8626909aa7d415b49ed0ba0b837219ded47021c42bffff83f13eba29867ee8eafe7b0c
languageName: node
linkType: hard
From 3d23b0cf6b16f7c54e83a4a3e496f3b7973dca8e Mon Sep 17 00:00:00 2001
From: Norbert de Langen
Date: Wed, 10 Apr 2024 14:59:24 +0200
Subject: [PATCH 086/380] iteration on actually being able to add args
---
.../src/utils/save-from-controls/astify.ts | 38 +++++++++++
.../save-from-controls/save-from-controls.ts | 3 +-
.../update-args-in-csf-file.test.ts | 27 ++++++--
.../update-args-in-csf-file.ts | 66 +++++++++++++------
4 files changed, 109 insertions(+), 25 deletions(-)
create mode 100644 code/lib/core-server/src/utils/save-from-controls/astify.ts
diff --git a/code/lib/core-server/src/utils/save-from-controls/astify.ts b/code/lib/core-server/src/utils/save-from-controls/astify.ts
new file mode 100644
index 000000000000..95378a732421
--- /dev/null
+++ b/code/lib/core-server/src/utils/save-from-controls/astify.ts
@@ -0,0 +1,38 @@
+import * as t from '@babel/types';
+import * as babylon from '@babel/parser';
+import traverse from '@babel/traverse';
+
+export function astify(literal: T) {
+ if (literal === null) {
+ return t.nullLiteral();
+ }
+ switch (typeof literal) {
+ case 'function':
+ const ast = babylon.parse(literal.toString(), {
+ allowReturnOutsideFunction: true,
+ allowSuperOutsideMethod: true,
+ });
+ return traverse.removeProperties(ast);
+ case 'number':
+ return t.numericLiteral(literal);
+ case 'string':
+ return t.stringLiteral(literal);
+ case 'boolean':
+ return t.booleanLiteral(literal);
+ case 'undefined':
+ return t.unaryExpression('void', t.numericLiteral(0), true);
+ default:
+ if (Array.isArray(literal)) {
+ return t.arrayExpression(literal.map(astify));
+ }
+ return t.objectExpression(
+ Object.keys(literal)
+ .filter((k) => {
+ return typeof literal[k] !== 'undefined';
+ })
+ .map((k) => {
+ return t.objectProperty(t.stringLiteral(k), astify(literal[k]));
+ })
+ );
+ }
+}
diff --git a/code/lib/core-server/src/utils/save-from-controls/save-from-controls.ts b/code/lib/core-server/src/utils/save-from-controls/save-from-controls.ts
index 18ff90195e7b..7ac906c16fdb 100644
--- a/code/lib/core-server/src/utils/save-from-controls/save-from-controls.ts
+++ b/code/lib/core-server/src/utils/save-from-controls/save-from-controls.ts
@@ -5,6 +5,7 @@ import { SAVE_STORY_REQUEST, SAVE_STORY_RESULT } from '@storybook/core-events';
import type { OptionsWithRequiredCache } from '../whats-new';
import { readCsf, writeCsf } from '@storybook/csf-tools';
import { join } from 'path';
+import { updateArgsInCsfFile } from './update-args-in-csf-file';
// import { sendTelemetryError } from '../withTelemetry';
interface RequestSaveStoryPayload {
@@ -50,7 +51,7 @@ export function initializeSaveFromControls(
}
// modify the AST node with the new args
- console.log({ node });
+ updateArgsInCsfFile(node, data.args);
// save the file
await writeCsf(csf, location);
diff --git a/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.test.ts b/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.test.ts
index f638a368a48c..c44e4d15fe7a 100644
--- a/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.test.ts
+++ b/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.test.ts
@@ -1,14 +1,33 @@
+/* eslint-disable no-underscore-dangle */
import { describe, test, expect } from 'vitest';
-import { readCsf, babelPrint } from '@storybook/csf-tools';
+import { readCsf, printCsf } from '@storybook/csf-tools';
+import { join } from 'path';
+import { getProjectRoot } from '@storybook/core-common';
+
+import { updateArgsInCsfFile } from './update-args-in-csf-file';
import { readFile } from 'fs/promises';
+const makeTitle = (userTitle: string) => userTitle;
+
+const FILES = {
+ tab: join(getProjectRoot(), 'code/ui/components/src/components/tabs/tabs.stories.tsx'),
+};
+
+// console.log(FILES);
+
describe('success', () => {
test('should return success', async () => {
- const before = await readFile('path/to/file', 'utf-8');
- const CSF = await readCsf('path/to/file', { makeTitle: (userTitle: string) => userTitle });
+ const before = await readFile(FILES.tab, 'utf-8');
+ const CSF = await readCsf(FILES.tab, { makeTitle });
const parsed = CSF.parse();
+ const names = Object.keys(parsed._stories);
+ const nodes = names.map((name) => CSF.getStoryExport(name));
+
+ updateArgsInCsfFile(nodes[0], { active: true, selected: 'test1' });
+
+ const after = printCsf(parsed);
- // parsed._stories
+ expect(after.code).not.toBe(before);
});
});
diff --git a/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.ts b/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.ts
index 947e70d2a02a..b4e3f3bb1c67 100644
--- a/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.ts
+++ b/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.ts
@@ -1,32 +1,58 @@
-import type * as t from '@babel/types';
+import * as t from '@babel/types';
import * as traverse from '@babel/traverse';
+import { astify } from './astify';
+
+export const updateArgsInCsfFile = async (node: t.Node, input: Record) => {
+ let found = false;
+ const args = Object.fromEntries(
+ Object.entries(input).map(([k, v]) => {
+ return [k, astify(v)];
+ })
+ );
-export const updateArgsInCsfFile = async (node: t.Node, args: Record) => {
traverse.default(node, {
ObjectExpression(path) {
+ if (found) {
+ return;
+ }
+
+ found = true;
const properties = path.get('properties');
- properties.forEach((property) => {
+ const argsProperty = properties.find((property) => {
if (property.isObjectProperty()) {
const key = property.get('key');
- if (key.isIdentifier() && key.node.name === 'args') {
- const value = property.get('value');
- if (value.isObjectExpression()) {
- args = {
- ...args,
- ...value.node.properties.reduce((acc, prop) => {
- if (prop.type === 'ObjectProperty') {
- const k = prop.key;
- if (k.type === 'Identifier') {
- acc[k.name] = prop.value;
- }
- }
- return acc;
- }, {}),
- };
- }
- }
+ return key.isIdentifier() && key.node.name === 'args';
}
+ return false;
});
+
+ if (argsProperty) {
+ const v = argsProperty.get('value');
+ if (t.isObjectExpression(v)) {
+ argsProperty.replaceWith(
+ t.objectProperty(
+ t.identifier('args'),
+ t.objectExpression(
+ Object.entries(args).map(([key, value]) =>
+ t.objectProperty(t.identifier(key), value)
+ )
+ )
+ )
+ );
+ }
+ } else {
+ path.pushContainer(
+ 'properties',
+ t.objectProperty(
+ t.identifier('args'),
+ t.objectExpression(
+ Object.entries(args).map(([key, value]) => t.objectProperty(t.identifier(key), value))
+ )
+ )
+ );
+ }
},
+
+ noScope: true,
});
};
From 5cee5e7c63dab36df28188f44342e36032ace8cc Mon Sep 17 00:00:00 2001
From: Valentin Palkovic
Date: Wed, 10 Apr 2024 15:12:29 +0200
Subject: [PATCH 087/380] Apply requested changes
---
code/addons/controls/package.json | 2 +-
.../create-new-story-channel.ts | 24 +++---------
.../src/utils/get-new-story-file.test.ts | 20 +++++-----
.../src/utils/get-new-story-file.ts | 37 ++++++++++---------
.../lib/core-server/src/utils/get-story-id.ts | 16 ++++----
.../new-story-templates/javascript.test.ts | 24 ++++++------
.../utils/new-story-templates/javascript.ts | 24 ++++++------
.../new-story-templates/typescript.test.ts | 20 +++++-----
.../utils/new-story-templates/typescript.ts | 24 ++++++------
code/lib/core-server/src/utils/posix.test.ts | 9 +++++
code/lib/core-server/src/utils/posix.ts | 7 ++++
code/yarn.lock | 2 +-
12 files changed, 110 insertions(+), 99 deletions(-)
create mode 100644 code/lib/core-server/src/utils/posix.test.ts
create mode 100644 code/lib/core-server/src/utils/posix.ts
diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json
index c0e43b6e5001..d13ea6560843 100644
--- a/code/addons/controls/package.json
+++ b/code/addons/controls/package.json
@@ -53,7 +53,6 @@
"dependencies": {
"@storybook/blocks": "workspace:*",
"lodash": "^4.17.21",
- "slash": "^5.0.0",
"ts-dedent": "^2.0.0"
},
"devDependencies": {
@@ -62,6 +61,7 @@
"@storybook/core-common": "workspace:*",
"@storybook/manager-api": "workspace:*",
"@storybook/node-logger": "workspace:*",
+ "@storybook/preview-api": "workspace:*",
"@storybook/theming": "workspace:*",
"@storybook/types": "workspace:*",
"react": "^18.2.0",
diff --git a/code/lib/core-server/src/server-channel/create-new-story-channel.ts b/code/lib/core-server/src/server-channel/create-new-story-channel.ts
index 5a6cc70648e5..7546c5910a70 100644
--- a/code/lib/core-server/src/server-channel/create-new-story-channel.ts
+++ b/code/lib/core-server/src/server-channel/create-new-story-channel.ts
@@ -1,19 +1,12 @@
import type { Options } from '@storybook/types';
import type { Channel } from '@storybook/channels';
import { CREATE_NEW_STORYFILE, CREATE_NEW_STORYFILE_RESULT } from '@storybook/core-events';
-import dedent from 'ts-dedent';
-import fs from 'fs/promises';
+import fs from 'node:fs/promises';
+import type { NewStoryData } from '../utils/get-new-story-file';
import { getNewStoryFile } from '../utils/get-new-story-file';
import { getStoryId } from '../utils/get-story-id';
-interface Data {
- // The filepath of the component for which the Story should be generated for (relative to the project root)
- filepath: string;
- // The name of the exported component
- componentExportName: string;
- // is default export
- default: boolean;
-}
+interface CreateNewStoryPayload extends NewStoryData {}
interface Result {
success: true | false;
@@ -27,16 +20,14 @@ export function initCreateNewStoryChannel(channel: Channel, options: Options) {
/**
* Listens for events to create a new storyfile
*/
- channel.on(CREATE_NEW_STORYFILE, async (data: Data) => {
+ channel.on(CREATE_NEW_STORYFILE, async (data: CreateNewStoryPayload) => {
try {
const { storyFilePath, exportedStoryName, storyFileContent } = await getNewStoryFile(
data,
options
);
- await fs.writeFile(storyFilePath, storyFileContent, {
- encoding: 'utf-8',
- });
+ await fs.writeFile(storyFilePath, storyFileContent, 'utf-8');
const storyId = await getStoryId({ storyFilePath, exportedStoryName }, options);
@@ -51,10 +42,7 @@ export function initCreateNewStoryChannel(channel: Channel, options: Options) {
channel.emit(CREATE_NEW_STORYFILE_RESULT, {
success: false,
result: null,
- error: dedent`
- An error occurred while creating a new story:
- ${e?.message}
- `,
+ error: `An error occurred while creating a new story:\n${e?.message}`,
} satisfies Result);
}
});
diff --git a/code/lib/core-server/src/utils/get-new-story-file.test.ts b/code/lib/core-server/src/utils/get-new-story-file.test.ts
index 9886cd56bc35..750ea322b264 100644
--- a/code/lib/core-server/src/utils/get-new-story-file.test.ts
+++ b/code/lib/core-server/src/utils/get-new-story-file.test.ts
@@ -14,9 +14,9 @@ describe('get-new-story-file', () => {
it('should create a new story file (TypeScript)', async () => {
const { exportedStoryName, storyFileContent, storyFilePath } = await getNewStoryFile(
{
- filepath: 'src/components/Page.tsx',
+ componentFilePath: 'src/components/Page.tsx',
componentExportName: 'Page',
- default: false,
+ componentIsDefaultExport: false,
},
{
presets: {
@@ -36,14 +36,14 @@ describe('get-new-story-file', () => {
import { Page } from './Page';
const meta = {
- component: Page
- } satisfies Meta
+ component: Page,
+ } satisfies Meta;
export default meta;
type Story = StoryObj;
- export const Default: Story = {}"
+ export const Default: Story = {};"
`);
expect(storyFilePath).toBe(path.join(__dirname, 'src', 'components', 'Page.stories.tsx'));
});
@@ -51,9 +51,9 @@ describe('get-new-story-file', () => {
it('should create a new story file (JavaScript)', async () => {
const { exportedStoryName, storyFileContent, storyFilePath } = await getNewStoryFile(
{
- filepath: 'src/components/Page.jsx',
+ componentFilePath: 'src/components/Page.jsx',
componentExportName: 'Page',
- default: true,
+ componentIsDefaultExport: true,
},
{
presets: {
@@ -71,12 +71,12 @@ describe('get-new-story-file', () => {
"import Component from './Page';
const meta = {
- component: Component
- }
+ component: Component,
+ };
export default meta;
- export const Default = {}"
+ export const Default = {};"
`);
expect(storyFilePath).toBe(path.join(__dirname, 'src', 'components', 'Page.stories.jsx'));
});
diff --git a/code/lib/core-server/src/utils/get-new-story-file.ts b/code/lib/core-server/src/utils/get-new-story-file.ts
index 0c561a01e1d9..fc302f13e8d1 100644
--- a/code/lib/core-server/src/utils/get-new-story-file.ts
+++ b/code/lib/core-server/src/utils/get-new-story-file.ts
@@ -5,25 +5,28 @@ import fs from 'fs';
import { getTypeScriptTemplateForNewStoryFile } from './new-story-templates/typescript';
import { getJavaScriptTemplateForNewStoryFile } from './new-story-templates/javascript';
-interface Data {
- filepath: string;
+export interface NewStoryData {
+ // The filepath of the component for which the Story should be generated for (relative to the project root)
+ componentFilePath: string;
+ // The name of the exported component
componentExportName: string;
- default: boolean;
+ // is default export
+ componentIsDefaultExport: boolean;
}
export async function getNewStoryFile(
- { filepath, componentExportName, default: isDefault }: Data,
+ { componentFilePath, componentExportName, componentIsDefaultExport }: NewStoryData,
options: Options
) {
- const isTypescript = /\.(ts|tsx|mts|cts)$/.test(filepath);
+ const isTypescript = /\.(ts|tsx|mts|cts)$/.test(componentFilePath);
const cwd = getProjectRoot();
- const frameworkPackage = await getFrameworkName(options);
+ const frameworkPackageName = await getFrameworkName(options);
- const basename = path.basename(filepath);
- const extension = path.extname(filepath);
+ const basename = path.basename(componentFilePath);
+ const extension = path.extname(componentFilePath);
const basenameWithoutExtension = basename.replace(extension, '');
- const dirname = path.dirname(filepath);
+ const dirname = path.dirname(componentFilePath);
const storyFileExtension = isTypescript ? 'tsx' : 'jsx';
const storyFileName = `${basenameWithoutExtension}.stories.${storyFileExtension}`;
@@ -33,20 +36,20 @@ export async function getNewStoryFile(
const storyFileContent = isTypescript
? getTypeScriptTemplateForNewStoryFile({
- basename: basenameWithoutExtension,
- componentExportName: componentExportName,
- default: isDefault,
- frameworkPackageName: frameworkPackage,
+ basenameWithoutExtension,
+ componentExportName,
+ componentIsDefaultExport,
+ frameworkPackageName,
exportedStoryName,
})
: getJavaScriptTemplateForNewStoryFile({
- basename: basenameWithoutExtension,
- componentExportName: componentExportName,
- default: isDefault,
+ basenameWithoutExtension,
+ componentExportName,
+ componentIsDefaultExport,
exportedStoryName,
});
- const doesStoryFileExist = fs.existsSync(path.join(cwd, filepath));
+ const doesStoryFileExist = fs.existsSync(path.join(cwd, componentFilePath));
const storyFilePath = doesStoryFileExist
? path.join(cwd, dirname, alternativeStoryFileName)
diff --git a/code/lib/core-server/src/utils/get-story-id.ts b/code/lib/core-server/src/utils/get-story-id.ts
index 299a9eadaaf5..acfbce990853 100644
--- a/code/lib/core-server/src/utils/get-story-id.ts
+++ b/code/lib/core-server/src/utils/get-story-id.ts
@@ -3,15 +3,15 @@ import dedent from 'ts-dedent';
import { normalizeStories, normalizeStoryPath } from '@storybook/core-common';
import path from 'path';
import { storyNameFromExport, toId } from '@storybook/csf';
-import slash from 'slash';
import { userOrAutoTitleFromSpecifier } from '@storybook/preview-api';
+import { posix } from './posix';
-interface Data {
+interface StoryIdData {
storyFilePath: string;
exportedStoryName: string;
}
-export async function getStoryId(data: Data, options: Options) {
+export async function getStoryId(data: StoryIdData, options: Options) {
const stories = await options.presets.apply('stories', [], options);
const workingDir = process.cwd();
@@ -22,7 +22,7 @@ export async function getStoryId(data: Data, options: Options) {
});
const relativePath = path.relative(workingDir, data.storyFilePath);
- const importPath = slash(normalizeStoryPath(relativePath));
+ const importPath = posix(normalizeStoryPath(relativePath));
const autoTitle = normalizedStories
.map((normalizeStory) => userOrAutoTitleFromSpecifier(importPath, normalizeStory))
@@ -31,10 +31,10 @@ export async function getStoryId(data: Data, options: Options) {
if (autoTitle === undefined) {
// eslint-disable-next-line local-rules/no-uncategorized-errors
throw new Error(dedent`
- The generation of your new Story file was successful! But it seems that we are unable to index it.
- Please make sure that the new Story file is matched by the 'stories' glob pattern in your Storybook configuration.
- The location of the new Story file is: ${relativePath}
- `);
+ The generation of your new Story file was successful but it seems that we are unable to index it.
+ Please make sure that the new Story file is matched by the 'stories' glob pattern in your Storybook configuration.
+ The location of the new Story file is: ${relativePath}
+ `);
}
const storyName = storyNameFromExport(data.exportedStoryName);
diff --git a/code/lib/core-server/src/utils/new-story-templates/javascript.test.ts b/code/lib/core-server/src/utils/new-story-templates/javascript.test.ts
index efebd20773b2..2d6dc4d3f0ea 100644
--- a/code/lib/core-server/src/utils/new-story-templates/javascript.test.ts
+++ b/code/lib/core-server/src/utils/new-story-templates/javascript.test.ts
@@ -4,9 +4,9 @@ import { getJavaScriptTemplateForNewStoryFile } from './javascript';
describe('javascript', () => {
it('should return a TypeScript template with a default import', () => {
const result = getJavaScriptTemplateForNewStoryFile({
- basename: 'foo',
+ basenameWithoutExtension: 'foo',
componentExportName: 'default',
- default: true,
+ componentIsDefaultExport: true,
exportedStoryName: 'Default',
});
@@ -14,20 +14,20 @@ describe('javascript', () => {
"import Component from './foo';
const meta = {
- component: Component
- }
-
+ component: Component,
+ };
+
export default meta;
-
- export const Default = {}"
+
+ export const Default = {};"
`);
});
it('should return a TypeScript template with a named import', () => {
const result = getJavaScriptTemplateForNewStoryFile({
- basename: 'foo',
+ basenameWithoutExtension: 'foo',
componentExportName: 'Example',
- default: false,
+ componentIsDefaultExport: false,
exportedStoryName: 'Default',
});
@@ -35,12 +35,12 @@ describe('javascript', () => {
"import { Example } from './foo';
const meta = {
- component: Example
- }
+ component: Example,
+ };
export default meta;
- export const Default = {}"
+ export const Default = {};"
`);
});
});
diff --git a/code/lib/core-server/src/utils/new-story-templates/javascript.ts b/code/lib/core-server/src/utils/new-story-templates/javascript.ts
index 165ea18506ff..5563f9faa1b8 100644
--- a/code/lib/core-server/src/utils/new-story-templates/javascript.ts
+++ b/code/lib/core-server/src/utils/new-story-templates/javascript.ts
@@ -1,27 +1,29 @@
import dedent from 'ts-dedent';
-export function getJavaScriptTemplateForNewStoryFile(data: {
+interface JavaScriptTemplateData {
/** The components file name without the extension */
- basename: string;
+ basenameWithoutExtension: string;
componentExportName: string;
- default: boolean;
+ componentIsDefaultExport: boolean;
/** The exported name of the default story */
exportedStoryName: string;
-}) {
- const importName = data.default ? 'Component' : data.componentExportName;
- const importStatement = data.default
- ? `import ${importName} from './${data.basename}';`
- : `import { ${importName} } from './${data.basename}';`;
+}
+
+export function getJavaScriptTemplateForNewStoryFile(data: JavaScriptTemplateData) {
+ const importName = data.componentIsDefaultExport ? 'Component' : data.componentExportName;
+ const importStatement = data.componentIsDefaultExport
+ ? `import ${importName} from './${data.basenameWithoutExtension}';`
+ : `import { ${importName} } from './${data.basenameWithoutExtension}';`;
return dedent`
${importStatement}
const meta = {
- component: ${importName}
- }
+ component: ${importName},
+ };
export default meta;
- export const ${data.exportedStoryName} = {}
+ export const ${data.exportedStoryName} = {};
`;
}
diff --git a/code/lib/core-server/src/utils/new-story-templates/typescript.test.ts b/code/lib/core-server/src/utils/new-story-templates/typescript.test.ts
index 58535aaea2c7..05cd39cca9f8 100644
--- a/code/lib/core-server/src/utils/new-story-templates/typescript.test.ts
+++ b/code/lib/core-server/src/utils/new-story-templates/typescript.test.ts
@@ -4,9 +4,9 @@ import { getTypeScriptTemplateForNewStoryFile } from './typescript';
describe('typescript', () => {
it('should return a TypeScript template with a default import', () => {
const result = getTypeScriptTemplateForNewStoryFile({
- basename: 'foo',
+ basenameWithoutExtension: 'foo',
componentExportName: 'default',
- default: true,
+ componentIsDefaultExport: true,
frameworkPackageName: '@storybook/nextjs',
exportedStoryName: 'Default',
});
@@ -17,22 +17,22 @@ describe('typescript', () => {
import Component from './foo';
const meta = {
- component: Component
- } satisfies Meta
+ component: Component,
+ } satisfies Meta;
export default meta;
type Story = StoryObj;
- export const Default: Story = {}"
+ export const Default: Story = {};"
`);
});
it('should return a TypeScript template with a named import', () => {
const result = getTypeScriptTemplateForNewStoryFile({
- basename: 'foo',
+ basenameWithoutExtension: 'foo',
componentExportName: 'Example',
- default: false,
+ componentIsDefaultExport: false,
frameworkPackageName: '@storybook/nextjs',
exportedStoryName: 'Default',
});
@@ -43,14 +43,14 @@ describe('typescript', () => {
import { Example } from './foo';
const meta = {
- component: Example
- } satisfies Meta
+ component: Example,
+ } satisfies Meta;
export default meta;
type Story = StoryObj;
- export const Default: Story = {}"
+ export const Default: Story = {};"
`);
});
});
diff --git a/code/lib/core-server/src/utils/new-story-templates/typescript.ts b/code/lib/core-server/src/utils/new-story-templates/typescript.ts
index 7be9b29880ba..38e9ffbe6e4f 100644
--- a/code/lib/core-server/src/utils/new-story-templates/typescript.ts
+++ b/code/lib/core-server/src/utils/new-story-templates/typescript.ts
@@ -1,19 +1,21 @@
import dedent from 'ts-dedent';
-export function getTypeScriptTemplateForNewStoryFile(data: {
+interface TypeScriptTemplateData {
/** The components file name without the extension */
- basename: string;
+ basenameWithoutExtension: string;
componentExportName: string;
- default: boolean;
+ componentIsDefaultExport: boolean;
/** The framework package name, e.g. @storybook/nextjs */
frameworkPackageName: string;
/** The exported name of the default story */
exportedStoryName: string;
-}) {
- const importName = data.default ? 'Component' : data.componentExportName;
- const importStatement = data.default
- ? `import ${importName} from './${data.basename}'`
- : `import { ${importName} } from './${data.basename}'`;
+}
+
+export function getTypeScriptTemplateForNewStoryFile(data: TypeScriptTemplateData) {
+ const importName = data.componentIsDefaultExport ? 'Component' : data.componentExportName;
+ const importStatement = data.componentIsDefaultExport
+ ? `import ${importName} from './${data.basenameWithoutExtension}'`
+ : `import { ${importName} } from './${data.basenameWithoutExtension}'`;
return dedent`
import type { Meta, StoryObj } from '${data.frameworkPackageName}';
@@ -21,13 +23,13 @@ export function getTypeScriptTemplateForNewStoryFile(data: {
${importStatement};
const meta = {
- component: ${importName}
- } satisfies Meta
+ component: ${importName},
+ } satisfies Meta;
export default meta;
type Story = StoryObj;
- export const ${data.exportedStoryName}: Story = {}
+ export const ${data.exportedStoryName}: Story = {};
`;
}
diff --git a/code/lib/core-server/src/utils/posix.test.ts b/code/lib/core-server/src/utils/posix.test.ts
new file mode 100644
index 000000000000..23c8d2ca3bec
--- /dev/null
+++ b/code/lib/core-server/src/utils/posix.test.ts
@@ -0,0 +1,9 @@
+import { describe, expect, it } from 'vitest';
+import { posix } from './posix';
+
+describe('posix', () => {
+ it('should replace backslashes with forward slashes', () => {
+ expect(posix('src\\components\\Page.tsx', '\\')).toBe('src/components/Page.tsx');
+ expect(posix('src\\\\components\\\\Page.tsx', '\\\\')).toBe('src/components/Page.tsx');
+ });
+});
diff --git a/code/lib/core-server/src/utils/posix.ts b/code/lib/core-server/src/utils/posix.ts
new file mode 100644
index 000000000000..d9b8224cdde5
--- /dev/null
+++ b/code/lib/core-server/src/utils/posix.ts
@@ -0,0 +1,7 @@
+import path from 'node:path';
+
+/**
+ * Replaces the path separator with forward slashes
+ */
+export const posix = (localPath: string, sep: string = path.sep) =>
+ localPath.split(sep).filter(Boolean).join(path.posix.sep);
diff --git a/code/yarn.lock b/code/yarn.lock
index 56ddebe3ade7..7be8a5f1fd96 100644
--- a/code/yarn.lock
+++ b/code/yarn.lock
@@ -4793,12 +4793,12 @@ __metadata:
"@storybook/core-common": "workspace:*"
"@storybook/manager-api": "workspace:*"
"@storybook/node-logger": "workspace:*"
+ "@storybook/preview-api": "workspace:*"
"@storybook/theming": "workspace:*"
"@storybook/types": "workspace:*"
lodash: "npm:^4.17.21"
react: "npm:^18.2.0"
react-dom: "npm:^18.2.0"
- slash: "npm:^5.0.0"
ts-dedent: "npm:^2.0.0"
languageName: unknown
linkType: soft
From 674a336295634837a5cb21e708694b344ad958ec Mon Sep 17 00:00:00 2001
From: Reuben Ellis
Date: Wed, 10 Apr 2024 07:34:58 -0600
Subject: [PATCH 088/380] Update import statement
---
code/lib/docs-tools/src/argTypes/convert/flow/convert.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/lib/docs-tools/src/argTypes/convert/flow/convert.ts b/code/lib/docs-tools/src/argTypes/convert/flow/convert.ts
index 0758bc8251a4..de3966467646 100644
--- a/code/lib/docs-tools/src/argTypes/convert/flow/convert.ts
+++ b/code/lib/docs-tools/src/argTypes/convert/flow/convert.ts
@@ -1,4 +1,4 @@
-import { UnknownFlowArgTypesError } from '@storybook/core-events/server-errors';
+import { UnknownArgTypesError } from '@storybook/core-events/server-errors';
import type { SBType } from '@storybook/types';
import type { FlowType, FlowSigType, FlowLiteralType } from './types';
@@ -19,7 +19,7 @@ const convertSig = (type: FlowSigType) => {
value: values,
};
default:
- throw new UnknownFlowArgTypesError({ type: type });
+ throw new UnknownArgTypesError({ type: type });
}
};
From b468667360a4a77697e270fc1eefa3d894051bbc Mon Sep 17 00:00:00 2001
From: Kasper Peulen
Date: Wed, 10 Apr 2024 16:03:45 +0200
Subject: [PATCH 089/380] Refactor cookies/headers a bit
---
code/frameworks/nextjs/src/headers/cookies.ts | 30 ++---
code/frameworks/nextjs/src/headers/headers.ts | 31 ++---
code/frameworks/nextjs/src/preview.tsx | 5 -
.../nextjs/yarn.lock | 126 +++++++++---------
4 files changed, 90 insertions(+), 102 deletions(-)
diff --git a/code/frameworks/nextjs/src/headers/cookies.ts b/code/frameworks/nextjs/src/headers/cookies.ts
index 6466ad439c55..75022baaea26 100644
--- a/code/frameworks/nextjs/src/headers/cookies.ts
+++ b/code/frameworks/nextjs/src/headers/cookies.ts
@@ -20,7 +20,7 @@ const stringifyCookies = (map: Map) => {
};
// Mostly copied from https://github.com/vercel/edge-runtime/blob/c25e2ded39104e2a3be82efc08baf8dc8fb436b3/packages/cookies/src/request-cookies.ts#L7
-class CookieStore implements RequestCookies {
+class RequestCookiesMock implements RequestCookies {
/** @internal */
private readonly _headers: HeadersStore;
@@ -41,15 +41,6 @@ class CookieStore implements RequestCookies {
return this._parsed[Symbol.iterator]();
}
- /** Used to restore the mocks. Called internally by @storybook/nextjs
- * to ensure that the mocks are restored between stories.
- * @internal
- * */
- mockRestore = () => {
- this.clear();
- this._headers.mockRestore();
- };
-
get size(): number {
return this._parsed.size;
}
@@ -122,11 +113,20 @@ class CookieStore implements RequestCookies {
}
}
-let cookieStore: CookieStore;
+let requestCookiesMock: RequestCookiesMock;
-export const cookies = (): CookieStore => {
- if (!cookieStore) {
- cookieStore = new CookieStore(headers());
+export const cookies = fn(() => {
+ if (!requestCookiesMock) {
+ requestCookiesMock = new RequestCookiesMock(headers());
}
- return cookieStore;
+ return requestCookiesMock;
+});
+
+const originalRestore = cookies.mockRestore.bind(null);
+
+// will be called automatically by the test loader
+cookies.mockRestore = () => {
+ originalRestore();
+ headers.mockRestore();
+ requestCookiesMock = new RequestCookiesMock(headers());
};
diff --git a/code/frameworks/nextjs/src/headers/headers.ts b/code/frameworks/nextjs/src/headers/headers.ts
index b71bece89695..13d55b95e7d4 100644
--- a/code/frameworks/nextjs/src/headers/headers.ts
+++ b/code/frameworks/nextjs/src/headers/headers.ts
@@ -5,17 +5,9 @@ import type { HeadersAdapter } from 'next/dist/server/web/spec-extension/adapter
// Mostly copied from https://github.com/vercel/next.js/blob/763b9a660433ec5278a10e59d7ae89d4010ba212/packages/next/src/server/web/spec-extension/adapters/headers.ts#L20
// @ts-expect-error unfortunately the headers property is private (and not protected) in HeadersAdapter
// and we can't access it so we need to redefine it, but that clashes with the type, hence the ts-expect-error comment.
-export class HeadersStore extends Headers implements HeadersAdapter {
+export class HeadersAdapterMock extends Headers implements HeadersAdapter {
private headers: IncomingHttpHeaders = {};
- /** Used to restore the mocks. Called internally by @storybook/nextjs
- * to ensure that the mocks are restored between stories.
- * @internal
- * */
- mockRestore = () => {
- this.forEach((key: string) => this.delete(key));
- };
-
/**
* Merges a header value into a string. This stores multiple values as an
* array, so we need to merge them into a string.
@@ -68,7 +60,7 @@ export class HeadersStore extends Headers implements HeadersAdapter {
).mockName('headers().forEach');
public entries = fn(
- function* (this: HeadersStore): IterableIterator<[string, string]> {
+ function* (this: HeadersAdapterMock): IterableIterator<[string, string]> {
for (const key of Object.keys(this.headers)) {
const name = key.toLowerCase();
// We assert here that this is a string because we got it from the
@@ -81,7 +73,7 @@ export class HeadersStore extends Headers implements HeadersAdapter {
).mockName('headers().entries');
public keys = fn(
- function* (this: HeadersStore): IterableIterator {
+ function* (this: HeadersAdapterMock): IterableIterator {
for (const key of Object.keys(this.headers)) {
const name = key.toLowerCase();
yield name;
@@ -90,7 +82,7 @@ export class HeadersStore extends Headers implements HeadersAdapter {
).mockName('headers().keys');
public values = fn(
- function* (this: HeadersStore): IterableIterator {
+ function* (this: HeadersAdapterMock): IterableIterator {
for (const key of Object.keys(this.headers)) {
// We assert here that this is a string because we got it from the
// Object.keys() call above.
@@ -106,11 +98,14 @@ export class HeadersStore extends Headers implements HeadersAdapter {
}
}
-let headerStore: HeadersStore;
+let headersAdapterMock: HeadersAdapterMock;
-export const headers = (): HeadersStore => {
- if (!headerStore) {
- headerStore = new HeadersStore();
- }
- return headerStore;
+export const headers = () => {
+ if (!headersAdapterMock) headersAdapterMock = new HeadersAdapterMock();
+ return headersAdapterMock;
+};
+
+// This fn is called by ./cookies to restore the headers in the right order
+headers.mockRestore = () => {
+ headersAdapterMock = new HeadersAdapterMock();
};
diff --git a/code/frameworks/nextjs/src/preview.tsx b/code/frameworks/nextjs/src/preview.tsx
index 7fb164d1f0de..cb4800a20a35 100644
--- a/code/frameworks/nextjs/src/preview.tsx
+++ b/code/frameworks/nextjs/src/preview.tsx
@@ -28,11 +28,6 @@ export const decorators: Addon_DecoratorFunction[] = [
HeadManagerDecorator,
];
-export const loaders: Addon_LoaderFunction = async () => {
- cookies().mockRestore();
- headers().mockRestore();
-};
-
export const parameters = {
docs: {
source: {
diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
index 7b54b424d5b9..ecd18b4c87b1 100644
--- a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
+++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock
@@ -2379,7 +2379,7 @@ __metadata:
"@storybook/addon-actions@file:../../../code/addons/actions::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-actions@file:../../../code/addons/actions#../../../code/addons/actions::hash=99649f&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-actions@file:../../../code/addons/actions#../../../code/addons/actions::hash=a58e61&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-events": "workspace:*"
"@storybook/global": "npm:^5.0.0"
@@ -2387,7 +2387,7 @@ __metadata:
dequal: "npm:^2.0.2"
polished: "npm:^4.2.2"
uuid: "npm:^9.0.0"
- checksum: 10/79a14c7a74591e404e5ec22c2b6c9eaa03dd48bf3316470dd2642e3c70abd7c90b168fd350e729b617967c7d759df2ef0107534d218d1138b12e737c8a3e888e
+ checksum: 10/448ef050488c32b161113c707a9bd3e4eb734f7a23f350d7cb05dd30927785c19b0eb1b2f01f8f5f7106e8f46dcc2cfc9496a089dee818754dc83ae5403d8ee6
languageName: node
linkType: hard
@@ -2403,17 +2403,13 @@ __metadata:
linkType: hard
"@storybook/addon-controls@file:../../../code/addons/controls::locator=portable-stories-nextjs%40workspace%3A.":
- version: 8.1.0-alpha.5
- resolution: "@storybook/addon-controls@file:../../../code/addons/controls#../../../code/addons/controls::hash=358687&locator=portable-stories-nextjs%40workspace%3A."
+ version: 8.1.0-alpha.6
+ resolution: "@storybook/addon-controls@file:../../../code/addons/controls#../../../code/addons/controls::hash=b28ca0&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/blocks": "workspace:*"
- "@storybook/core-common": "workspace:*"
- cjs-module-lexer: "npm:^1.2.3"
- es-module-lexer: "npm:^1.5.0"
- globby: "npm:^14.0.1"
lodash: "npm:^4.17.21"
ts-dedent: "npm:^2.0.0"
- checksum: 10/feb098e18f942562769dfdfb4afc70655f67f11e6d14acf8e3ca4cfe9a22e09e89ede9f17be6ff1c07a56bed8a6fa1961fa044137a3e7a34471345bcccd091f2
+ checksum: 10/f68a13e40bda392c1abc4cee2f2294fe98f11e8b34af8213532ae14027327efbafb3c9a8d75d300a3c58fb8d036a09f349e60cd064dd8dbde504add2945bab6b
languageName: node
linkType: hard
@@ -2478,7 +2474,7 @@ __metadata:
"@storybook/addon-interactions@file:../../../code/addons/interactions::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/addon-interactions@file:../../../code/addons/interactions#../../../code/addons/interactions::hash=e7e04a&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/addon-interactions@file:../../../code/addons/interactions#../../../code/addons/interactions::hash=43a156&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
"@storybook/instrumenter": "workspace:*"
@@ -2486,7 +2482,7 @@ __metadata:
"@storybook/types": "workspace:*"
polished: "npm:^4.2.2"
ts-dedent: "npm:^2.2.0"
- checksum: 10/c66d7db9c1356903d444211962054b0a692a56f7ed5debcaa1f2e40fd57575975b8de86c2fb3be3a140e69cdc8f36b25f81be6e2ca55fb4facf826694d8be65f
+ checksum: 10/7ab50dfb5ccfde231d5ebde1e695512c5bb3706e5fe9bc580fbf23d5298ac7685e9648fbbc5f65605779954dc2f04ac1ce799e47b387d7eaaff5c9d7e8485602
languageName: node
linkType: hard
@@ -2590,7 +2586,7 @@ __metadata:
"@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5#../../../code/builders/builder-webpack5::hash=983659&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/builder-webpack5@file:../../../code/builders/builder-webpack5#../../../code/builders/builder-webpack5::hash=c0c586&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2629,26 +2625,26 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/f84f41cd8ac80376ba603f4bb58da565f2b0e95ed37593279d85c4e5573de64633f10b7c6f2bd399f6d40057f1c97934760b969326520250f6de5efd07ac967b
+ checksum: 10/f4fe0264184b91d9a96baf2d35fc7c7c212b516901650c852f61c2aec2e6b7d81f6828b7ca7ce34f1623bab5cd838936d5877d982df0fa75cab577af78ce79ef
languageName: node
linkType: hard
"@storybook/channels@file:../../../code/lib/channels::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/channels@file:../../../code/lib/channels#../../../code/lib/channels::hash=3a33a2&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/channels@file:../../../code/lib/channels#../../../code/lib/channels::hash=413c8e&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/core-events": "workspace:*"
"@storybook/global": "npm:^5.0.0"
telejson: "npm:^7.2.0"
tiny-invariant: "npm:^1.3.1"
- checksum: 10/cda1b155f07fdac919a29e5a5287ae33ef4b3ed9c5c9816c29e17e3aa0dd788dc59da8775c40341ebcbd426ecf4f9ab629949dfe945834f48db7ca6053c062f1
+ checksum: 10/6091e0ca5a19b46589877a6a17cac725ef863a8cdf61d812261673e16227490f8b80fcf26daa8924dbcaad434c91118ac399f3a610c7eec5ed094e7b0dfd0947
languageName: node
linkType: hard
"@storybook/cli@file:../../../code/lib/cli::locator=portable-stories-nextjs%40workspace%3A.":
- version: 8.1.0-alpha.5
- resolution: "@storybook/cli@file:../../../code/lib/cli#../../../code/lib/cli::hash=49e395&locator=portable-stories-nextjs%40workspace%3A."
+ version: 8.1.0-alpha.6
+ resolution: "@storybook/cli@file:../../../code/lib/cli#../../../code/lib/cli::hash=2914c7&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/core": "npm:^7.23.0"
"@babel/types": "npm:^7.23.0"
@@ -2689,16 +2685,16 @@ __metadata:
bin:
getstorybook: ./bin/index.js
sb: ./bin/index.js
- checksum: 10/37be78e7b11cfb9d712f9b948e3017665fcee970e1b3a4806f3f8307ea9db7e39f4b12fa919086a53efbe4e24a5e6196b2daafb958c11145e9e5d224fa70af55
+ checksum: 10/6c967c34ef47687aa6ccbc70d82f22e375be79af1bf5eec3e1163c7774b65fda69a414c0aa712039062a9f184bc84d70e7fcf713712c28d4a121cc3848a32600
languageName: node
linkType: hard
"@storybook/client-logger@file:../../../code/lib/client-logger::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/client-logger@file:../../../code/lib/client-logger#../../../code/lib/client-logger::hash=f3ac76&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/client-logger@file:../../../code/lib/client-logger#../../../code/lib/client-logger::hash=6408e1&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/global": "npm:^5.0.0"
- checksum: 10/00b5cfade208483f5ec85c8aa59cabf402502a4cf1d9c3ee24a311a396e65ce97f0a3d4356aac9f413c8d84c9804ccb07aaeda6f3d553799e6e036960f4a2fbe
+ checksum: 10/ff3312279cf1bcaa3fcf91149951e4b7b6cba79ddbb0f80e488126a38bf1f7ceab4ad43cf40324b5ec9c3a8a786695042bc7cd47a0ae0a4835f06dddc5fb214e
languageName: node
linkType: hard
@@ -2727,7 +2723,7 @@ __metadata:
"@storybook/components@file:../../../code/ui/components::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/components@file:../../../code/ui/components#../../../code/ui/components::hash=2c348b&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/components@file:../../../code/ui/components#../../../code/ui/components::hash=636348&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@radix-ui/react-slot": "npm:^1.0.2"
"@storybook/client-logger": "workspace:*"
@@ -2741,13 +2737,13 @@ __metadata:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
- checksum: 10/5ca7607bebb485e1dbb5c26f5dc3482e661d1646381be3ae26284c1e82cb0e2de51e05f5c4272ebe4d5fa6536aecb8dcd46e3da871aad90ba67a2e7e8987d278
+ checksum: 10/02326f8b50631922d80cf64163abf4e723c5a1fd78c1ae1b276c95ff7992c0a826736badf1b7222038d83775b2937ef60de426aab7a6d5262a7b1152f5825abc
languageName: node
linkType: hard
"@storybook/core-common@file:../../../code/lib/core-common::locator=portable-stories-nextjs%40workspace%3A.":
- version: 8.1.0-alpha.5
- resolution: "@storybook/core-common@file:../../../code/lib/core-common#../../../code/lib/core-common::hash=55d292&locator=portable-stories-nextjs%40workspace%3A."
+ version: 8.1.0-alpha.6
+ resolution: "@storybook/core-common@file:../../../code/lib/core-common#../../../code/lib/core-common::hash=26f1e6&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-events": "workspace:*"
"@storybook/csf-tools": "workspace:*"
@@ -2777,22 +2773,22 @@ __metadata:
tiny-invariant: "npm:^1.3.1"
ts-dedent: "npm:^2.0.0"
util: "npm:^0.12.4"
- checksum: 10/e9308c3683651e2c925823e4bee0f91156ba544b0dc72ee6291810e7bd2e17690bce3f426c10d942fd5e18eb545589e5a3347cd02eb6ecceb058dad7a56bb775
+ checksum: 10/7b692d71f9d170253ad376d67d364d351eff3d6f9b21fcf2471aefbf78fe4fdfb61a24f444630ad0bcbe3d560b92350271087e03f7e040cedbbfbb142ef0bc7b
languageName: node
linkType: hard
"@storybook/core-events@file:../../../code/lib/core-events::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-events@file:../../../code/lib/core-events#../../../code/lib/core-events::hash=840150&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-events@file:../../../code/lib/core-events#../../../code/lib/core-events::hash=8a7a19&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
ts-dedent: "npm:^2.0.0"
- checksum: 10/ccfa4397af9c114f401ac87d232f66c0cb37e7ee104647b36dd34e7bf598ff7e3a22fb18a6fb9d1529cef35f053056e34fa3f7626e62c5e133d31bd58fd6b5cb
+ checksum: 10/ac72fe623b6bf6a6897db1cce99539e67c75ce958d29c09b53930e696e7b6aa6d23cfe0fe41a3415b8f281e972b5c010efe89b9fd8783960a0c982088ecbe928
languageName: node
linkType: hard
"@storybook/core-server@file:../../../code/lib/core-server::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-server@file:../../../code/lib/core-server#../../../code/lib/core-server::hash=2c034c&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-server@file:../../../code/lib/core-server#../../../code/lib/core-server::hash=e5bcbd&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@aw-web-design/x-default-browser": "npm:1.4.126"
"@babel/core": "npm:^7.23.9"
@@ -2817,9 +2813,11 @@ __metadata:
"@types/semver": "npm:^7.3.4"
better-opn: "npm:^3.0.2"
chalk: "npm:^4.1.0"
+ cjs-module-lexer: "npm:^1.2.3"
cli-table3: "npm:^0.6.1"
compression: "npm:^1.7.4"
detect-port: "npm:^1.3.0"
+ es-module-lexer: "npm:^1.5.0"
express: "npm:^4.17.3"
fs-extra: "npm:^11.1.0"
globby: "npm:^14.0.1"
@@ -2837,20 +2835,20 @@ __metadata:
util-deprecate: "npm:^1.0.2"
watchpack: "npm:^2.2.0"
ws: "npm:^8.2.3"
- checksum: 10/83c58dfa24e67e8ea10107858e723eebe3ebafa17580fbe9526022e02d1ba2467ef5e75ba3b303436c470a7151f183ad2d781b4cef1201a73cdf8f10d317cc57
+ checksum: 10/1f4f9495d5d3158613966a1b84f8fb19d8fcee6d05f06c885d27315cf8416fe36b18c898d577ff2a5ad72157d7f7e63171d9b49bf0191cdc45519f224e5c5ad7
languageName: node
linkType: hard
"@storybook/core-webpack@file:../../../code/lib/core-webpack::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/core-webpack@file:../../../code/lib/core-webpack#../../../code/lib/core-webpack::hash=d17dda&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/core-webpack@file:../../../code/lib/core-webpack#../../../code/lib/core-webpack::hash=1c6e9a&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-common": "workspace:*"
"@storybook/node-logger": "workspace:*"
"@storybook/types": "workspace:*"
"@types/node": "npm:^18.0.0"
ts-dedent: "npm:^2.0.0"
- checksum: 10/2e56db38374ec96f01c00c0fa4c8a9090c1db1d56c8c611a93d1a0c60769aa6a2c751ed29fa6c3a3a7adbf99d457287908e8e01ee1848ab6c59f6837934d81bf
+ checksum: 10/af79e1e751158c7d47475736c052cf1fd6535fbaa131168141a06eef2ed5f178165771dba4e4995a567d5d180d4af33a4e75c573153ec39a838901cbb16aa4c1
languageName: node
linkType: hard
@@ -2866,7 +2864,7 @@ __metadata:
"@storybook/csf-tools@file:../../../code/lib/csf-tools::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/csf-tools@file:../../../code/lib/csf-tools#../../../code/lib/csf-tools::hash=69584a&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/csf-tools@file:../../../code/lib/csf-tools#../../../code/lib/csf-tools::hash=703916&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/generator": "npm:^7.23.0"
"@babel/parser": "npm:^7.23.0"
@@ -2877,7 +2875,7 @@ __metadata:
fs-extra: "npm:^11.1.0"
recast: "npm:^0.23.5"
ts-dedent: "npm:^2.0.0"
- checksum: 10/7fce79866ace04b9a2bc78a66a03e27e6e770b4279e1b40c08634bce01eb57be22f5f192f73c6a65cc959c8910f63a3d35e31a71fe3ac821aea095722e324710
+ checksum: 10/b597a467657223667710c73bcdd8d85e481a7c088e816539dd9513f2a42cb825e1d3fdd5461772d969201d2f6901280c30a9712d8711b7e12661a01d692f6871
languageName: node
linkType: hard
@@ -2908,7 +2906,7 @@ __metadata:
"@storybook/docs-tools@file:../../../code/lib/docs-tools::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/docs-tools@file:../../../code/lib/docs-tools#../../../code/lib/docs-tools::hash=4be280&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/docs-tools@file:../../../code/lib/docs-tools#../../../code/lib/docs-tools::hash=0f1a92&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-common": "workspace:*"
"@storybook/preview-api": "workspace:*"
@@ -2917,7 +2915,7 @@ __metadata:
assert: "npm:^2.1.0"
doctrine: "npm:^3.0.0"
lodash: "npm:^4.17.21"
- checksum: 10/121355441e903b87a0b9e590eca45a9b355af949148da6d23434f59b2aa753f00e0ffb8bc625d4ca91cf01e5e9782caceb561537d62729a2b2e240b6e640a0f4
+ checksum: 10/6efb67c748bf9616313844cc482a31b49834d7b94767a544b7a5ed9a2e2d28c3d8a945162040b09f39af3f36c5288c00a83a67166c5d6a91b38875b8ff039acd
languageName: node
linkType: hard
@@ -2940,7 +2938,7 @@ __metadata:
"@storybook/instrumenter@file:../../../code/lib/instrumenter::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/instrumenter@file:../../../code/lib/instrumenter#../../../code/lib/instrumenter::hash=ffe9d7&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/instrumenter@file:../../../code/lib/instrumenter#../../../code/lib/instrumenter::hash=da2c8f&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2949,13 +2947,13 @@ __metadata:
"@storybook/preview-api": "workspace:*"
"@vitest/utils": "npm:^1.3.1"
util: "npm:^0.12.4"
- checksum: 10/84948fcfafe05e5934117e6c514a1788f9d146d28f749c11313e5f65c60f3f20be0e659e97f14a6b5ce405b01afa4941571f644a9cb88d8b3a956c2c79413723
+ checksum: 10/a55b3615eee655ef969641128c408ad5a6f3a0196af135e4ea1aa9289b9a2c98d84b34c3a57a25ca8cf6e619faad5fe6440232097fb99ecf7fc0341395a8ce16
languageName: node
linkType: hard
"@storybook/manager-api@file:../../../code/lib/manager-api::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/manager-api@file:../../../code/lib/manager-api#../../../code/lib/manager-api::hash=3e3312&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/manager-api@file:../../../code/lib/manager-api#../../../code/lib/manager-api::hash=4ab1f3&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -2972,20 +2970,20 @@ __metadata:
store2: "npm:^2.14.2"
telejson: "npm:^7.2.0"
ts-dedent: "npm:^2.0.0"
- checksum: 10/dcc92a7797ccf0f986ef2eb9077884799e4cc92603ca52a69071b4943ca149fd17d771c64bd1fd474c8287b4bda5385c7b24bada7acc9f7413deac152ec32157
+ checksum: 10/ef8fe488bd220f3b895d26895e5a55a9bc110ee799f062f06d3c32dfa5ccd834c04074d96d8d4dc8c41336e322b2d3a4e0f93dc518442b22a9b36ddbfc92f990
languageName: node
linkType: hard
"@storybook/manager@file:../../../code/ui/manager::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/manager@file:../../../code/ui/manager#../../../code/ui/manager::hash=257346&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/cdfcb34cdfaa7b7fbd388c54f2ecc85e0b4276ba1d915cc4b36dfcdd9ab8c5391815ae502089aa77e5dad8e51a064f86771969f20e9d10b5b14973d8e4e80a8b
+ resolution: "@storybook/manager@file:../../../code/ui/manager#../../../code/ui/manager::hash=645d43&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/9708627cc2f3a886c53dfec9402088f6b18b40ba8f472289d08c6b25c0e2e1e71871d6a79f19e57586751b287b55506c72372d1a0fab2efa89847719bf7c50f7
languageName: node
linkType: hard
"@storybook/nextjs@file:../../../code/frameworks/nextjs::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/nextjs@file:../../../code/frameworks/nextjs#../../../code/frameworks/nextjs::hash=a5b14e&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/nextjs@file:../../../code/frameworks/nextjs#../../../code/frameworks/nextjs::hash=8cda79&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@babel/core": "npm:^7.23.2"
"@babel/plugin-syntax-bigint": "npm:^7.8.3"
@@ -3043,20 +3041,20 @@ __metadata:
optional: true
webpack:
optional: true
- checksum: 10/86d287d5088a26adabce7b6ca5e56eebedf44df95bd07b1085253e095bea2d1d54898eed384ff7ca75866b00ffa36dd0a0c8f252edc1b4feb48725b6ca2ca851
+ checksum: 10/6a1ccdb267a0a9dfc99716dc16fff89d1ec49d4abcf56631185ec57107a8a7a500771e65174e65b7c2f14a5049a17777bb3934034d9ec7793c685a945c3c93f5
languageName: node
linkType: hard
"@storybook/node-logger@file:../../../code/lib/node-logger::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/node-logger@file:../../../code/lib/node-logger#../../../code/lib/node-logger::hash=0d5379&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/ba3b49b55a325ec5d885898e5cd61370c19ad27a54315025c315bb08b6a09a64cfd3097748225be1f4b07aad42245a239ac9ba6e957c854ebb48718a43e5c215
+ resolution: "@storybook/node-logger@file:../../../code/lib/node-logger#../../../code/lib/node-logger::hash=76992b&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/39a64d0cfc1ab16e4e808edc63fb9b5b76c038acb864b00d756260f9b5cf66116a758f6969dcc06daab8e69a8965fceef11c1d3cab8b524de1021b97dfd5b0e4
languageName: node
linkType: hard
"@storybook/preset-react-webpack@file:../../../code/presets/react-webpack::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preset-react-webpack@file:../../../code/presets/react-webpack#../../../code/presets/react-webpack::hash=3c5b01&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/preset-react-webpack@file:../../../code/presets/react-webpack#../../../code/presets/react-webpack::hash=f3317c&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/core-webpack": "workspace:*"
"@storybook/docs-tools": "workspace:*"
@@ -3079,13 +3077,13 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/3baffd6ce4e642f852c370ccd4ae8098a5e730f4493ce43c8414f0b44e59c8bc8a99d9975cf5149b655f1808e54d274754044f45983b9f1be7c9a28f00931ac2
+ checksum: 10/ee2981fac009bed8163403a304fc34ea8e6f307bd11c26dc6b9e1682e5116facfef0a1e6c59dafe179977b1f5e366912db7e6cac7530cd7074a7c2dd071bd91e
languageName: node
linkType: hard
"@storybook/preview-api@file:../../../code/lib/preview-api::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preview-api@file:../../../code/lib/preview-api#../../../code/lib/preview-api::hash=2e825a&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/preview-api@file:../../../code/lib/preview-api#../../../code/lib/preview-api::hash=8ed046&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
@@ -3101,14 +3099,14 @@ __metadata:
tiny-invariant: "npm:^1.3.1"
ts-dedent: "npm:^2.0.0"
util-deprecate: "npm:^1.0.2"
- checksum: 10/8cb6df33b082d43c40daa182241aef50e583fc3c45d954730df0fbf305645926b2904b5177661a7a6294969014bda8c647f24960afd6114333e7c4bb00caa869
+ checksum: 10/d5a6dc59d0cf9660869c7059567ffe09e1d590835aa781a5a94fc109ae67ae961f82db05a5e983b209e76a595ef3b9669f25897a174701fbcd2846a321ddd8e6
languageName: node
linkType: hard
"@storybook/preview@file:../../../code/lib/preview::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/preview@file:../../../code/lib/preview#../../../code/lib/preview::hash=dccd68&locator=portable-stories-nextjs%40workspace%3A."
- checksum: 10/834521c05fe7496e5d411dd9dc8cd3d2e3902bd101fcfe9e1caa2bace894fb6698d035fd190072a3cf2e294c86324315f30732c16bc30f75a1307feab53c16d1
+ resolution: "@storybook/preview@file:../../../code/lib/preview#../../../code/lib/preview::hash=98d894&locator=portable-stories-nextjs%40workspace%3A."
+ checksum: 10/a528ce775b0cbd9572b870f14837025294d771f9717f6f8d6cbb8ccab6c05b6d3392d5a4211f09a8ec3073080beaef18d86ebeb1f00d137b49f71f15815d2d51
languageName: node
linkType: hard
@@ -3132,17 +3130,17 @@ __metadata:
"@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim#../../../code/lib/react-dom-shim::hash=062b74&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/react-dom-shim@file:../../../code/lib/react-dom-shim#../../../code/lib/react-dom-shim::hash=4a12a1&locator=portable-stories-nextjs%40workspace%3A."
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
- checksum: 10/ba63271a1f2d663cd53354798c490d306787b8033586a1062175b89fe4409759cbc959aa34dad12ff8f9bf2e9c141a391784eda81f23cbc9d13495128c9e1611
+ checksum: 10/1328cd24014a00ea7b07c2359c0d6af7fd7973a8635e1e42ff8f462524ad0961fccfc3200f25f86e1fdd75d151f2f50038db70e88c5fb4c9ff7a93cfa387d4dd
languageName: node
linkType: hard
"@storybook/react@file:../../../code/renderers/react::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/react@file:../../../code/renderers/react#../../../code/renderers/react::hash=f60a6b&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/react@file:../../../code/renderers/react#../../../code/renderers/react::hash=bd65ea&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/docs-tools": "workspace:*"
@@ -3172,18 +3170,18 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 10/aa5c6739bfda7f26dcf2155cc61cc02c7387046fd3f1ef0029fa851b56024e5c81e69ef11c7a3f167bf66715161586abc2e29bbcdd5e3ea4ff9f0a34bbdac095
+ checksum: 10/cd74c903f1353af291132c4a3a04f6dbdae6a131723d41f8cf38fb6181a0dc1c0b1a292e293338386f72b29f1f9cb2e4e660ab50ac61914e5236fad1f376a290
languageName: node
linkType: hard
"@storybook/router@file:../../../code/lib/router::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/router@file:../../../code/lib/router#../../../code/lib/router::hash=f3d914&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/router@file:../../../code/lib/router#../../../code/lib/router::hash=2f121e&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
memoizerific: "npm:^1.11.3"
qs: "npm:^6.10.0"
- checksum: 10/ae4218eb5cb26c1fd31b334a5431a228a4fd6f30bff1e4feb68c188317ceece7b91510c0c98c4a2d4fe419baebb2da21ea03d65dfe5123257befdb8ad9e0770c
+ checksum: 10/8fcccb54ade96e59e716e74c9985633d6ff4a9e025f80e83cb1c8c61443910cb3205d2b2753f7a455544b8d39be832c456db4ecff2e58753b0fd45a0f828b6b6
languageName: node
linkType: hard
@@ -3205,7 +3203,7 @@ __metadata:
"@storybook/test@file:../../../code/lib/test::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/test@file:../../../code/lib/test#../../../code/lib/test::hash=cd3c93&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/test@file:../../../code/lib/test#../../../code/lib/test::hash=4192cc&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/client-logger": "workspace:*"
"@storybook/core-events": "workspace:*"
@@ -3218,13 +3216,13 @@ __metadata:
"@vitest/spy": "npm:^1.3.1"
chai: "npm:^4.4.1"
util: "npm:^0.12.4"
- checksum: 10/783d04972494921194bbf60ba366dd62c81340257671acdb2693156dc64c709c64a51efc5fcf528c5a43d11167b2193d4582d24e5012e86407b64fbeda4c1c66
+ checksum: 10/ae7add4394f4c590aaac487da53f0e335051560ecd18f0e831f6e62ffb15aad2299060f58e6149bf3637dd8ed48217e7ae3bd54b58a5ea35ab8fea3982aabbc2
languageName: node
linkType: hard
"@storybook/theming@file:../../../code/lib/theming::locator=portable-stories-nextjs%40workspace%3A.":
version: 8.1.0-alpha.6
- resolution: "@storybook/theming@file:../../../code/lib/theming#../../../code/lib/theming::hash=9cc340&locator=portable-stories-nextjs%40workspace%3A."
+ resolution: "@storybook/theming@file:../../../code/lib/theming#../../../code/lib/theming::hash=f968b9&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1"
"@storybook/client-logger": "workspace:*"
@@ -3238,18 +3236,18 @@ __metadata:
optional: true
react-dom:
optional: true
- checksum: 10/e64850170fec111310877caa5a994ad53c9e072f324d0871d98e34f7d30688dadd7b24914441b3c50f3e9dc3f80909c60fa292e61f7fe6b257a6e19521a6c8e1
+ checksum: 10/e603c954ca9f8a99cb82deac40c66f1fd71d170900f6c8a4e0f3157921b6b1da6c0d644519960312eefa1def67a99c50a4e4cd6c6e92fd121d99a9fcb822f6b9
languageName: node
linkType: hard
"@storybook/types@file:../../../code/lib/types::locator=portable-stories-nextjs%40workspace%3A.":
- version: 8.1.0-alpha.5
- resolution: "@storybook/types@file:../../../code/lib/types#../../../code/lib/types::hash=0524c9&locator=portable-stories-nextjs%40workspace%3A."
+ version: 8.1.0-alpha.6
+ resolution: "@storybook/types@file:../../../code/lib/types#../../../code/lib/types::hash=c292b3&locator=portable-stories-nextjs%40workspace%3A."
dependencies:
"@storybook/channels": "workspace:*"
"@types/express": "npm:^4.7.0"
file-system-cache: "npm:2.3.0"
- checksum: 10/b2835c9386c22e535e62263fe03ead9c43a1c9762b6524ed8a9b1954887e8853311d580caa7711d57a1eecc9ce30cd7cfd9d814a45723e8434397b7adced1871
+ checksum: 10/66db65b0e5185de6e9df7fb239b4a45beaf5e42d1f558ae465346b850f8626909aa7d415b49ed0ba0b837219ded47021c42bffff83f13eba29867ee8eafe7b0c
languageName: node
linkType: hard
From 3893f71e8d68a84cf6deac7df0fbe3c09c270ed0 Mon Sep 17 00:00:00 2001
From: Norbert de Langen
Date: Wed, 10 Apr 2024 16:08:43 +0200
Subject: [PATCH 090/380] wip
---
.../utils/save-from-controls/update-args-in-csf-file.test.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.test.ts b/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.test.ts
index c44e4d15fe7a..5e4fd1323a88 100644
--- a/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.test.ts
+++ b/code/lib/core-server/src/utils/save-from-controls/update-args-in-csf-file.test.ts
@@ -13,8 +13,6 @@ const FILES = {
tab: join(getProjectRoot(), 'code/ui/components/src/components/tabs/tabs.stories.tsx'),
};
-// console.log(FILES);
-
describe('success', () => {
test('should return success', async () => {
const before = await readFile(FILES.tab, 'utf-8');
@@ -29,5 +27,7 @@ describe('success', () => {
const after = printCsf(parsed);
expect(after.code).not.toBe(before);
+
+ // TODO, how to assert the change? without diffing the whole file
});
});
From 218b865e91195ecf948322fcbc1956f5c37ca516 Mon Sep 17 00:00:00 2001
From: Gert Hengeveld
Date: Wed, 10 Apr 2024 16:25:40 +0200
Subject: [PATCH 091/380] Hide info text on overflow
---
.../components/ArgsTable/SaveFromControls.tsx | 34 +++++++++++--------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/code/ui/blocks/src/components/ArgsTable/SaveFromControls.tsx b/code/ui/blocks/src/components/ArgsTable/SaveFromControls.tsx
index 5332ff7632f9..e1daafc80dbc 100644
--- a/code/ui/blocks/src/components/ArgsTable/SaveFromControls.tsx
+++ b/code/ui/blocks/src/components/ArgsTable/SaveFromControls.tsx
@@ -26,8 +26,10 @@ const Container = styled.div({
const Bar = styled(BaseBar)(({ theme }) => ({
display: 'flex',
+ flexDirection: 'row-reverse', // hide Info rather than Actions on overflow
alignItems: 'center',
justifyContent: 'space-between',
+ flexWrap: 'wrap',
gap: 6,
padding: '6px 10px',
animation: `${slideIn} 300ms forwards`,
@@ -36,13 +38,23 @@ const Bar = styled(BaseBar)(({ theme }) => ({
fontSize: theme.typography.size.s2,
}));
-const Content = styled.div({
+const Info = styled.div({
display: 'flex',
+ flex: '99 0 auto',
alignItems: 'center',
marginLeft: 10,
gap: 6,
});
+const Actions = styled.div(({ theme }) => ({
+ display: 'flex',
+ flex: '1 0 0',
+ alignItems: 'center',
+ gap: 2,
+ color: theme.color.mediumdark,
+ fontSize: theme.typography.size.s2,
+}));
+
const Label = styled.div({
'@container (max-width: 799px)': {
lineHeight: 0,
@@ -65,14 +77,6 @@ const ModalInput = styled(Form.Input)(({ theme }) => ({
},
}));
-const Actions = styled.div(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- gap: 2,
- color: theme.color.mediumdark,
- fontSize: theme.typography.size.s2,
-}));
-
type SaveFromControlsProps = {
saveStory: () => void;
createStory: (storyName: string) => void;
@@ -116,12 +120,6 @@ export const SaveFromControls = ({ saveStory, createStory, resetArgs }: SaveFrom
return (
-
-
- You modified this story. Do you want to save your changes?
-
-
-
+
+
+ You modified this story. Do you want to save your changes?
+
+
+