-```
-
-This means that if you take DOM snapshots of your stories, they will be affected and you will have to update them.
-
-The id calculation is based on different heuristics based on your Meta title and Story name. When using `composeStories`, the id can be inferred automatically. However, when using `composeStory` and your story does not explicitly have a `storyName` property, the story name can't be inferred automatically. As a result, its name will be "Unnamed Story", resulting in a wrapper id like `"#storybook-story-button--unnamed-story"`. If the id matters to you and you want to fix it, you have to specify the `exportsName` property like so:
-
-```ts
-test("snapshots the story with custom id", () => {
- const Primary = composeStory(
- stories.Primary,
- stories.default,
- undefined,
- // If you do not want the `unnamed-story` id, you have to pass the name of the story as a parameter
- "Primary"
- );
-
- const { baseElement } = render();
- expect(baseElement).toMatchSnapshot();
-});
-```
-
#### Composed Vue stories are now components instead of functions
`composeStory` (and `composeStories`) from `@storybook/vue3` now return Vue components rather than story functions that return components. This means that when rendering these composed stories you just pass the composed story _without_ first calling it.
@@ -1068,6 +1039,45 @@ The following exports from `@storybook/preview-api` are now removed:
Please file an issue if you need these APIs.
+#### Removals in @storybook/components
+
+The `TooltipLinkList` UI component used to customize the Storybook toolbar has been updated to use the `icon` property instead of the `left` property to position its content. If you've enabled this property in your `globalTypes` configuration, addons, or any other place, you'll need to replace it with an `icon` property to mimic the same behavior. For example:
+
+```diff
+// .storybook/preview.js|ts
+// Replace your-framework with the framework you are using (e.g., react, vue3)
+import { Preview } from '@storybook/your-framework';
+
+const preview: Preview = {
+ globalTypes: {
+ locale: {
+ description: 'Internationalization locale',
+ defaultValue: 'en',
+ toolbar: {
+ icon: 'globe',
+ items: [
+ {
+ value: 'en',
+ right: 'πΊπΈ',
+- left: 'οΌ'
++ icon: 'facehappy'
+ title: 'English'
+ },
+ { value: 'fr', right: 'π«π·', title: 'FranΓ§ais' },
+ { value: 'es', right: 'πͺπΈ', title: 'EspaΓ±ol' },
+ { value: 'zh', right: 'π¨π³', title: 'δΈζ' },
+ { value: 'kr', right: 'π°π·', title: 'νκ΅μ΄' },
+ ],
+ },
+ },
+ },
+};
+
+export default preview;
+```
+
+To learn more about the available icons and their names, see the [Storybook documentation](https://storybook.js.org/docs/8.0/faq#what-icons-are-available-for-my-toolbar-or-my-addon).
+
#### Removals in @storybook/types
The following exports from `@storybook/types` are now removed:
diff --git a/code/.yarn/patches/@vitest-expect-npm-1.1.3-2062bf533f.patch b/code/.yarn/patches/@vitest-expect-npm-1.3.1-973071a540.patch
similarity index 85%
rename from code/.yarn/patches/@vitest-expect-npm-1.1.3-2062bf533f.patch
rename to code/.yarn/patches/@vitest-expect-npm-1.3.1-973071a540.patch
index 9a1b74e203bd..b2028a85b1ff 100644
--- a/code/.yarn/patches/@vitest-expect-npm-1.1.3-2062bf533f.patch
+++ b/code/.yarn/patches/@vitest-expect-npm-1.3.1-973071a540.patch
@@ -1,10 +1,10 @@
diff --git a/dist/index.js b/dist/index.js
-index 974d6b26f626024fc9904908100c9ecaa54f43e1..5d9d92a0796e02630ccdd1174d4fd25e016d2b06 100644
+index 640839e4b9fef0f25d08d055d4350845a8a29791..844f3d5834147848b5fa54276e96e665bcc675f9 100644
--- a/dist/index.js
+++ b/dist/index.js
-@@ -6,28 +6,35 @@ import { processError } from '@vitest/utils/error';
+@@ -6,26 +6,32 @@ import { processError } from '@vitest/utils/error';
import { util } from 'chai';
-
+
const MATCHERS_OBJECT = Symbol.for("matchers-object");
-const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
+// Patched this symbol for storybook, so that @storybook/test can be used in a jest environment as well.
@@ -12,10 +12,11 @@ index 974d6b26f626024fc9904908100c9ecaa54f43e1..5d9d92a0796e02630ccdd1174d4fd25e
+const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object-storybook");
const GLOBAL_EXPECT = Symbol.for("expect-global");
const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object");
-
+
if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
const globalState = /* @__PURE__ */ new WeakMap();
- const matchers = /* @__PURE__ */ Object.create(null);
+- const customEqualityTesters = [];
- const assymetricMatchers = /* @__PURE__ */ Object.create(null);
Object.defineProperty(globalThis, MATCHERS_OBJECT, {
get: () => globalState
@@ -23,12 +24,14 @@ index 974d6b26f626024fc9904908100c9ecaa54f43e1..5d9d92a0796e02630ccdd1174d4fd25e
+}
+if (!Object.prototype.hasOwnProperty.call(globalThis, JEST_MATCHERS_OBJECT)) {
+ const matchers = /* @__PURE__ */ Object.create(null);
++ const customEqualityTesters = [];
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
configurable: true,
get: () => ({
- state: globalState.get(globalThis[GLOBAL_EXPECT]),
+ state: globalThis[MATCHERS_OBJECT].get(globalThis[GLOBAL_EXPECT]),
- matchers
+ matchers,
+ customEqualityTesters
})
});
+}
@@ -37,8 +40,3 @@ index 974d6b26f626024fc9904908100c9ecaa54f43e1..5d9d92a0796e02630ccdd1174d4fd25e
Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, {
get: () => assymetricMatchers
});
- }
-+
- function getState(expect) {
- return globalThis[MATCHERS_OBJECT].get(expect);
- }
diff --git a/code/addons/a11y/package.json b/code/addons/a11y/package.json
index abe43c249f6b..68c3ea37f99b 100644
--- a/code/addons/a11y/package.json
+++ b/code/addons/a11y/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Test component compliance with web accessibility standards",
"keywords": [
"a11y",
diff --git a/code/addons/actions/package.json b/code/addons/actions/package.json
index 5dcdd61e3c52..485f6d1b8d1b 100644
--- a/code/addons/actions/package.json
+++ b/code/addons/actions/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-actions",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Get UI feedback when an action is performed on an interactive element",
"keywords": [
"storybook",
diff --git a/code/addons/actions/src/loaders.ts b/code/addons/actions/src/loaders.ts
index cc6c8494b7fc..3acfa9795eef 100644
--- a/code/addons/actions/src/loaders.ts
+++ b/code/addons/actions/src/loaders.ts
@@ -2,6 +2,8 @@
import type { LoaderFunction } from '@storybook/types';
import { action } from './runtime';
+export const tinySpyInternalState = Symbol.for('tinyspy:spy');
+
const attachActionsToFunctionMocks: LoaderFunction = (context) => {
const {
args,
@@ -15,7 +17,11 @@ const attachActionsToFunctionMocks: LoaderFunction = (context) => {
typeof value === 'function' && '_isMockFunction' in value && value._isMockFunction
)
.forEach(([key, value]) => {
- const previous = value.getMockImplementation();
+ // See this discussion for context:
+ // https://github.com/vitest-dev/vitest/pull/5352
+ const previous =
+ value.getMockImplementation() ??
+ (tinySpyInternalState in value ? value[tinySpyInternalState]?.getOriginal() : undefined);
if (previous?._actionAttached !== true && previous?.isAction !== true) {
const implementation = (...params: unknown[]) => {
action(key)(...params);
diff --git a/code/addons/backgrounds/package.json b/code/addons/backgrounds/package.json
index 17a842b06f13..2caf3521463a 100644
--- a/code/addons/backgrounds/package.json
+++ b/code/addons/backgrounds/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-backgrounds",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Switch backgrounds to view components in different settings",
"keywords": [
"addon",
diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json
index 3df650748609..29d450db6287 100644
--- a/code/addons/controls/package.json
+++ b/code/addons/controls/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-controls",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Interact with component inputs dynamically in the Storybook UI",
"keywords": [
"addon",
diff --git a/code/addons/docs/package.json b/code/addons/docs/package.json
index a74ff2e67653..394e76fd8c13 100644
--- a/code/addons/docs/package.json
+++ b/code/addons/docs/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-docs",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Document component usage and properties in Markdown",
"keywords": [
"addon",
diff --git a/code/addons/docs/template/stories/docspage/autoplay.stories.ts b/code/addons/docs/template/stories/docspage/autoplay.stories.ts
index 36fc395949d8..6ebdc43b3ad7 100644
--- a/code/addons/docs/template/stories/docspage/autoplay.stories.ts
+++ b/code/addons/docs/template/stories/docspage/autoplay.stories.ts
@@ -1,6 +1,5 @@
import { global as globalThis } from '@storybook/global';
-import { expect } from '@storybook/test';
-import { within } from '@storybook/testing-library';
+import { expect, within } from '@storybook/test';
export default {
component: globalThis.Components.Pre,
diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json
index 5b01bbd974b1..afb37f3424a2 100644
--- a/code/addons/essentials/package.json
+++ b/code/addons/essentials/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-essentials",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Curated addons to bring out the best of Storybook",
"keywords": [
"addon",
diff --git a/code/addons/gfm/package.json b/code/addons/gfm/package.json
index 031416826745..62d9fc14d34e 100644
--- a/code/addons/gfm/package.json
+++ b/code/addons/gfm/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-mdx-gfm",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "GitHub Flavored Markdown in Storybook",
"keywords": [
"addon",
diff --git a/code/addons/highlight/package.json b/code/addons/highlight/package.json
index e4802d08da43..3e86ac6520a1 100644
--- a/code/addons/highlight/package.json
+++ b/code/addons/highlight/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-highlight",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Highlight DOM nodes within your stories",
"keywords": [
"storybook-addons",
diff --git a/code/addons/interactions/package.json b/code/addons/interactions/package.json
index 29d753da6fbf..c8baa6166260 100644
--- a/code/addons/interactions/package.json
+++ b/code/addons/interactions/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-interactions",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Automate, test and debug user interactions",
"keywords": [
"storybook-addons",
@@ -50,8 +50,9 @@
},
"dependencies": {
"@storybook/global": "^5.0.0",
+ "@storybook/instrumenter": "workspace:*",
+ "@storybook/test": "workspace:*",
"@storybook/types": "workspace:*",
- "jest-mock": "^27.0.6",
"polished": "^4.2.2",
"ts-dedent": "^2.2.0"
},
@@ -62,10 +63,8 @@
"@storybook/core-common": "workspace:*",
"@storybook/core-events": "workspace:*",
"@storybook/icons": "^1.2.5",
- "@storybook/instrumenter": "workspace:*",
"@storybook/manager-api": "workspace:*",
"@storybook/preview-api": "workspace:*",
- "@storybook/testing-library": "next",
"@storybook/theming": "workspace:*",
"@types/node": "^18.0.0",
"formik": "^2.2.9",
diff --git a/code/addons/interactions/src/components/Interaction.stories.tsx b/code/addons/interactions/src/components/Interaction.stories.tsx
index b18cd7136c6a..a6f8bd3a3b46 100644
--- a/code/addons/interactions/src/components/Interaction.stories.tsx
+++ b/code/addons/interactions/src/components/Interaction.stories.tsx
@@ -1,7 +1,6 @@
import type { StoryObj, Meta } from '@storybook/react';
-import { expect } from '@storybook/test';
import { CallStates } from '@storybook/instrumenter';
-import { userEvent, within } from '@storybook/testing-library';
+import { userEvent, within, expect } from '@storybook/test';
import { getCalls } from '../mocks';
import { Interaction } from './Interaction';
diff --git a/code/addons/interactions/src/components/InteractionsPanel.stories.tsx b/code/addons/interactions/src/components/InteractionsPanel.stories.tsx
index a2435113ef02..89f7ef115b59 100644
--- a/code/addons/interactions/src/components/InteractionsPanel.stories.tsx
+++ b/code/addons/interactions/src/components/InteractionsPanel.stories.tsx
@@ -2,8 +2,7 @@ import React from 'react';
import type { StoryObj, Meta } from '@storybook/react';
import { CallStates } from '@storybook/instrumenter';
import { styled } from '@storybook/theming';
-import { userEvent, within, waitFor } from '@storybook/testing-library';
-import { expect } from '@storybook/test';
+import { userEvent, within, waitFor, expect } from '@storybook/test';
import isChromatic from 'chromatic/isChromatic';
import { getCalls, getInteractions } from '../mocks';
diff --git a/code/addons/jest/package.json b/code/addons/jest/package.json
index 7284de78eec3..c878c2004dce 100644
--- a/code/addons/jest/package.json
+++ b/code/addons/jest/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-jest",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "React storybook addon that show component jest report",
"keywords": [
"addon",
diff --git a/code/addons/links/package.json b/code/addons/links/package.json
index a23690c6e9b2..e23c945975df 100644
--- a/code/addons/links/package.json
+++ b/code/addons/links/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-links",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Link stories together to build demos and prototypes with your UI components",
"keywords": [
"addon",
diff --git a/code/addons/measure/package.json b/code/addons/measure/package.json
index 843dd37f5197..53824330a8d6 100644
--- a/code/addons/measure/package.json
+++ b/code/addons/measure/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-measure",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Inspect layouts by visualizing the box model",
"keywords": [
"storybook-addons",
diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json
index 5064aa48addb..540337fa698b 100644
--- a/code/addons/onboarding/package.json
+++ b/code/addons/onboarding/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-onboarding",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook Addon Onboarding - Introduces a new onboarding experience",
"keywords": [
"storybook-addons",
@@ -55,7 +55,6 @@
"@storybook/react": "workspace:*",
"@storybook/telemetry": "workspace:*",
"@storybook/test": "workspace:*",
- "@storybook/testing-library": "next",
"@storybook/theming": "workspace:*",
"@storybook/types": "workspace:*",
"framer-motion": "^11.0.3",
diff --git a/code/addons/onboarding/src/components/List/List.stories.tsx b/code/addons/onboarding/src/components/List/List.stories.tsx
index 380fd07ca4cc..9ff667586fc3 100644
--- a/code/addons/onboarding/src/components/List/List.stories.tsx
+++ b/code/addons/onboarding/src/components/List/List.stories.tsx
@@ -1,7 +1,6 @@
import React, { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
-import { userEvent, waitFor, within } from '@storybook/testing-library';
-import { expect } from '@storybook/test';
+import { userEvent, waitFor, within, expect } from '@storybook/test';
import { List } from './List';
import { ListItem } from './ListItem/ListItem';
diff --git a/code/addons/onboarding/src/components/Modal/Modal.stories.tsx b/code/addons/onboarding/src/components/Modal/Modal.stories.tsx
index 51d19c49b4f5..527aa87d4323 100644
--- a/code/addons/onboarding/src/components/Modal/Modal.stories.tsx
+++ b/code/addons/onboarding/src/components/Modal/Modal.stories.tsx
@@ -1,7 +1,6 @@
import React, { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
-import { userEvent, within } from '@storybook/testing-library';
-import { expect } from '@storybook/test';
+import { userEvent, within, expect } from '@storybook/test';
import { Modal } from './Modal';
diff --git a/code/addons/onboarding/src/components/PulsatingEffect/PulsatingEffect.stories.tsx b/code/addons/onboarding/src/components/PulsatingEffect/PulsatingEffect.stories.tsx
index 67b31843dc45..6a87a2147c0a 100644
--- a/code/addons/onboarding/src/components/PulsatingEffect/PulsatingEffect.stories.tsx
+++ b/code/addons/onboarding/src/components/PulsatingEffect/PulsatingEffect.stories.tsx
@@ -1,8 +1,7 @@
import type { Meta, StoryObj } from '@storybook/react';
import { PulsatingEffect } from './PulsatingEffect';
import React from 'react';
-import { within } from '@storybook/testing-library';
-import { expect } from '@storybook/test';
+import { within, expect } from '@storybook/test';
const meta: Meta = {
component: PulsatingEffect,
diff --git a/code/addons/onboarding/src/features/WriteStoriesModal/WriteStoriesModal.stories.tsx b/code/addons/onboarding/src/features/WriteStoriesModal/WriteStoriesModal.stories.tsx
index d2284dbd913f..d2fe6ba470b4 100644
--- a/code/addons/onboarding/src/features/WriteStoriesModal/WriteStoriesModal.stories.tsx
+++ b/code/addons/onboarding/src/features/WriteStoriesModal/WriteStoriesModal.stories.tsx
@@ -1,8 +1,7 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
-import { waitFor, within } from '@storybook/testing-library';
-import { expect, fn } from '@storybook/test';
+import { waitFor, within, expect, fn } from '@storybook/test';
import { STORY_INDEX_INVALIDATED, STORY_RENDERED } from '@storybook/core-events';
import { WriteStoriesModal } from './WriteStoriesModal';
import typescriptSnippet from './code/typescript';
diff --git a/code/addons/outline/package.json b/code/addons/outline/package.json
index b5b5771d6049..346b5808b5d4 100644
--- a/code/addons/outline/package.json
+++ b/code/addons/outline/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-outline",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Outline all elements with CSS to help with layout placement and alignment",
"keywords": [
"storybook-addons",
diff --git a/code/addons/storysource/package.json b/code/addons/storysource/package.json
index e060751d1a6f..d527dcafdadd 100644
--- a/code/addons/storysource/package.json
+++ b/code/addons/storysource/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-storysource",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "View a storyβs source code to see how it works and paste into your app",
"keywords": [
"addon",
diff --git a/code/addons/themes/package.json b/code/addons/themes/package.json
index a13dcf595c17..4a795e2551b2 100644
--- a/code/addons/themes/package.json
+++ b/code/addons/themes/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-themes",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Switch between multiple themes for you components in Storybook",
"keywords": [
"css",
diff --git a/code/addons/themes/src/constants.ts b/code/addons/themes/src/constants.ts
index a1872de9e88e..677c9499a7b4 100644
--- a/code/addons/themes/src/constants.ts
+++ b/code/addons/themes/src/constants.ts
@@ -1,5 +1,5 @@
export const PARAM_KEY = 'themes' as const;
-export const ADDON_ID = `storybook/${PARAM_KEY}}` as const;
+export const ADDON_ID = `storybook/${PARAM_KEY}` as const;
export const GLOBAL_KEY = 'theme' as const;
export const THEME_SWITCHER_ID = `${ADDON_ID}/theme-switcher` as const;
diff --git a/code/addons/themes/src/theme-switcher.tsx b/code/addons/themes/src/theme-switcher.tsx
index ef27f0d25769..0a0ac5f34bec 100644
--- a/code/addons/themes/src/theme-switcher.tsx
+++ b/code/addons/themes/src/theme-switcher.tsx
@@ -1,5 +1,11 @@
import React, { Fragment, useMemo } from 'react';
-import { useAddonState, useChannel, useGlobals, useParameter } from '@storybook/manager-api';
+import {
+ useAddonState,
+ useChannel,
+ useGlobals,
+ useParameter,
+ addons,
+} from '@storybook/manager-api';
import { styled } from '@storybook/theming';
import { IconButton, WithTooltip, TooltipLinkList } from '@storybook/components';
@@ -20,16 +26,23 @@ const IconButtonLabel = styled.div(({ theme }) => ({
const hasMultipleThemes = (themesList: ThemeAddonState['themesList']) => themesList.length > 1;
const hasTwoThemes = (themesList: ThemeAddonState['themesList']) => themesList.length === 2;
-export const ThemeSwitcher = () => {
+export const ThemeSwitcher = React.memo(function ThemeSwitcher() {
const { themeOverride } = useParameter(
PARAM_KEY,
DEFAULT_THEME_PARAMETERS
) as ThemeParameters;
const [{ theme: selected }, updateGlobals] = useGlobals();
+ const channel = addons.getChannel();
+ const fromLast = channel.last(THEMING_EVENTS.REGISTER_THEMES);
+ const initializeThemeState = Object.assign({}, DEFAULT_ADDON_STATE, {
+ themesList: fromLast?.[0]?.themes || [],
+ themeDefault: fromLast?.[0]?.defaultTheme || '',
+ });
+
const [{ themesList, themeDefault }, updateState] = useAddonState(
THEME_SWITCHER_ID,
- DEFAULT_ADDON_STATE
+ initializeThemeState
);
useChannel({
@@ -103,4 +116,4 @@ export const ThemeSwitcher = () => {
}
return null;
-};
+});
diff --git a/code/addons/toolbars/package.json b/code/addons/toolbars/package.json
index b1bdae2a70cd..77859b045279 100644
--- a/code/addons/toolbars/package.json
+++ b/code/addons/toolbars/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-toolbars",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Create your own toolbar items that control story rendering",
"keywords": [
"addon",
diff --git a/code/addons/toolbars/src/types.ts b/code/addons/toolbars/src/types.ts
index e07d11f73ae0..8427c53e4606 100644
--- a/code/addons/toolbars/src/types.ts
+++ b/code/addons/toolbars/src/types.ts
@@ -15,7 +15,6 @@ export type ToolbarShortcuts = Record {
registerShortcuts(api, globals, updateGlobals, Object.keys(viewports));
- }, [viewports, globals.viewport]);
+ }, [viewports, globals, globals.viewport, updateGlobals, api]);
useEffect(() => {
const defaultRotated = defaultOrientation === 'landscape';
@@ -150,7 +150,18 @@ export const ViewportTool: FC = memo(
viewportRotated: defaultRotated,
});
}
- }, [defaultOrientation, defaultViewport, globals, updateGlobals]);
+ // NOTE: we don't want to re-run this effect when `globals` changes
+ // due to https://github.com/storybookjs/storybook/issues/26334
+ //
+ // Also, this *will* rerun every time you change story as the parameter is briefly `undefined`.
+ // This behaviour is intentional, if a bit of a happy accident in implementation.
+ //
+ // Ultimately this process of "locking in" a parameter value should be
+ // replaced by https://github.com/storybookjs/storybook/discussions/23347
+ // or something similar.
+ //
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [defaultOrientation, defaultViewport, updateGlobals]);
const item =
list.find((i) => i.id === globals.viewport) ||
diff --git a/code/builders/builder-manager/package.json b/code/builders/builder-manager/package.json
index c53e7272fb60..d692ee77e176 100644
--- a/code/builders/builder-manager/package.json
+++ b/code/builders/builder-manager/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/builder-manager",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook manager builder",
"keywords": [
"storybook"
@@ -52,7 +52,7 @@
"@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10",
"browser-assert": "^1.2.1",
"ejs": "^3.1.8",
- "esbuild": "^18.0.0 || ^19.0.0 || ^0.20.0",
+ "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0",
"esbuild-plugin-alias": "^0.2.1",
"express": "^4.17.3",
"fs-extra": "^11.1.0",
diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json
index affa9c2fa59b..0c871173a00b 100644
--- a/code/builders/builder-vite/package.json
+++ b/code/builders/builder-vite/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/builder-vite",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "A plugin to run and build Storybooks with Vite",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme",
"bugs": {
diff --git a/code/builders/builder-vite/src/optimizeDeps.ts b/code/builders/builder-vite/src/optimizeDeps.ts
index 1972fde8e8e7..7d38b61cb747 100644
--- a/code/builders/builder-vite/src/optimizeDeps.ts
+++ b/code/builders/builder-vite/src/optimizeDeps.ts
@@ -3,6 +3,8 @@ import type { InlineConfig as ViteInlineConfig, UserConfig } from 'vite';
import type { Options } from '@storybook/types';
import { listStories } from './list-stories';
+// It ensures that vite converts cjs deps into esm without vite having to find them during startup and then having to log a message about them and restart
+// TODO: Many of the deps might be prebundled now though, so probably worth trying to remove and see what happens
const INCLUDE_CANDIDATES = [
'@base2/pretty-print-object',
'@emotion/core',
@@ -27,7 +29,6 @@ const INCLUDE_CANDIDATES = [
'fast-deep-equal',
'html-tags',
'isobject',
- 'jest-mock',
'loader-utils',
'lodash/camelCase.js',
'lodash/camelCase',
diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json
index 9565198092f8..6b19424af541 100644
--- a/code/builders/builder-webpack5/package.json
+++ b/code/builders/builder-webpack5/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/builder-webpack5",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"
diff --git a/code/e2e-tests/addon-viewport.spec.ts b/code/e2e-tests/addon-viewport.spec.ts
index ec96a3bd93ea..64f8eb097dfb 100644
--- a/code/e2e-tests/addon-viewport.spec.ts
+++ b/code/e2e-tests/addon-viewport.spec.ts
@@ -40,4 +40,26 @@ test.describe('addon-viewport', () => {
// Compare the two widths
await expect(adjustedDimensions?.width).not.toBe(originalDimensions?.width);
});
+
+ test('viewport should be editable when a default viewport is set', async ({ page }) => {
+ const sbPage = new SbPage(page);
+
+ // Story parameters/selected is set to small mobile
+ await sbPage.navigateToStory('addons/viewport/parameters', 'selected');
+
+ // Measure the original dimensions of previewRoot
+ const originalDimensions = await sbPage.getCanvasBodyElement().boundingBox();
+ await expect(originalDimensions?.width).toBeDefined();
+
+ // Manually select "large mobile" and give it time to adjust
+ await sbPage.selectToolbar('[title="Change the size of the preview"]', '#list-item-mobile2');
+ await new Promise((r) => setTimeout(r, 200));
+
+ // Measure the adjusted dimensions of previewRoot after clicking the mobile item.
+ const adjustedDimensions = await sbPage.getCanvasBodyElement().boundingBox();
+ await expect(adjustedDimensions?.width).toBeDefined();
+
+ // Compare the two widths
+ await expect(adjustedDimensions?.width).not.toBe(originalDimensions?.width);
+ });
});
diff --git a/code/frameworks/angular/README.md b/code/frameworks/angular/README.md
index d97e1ab93f2a..4bfadb7f16f4 100644
--- a/code/frameworks/angular/README.md
+++ b/code/frameworks/angular/README.md
@@ -1,324 +1,3 @@
# Storybook for Angular
-- [Storybook for Angular](#storybook-for-angular)
- - [Getting Started](#getting-started)
- - [Setup Storybook for your Angular projects](#setup-storybook-for-your-angular-projects)
- - [Run Storybook](#run-storybook)
- - [Setup Compodoc](#setup-compodoc)
- - [Automatic setup](#automatic-setup)
- - [Manual setup](#manual-setup)
- - [moduleMetadata decorator](#modulemetadata-decorator)
- - [applicationConfig decorator](#applicationconfig-decorator)
- - [FAQ](#faq)
- - [How do I migrate to an Angular Storybook builder?](#how-do-i-migrate-to-an-angular-storybook-builder)
- - [Do you have only one Angular project in your workspace?](#do-you-have-only-one-angular-project-in-your-workspace)
- - [Adjust your `package.json`](#adjust-your-packagejson)
- - [I have multiple projects in my Angular workspace](#i-have-multiple-projects-in-my-angular-workspace)
-
-Storybook for Angular is a UI development environment for your Angular components.
-With it, you can visualize different states of your UI components and develop them interactively.
-
-![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)
-
-Storybook runs outside of your app.
-So you can develop UI components in isolation without worrying about app specific dependencies and requirements.
-
-## Getting Started
-
-```sh
-cd my-angular-app
-npx storybook@latest init
-```
-
-## Setup Storybook for your Angular projects
-
-Storybook supports Angular multi-project workspace. You can setup Storybook for each project in the workspace. When running `npx storybook@latest init` you will be asked for which project Storybook should be set up. Essentially, during initialization, the `.storybook` folder will be created and the `angular.json` will be edited to add the Storybook configuration for the selected project. The configuration looks approximately like this:
-
-```json
-// angular.json
-{
- ...
- "projects": {
- ...
- "your-project": {
- ...
- "architect": {
- ...
- "storybook": {
- "builder": "@storybook/angular:start-storybook",
- "options": {
- // the path to the storybook config directory
- "configDir": ".storybook",
- // the build target of your project
- "browserTarget": "your-project:build",
- // the port you want to start Storybook on
- "port": 6006
- // further options are available and can be found in
- // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/start-storybook/schema.json
- }
- },
- "build-storybook": {
- "builder": "@storybook/angular:build-storybook",
- "options": {
- "configDir": ".storybook",
- "browserTarget": "your-project:build",
- "outputDir": "dist/storybook/your-project"
- // further options are available and can be found in
- // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/build-storybook/schema.json
- }
- }
- }
- }
- }
-}
-```
-
-## Run Storybook
-
-To run Storybook for a particular project, please run:
-
-```sh
-ng run :storybook
-```
-
-To build Storybook, run:
-
-```sh
-ng run :build-storybook
-```
-
-You will find the output in `dist/storybook/your-project`.
-
-For more information visit: [storybook.js.org](https://storybook.js.org)
-
-## Setup Compodoc
-
-You can include JSDoc comments above components, directives, and other parts of your Angular code to include documentation for those elements. Compodoc uses these comments to generate documentation for your application. In Storybook, it is useful to add explanatory comments above @Inputs and @Outputs, since these are the main elements that Storybook displays in its user interface. The @Inputs and @Outputs are the elements that you can interact with in Storybook, such as controls.
-
-### Automatic setup
-
-When installing Storybook via `sb init`, you will be given the option to set up Compodoc automatically.
-
-### Manual setup
-
-If you have already installed Storybook, you can set up Compodoc manually.
-
-Install the following dependencies:
-
-```sh
-npm i -D @compodoc/compodoc
-```
-
-Add the following option to your to the Storybook Builder:
-
-```json
-{
- ...
- "projects": {
- ...
- "your-project": {
- ...
- "architect": {
- ...
- "storybook": {
- "builder": "@storybook/angular:start-storybook",
- "options": {
- ...
- "compodoc": true,
- "compodocArgs": [
- "-e",
- "json",
- "-d",
- // Where to store the generated documentation. It's usually the root of your Angular project. It's not necessarily the root of your Angular Workspace!
- "."
- ],
- }
- },
- "build-storybook": {
- "builder": "@storybook/angular:build-storybook",
- "options": {
- ...
- "compodoc": true,
- "compodocArgs": [
- "-e",
- "json",
- "-d",
- "."
- ],
- }
- }
- }
- }
- }
-}
-```
-
-Go to your `.storybook/preview.js` and add the following:
-
-```js
-import { setCompodocJson } from '@storybook/addon-docs/angular';
-import docJson from '../documentation.json';
-setCompodocJson(docJson);
-
-const preview: Preview = {
- ...
-};
-
-export default preview;
-```
-
-## moduleMetadata decorator
-
-If your component has dependencies on other Angular directives and modules, these can be supplied using the moduleMetadata decorator either for all stories or for individual stories.
-
-```js
-import { StoryFn, Meta, moduleMetadata } from '@storybook/angular';
-import { SomeComponent } from './some.component';
-
-export default {
- component: SomeComponent,
- decorators: [
- // Apply metadata to all stories
- moduleMetadata({
- // import necessary ngModules or standalone components
- imports: [...],
- // declare components that are used in the template
- declarations: [...],
- // List of providers that should be available to the root component and all its children.
- providers: [...],
- }),
- ],
-} as Meta;
-
-const Template = (): StoryFn => (args) => ({
- props: args,
-});
-
-export const Base = Template();
-
-export const WithCustomProvider = Template();
-WithCustomProvider.decorators = [
- // Apply metadata to a specific story
- moduleMetadata({
- imports: [...],
- declarations: [...],
- providers: [...]
- }),
-];
-```
-
-## applicationConfig decorator
-
-If your component relies on application-wide providers, like the ones defined by BrowserAnimationsModule or any other modules which use the forRoot pattern to provide a ModuleWithProviders, you can use the applicationConfig decorator on the meta default export to provide them to the [bootstrapApplication function](https://angular.io/guide/standalone-components#configuring-dependency-injection), which we use to bootstrap the component in Storybook.
-
-```js
-
-import { StoryObj, Meta, applicationConfig } from '@storybook/angular';
-import { BrowserAnimationsModule, provideAnimations } from '@angular/platform-browser/animations';
-import { importProvidersFrom } from '@angular/core';
-import { ChipsModule } from './angular-src/chips.module';
-
-const meta: Meta = {
- component: ChipsGroupComponent,
- decorators: [
- // Apply application config to all stories
- applicationConfig({
- // List of providers and environment providers that should be available to the root component and all its children.
- providers: [
- ...
- // Import application-wide providers from a module
- importProvidersFrom(BrowserAnimationsModule)
- // Or use provide-style functions if available instead, e.g.
- provideAnimations()
- ],
- }),
- ],
-};
-
-export default meta;
-
-type Story = StoryObj;
-
-export const WithCustomApplicationProvider: Story = {
- render: () => ({
- // Apply application config to a specific story
- applicationConfig: {
- // The providers will be merged with the ones defined in the applicationConfig decorators providers array of the global meta object
- providers: [...]
- }
- })
-}
-```
-
-## FAQ
-
-### How do I migrate to an Angular Storybook builder?
-
-The Storybook [Angular builder](https://angular.io/guide/glossary#builder) is a new way to run Storybook in an Angular workspace. It is a drop-in replacement for running `storybook dev` and `storybook build` directly.
-
-You can run `npx storybook@next automigrate` to try let Storybook detect and automatically fix your configuration. Otherwise, you can follow the next steps to manually adjust your configuration.
-
-#### Do you have only one Angular project in your workspace?
-
-In this case go to your `angular.json` and add `storybook` and `build-storybook` entries in `architect` section of your project like shown above.
-
-##### Adjust your `package.json`
-
-Go to your `package.json` and adjust your script section. Usually, it will look like this:
-
-```json
-{
- "scripts": {
- "storybook": "start-storybook -p 6006", // or `storybook dev -p 6006`
- "build-storybook": "build-storybook" // or `storybook build`
- }
-}
-```
-
-Now, you can run Storybook with `ng run :storybook` and build it with `ng run :build-storybook`. Adjust the scripts in your `package.json` accordingly.
-
-```json
-{
- "scripts": {
- "storybook": "ng run :storybook", // or `storybook dev -p 6006`
- "build-storybook": "ng run :build-storybook" // or `storybook build`
- }
-}
-```
-
-Also remove the compodoc part in your script section if you have set it up previously.
-It is now built-in in `@storybook/angular` and you don't have to call it explicitly:
-
-```json
-{
- "scripts": {
- "docs:json": "compodoc -p tsconfig.json -e json -d ./documentation",
- "storybook": "npm run docs:json && start-storybook -p 6006",
- "build-storybook": "npm run docs:json && build-storybook"
- }
-}
-```
-
-Change it to:
-
-```json
-{
- "scripts": {
- "storybook": "ng run :storybook",
- "build-storybook": "ng run :build-storybook"
- }
-}
-```
-
-#### I have multiple projects in my Angular workspace
-
-In this case you have to adjust your `angular.json` and `package.json` as described above for each project in which you want to use Storybook. Please note, that each project should have a dedicated `.storybook` folder, which should be placed in the root of the project.
-
-You can run `npx sb init` sequentially for each project to setup Storybook for each of them to automatically create the `.storybook` folder and create the necessary configuration in your `angular.json`.
-
-You can then use [Storybook composition](https://storybook.js.org/docs/angular/sharing/storybook-composition) to composite multiple Storybooks into one.
-
----
-
-Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
-You can also build a [static version](https://storybook.js.org/docs/angular/sharing/publish-storybook) of your Storybook and deploy it anywhere you want.
+See [documentation](https://storybook.js.org/docs/8.0/get-started/angular?renderer=angular) for installation instructions, usage examples, APIs, and more.
diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json
index 8639c28d08c2..726c56bb92fc 100644
--- a/code/frameworks/angular/package.json
+++ b/code/frameworks/angular/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/angular",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.",
"keywords": [
"storybook",
diff --git a/code/frameworks/angular/template/cli/header.stories.ts b/code/frameworks/angular/template/cli/header.stories.ts
index 3222518ace44..3f3fb684e855 100644
--- a/code/frameworks/angular/template/cli/header.stories.ts
+++ b/code/frameworks/angular/template/cli/header.stories.ts
@@ -1,6 +1,7 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { HeaderComponent } from './header.component';
+import { fn } from '@storybook/test';
const meta: Meta = {
title: 'Example/Header',
@@ -11,6 +12,11 @@ const meta: Meta = {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
layout: 'fullscreen',
},
+ args: {
+ onLogin: fn(),
+ onLogout: fn(),
+ onCreateAccount: fn(),
+ },
};
export default meta;
diff --git a/code/frameworks/angular/template/stories/core/applicationConfig/with-browser-animations.stories.ts b/code/frameworks/angular/template/stories/core/applicationConfig/with-browser-animations.stories.ts
index f61db00d8f0e..ef30854c26f9 100644
--- a/code/frameworks/angular/template/stories/core/applicationConfig/with-browser-animations.stories.ts
+++ b/code/frameworks/angular/template/stories/core/applicationConfig/with-browser-animations.stories.ts
@@ -1,7 +1,6 @@
import { Meta, StoryObj, applicationConfig } from '@storybook/angular';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { within, userEvent } from '@storybook/testing-library';
-import { expect } from '@storybook/test';
+import { within, userEvent, expect } from '@storybook/test';
import { importProvidersFrom } from '@angular/core';
import { OpenCloseComponent } from '../moduleMetadata/angular-src/open-close-component/open-close.component';
diff --git a/code/frameworks/angular/template/stories/core/applicationConfig/with-noop-browser-animations.stories.ts b/code/frameworks/angular/template/stories/core/applicationConfig/with-noop-browser-animations.stories.ts
index 1a4341ec77cf..3369b9949d33 100644
--- a/code/frameworks/angular/template/stories/core/applicationConfig/with-noop-browser-animations.stories.ts
+++ b/code/frameworks/angular/template/stories/core/applicationConfig/with-noop-browser-animations.stories.ts
@@ -1,7 +1,6 @@
import { Meta, StoryObj } from '@storybook/angular';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
-import { within, userEvent } from '@storybook/testing-library';
-import { expect } from '@storybook/test';
+import { within, userEvent, expect } from '@storybook/test';
import { importProvidersFrom } from '@angular/core';
import { OpenCloseComponent } from '../moduleMetadata/angular-src/open-close-component/open-close.component';
diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json
index db1b2cfe14aa..8331d7d0b744 100644
--- a/code/frameworks/ember/package.json
+++ b/code/frameworks/ember/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/ember",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.",
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember",
"bugs": {
diff --git a/code/frameworks/ember/template/cli/Button.stories.js b/code/frameworks/ember/template/cli/Button.stories.js
index 61de1a4f9cc9..c8fffd70feb0 100644
--- a/code/frameworks/ember/template/cli/Button.stories.js
+++ b/code/frameworks/ember/template/cli/Button.stories.js
@@ -1,6 +1,7 @@
import { hbs } from 'ember-cli-htmlbars';
import { action } from '@storybook/addon-actions';
import { linkTo } from '@storybook/addon-links';
+import { fn } from '@storybook/test';
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
export default {
@@ -14,20 +15,19 @@ export default {
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/ember/writing-docs/autodocs
tags: ['autodocs'],
+ args: { onClick: fn() },
};
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Text = {
args: {
label: 'Button',
- onClick: action('onClick'),
},
};
export const Emoji = {
args: {
label: 'π π π π―',
- onClick: action('onClick'),
},
};
diff --git a/code/frameworks/html-vite/package.json b/code/frameworks/html-vite/package.json
index 5fb64a4a8c48..1005843c6bd5 100644
--- a/code/frameworks/html-vite/package.json
+++ b/code/frameworks/html-vite/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/html-vite",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/html-webpack5/package.json b/code/frameworks/html-webpack5/package.json
index 55e6496baa3c..04976553bdfb 100644
--- a/code/frameworks/html-webpack5/package.json
+++ b/code/frameworks/html-webpack5/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/html-webpack5",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json
index f622f9eeaabe..ec578f0a3182 100644
--- a/code/frameworks/nextjs/package.json
+++ b/code/frameworks/nextjs/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/nextjs",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Next.js",
"keywords": [
"storybook",
diff --git a/code/frameworks/nextjs/template/cli/js/Header.stories.js b/code/frameworks/nextjs/template/cli/js/Header.stories.js
index a1d32b3ad65e..982cd970fb5c 100644
--- a/code/frameworks/nextjs/template/cli/js/Header.stories.js
+++ b/code/frameworks/nextjs/template/cli/js/Header.stories.js
@@ -1,3 +1,4 @@
+import { fn } from '@storybook/test';
import { Header } from './Header';
export default {
@@ -9,6 +10,11 @@ export default {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
layout: 'fullscreen',
},
+ args: {
+ onLogin: fn(),
+ onLogout: fn(),
+ onCreateAccount: fn(),
+ },
};
export const LoggedIn = {
args: {
diff --git a/code/frameworks/nextjs/template/cli/ts-3-8/Header.stories.ts b/code/frameworks/nextjs/template/cli/ts-3-8/Header.stories.ts
index 82a109720879..feddeae98faf 100644
--- a/code/frameworks/nextjs/template/cli/ts-3-8/Header.stories.ts
+++ b/code/frameworks/nextjs/template/cli/ts-3-8/Header.stories.ts
@@ -1,4 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react';
+import { fn } from '@storybook/test';
+
import { Header } from './Header';
const meta: Meta = {
@@ -10,6 +12,11 @@ const meta: Meta = {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
layout: 'fullscreen',
},
+ args: {
+ onLogin: fn(),
+ onLogout: fn(),
+ onCreateAccount: fn(),
+ },
};
export default meta;
diff --git a/code/frameworks/nextjs/template/cli/ts-4-9/Header.stories.ts b/code/frameworks/nextjs/template/cli/ts-4-9/Header.stories.ts
index 046982e62673..39d15874f4c1 100644
--- a/code/frameworks/nextjs/template/cli/ts-4-9/Header.stories.ts
+++ b/code/frameworks/nextjs/template/cli/ts-4-9/Header.stories.ts
@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
+import { fn } from '@storybook/test';
import { Header } from './Header';
const meta = {
@@ -10,6 +11,11 @@ const meta = {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
layout: 'fullscreen',
},
+ args: {
+ onLogin: fn(),
+ onLogout: fn(),
+ onCreateAccount: fn(),
+ },
} satisfies Meta;
export default meta;
diff --git a/code/frameworks/nextjs/template/stories/Image.stories.jsx b/code/frameworks/nextjs/template/stories/Image.stories.jsx
index 8fa4f6a53de1..79ab308e1286 100644
--- a/code/frameworks/nextjs/template/stories/Image.stories.jsx
+++ b/code/frameworks/nextjs/template/stories/Image.stories.jsx
@@ -1,6 +1,5 @@
import React, { useRef, useState } from 'react';
import Image from 'next/image';
-import { waitFor } from '@storybook/testing-library';
import Accessibility from '../../assets/accessibility.svg';
import AvifImage from '../../assets/avif-test-image.avif';
diff --git a/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx b/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx
index f031096d6ced..1e43bb39eba6 100644
--- a/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx
+++ b/code/frameworks/nextjs/template/stories_nextjs-default-js/Head.stories.jsx
@@ -1,7 +1,6 @@
-import { expect } from '@storybook/test';
import Head from 'next/head';
import React from 'react';
-import { within, userEvent, waitFor } from '@storybook/testing-library';
+import { waitFor, expect } from '@storybook/test';
function Component() {
return (
diff --git a/code/frameworks/preact-vite/package.json b/code/frameworks/preact-vite/package.json
index 19e035c0740d..b801e8425438 100644
--- a/code/frameworks/preact-vite/package.json
+++ b/code/frameworks/preact-vite/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/preact-vite",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/preact-webpack5/package.json b/code/frameworks/preact-webpack5/package.json
index 8423ab98fade..d91973ee5f72 100644
--- a/code/frameworks/preact-webpack5/package.json
+++ b/code/frameworks/preact-webpack5/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/preact-webpack5",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Preact: Develop Preact Component in isolation.",
"keywords": [
"storybook"
diff --git a/code/frameworks/react-vite/README.md b/code/frameworks/react-vite/README.md
index e8a35450aec9..272f8f50d55f 100644
--- a/code/frameworks/react-vite/README.md
+++ b/code/frameworks/react-vite/README.md
@@ -1 +1,3 @@
-# Storybook for React
+# Storybook for React & Vite
+
+See [documentation](https://storybook.js.org/docs/8.0/get-started/react-vite?renderer=react) for installation instructions, usage examples, APIs, and more.
\ No newline at end of file
diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json
index a76d1c4cbddc..b6a2256d8f86 100644
--- a/code/frameworks/react-vite/package.json
+++ b/code/frameworks/react-vite/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/react-vite",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/react-webpack5/README.md b/code/frameworks/react-webpack5/README.md
index b3b1d877eaa2..53e3de782715 100644
--- a/code/frameworks/react-webpack5/README.md
+++ b/code/frameworks/react-webpack5/README.md
@@ -1,47 +1,3 @@
-# Storybook for React
+# Storybook for React & Webpack
-Storybook for React is a UI development environment for your React components.
-With it, you can visualize different states of your UI components and develop them interactively.
-
-![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)
-
-Storybook runs outside of your app.
-So you can develop UI components in isolation without worrying about app specific dependencies and requirements.
-
-## Getting Started
-
-```sh
-cd my-react-app
-npx storybook@latest init
-```
-
-For more information visit: [storybook.js.org](https://storybook.js.org)
-
----
-
-Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
-You can also build a [static version](https://storybook.js.org/docs/react/sharing/publish-storybook) of your Storybook and deploy it anywhere you want.
-
-Here are some featured storybooks that you can reference to see how Storybook works:
-
-- [Demo of Storybook Design System](https://storybook.js.org/design-system) - [source](https://github.com/storybookjs/design-system)
-
-## Create React App
-
-Support for [Create React App](https://create-react-app.dev/) is handled by [`@storybook/preset-create-react-app`](https://github.com/storybookjs/presets/tree/master/packages/preset-create-react-app).
-
-This preset enables support for all Create React App features, including Sass/SCSS and TypeScript.
-
-If you're working on an app that was initialized manually (i.e., without the use of Create React App), ensure that your app has [react-dom](https://www.npmjs.com/package/react-dom) included as a dependency. Failing to do so can lead to unforeseen issues with Storybook and your project.
-
-## Typescript
-
-`@storybook/react` is now exporting its own types to use with Typescript.
-You don't need to have `@types/storybook__react` installed anymore if it was your case.
-But you probably also need to use types from `@types/node @types/react`.
-
-## Docs
-
-- [Basics](https://storybook.js.org/docs/react/get-started)
-- [Configurations](https://storybook.js.org/docs/react/configure)
-- [Addons](https://storybook.js.org/docs/react/configure/storybook-addons)
+See [documentation](https://storybook.js.org/docs/8.0/get-started/react-webpack5?renderer=react) for installation instructions, usage examples, APIs, and more.
\ No newline at end of file
diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json
index a2096ef8e059..f39f13c00312 100644
--- a/code/frameworks/react-webpack5/package.json
+++ b/code/frameworks/react-webpack5/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/react-webpack5",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for React: Develop React Component in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/server-webpack5/package.json b/code/frameworks/server-webpack5/package.json
index 7c3771652cfd..b9edea51d8e1 100644
--- a/code/frameworks/server-webpack5/package.json
+++ b/code/frameworks/server-webpack5/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/server-webpack5",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/svelte-vite/README.md b/code/frameworks/svelte-vite/README.md
index 30a7c36ca01e..1f1dc740151d 100644
--- a/code/frameworks/svelte-vite/README.md
+++ b/code/frameworks/svelte-vite/README.md
@@ -1 +1,3 @@
-# Storybook for Svelte
+# Storybook for Svelte & Vite
+
+See [documentation](https://storybook.js.org/docs/8.0/get-started/svelte-vite?renderer=svelte) for installation instructions, usage examples, APIs, and more.
diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json
index edac75e5589d..28bec0d59fde 100644
--- a/code/frameworks/svelte-vite/package.json
+++ b/code/frameworks/svelte-vite/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/svelte-vite",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/svelte-webpack5/README.md b/code/frameworks/svelte-webpack5/README.md
index d490ff6af11c..fa37e5b2e74b 100644
--- a/code/frameworks/svelte-webpack5/README.md
+++ b/code/frameworks/svelte-webpack5/README.md
@@ -1,32 +1,3 @@
-# Storybook for Svelte
+# Storybook for Svelte & Webpack
-Storybook for Svelte is a UI development environment for your Svelte components.
-With it, you can visualize different states of your UI components and develop them interactively.
-
-![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)
-
-Storybook runs outside of your app.
-So you can develop UI components in isolation without worrying about app specific dependencies and requirements.
-
-## Getting Started
-
-```sh
-cd my-svelte-app
-npx storybook@latest init
-```
-
-For more information visit: [storybook.js.org](https://storybook.js.org)
-
----
-
-Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
-You can also build a [static version](https://storybook.js.org/docs/svelte/sharing/publish-storybook) of your Storybook and deploy it anywhere you want.
-
-## TODOs
-
-- Support `addon-info`
-- Support Svelte markup directly in stories
-- Add Svelte storybook generator
-- Provide stories that show advanced Svelte use cases
-- Hydratable
-- Advanced mount options
+See [documentation](https://storybook.js.org/docs/8.0/get-started/svelte-webpack5?renderer=svelte) for installation instructions, usage examples, APIs, and more.
diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json
index 85a17dfc6a76..725b3bb7a131 100644
--- a/code/frameworks/svelte-webpack5/package.json
+++ b/code/frameworks/svelte-webpack5/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/svelte-webpack5",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/sveltekit/README.md b/code/frameworks/sveltekit/README.md
index 0243fde57b23..8bb8789a879d 100644
--- a/code/frameworks/sveltekit/README.md
+++ b/code/frameworks/sveltekit/README.md
@@ -1,190 +1,6 @@
-# Storybook for SvelteKit
+# Storybook for SvelteKit
-Our goal is to help you use the tools you love together with Storybook. Thatβs why Storybook has zero-config support for SvelteKit with the `@storybook/sveltekit` package.
-
-Check out our [Frameworks API](https://storybook.js.org/blog/framework-api/) announcement for what this all means for you and our continued efforts to make Storybook a seamless integration for any project.
-
-## Table of Contents
-
-- [Supported features](#supported-features)
-- [Requirements](#requirements)
-- [Getting Started](#getting-started)
- - [In a project without Storybook](#in-a-project-without-storybook)
- - [In a project with Storybook](#in-a-project-with-storybook)
- - [Automatic migration](#automatic-migration)
- - [Manual migration](#manual-migration)
-- [How to mock](#how-to-mock)
- - [Mocking links](#mocking-links)
-- [Troubleshooting](#troubleshooting)
- - [Error: `ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared` when starting Storybook](#error-err-syntaxerror-identifier-__esbuild_register_import_meta_url__-has-already-been-declared-when-starting-storybook)
-- [Acknowledgements](#acknowledgements)
-
-## Supported features
-
-All Svelte language features are supported out of the box, as Storybook uses the Svelte compiler underneath.
-However SvelteKit has some [Kit-specific modules](https://kit.svelte.dev/docs/modules) that currently aren't supported. It's on our roadmap to support most of them soon:
-
-| **Module** | **Status** | **Note** |
-| ---------------------------------------------------------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
-| [`$app/environment`](https://kit.svelte.dev/docs/modules#$app-environment) | β Supported | `version` is always empty in Storybook. |
-| [`$app/forms`](https://kit.svelte.dev/docs/modules#$app-forms) | β Supported | See [How to mock](#how-to-mock) |
-| [`$app/navigation`](https://kit.svelte.dev/docs/modules#$app-navigation) | β Supported | See [How to mock](#how-to-mock) |
-| [`$app/paths`](https://kit.svelte.dev/docs/modules#$app-paths) | β Supported | Requires SvelteKit 1.4.0 or newer |
-| [`$app/stores`](https://kit.svelte.dev/docs/modules#$app-stores) | β Supported | See [How to mock](#how-to-mock) |
-| [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private) | β Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. |
-| [`$env/dynamic/public`](https://kit.svelte.dev/docs/modules#$env-dynamic-public) | π§ Partially supported | Only supported in development mode. Storybook is built as a static app with no server-side API so cannot dynamically serve content. |
-| [`$env/static/private`](https://kit.svelte.dev/docs/modules#$env-static-private) | β Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. |
-| [`$env/static/public`](https://kit.svelte.dev/docs/modules#$env-static-public) | β Supported | |
-| [`$lib`](https://kit.svelte.dev/docs/modules#$lib) | β Supported | |
-| [`$service-worker`](https://kit.svelte.dev/docs/modules#$service-worker) | β Not supported | They are only meant to be used in service workers |
-| [`@sveltejs/kit/*`](https://kit.svelte.dev/docs/modules#sveltejs-kit) | β Supported | |
-
-This is just the beginning. We're close to adding basic support for many of the SvelteKit features. Longer term we're planning on making it an even better experience to [build](https://storybook.js.org/docs/svelte/writing-stories), [test](https://storybook.js.org/docs/svelte/writing-tests) and [document](https://storybook.js.org/docs/svelte/writing-docs) all the SvelteKit goodies like [pages](https://kit.svelte.dev/docs/routing), [forms](https://kit.svelte.dev/docs/form-actions) and [layouts](https://kit.svelte.dev/docs/routing#layout) in Storybook, while still integrating with all the addons and workflows you know and love.
-
-## Requirements
-
-- [SvelteKit](https://kit.svelte.dev/) >= 1.0.0 (not including beta versions)
-- [Storybook](https://storybook.js.org/) >= 7.x
-
-## Getting Started
-
-### In a project without Storybook
-
-Run the following command in your SvelteKit project's root directory, and follow the prompts:
-
-```bash
-npx storybook@latest init
-```
-
-[More on getting started with Storybook](https://storybook.js.org/docs/svelte/get-started/install)
-
-### In a project with Storybook
-
-This framework is designed to work with Storybook 7. If youβre not already using v7, upgrade with this command:
-
-```bash
-npx storybook@latest upgrade
-```
-
-#### Automatic migration
-
-When running the `upgrade` command above you should get a prompt asking you to migrate to `@storybook/sveltekit`, which should handle everything for you. In some cases it can't migrate for you, eg. if your existing Storybook setup is based on Webpack. In such cases, refer to the manual migration below.
-
-Storybook 7.0 automatically loads your Vite config, and by extension your Svelte config. If you had a `svelteOptions` property in `.storybook/main.js` the automigration will have removed it, as it is no longer supported.
-
-#### Manual migration
-
-Install the framework:
-
-```bash
-yarn add -D @storybook/sveltekit
-```
-
-Update your `main.js` to change the framework property:
-
-```js
-// .storybook/main.js
-export default {
- ...
- framework: '@storybook/sveltekit',
-};
-```
-
-Storybook 7.0 automatically loads your Vite config, and by extension your Svelte config. If you have a `svelteOptions` property in `.storybook/main.js` you need to remove that. See [Troubleshooting](#error-about-__esbuild_register_import_meta_url__-when-starting-storybook) below.
-
-Remove any redundant dependencies, if you have them:
-
-```bash
-yarn remove @storybook/svelte-vite
-yarn remove @storybook/svelte-webpack5
-yarn remove storybook-builder-vite
-yarn remove @storybook/builder-vite
-```
-
-## How to mock
-
-To mock a SvelteKit import you can set it on `parameters.sveltekit_experimental`:
-
-```ts
-export const MyStory = {
- parameters: {
- sveltekit_experimental: {
- stores: {
- page: {
- data: {
- test: 'passed',
- },
- },
- navigating: {
- route: {
- id: '/storybook',
- },
- },
- updated: true,
- },
- },
- },
-};
-```
-
-You can add the name of the module you want to mock to `parameters.sveltekit_experimental` (in the example above we are mocking the `stores` module which correspond to `$app/stores`) and then pass the following kind of objects:
-
-| Module | Path in parameters | Kind of objects |
-| ------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
-| `import { page } from "$app/stores"` | `parameters.sveltekit_experimental.stores.page` | A Partial of the page store |
-| `import { navigating } from "$app/stores"` | `parameters.sveltekit_experimental.stores.navigating` | A Partial of the navigating store |
-| `import { updated } from "$app/stores"` | `parameters.sveltekit_experimental.stores.updated` | A boolean representing the value of updated (you can also access `check()` which will be a noop) |
-| `import { goto } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.goto` | A callback that will be called whenever goto is called, in no function is provided an action will be logged to the Actions panel |
-| `import { pushState } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.pushState` | A callback that will be called whenever pushState is called, in no function is provided an action will be logged to the Actions panel |
-| `import { replaceState } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.replaceState` | A callback that will be called whenever replaceState is called, in no function is provided an action will be logged to the Actions panel |
-| `import { invalidate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidate` | A callback that will be called whenever invalidate is called, in no function is provided an action will be logged to the Actions panel |
-| `import { invalidateAll } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidateAll` | A callback that will be called whenever invalidateAll is called, in no function is provided an action will be logged to the Actions panel |
-| `import { afterNavigate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.afterNavigate` | An object that will be passed to the afterNavigate function (which will be invoked onMount) called |
-| `import { enhance } from "$app/forms"` | `parameters.sveltekit_experimental.forms.enhance` | A callback that will called when a form with `use:enhance` is submitted |
-
-All the other functions are still exported as `noop` from the mocked modules so that your application will still work.
-
-### Mocking links
-
-The default link-handling behavior (ie. clicking an `` tag with an `href` attribute) is to log an action to the Actions panel.
-
-You can override this by setting an object on `parameter.sveltekit_experimental.hrefs`, where the keys are strings representing an href and the values are objects typed as `{ callback: (href, event) => void, asRegex?: boolean }`.
-
-If you have an `` tag inside your code with the `href` attribute that matches one or more of the links defined (treated as regex based on the `asRegex` property) the corresponding `callback` will be called.
-
-Example:
-
-```ts
-export const MyStory = {
- parameters: {
- sveltekit_experimental: {
- hrefs: {
- '/basic-href': (to, event) => {
- console.log(to, event);
- },
- '/root.*': {
- callback: (to, event) => {
- console.log(to, event);
- },
- asRegex: true,
- },
- },
- },
- },
-};
-```
-
-## Troubleshooting
-
-### Error: `ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared` when starting Storybook
-
-> When starting Storybook after upgrading to v7.0, it breaks with the following error:
->
-> ```
-> ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared
-> ```
-
-You'll get this error when manually upgrading from 6.5 to 7.0. You need to remove the `svelteOptions` property in `.storybook/main.js`, as that is not supported by Storybook 7.0 + SvelteKit. The property is also not necessary anymore because the Vite and Svelte configurations are loaded automatically in Storybook 7.0.
+See [documentation](https://storybook.js.org/docs/8.0/get-started/sveltekit?renderer=svelte) for installation instructions, usage examples, APIs, and more.
## Acknowledgements
diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json
index b6450c030f5f..4e7f20ff77a8 100644
--- a/code/frameworks/sveltekit/package.json
+++ b/code/frameworks/sveltekit/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/sveltekit",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for SvelteKit",
"keywords": [
"storybook",
diff --git a/code/frameworks/vue3-vite/README.md b/code/frameworks/vue3-vite/README.md
index bb1eb15f980e..08eb5ae95c13 100644
--- a/code/frameworks/vue3-vite/README.md
+++ b/code/frameworks/vue3-vite/README.md
@@ -1,44 +1,3 @@
-# Storybook for Vue 3 and Vite
+# Storybook for Vue and Vite
-Storybook for Vue 3 is a UI development environment for your Vue 3 components.
-With it, you can visualize different states of your UI components and develop them interactively.
-
-![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)
-
-Storybook runs outside of your app.
-So you can develop UI components in isolation without worrying about app specific dependencies and requirements.
-
-## Getting Started
-
-```sh
-cd my-vue3-app
-npx storybook@latest init
-```
-
-For more information visit: [storybook.js.org](https://storybook.js.org)
-
----
-
-Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
-You can also build a [static version](https://storybook.js.org/docs/sharing/publish-storybook) of your Storybook and deploy it anywhere you want.
-
-## Extending the Vue application
-
-Storybook creates a [Vue 3 application](https://vuejs.org/api/application.html#application-api) for your component preview.
-When using global custom components (`app.component`), directives (`app.directive`), extensions (`app.use`), or other application methods, you will need to configure those in the `./storybook/preview.js` file.
-
-Therefore, Storybook provides you with a `setup` function exported from this package, which receives as a callback your Storybook instance, which you can interact with and add your custom configuration.
-
-```js
-// .storybook/preview.js
-
-import { setup } from '@storybook/vue3';
-
-setup((app) => {
- app.use(MyPlugin);
- app.component('my-component', MyComponent);
- app.mixin({
- /* My mixin */
- });
-});
-```
+See [documentation](https://storybook.js.org/docs/8.0/get-started/vue3-vite?renderer=vue) for installation instructions, usage examples, APIs, and more.
diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json
index 58e9602305b1..60cc82ddd78c 100644
--- a/code/frameworks/vue3-vite/package.json
+++ b/code/frameworks/vue3-vite/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/vue3-vite",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/vue3-webpack5/README.md b/code/frameworks/vue3-webpack5/README.md
index 2e365a8a7f8e..a4e696468d58 100644
--- a/code/frameworks/vue3-webpack5/README.md
+++ b/code/frameworks/vue3-webpack5/README.md
@@ -1,44 +1,3 @@
# Storybook for Vue 3 and Webpack
-Storybook for Vue 3 is a UI development environment for your Vue 3 components.
-With it, you can visualize different states of your UI components and develop them interactively.
-
-![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)
-
-Storybook runs outside of your app.
-So you can develop UI components in isolation without worrying about app specific dependencies and requirements.
-
-## Getting Started
-
-```sh
-cd my-vue3-app
-npx storybook@latest init
-```
-
-For more information visit: [storybook.js.org](https://storybook.js.org)
-
----
-
-Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
-You can also build a [static version](https://storybook.js.org/docs/sharing/publish-storybook) of your Storybook and deploy it anywhere you want.
-
-## Extending the Vue application
-
-Storybook creates a [Vue 3 application](https://vuejs.org/api/application.html#application-api) for your component preview.
-When using global custom components (`app.component`), directives (`app.directive`), extensions (`app.use`), or other application methods, you will need to configure those in the `./storybook/preview.js` file.
-
-Therefore, Storybook provides you with a `setup` function exported from this package, which receives as a callback your Storybook instance, which you can interact with and add your custom configuration.
-
-```js
-// .storybook/preview.js
-
-import { setup } from '@storybook/vue3';
-
-setup((app) => {
- app.use(MyPlugin);
- app.component('my-component', MyComponent);
- app.mixin({
- /* My mixin */
- });
-});
-```
+See [documentation](https://storybook.js.org/docs/8.0/get-started/vue3-webpack5?renderer=vue) for installation instructions, usage examples, APIs, and more.
\ No newline at end of file
diff --git a/code/frameworks/vue3-webpack5/package.json b/code/frameworks/vue3-webpack5/package.json
index a23d5980b17f..7575b4b5ad70 100644
--- a/code/frameworks/vue3-webpack5/package.json
+++ b/code/frameworks/vue3-webpack5/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/vue3-webpack5",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/web-components-vite/README.md b/code/frameworks/web-components-vite/README.md
index 9c68eca98041..af1a9ffaa853 100644
--- a/code/frameworks/web-components-vite/README.md
+++ b/code/frameworks/web-components-vite/README.md
@@ -1 +1,3 @@
-# Storybook for Web components
+# Storybook for Web components & Vite
+
+See [documentation](https://storybook.js.org/docs/8.0/get-started/web-components-vite?renderer=web-components) for installation instructions, usage examples, APIs, and more.
diff --git a/code/frameworks/web-components-vite/package.json b/code/frameworks/web-components-vite/package.json
index 6c559ff1a849..0ad55a968eff 100644
--- a/code/frameworks/web-components-vite/package.json
+++ b/code/frameworks/web-components-vite/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/web-components-vite",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.",
"keywords": [
"storybook"
diff --git a/code/frameworks/web-components-webpack5/README.md b/code/frameworks/web-components-webpack5/README.md
index 4562b5dc35ee..d9ee9b9fd385 100644
--- a/code/frameworks/web-components-webpack5/README.md
+++ b/code/frameworks/web-components-webpack5/README.md
@@ -1,71 +1,3 @@
-# Storybook for web-components
+# Storybook for Web components & Webpack
----
-
-Storybook for web-components is a UI development environment for your plain web-component snippets.
-With it, you can visualize different states of your UI components and develop them interactively.
-
-![Storybook Screenshot](https://github.com/storybookjs/storybook/blob/main/media/storybook-intro.gif)
-
-Storybook runs outside of your app.
-So you can develop UI components in isolation without worrying about app specific dependencies and requirements.
-
-## Getting Started
-
-```sh
-cd my-app
-npx storybook@latest init -t web_components
-```
-
-For more information visit: [storybook.js.org](https://storybook.js.org)
-
----
-
-Storybook also comes with a lot of [addons](https://storybook.js.org/addons) and a great API to customize as you wish.
-You can also build a [static version](https://storybook.js.org/docs/web-components/sharing/publish-storybook) of your storybook and deploy it anywhere you want.
-
-# Hot Module Reloading (HMR)
-
-As web components register on a global registry which only accepts a certain name/class once it can lead to errors when using classical HMR. There are ideas on how to archive HMR with a static registry but there is no proven solution yet. Therefore the best approach for now is to do full page reloads. If you keep your stories to specific states of components (which we would recommend anyways) this usually means it is fast.
-
-# Setup es6/7 dependencies
-
-By default storybook only works with precompiled ES5 code but as most web components themselves and their libs are distributed as ES2017 you will need to manually mark those packages as "needs transpilation".
-
-For example if you have a library called `my-library` which is in ES2017 then you can add it like so
-
-```js
-// .storybook/main.js
-
-export default {
- webpackFinal: async (config) => {
- // find web-components rule for extra transpilation
- const webComponentsRule = config.module.rules.find(
- (rule) => rule.use && rule.use.options && rule.use.options.babelrc === false
- );
- // add your own `my-library`
- webComponentsRule.test.push(new RegExp(`node_modules(\\/|\\\\)my-library(.*)\\.js$`));
-
- return config;
- },
-};
-```
-
-By default the following folders are included
-
-- `src/*.js`
-- `packages/*/src/*.js`
-- `node_modules/lit-html/*.js`
-- `node_modules/lit-element/*.js`
-- `node_modules/@open-wc/*.js`
-- `node_modules/@polymer/*.js`
-- `node_modules/@vaadin/*.js`
-
-As you can see the `src` folder is also included.
-The reason for that is as it has some extra configuration to allow for example `import.meta`.
-If you use a different folder you will need to make sure webpack/babel can handle it.
-
-# FAQ
-
-- While working on my component I get the error `Failed to execute 'define' on 'CustomElementRegistry': the name "..." has already been used with this registry`
- => please see Setup page reload via HMR
+See [documentation](https://storybook.js.org/docs/8.0/get-started/web-components-webpack5?renderer=web-components) for installation instructions, usage examples, APIs, and more.
diff --git a/code/frameworks/web-components-webpack5/package.json b/code/frameworks/web-components-webpack5/package.json
index 04f0b31cbf1f..58e8127374d7 100644
--- a/code/frameworks/web-components-webpack5/package.json
+++ b/code/frameworks/web-components-webpack5/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/web-components-webpack5",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.",
"keywords": [
"lit",
diff --git a/code/lib/channels/package.json b/code/lib/channels/package.json
index 6020059195b0..babfab81a6f3 100644
--- a/code/lib/channels/package.json
+++ b/code/lib/channels/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/channels",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "",
"keywords": [
"storybook"
@@ -47,7 +47,6 @@
"@storybook/client-logger": "workspace:*",
"@storybook/core-events": "workspace:*",
"@storybook/global": "^5.0.0",
- "qs": "^6.10.0",
"telejson": "^7.2.0",
"tiny-invariant": "^1.3.1"
},
diff --git a/code/lib/channels/src/postmessage/index.ts b/code/lib/channels/src/postmessage/index.ts
index 267e8a34f18a..1320a6577b4c 100644
--- a/code/lib/channels/src/postmessage/index.ts
+++ b/code/lib/channels/src/postmessage/index.ts
@@ -5,7 +5,6 @@ import { global } from '@storybook/global';
import * as EVENTS from '@storybook/core-events';
import { logger, pretty } from '@storybook/client-logger';
import { isJSON, parse, stringify } from 'telejson';
-import qs from 'qs';
import invariant from 'tiny-invariant';
import type {
ChannelTransport,
@@ -102,13 +101,13 @@ export class PostMessageTransport implements ChannelTransport {
const frames = this.getFrames(target);
- const query = qs.parse(location?.search || '', { ignoreQueryPrefix: true });
+ const query = new URLSearchParams(location?.search || '');
const data = stringify(
{
key: KEY,
event,
- refId: query.refId,
+ refId: query.get('refId'),
},
stringifyOptions
);
diff --git a/code/lib/cli-sb/package.json b/code/lib/cli-sb/package.json
index 821450e6252c..cf44c6af83c6 100644
--- a/code/lib/cli-sb/package.json
+++ b/code/lib/cli-sb/package.json
@@ -1,6 +1,6 @@
{
"name": "sb",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook CLI",
"keywords": [
"storybook"
diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json
index 17585083a303..2c1ebe24b774 100644
--- a/code/lib/cli-storybook/package.json
+++ b/code/lib/cli-storybook/package.json
@@ -1,6 +1,6 @@
{
"name": "storybook",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook CLI",
"keywords": [
"storybook"
diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json
index 0f8d72361143..a781b00c1a44 100644
--- a/code/lib/cli/package.json
+++ b/code/lib/cli/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/cli",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook's CLI - install, dev, build, upgrade, and more",
"keywords": [
"cli",
diff --git a/code/lib/cli/src/automigrate/fixes/index.ts b/code/lib/cli/src/automigrate/fixes/index.ts
index 17b3d4942be1..022074fa8301 100644
--- a/code/lib/cli/src/automigrate/fixes/index.ts
+++ b/code/lib/cli/src/automigrate/fixes/index.ts
@@ -26,6 +26,7 @@ import { removeJestTestingLibrary } from './remove-jest-testing-library';
import { addonsAPI } from './addons-api';
import { mdx1to3 } from './mdx-1-to-3';
import { addonPostCSS } from './addon-postcss';
+import { upgradeStorybookRelatedDependencies } from './upgrade-storybook-related-dependencies';
export * from '../types';
@@ -56,6 +57,7 @@ export const allFixes: Fix[] = [
removeLegacyMDX1,
webpack5CompilerSetup,
mdx1to3,
+ upgradeStorybookRelatedDependencies,
];
export const initFixes: Fix[] = [eslintPlugin];
diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.test.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.test.ts
new file mode 100644
index 000000000000..0c16309647bd
--- /dev/null
+++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.test.ts
@@ -0,0 +1,95 @@
+import { describe, afterEach, it, expect, vi } from 'vitest';
+import type { StorybookConfig } from '@storybook/types';
+import type { JsPackageManager } from '@storybook/core-common';
+import * as docsUtils from '../../doctor/getIncompatibleStorybookPackages';
+
+import { upgradeStorybookRelatedDependencies } from './upgrade-storybook-related-dependencies';
+
+vi.mock('../../doctor/getIncompatibleStorybookPackages');
+
+const check = async ({
+ packageManager,
+ main: mainConfig = {},
+ storybookVersion = '8.0.0',
+}: {
+ packageManager: Partial;
+ main?: Partial & Record;
+ storybookVersion?: string;
+}) => {
+ return upgradeStorybookRelatedDependencies.check({
+ packageManager: packageManager as any,
+ configDir: '',
+ mainConfig: mainConfig as any,
+ storybookVersion,
+ });
+};
+
+describe('upgrade-storybook-related-dependencies fix', () => {
+ afterEach(() => {
+ vi.restoreAllMocks();
+ });
+
+ it('should detect storyshots registered in main.js', async () => {
+ const analyzedPackages = [
+ {
+ packageName: '@chromatic-com/storybook',
+ packageVersion: '1.2.9',
+ availableUpgrade: '2.0.0',
+ hasIncompatibleDependencies: false,
+ },
+ {
+ packageName: '@storybook/jest',
+ packageVersion: '0.2.3',
+ availableUpgrade: '1.0.0',
+ hasIncompatibleDependencies: false,
+ },
+ {
+ packageName: '@storybook/preset-create-react-app',
+ packageVersion: '3.2.0',
+ availableUpgrade: '8.0.0',
+ hasIncompatibleDependencies: true,
+ },
+ {
+ packageName: 'storybook',
+ packageVersion: '8.0.0',
+ availableUpgrade: undefined,
+ hasIncompatibleDependencies: true,
+ },
+ ];
+ vi.mocked(docsUtils.getIncompatibleStorybookPackages).mockResolvedValue(analyzedPackages);
+ await expect(
+ check({
+ packageManager: {
+ getAllDependencies: async () => ({
+ '@chromatic-com/storybook': '1.2.9',
+ '@storybook/jest': '0.2.3',
+ '@storybook/preset-create-react-app': '3.2.0',
+ storybook: '8.0.0',
+ }),
+ latestVersion: async (pkgName) =>
+ analyzedPackages.find((pkg) => pkg.packageName === pkgName)?.availableUpgrade || '',
+ },
+ })
+ ).resolves.toMatchInlineSnapshot(`
+ {
+ "upgradable": [
+ {
+ "afterVersion": "2.0.0",
+ "beforeVersion": "1.2.9",
+ "packageName": "@chromatic-com/storybook",
+ },
+ {
+ "afterVersion": "1.0.0",
+ "beforeVersion": "0.2.3",
+ "packageName": "@storybook/jest",
+ },
+ {
+ "afterVersion": "8.0.0",
+ "beforeVersion": "3.2.0",
+ "packageName": "@storybook/preset-create-react-app",
+ },
+ ],
+ }
+ `);
+ });
+});
diff --git a/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts
new file mode 100644
index 000000000000..5614b7e35ad0
--- /dev/null
+++ b/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts
@@ -0,0 +1,162 @@
+import { dedent } from 'ts-dedent';
+import { cyan, yellow } from 'chalk';
+import { valid, coerce } from 'semver';
+import type { JsPackageManager } from '@storybook/core-common';
+import { isCorePackage } from '@storybook/core-common';
+import type { Fix } from '../types';
+import { getIncompatibleStorybookPackages } from '../../doctor/getIncompatibleStorybookPackages';
+
+type PackageMetadata = {
+ packageName: string;
+ beforeVersion: string | null;
+ afterVersion: string | null;
+};
+
+interface Options {
+ upgradable: PackageMetadata[];
+}
+
+async function getLatestVersions(
+ packageManager: JsPackageManager,
+ packages: [string, string][]
+): Promise {
+ return Promise.all(
+ packages.map(async ([packageName, beforeVersion]) => ({
+ packageName,
+ beforeVersion: coerce(beforeVersion)?.toString() || null,
+ afterVersion: await packageManager.latestVersion(packageName).catch(() => null),
+ }))
+ );
+}
+
+function isPackageUpgradable(
+ afterVersion: string,
+ packageName: string,
+ allDependencies: Record
+) {
+ const installedVersion = coerce(allDependencies[packageName])?.toString();
+
+ return valid(afterVersion) && afterVersion !== installedVersion;
+}
+
+/**
+ * Is the user upgrading to the `latest` version of Storybook?
+ * Let's try to pull along some of the storybook related dependencies to `latest` as well!
+ *
+ * We communicate clearly that this migration is a helping hand, but not a complete solution.
+ * The user should still manually check for other dependencies that might be incompatible.
+ *
+ * see: https://github.com/storybookjs/storybook/issues/25731#issuecomment-1977346398
+ */
+export const upgradeStorybookRelatedDependencies = {
+ id: 'upgradeStorybookRelatedDependencies',
+ versionRange: ['*.*.*', '*.*.*'],
+ promptType: 'auto',
+ promptDefaultValue: false,
+
+ async check({ packageManager, storybookVersion }) {
+ const analyzedPackages = await getIncompatibleStorybookPackages({
+ currentStorybookVersion: storybookVersion,
+ packageManager,
+ skipErrors: true,
+ });
+
+ const allDependencies = (await packageManager.getAllDependencies()) as Record;
+ const storybookDependencies = Object.keys(allDependencies)
+ .filter((dep) => dep.includes('storybook'))
+ .filter((dep) => !isCorePackage(dep));
+ const incompatibleDependencies = analyzedPackages
+ .filter((pkg) => pkg.hasIncompatibleDependencies)
+ .map((pkg) => pkg.packageName);
+
+ const uniquePackages = Array.from(
+ new Set([...storybookDependencies, ...incompatibleDependencies])
+ ).map((packageName) => [packageName, allDependencies[packageName]]) as [string, string][];
+
+ const packageVersions = await getLatestVersions(packageManager, uniquePackages);
+
+ const upgradablePackages = packageVersions.filter(
+ ({ packageName, afterVersion, beforeVersion }) => {
+ if (beforeVersion === null || afterVersion === null) {
+ return false;
+ }
+
+ return isPackageUpgradable(afterVersion, packageName, allDependencies);
+ }
+ );
+
+ return upgradablePackages.length > 0 ? { upgradable: upgradablePackages } : null;
+ },
+
+ prompt({ upgradable }) {
+ return dedent`
+ You're upgrading to the latest version of Storybook. We recommend upgrading the following packages:
+ ${upgradable
+ .map(({ packageName, afterVersion, beforeVersion }) => {
+ return `- ${cyan(packageName)}: ${cyan(beforeVersion)} => ${cyan(afterVersion)}`;
+ })
+ .join('\n')}
+
+ After upgrading, we will run the dedupe command, which could possibly have effects on dependencies that are not Storybook related.
+ see: https://docs.npmjs.com/cli/commands/npm-dedupe
+
+ Do you want to proceed (upgrade the detected packages)?
+ `;
+ },
+
+ async run({ result: { upgradable }, packageManager, dryRun }) {
+ if (dryRun) {
+ console.log(dedent`
+ We would have upgrade the following:
+ ${upgradable
+ .map(
+ ({ packageName, afterVersion, beforeVersion }) =>
+ `${packageName}: ${beforeVersion} => ${afterVersion}`
+ )
+ .join('\n')}
+ `);
+ return;
+ }
+
+ if (upgradable.length > 0) {
+ const packageJson = await packageManager.readPackageJson();
+
+ upgradable.forEach((item) => {
+ if (!item) {
+ return;
+ }
+
+ const { packageName, afterVersion: version } = item;
+ const prefixed = `^${version}`;
+
+ if (packageJson.dependencies?.[packageName]) {
+ packageJson.dependencies[packageName] = prefixed;
+ }
+ if (packageJson.devDependencies?.[packageName]) {
+ packageJson.devDependencies[packageName] = prefixed;
+ }
+ if (packageJson.peerDependencies?.[packageName]) {
+ packageJson.peerDependencies[packageName] = prefixed;
+ }
+ });
+
+ await packageManager.writePackageJson(packageJson);
+ await packageManager.installDependencies();
+
+ await packageManager
+ .executeCommand({ command: 'dedupe', args: [], stdio: 'ignore' })
+ .catch(() => {});
+
+ console.log();
+ console.log(dedent`
+ We upgraded ${yellow(upgradable.length)} packages:
+ ${upgradable
+ .map(({ packageName, afterVersion, beforeVersion }) => {
+ return `- ${cyan(packageName)}: ${cyan(beforeVersion)} => ${cyan(afterVersion)}`;
+ })
+ .join('\n')}
+ `);
+ }
+ console.log();
+ },
+} satisfies Fix;
diff --git a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts
index 6a8dd9ec0e02..e81637dc6cb2 100644
--- a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts
+++ b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts
@@ -97,25 +97,25 @@ export const viteConfigFile = {
prompt({ existed, plugins }) {
if (existed) {
return dedent`
- Since version 8.0.0, Storybook no longer ships with a Vite config build-in.
+ Since version 8.0.0, Storybook no longer ships with an in-built Vite config.
We've detected you do have a Vite config, but you may be missing the following plugins in it.
${plugins.map((plugin) => ` - ${plugin}`).join('\n')}
- If you do already have these plugins, you can ignore this message.
+ If you already have these plugins, you can ignore this message.
You can find more information on how to do this here:
- https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-specific-vite-plugins-have-to-be-explicitly-added
+ https://storybook.js.org/docs/8.0/migration-guide/#missing-viteconfigjs-file
This change was necessary to support newer versions of Vite.
`;
}
return dedent`
- Since version 8.0.0, Storybook no longer ships with a Vite config build-in.
+ Since version 8.0.0, Storybook no longer ships with an in-built Vite config.
Please add a vite.config.js file to your project root.
You can find more information on how to do this here:
- https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-specific-vite-plugins-have-to-be-explicitly-added
+ https://storybook.js.org/docs/8.0/migration-guide/#missing-viteconfigjs-file
This change was necessary to support newer versions of Vite.
`;
diff --git a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts
index f43e84370852..eb49848ab2c0 100644
--- a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts
+++ b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts
@@ -129,35 +129,7 @@ describe('getMigrationSummary', () => {
The automigrations try to migrate common patterns in your project, but might not contain everything needed to migrate to the latest version of Storybook.
Please check the changelog and migration guide for manual migrations and more information: https://storybook.js.org/docs/8.0/migration-guide
- And reach out on Discord if you need help: https://discord.gg/storybook
-
- βββββββββββββββββββββββββββββββββββββββββββββββββ
-
- Critical: The following dependencies are duplicated and WILL cause unexpected behavior:
-
- @storybook/instrumenter:
- 6.0.0, 7.1.0
-
- @storybook/core-common:
- 6.0.0, 7.1.0
-
-
-
-
- Attention: The following dependencies are duplicated which might cause unexpected behavior:
-
- @storybook/addon-essentials:
- 7.0.0, 7.1.0
-
-
-
-
- Please try de-duplicating these dependencies by running yarn dedupe
-
-
-
-
- You can find more information for a given dependency by running yarn why "
+ And reach out on Discord if you need help: https://discord.gg/storybook"
`);
});
diff --git a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.ts b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.ts
index aa0503865749..12c8ac07bfa7 100644
--- a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.ts
+++ b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.ts
@@ -4,7 +4,6 @@ import dedent from 'ts-dedent';
import type { InstallationMetadata } from '@storybook/core-common';
import type { FixSummary } from '../types';
import { FixStatus } from '../types';
-import { getDuplicatedDepsWarnings } from '../../doctor/getDuplicatedDepsWarnings';
export const messageDivider = '\n\n';
const segmentDivider = '\n\nβββββββββββββββββββββββββββββββββββββββββββββββββ\n\n';
@@ -75,14 +74,6 @@ export function getMigrationSummary({
And reach out on Discord if you need help: ${chalk.yellow('https://discord.gg/storybook')}
`);
- const duplicatedDepsMessage = installationMetadata
- ? getDuplicatedDepsWarnings(installationMetadata)
- : getDuplicatedDepsWarnings();
-
- if (duplicatedDepsMessage) {
- messages.push(duplicatedDepsMessage.join(messageDivider));
- }
-
const hasNoFixes = Object.values(fixResults).every((r) => r === FixStatus.UNNECESSARY);
const hasFailures = Object.values(fixResults).some(
(r) => r === FixStatus.FAILED || r === FixStatus.CHECK_FAILED
diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts
index 8a84476b5e93..340a90f7ec38 100644
--- a/code/lib/cli/src/automigrate/index.ts
+++ b/code/lib/cli/src/automigrate/index.ts
@@ -29,6 +29,9 @@ import { getMigrationSummary } from './helpers/getMigrationSummary';
import { getStorybookData } from './helpers/mainConfigFile';
import { doctor } from '../doctor';
+import { upgradeStorybookRelatedDependencies } from './fixes/upgrade-storybook-related-dependencies';
+import dedent from 'ts-dedent';
+
const logger = console;
const LOG_FILE_NAME = 'migration-storybook.log';
const LOG_FILE_PATH = join(process.cwd(), LOG_FILE_NAME);
@@ -56,8 +59,16 @@ const cleanup = () => {
};
const logAvailableMigrations = () => {
- const availableFixes = allFixes.map((f) => chalk.yellow(f.id)).join(', ');
- logger.info(`\nThe following migrations are available: ${availableFixes}`);
+ const availableFixes = allFixes
+ .map((f) => chalk.yellow(f.id))
+ .map((x) => `- ${x}`)
+ .join('\n');
+
+ console.log();
+ logger.info(dedent`
+ The following migrations are available:
+ ${availableFixes}
+ `);
};
export const doAutomigrate = async (options: AutofixOptionsFromCLI) => {
@@ -84,7 +95,7 @@ export const doAutomigrate = async (options: AutofixOptionsFromCLI) => {
throw new Error('Could not determine main config path');
}
- await automigrate({
+ const outcome = await automigrate({
...options,
packageManager,
storybookVersion,
@@ -92,9 +103,12 @@ export const doAutomigrate = async (options: AutofixOptionsFromCLI) => {
mainConfigPath,
configDir,
isUpgrade: false,
+ isLatest: false,
});
- await doctor({ configDir, packageManager: options.packageManager });
+ if (outcome) {
+ await doctor({ configDir, packageManager: options.packageManager });
+ }
};
export const automigrate = async ({
@@ -112,6 +126,7 @@ export const automigrate = async ({
skipInstall,
hideMigrationSummary = false,
isUpgrade,
+ isLatest,
}: AutofixOptions): Promise<{
fixResults: Record;
preCheckFailure?: PreCheckFailure;
@@ -121,8 +136,21 @@ export const automigrate = async ({
return null;
}
- const selectedFixes = inputFixes || allFixes;
- const fixes = fixId ? selectedFixes.filter((f) => f.id === fixId) : selectedFixes;
+ const selectedFixes: Fix[] =
+ inputFixes ||
+ allFixes.filter((fix) => {
+ // we only allow this automigration when the user explicitly asks for it, or they are upgrading to the latest version of storybook
+ if (
+ fix.id === upgradeStorybookRelatedDependencies.id &&
+ isLatest === false &&
+ fixId !== upgradeStorybookRelatedDependencies.id
+ ) {
+ return false;
+ }
+
+ return true;
+ });
+ const fixes: Fix[] = fixId ? selectedFixes.filter((f) => f.id === fixId) : selectedFixes;
if (fixId && fixes.length === 0) {
logger.info(`π No migrations found for ${chalk.magenta(fixId)}.`);
@@ -143,7 +171,7 @@ export const automigrate = async ({
mainConfigPath,
storybookVersion,
beforeVersion,
- isUpgrade,
+ isUpgrade: !!isUpgrade,
dryRun,
yes,
});
@@ -314,7 +342,7 @@ export async function runFixes({
type: 'confirm',
name: 'fix',
message: `Do you want to run the '${chalk.cyan(f.id)}' migration on your project?`,
- initial: true,
+ initial: f.promptDefaultValue ?? true,
},
{
onCancel: () => {
diff --git a/code/lib/cli/src/automigrate/types.ts b/code/lib/cli/src/automigrate/types.ts
index d8cc9f06af3e..43447102162f 100644
--- a/code/lib/cli/src/automigrate/types.ts
+++ b/code/lib/cli/src/automigrate/types.ts
@@ -1,5 +1,5 @@
-import type { StorybookConfigRaw } from '@storybook/types';
import type { JsPackageManager, PackageManagerName } from '@storybook/core-common';
+import type { StorybookConfigRaw } from '@storybook/types';
export interface CheckOptions {
packageManager: JsPackageManager;
@@ -37,6 +37,7 @@ type BaseFix = {
versionRange: [from: string, to: string];
check: (options: CheckOptions) => Promise;
prompt: (result: ResultType) => string;
+ promptDefaultValue?: boolean;
};
type PromptType =
@@ -75,6 +76,7 @@ export interface AutofixOptions extends Omit {
- const storybookVersion = semver.coerce(currentStorybookVersion);
- const packageVersion = semver.coerce(installedVersion);
- return storybookVersion?.major !== packageVersion?.major;
-};
-
export const checkPackageCompatibility = async (dependency: string, context: Context) => {
const { currentStorybookVersion, skipErrors, packageManager } = context;
try {
@@ -46,12 +40,12 @@ export const checkPackageCompatibility = async (dependency: string, context: Con
...peerDependencies,
})
.filter(([dep]) => storybookCorePackages[dep as keyof typeof storybookCorePackages])
- .find(([, version]) => {
+ .find(([_, versionRange]) => {
// prevent issues with "tag" based versions e.g. "latest" or "next" instead of actual numbers
return (
- version &&
- semver.validRange(version) &&
- isPackageIncompatible(version, currentStorybookVersion)
+ versionRange &&
+ semver.validRange(versionRange) &&
+ !semver.satisfies(currentStorybookVersion, versionRange)
);
});
diff --git a/code/lib/cli/src/migrate.ts b/code/lib/cli/src/migrate.ts
index 15d2169120e7..29ee10dc82a3 100644
--- a/code/lib/cli/src/migrate.ts
+++ b/code/lib/cli/src/migrate.ts
@@ -1,11 +1,12 @@
import { listCodemods, runCodemod } from '@storybook/codemod';
-import { runFixes } from './automigrate';
-import { mdxToCSF } from './automigrate/fixes/mdx-to-csf';
import {
JsPackageManagerFactory,
- getStorybookInfo,
getCoercedStorybookVersion,
+ getStorybookInfo,
} from '@storybook/core-common';
+
+import { runFixes } from './automigrate';
+import { mdxToCSF } from './automigrate/fixes/mdx-to-csf';
import { getStorybookVersionSpecifier } from './helpers';
const logger = console;
diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts
index 182e49798148..b28021be7049 100644
--- a/code/lib/cli/src/sandbox-templates.ts
+++ b/code/lib/cli/src/sandbox-templates.ts
@@ -443,7 +443,7 @@ const baseTemplates = {
},
'qwik-vite/default-ts': {
name: 'Qwik CLI Latest (Vite | TypeScript)',
- script: 'yarn create qwik basic {{beforeDir}}',
+ script: 'npm create qwik basic {{beforeDir}}',
// TODO: The community template does not provide standard stories, which is required for e2e tests. Reenable once it does.
inDevelopment: true,
expected: {
diff --git a/code/lib/cli/src/upgrade.ts b/code/lib/cli/src/upgrade.ts
index 179c7d806a2f..f0b7cc5ff612 100644
--- a/code/lib/cli/src/upgrade.ts
+++ b/code/lib/cli/src/upgrade.ts
@@ -148,6 +148,7 @@ export const doUpgrade = async ({
]);
const isOutdated = lt(currentVersion, latestVersion);
+ const isExactLatest = currentVersion === latestVersion;
const isPrerelease = prerelease(currentVersion) !== null;
const borderColor = isOutdated ? '#FC521F' : '#F1618C';
@@ -261,7 +262,8 @@ export const doUpgrade = async ({
mainConfigPath,
beforeVersion,
storybookVersion: currentVersion,
- isUpgrade: true,
+ isUpgrade: isOutdated,
+ isLatest: isExactLatest,
});
}
diff --git a/code/lib/client-logger/package.json b/code/lib/client-logger/package.json
index 60716ac1c3cb..1b93dcdb7a93 100644
--- a/code/lib/client-logger/package.json
+++ b/code/lib/client-logger/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/client-logger",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "",
"keywords": [
"storybook"
diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json
index dbcac376c369..2c48f148ba76 100644
--- a/code/lib/codemod/package.json
+++ b/code/lib/codemod/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/codemod",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "A collection of codemod scripts written with JSCodeshift",
"keywords": [
"storybook"
diff --git a/code/lib/core-common/package.json b/code/lib/core-common/package.json
index 303b4cd42734..6755631bf49c 100644
--- a/code/lib/core-common/package.json
+++ b/code/lib/core-common/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/core-common",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"
@@ -52,7 +52,7 @@
"@yarnpkg/libzip": "2.3.0",
"chalk": "^4.1.0",
"cross-spawn": "^7.0.3",
- "esbuild": "^18.0.0 || ^19.0.0 || ^0.20.0",
+ "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0",
"esbuild-register": "^3.5.0",
"execa": "^5.0.0",
"file-system-cache": "2.3.0",
diff --git a/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts b/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts
index 692402ba5844..db4820b02ec6 100644
--- a/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts
+++ b/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts
@@ -17,6 +17,7 @@ const essentialAddons = [
'toolbars',
'measure',
'outline',
+ 'highlight',
];
const pkgName = (entry: CoreCommon_AddonEntry): string => {
@@ -42,6 +43,22 @@ afterEach(() => {
describe.each([
['docs', 'controls', ['docs', 'controls']],
['docs', 'controls', ['docs', 'foo/node_modules/@storybook/addon-controls']],
+ [
+ 'actions',
+ 'interactions',
+ [
+ 'foo\\node_modules\\@storybook\\addon-essentials',
+ 'foo\\node_modules\\@storybook\\addon-interactions',
+ ],
+ ],
+ [
+ 'actions',
+ 'interactions',
+ [
+ 'foo\\\\node_modules\\\\@storybook\\\\addon-essentials',
+ 'foo\\\\node_modules\\\\@storybook\\\\addon-interactions',
+ ],
+ ],
['docs', 'controls', [{ name: '@storybook/addon-docs' }, 'controls']],
['docs', 'controls', ['essentials', 'controls']],
['docs', 'controls', ['essentials']],
diff --git a/code/lib/core-common/src/utils/check-addon-order.ts b/code/lib/core-common/src/utils/check-addon-order.ts
index 58faeccee228..b91c93e7df02 100644
--- a/code/lib/core-common/src/utils/check-addon-order.ts
+++ b/code/lib/core-common/src/utils/check-addon-order.ts
@@ -15,7 +15,7 @@ interface Options {
const predicateFor = (addon: string) => (entry: CoreCommon_AddonEntry) => {
const name = (entry as CoreCommon_OptionsEntry).name || (entry as string);
- return name && name.includes(addon);
+ return name && name.replaceAll(/(\\){1,2}/g, '/').includes(addon);
};
const isCorrectOrder = (
diff --git a/code/lib/core-common/src/versions.ts b/code/lib/core-common/src/versions.ts
index 1de3269c4e5b..7ccc1ac33235 100644
--- a/code/lib/core-common/src/versions.ts
+++ b/code/lib/core-common/src/versions.ts
@@ -1,83 +1,83 @@
// auto generated file, do not edit
export default {
- '@storybook/addon-a11y': '8.0.0-rc.2',
- '@storybook/addon-actions': '8.0.0-rc.2',
- '@storybook/addon-backgrounds': '8.0.0-rc.2',
- '@storybook/addon-controls': '8.0.0-rc.2',
- '@storybook/addon-docs': '8.0.0-rc.2',
- '@storybook/addon-essentials': '8.0.0-rc.2',
- '@storybook/addon-highlight': '8.0.0-rc.2',
- '@storybook/addon-interactions': '8.0.0-rc.2',
- '@storybook/addon-jest': '8.0.0-rc.2',
- '@storybook/addon-links': '8.0.0-rc.2',
- '@storybook/addon-mdx-gfm': '8.0.0-rc.2',
- '@storybook/addon-measure': '8.0.0-rc.2',
- '@storybook/addon-onboarding': '8.0.0-rc.2',
- '@storybook/addon-outline': '8.0.0-rc.2',
- '@storybook/addon-storysource': '8.0.0-rc.2',
- '@storybook/addon-themes': '8.0.0-rc.2',
- '@storybook/addon-toolbars': '8.0.0-rc.2',
- '@storybook/addon-viewport': '8.0.0-rc.2',
- '@storybook/angular': '8.0.0-rc.2',
- '@storybook/blocks': '8.0.0-rc.2',
- '@storybook/builder-manager': '8.0.0-rc.2',
- '@storybook/builder-vite': '8.0.0-rc.2',
- '@storybook/builder-webpack5': '8.0.0-rc.2',
- '@storybook/channels': '8.0.0-rc.2',
- '@storybook/cli': '8.0.0-rc.2',
- '@storybook/client-logger': '8.0.0-rc.2',
- '@storybook/codemod': '8.0.0-rc.2',
- '@storybook/components': '8.0.0-rc.2',
- '@storybook/core-common': '8.0.0-rc.2',
- '@storybook/core-events': '8.0.0-rc.2',
- '@storybook/core-server': '8.0.0-rc.2',
- '@storybook/core-webpack': '8.0.0-rc.2',
- '@storybook/csf-plugin': '8.0.0-rc.2',
- '@storybook/csf-tools': '8.0.0-rc.2',
- '@storybook/docs-tools': '8.0.0-rc.2',
- '@storybook/ember': '8.0.0-rc.2',
- '@storybook/html': '8.0.0-rc.2',
- '@storybook/html-vite': '8.0.0-rc.2',
- '@storybook/html-webpack5': '8.0.0-rc.2',
- '@storybook/instrumenter': '8.0.0-rc.2',
- '@storybook/manager': '8.0.0-rc.2',
- '@storybook/manager-api': '8.0.0-rc.2',
- '@storybook/nextjs': '8.0.0-rc.2',
- '@storybook/node-logger': '8.0.0-rc.2',
- '@storybook/preact': '8.0.0-rc.2',
- '@storybook/preact-vite': '8.0.0-rc.2',
- '@storybook/preact-webpack5': '8.0.0-rc.2',
- '@storybook/preset-create-react-app': '8.0.0-rc.2',
- '@storybook/preset-html-webpack': '8.0.0-rc.2',
- '@storybook/preset-preact-webpack': '8.0.0-rc.2',
- '@storybook/preset-react-webpack': '8.0.0-rc.2',
- '@storybook/preset-server-webpack': '8.0.0-rc.2',
- '@storybook/preset-svelte-webpack': '8.0.0-rc.2',
- '@storybook/preset-vue3-webpack': '8.0.0-rc.2',
- '@storybook/preview': '8.0.0-rc.2',
- '@storybook/preview-api': '8.0.0-rc.2',
- '@storybook/react': '8.0.0-rc.2',
- '@storybook/react-dom-shim': '8.0.0-rc.2',
- '@storybook/react-vite': '8.0.0-rc.2',
- '@storybook/react-webpack5': '8.0.0-rc.2',
- '@storybook/router': '8.0.0-rc.2',
- '@storybook/server': '8.0.0-rc.2',
- '@storybook/server-webpack5': '8.0.0-rc.2',
- '@storybook/source-loader': '8.0.0-rc.2',
- '@storybook/svelte': '8.0.0-rc.2',
- '@storybook/svelte-vite': '8.0.0-rc.2',
- '@storybook/svelte-webpack5': '8.0.0-rc.2',
- '@storybook/sveltekit': '8.0.0-rc.2',
- '@storybook/telemetry': '8.0.0-rc.2',
- '@storybook/test': '8.0.0-rc.2',
- '@storybook/theming': '8.0.0-rc.2',
- '@storybook/types': '8.0.0-rc.2',
- '@storybook/vue3': '8.0.0-rc.2',
- '@storybook/vue3-vite': '8.0.0-rc.2',
- '@storybook/vue3-webpack5': '8.0.0-rc.2',
- '@storybook/web-components': '8.0.0-rc.2',
- '@storybook/web-components-vite': '8.0.0-rc.2',
- '@storybook/web-components-webpack5': '8.0.0-rc.2',
- sb: '8.0.0-rc.2',
- storybook: '8.0.0-rc.2',
+ '@storybook/addon-a11y': '8.1.0-alpha.1',
+ '@storybook/addon-actions': '8.1.0-alpha.1',
+ '@storybook/addon-backgrounds': '8.1.0-alpha.1',
+ '@storybook/addon-controls': '8.1.0-alpha.1',
+ '@storybook/addon-docs': '8.1.0-alpha.1',
+ '@storybook/addon-essentials': '8.1.0-alpha.1',
+ '@storybook/addon-highlight': '8.1.0-alpha.1',
+ '@storybook/addon-interactions': '8.1.0-alpha.1',
+ '@storybook/addon-jest': '8.1.0-alpha.1',
+ '@storybook/addon-links': '8.1.0-alpha.1',
+ '@storybook/addon-mdx-gfm': '8.1.0-alpha.1',
+ '@storybook/addon-measure': '8.1.0-alpha.1',
+ '@storybook/addon-onboarding': '8.1.0-alpha.1',
+ '@storybook/addon-outline': '8.1.0-alpha.1',
+ '@storybook/addon-storysource': '8.1.0-alpha.1',
+ '@storybook/addon-themes': '8.1.0-alpha.1',
+ '@storybook/addon-toolbars': '8.1.0-alpha.1',
+ '@storybook/addon-viewport': '8.1.0-alpha.1',
+ '@storybook/angular': '8.1.0-alpha.1',
+ '@storybook/blocks': '8.1.0-alpha.1',
+ '@storybook/builder-manager': '8.1.0-alpha.1',
+ '@storybook/builder-vite': '8.1.0-alpha.1',
+ '@storybook/builder-webpack5': '8.1.0-alpha.1',
+ '@storybook/channels': '8.1.0-alpha.1',
+ '@storybook/cli': '8.1.0-alpha.1',
+ '@storybook/client-logger': '8.1.0-alpha.1',
+ '@storybook/codemod': '8.1.0-alpha.1',
+ '@storybook/components': '8.1.0-alpha.1',
+ '@storybook/core-common': '8.1.0-alpha.1',
+ '@storybook/core-events': '8.1.0-alpha.1',
+ '@storybook/core-server': '8.1.0-alpha.1',
+ '@storybook/core-webpack': '8.1.0-alpha.1',
+ '@storybook/csf-plugin': '8.1.0-alpha.1',
+ '@storybook/csf-tools': '8.1.0-alpha.1',
+ '@storybook/docs-tools': '8.1.0-alpha.1',
+ '@storybook/ember': '8.1.0-alpha.1',
+ '@storybook/html': '8.1.0-alpha.1',
+ '@storybook/html-vite': '8.1.0-alpha.1',
+ '@storybook/html-webpack5': '8.1.0-alpha.1',
+ '@storybook/instrumenter': '8.1.0-alpha.1',
+ '@storybook/manager': '8.1.0-alpha.1',
+ '@storybook/manager-api': '8.1.0-alpha.1',
+ '@storybook/nextjs': '8.1.0-alpha.1',
+ '@storybook/node-logger': '8.1.0-alpha.1',
+ '@storybook/preact': '8.1.0-alpha.1',
+ '@storybook/preact-vite': '8.1.0-alpha.1',
+ '@storybook/preact-webpack5': '8.1.0-alpha.1',
+ '@storybook/preset-create-react-app': '8.1.0-alpha.1',
+ '@storybook/preset-html-webpack': '8.1.0-alpha.1',
+ '@storybook/preset-preact-webpack': '8.1.0-alpha.1',
+ '@storybook/preset-react-webpack': '8.1.0-alpha.1',
+ '@storybook/preset-server-webpack': '8.1.0-alpha.1',
+ '@storybook/preset-svelte-webpack': '8.1.0-alpha.1',
+ '@storybook/preset-vue3-webpack': '8.1.0-alpha.1',
+ '@storybook/preview': '8.1.0-alpha.1',
+ '@storybook/preview-api': '8.1.0-alpha.1',
+ '@storybook/react': '8.1.0-alpha.1',
+ '@storybook/react-dom-shim': '8.1.0-alpha.1',
+ '@storybook/react-vite': '8.1.0-alpha.1',
+ '@storybook/react-webpack5': '8.1.0-alpha.1',
+ '@storybook/router': '8.1.0-alpha.1',
+ '@storybook/server': '8.1.0-alpha.1',
+ '@storybook/server-webpack5': '8.1.0-alpha.1',
+ '@storybook/source-loader': '8.1.0-alpha.1',
+ '@storybook/svelte': '8.1.0-alpha.1',
+ '@storybook/svelte-vite': '8.1.0-alpha.1',
+ '@storybook/svelte-webpack5': '8.1.0-alpha.1',
+ '@storybook/sveltekit': '8.1.0-alpha.1',
+ '@storybook/telemetry': '8.1.0-alpha.1',
+ '@storybook/test': '8.1.0-alpha.1',
+ '@storybook/theming': '8.1.0-alpha.1',
+ '@storybook/types': '8.1.0-alpha.1',
+ '@storybook/vue3': '8.1.0-alpha.1',
+ '@storybook/vue3-vite': '8.1.0-alpha.1',
+ '@storybook/vue3-webpack5': '8.1.0-alpha.1',
+ '@storybook/web-components': '8.1.0-alpha.1',
+ '@storybook/web-components-vite': '8.1.0-alpha.1',
+ '@storybook/web-components-webpack5': '8.1.0-alpha.1',
+ sb: '8.1.0-alpha.1',
+ storybook: '8.1.0-alpha.1',
};
diff --git a/code/lib/core-events/package.json b/code/lib/core-events/package.json
index 8ada1c3ee9a4..aaa150c0cd98 100644
--- a/code/lib/core-events/package.json
+++ b/code/lib/core-events/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/core-events",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Event names used in storybook core",
"keywords": [
"storybook"
diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json
index 1d4f1d43c88b..6a2428523cb6 100644
--- a/code/lib/core-server/package.json
+++ b/code/lib/core-server/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/core-server",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"
diff --git a/code/lib/core-webpack/package.json b/code/lib/core-webpack/package.json
index 84199b59fc20..22af5e8e2400 100644
--- a/code/lib/core-webpack/package.json
+++ b/code/lib/core-webpack/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/core-webpack",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook framework-agnostic API",
"keywords": [
"storybook"
diff --git a/code/lib/csf-plugin/package.json b/code/lib/csf-plugin/package.json
index 7c69964a2bf5..258f868ba615 100644
--- a/code/lib/csf-plugin/package.json
+++ b/code/lib/csf-plugin/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/csf-plugin",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Enrich CSF files via static analysis",
"keywords": [
"storybook"
diff --git a/code/lib/csf-tools/package.json b/code/lib/csf-tools/package.json
index 3aecb2b4c989..d713f09c8ad6 100644
--- a/code/lib/csf-tools/package.json
+++ b/code/lib/csf-tools/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/csf-tools",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Parse and manipulate CSF and Storybook config files",
"keywords": [
"storybook"
diff --git a/code/lib/docs-tools/package.json b/code/lib/docs-tools/package.json
index faead07c757d..e57e812eb307 100644
--- a/code/lib/docs-tools/package.json
+++ b/code/lib/docs-tools/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/docs-tools",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Shared utility functions for frameworks to implement docs",
"keywords": [
"storybook"
diff --git a/code/lib/instrumenter/package.json b/code/lib/instrumenter/package.json
index 29aafd117e78..b7cbb75e41e1 100644
--- a/code/lib/instrumenter/package.json
+++ b/code/lib/instrumenter/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/instrumenter",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "",
"keywords": [
"storybook"
@@ -49,7 +49,7 @@
"@storybook/core-events": "workspace:*",
"@storybook/global": "^5.0.0",
"@storybook/preview-api": "workspace:*",
- "@vitest/utils": "^0.34.6",
+ "@vitest/utils": "^1.3.1",
"util": "^0.12.4"
},
"devDependencies": {
diff --git a/code/lib/manager-api/package.json b/code/lib/manager-api/package.json
index 6ce5d7c94478..8832ff4bd12f 100644
--- a/code/lib/manager-api/package.json
+++ b/code/lib/manager-api/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/manager-api",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Core Storybook Manager API & Context",
"keywords": [
"storybook"
@@ -60,12 +60,10 @@
"ts-dedent": "^2.0.0"
},
"devDependencies": {
- "@jest/globals": "^29.3.1",
"@types/lodash": "^4.14.167",
"@types/qs": "^6",
"@types/semver": "^7.3.4",
"flush-promises": "^1.0.2",
- "qs": "^6.10.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"semver": "^7.3.7",
diff --git a/code/lib/manager-api/src/modules/notifications.ts b/code/lib/manager-api/src/modules/notifications.ts
index 83e95d3928ca..3358dd67a241 100644
--- a/code/lib/manager-api/src/modules/notifications.ts
+++ b/code/lib/manager-api/src/modules/notifications.ts
@@ -37,11 +37,13 @@ export const init: ModuleFn = ({ store }) => {
clearNotification: (id) => {
const { notifications } = store.getState();
- store.setState({ notifications: notifications.filter((n) => n.id !== id) });
-
const notification = notifications.find((n) => n.id === id);
- if (notification && notification.onClear) {
- notification.onClear({ dismissed: false });
+
+ if (notification) {
+ store.setState({ notifications: notifications.filter((n) => n.id !== id) });
+ if (notification.onClear) {
+ notification.onClear({ dismissed: false });
+ }
}
},
};
diff --git a/code/lib/manager-api/src/modules/refs.ts b/code/lib/manager-api/src/modules/refs.ts
index bc4b94755a53..4a5fca881f48 100644
--- a/code/lib/manager-api/src/modules/refs.ts
+++ b/code/lib/manager-api/src/modules/refs.ts
@@ -43,7 +43,7 @@ export interface SubAPI {
* @param {string} id - The ID of the composed ref.
* @param {API_ComposedRefUpdate} ref - The update object for the composed ref.
*/
- updateRef: (id: string, ref: API_ComposedRefUpdate) => void;
+ updateRef: (id: string, ref: API_ComposedRefUpdate) => Promise;
/**
* Gets all composed refs.
* @returns {API_Refs} - The composed refs object.
@@ -60,7 +60,7 @@ export interface SubAPI {
* @param {string} id - The ID of the composed ref.
* @param {string} url - The new URL for the composed ref.
*/
- changeRefVersion: (id: string, url: string) => void;
+ changeRefVersion: (id: string, url: string) => Promise;
/**
* Changes the state of a composed ref by its ID and previewInitialized flag.
* @param {string} id - The ID of the composed ref.
@@ -168,12 +168,12 @@ export const init: ModuleFn = (
return Object.values(refs).find(({ url }: any) => url.match(source));
},
- changeRefVersion: (id, url) => {
+ changeRefVersion: async (id, url) => {
const { versions, title } = api.getRefs()[id];
const ref: API_SetRefData = { id, url, versions, title, index: {}, expanded: true };
- api.setRef(id, { ...ref, type: 'unknown' }, false);
- api.checkRef(ref);
+ await api.setRef(id, { ...ref, type: 'unknown' }, false);
+ await api.checkRef(ref);
},
changeRefState: (id, previewInitialized) => {
const { [id]: ref, ...updated } = api.getRefs();
@@ -276,7 +276,7 @@ export const init: ModuleFn = (
return refs;
},
- setRef: (id, { storyIndex, setStoriesData, ...rest }, ready = false) => {
+ setRef: async (id, { storyIndex, setStoriesData, ...rest }, ready = false) => {
if (singleStory) {
return;
}
@@ -307,10 +307,10 @@ export const init: ModuleFn = (
index = addRefIds(index, ref);
}
- api.updateRef(id, { ...ref, ...rest, index, internal_index });
+ await api.updateRef(id, { ...ref, ...rest, index, internal_index });
},
- updateRef: (id, data) => {
+ updateRef: async (id, data) => {
const { [id]: ref, ...updated } = api.getRefs();
updated[id] = { ...ref, ...data };
@@ -320,7 +320,7 @@ export const init: ModuleFn = (
return obj;
}, {});
- store.setState({
+ await store.setState({
refs: ordered,
});
},
@@ -331,8 +331,11 @@ export const init: ModuleFn = (
const initialState: SubState['refs'] = refs;
if (runCheck) {
- Object.entries(refs).forEach(([id, ref]) => {
- api.checkRef({ ...ref!, stories: {} } as API_SetRefData);
+ new Promise(async (resolve) => {
+ for (const ref of Object.values(refs)) {
+ await api.checkRef({ ...ref!, stories: {} } as API_SetRefData);
+ }
+ resolve(undefined);
});
}
diff --git a/code/lib/manager-api/src/modules/whatsnew.ts b/code/lib/manager-api/src/modules/whatsnew.ts
index eeeb9558a59f..8f465325d503 100644
--- a/code/lib/manager-api/src/modules/whatsnew.ts
+++ b/code/lib/manager-api/src/modules/whatsnew.ts
@@ -92,10 +92,10 @@ export const init: ModuleFn = ({ fullAPI, store, provider }) => {
id: WHATS_NEW_NOTIFICATION_ID,
link: '/settings/whats-new',
content: {
- headline: whatsNewData.excerpt,
- subHeadline: "Click to learn what's new in Storybook",
+ headline: whatsNewData.title,
+ subHeadline: "Learn what's new in Storybook",
},
- icon: { name: 'hearthollow' },
+ icon: { name: 'storybook' },
onClear({ dismissed }: any) {
if (dismissed) {
setWhatsNewCache({ lastDismissedPost: whatsNewData.url });
diff --git a/code/lib/manager-api/src/tests/refs.test.ts b/code/lib/manager-api/src/tests/refs.test.ts
index 791325c27337..950b5e3e7a63 100644
--- a/code/lib/manager-api/src/tests/refs.test.ts
+++ b/code/lib/manager-api/src/tests/refs.test.ts
@@ -171,6 +171,9 @@ describe('Refs API', () => {
// given
initRefs({ provider, store } as any);
+ // the `runCheck` is async, so we need to wait for it to finish
+ await vi.waitFor(() => fetchMock.mock.calls.length > 0);
+
expect(fetchMock.mock.calls).toMatchInlineSnapshot(`
[
[
@@ -207,6 +210,9 @@ describe('Refs API', () => {
};
initRefs({ provider, store } as any);
+ // the `runCheck` is async, so we need to wait for it to finish
+ await vi.waitFor(() => fetchMock.mock.calls.length > 0);
+
expect(fetchMock.mock.calls).toMatchInlineSnapshot(`
[
[
diff --git a/code/lib/manager-api/src/tests/url.test.js b/code/lib/manager-api/src/tests/url.test.js
index 02048e903c37..817cb118ff41 100644
--- a/code/lib/manager-api/src/tests/url.test.js
+++ b/code/lib/manager-api/src/tests/url.test.js
@@ -1,5 +1,4 @@
import { describe, beforeEach, it, expect, vi } from 'vitest';
-import qs from 'qs';
import { SET_CURRENT_STORY, GLOBALS_UPDATED, UPDATE_QUERY_PARAMS } from '@storybook/core-events';
@@ -15,7 +14,7 @@ describe('initial state', () => {
describe('config query parameters', () => {
it('handles full parameter', () => {
const navigate = vi.fn();
- const location = { search: qs.stringify({ full: '1' }) };
+ const location = { search: new URLSearchParams({ full: '1' }).toString() };
const {
state: { layout },
@@ -30,7 +29,7 @@ describe('initial state', () => {
it('handles nav parameter', () => {
const navigate = vi.fn();
- const location = { search: qs.stringify({ nav: '0' }) };
+ const location = { search: new URLSearchParams({ nav: '0' }).toString() };
const {
state: { layout },
@@ -41,7 +40,7 @@ describe('initial state', () => {
it('handles shortcuts parameter', () => {
const navigate = vi.fn();
- const location = { search: qs.stringify({ shortcuts: '0' }) };
+ const location = { search: new URLSearchParams({ shortcuts: '0' }).toString() };
const {
state: { ui },
@@ -52,7 +51,7 @@ describe('initial state', () => {
it('handles panel parameter, bottom', () => {
const navigate = vi.fn();
- const location = { search: qs.stringify({ panel: 'bottom' }) };
+ const location = { search: new URLSearchParams({ panel: 'bottom' }).toString() };
const {
state: { layout },
@@ -63,7 +62,7 @@ describe('initial state', () => {
it('handles panel parameter, right', () => {
const navigate = vi.fn();
- const location = { search: qs.stringify({ panel: 'right' }) };
+ const location = { search: new URLSearchParams({ panel: 'right' }).toString() };
const {
state: { layout },
@@ -74,7 +73,7 @@ describe('initial state', () => {
it('handles panel parameter, 0', () => {
const navigate = vi.fn();
- const location = { search: qs.stringify({ panel: '0' }) };
+ const location = { search: new URLSearchParams({ panel: '0' }).toString() };
const {
state: { layout },
diff --git a/code/lib/manager-api/src/version.ts b/code/lib/manager-api/src/version.ts
index 7900754c895d..a6d040b0eac6 100644
--- a/code/lib/manager-api/src/version.ts
+++ b/code/lib/manager-api/src/version.ts
@@ -1 +1 @@
-export const version = '8.0.0-rc.2';
+export const version = '8.1.0-alpha.1';
diff --git a/code/lib/node-logger/package.json b/code/lib/node-logger/package.json
index eab0c64bfa00..4bbefd1d2ba4 100644
--- a/code/lib/node-logger/package.json
+++ b/code/lib/node-logger/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/node-logger",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "",
"keywords": [
"storybook"
diff --git a/code/lib/preview-api/package.json b/code/lib/preview-api/package.json
index 8706fb1e6f0e..4fb9ccb2070d 100644
--- a/code/lib/preview-api/package.json
+++ b/code/lib/preview-api/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/preview-api",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "",
"keywords": [
"storybook"
@@ -60,7 +60,6 @@
"util-deprecate": "^1.0.2"
},
"devDependencies": {
- "@jest/globals": "^29.5.0",
"@storybook/core-common": "workspace:*",
"ansi-to-html": "^0.6.11",
"slash": "^5.0.0"
diff --git a/code/lib/preview-api/src/index.ts b/code/lib/preview-api/src/index.ts
index 63d45114dc23..e47cdaa0a0dd 100644
--- a/code/lib/preview-api/src/index.ts
+++ b/code/lib/preview-api/src/index.ts
@@ -56,7 +56,6 @@ export {
filterArgTypes,
sanitizeStoryContextUpdate,
setProjectAnnotations,
- getPortableStoryWrapperId,
inferControls,
userOrAutoTitleFromSpecifier,
userOrAutoTitle,
diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts
index 0974f0908526..bee091bfda4b 100644
--- a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts
+++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts
@@ -26,10 +26,6 @@ import { normalizeProjectAnnotations } from './normalizeProjectAnnotations';
let globalProjectAnnotations: ProjectAnnotations = {};
-export function getPortableStoryWrapperId(storyId: string) {
- return `storybook-story-${storyId}`;
-}
-
export function setProjectAnnotations(
projectAnnotations: ProjectAnnotations | ProjectAnnotations[]
) {
@@ -99,11 +95,7 @@ export function composeStory = {
layout: 'fullscreen',
},
// More on argTypes: https://storybook.js.org/docs/api/argtypes
- argTypes: {
- onLogin: { action: 'onLogin' },
- onLogout: { action: 'onLogout' },
- onCreateAccount: { action: 'onCreateAccount' },
+ args: {
+ onLogin: fn(),
+ onLogout: fn(),
+ onCreateAccount: fn(),
},
};
diff --git a/code/renderers/html/template/cli/ts-4-9/Header.stories.ts b/code/renderers/html/template/cli/ts-4-9/Header.stories.ts
index 7570a625a869..189c6c8abebd 100644
--- a/code/renderers/html/template/cli/ts-4-9/Header.stories.ts
+++ b/code/renderers/html/template/cli/ts-4-9/Header.stories.ts
@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from '@storybook/html';
+import { fn } from '@storybook/test';
import type { HeaderProps } from './Header';
import { createHeader } from './Header';
@@ -12,10 +13,10 @@ const meta = {
layout: 'fullscreen',
},
// More on argTypes: https://storybook.js.org/docs/api/argtypes
- argTypes: {
- onLogin: { action: 'onLogin' },
- onLogout: { action: 'onLogout' },
- onCreateAccount: { action: 'onCreateAccount' },
+ args: {
+ onLogin: fn(),
+ onLogout: fn(),
+ onCreateAccount: fn(),
},
} satisfies Meta;
diff --git a/code/renderers/preact/package.json b/code/renderers/preact/package.json
index 964a280e875c..ff6217b7121f 100644
--- a/code/renderers/preact/package.json
+++ b/code/renderers/preact/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/preact",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook Preact renderer",
"keywords": [
"storybook"
diff --git a/code/renderers/preact/template/cli/Header.stories.jsx b/code/renderers/preact/template/cli/Header.stories.jsx
index 58b353a57db2..160f7fdff166 100644
--- a/code/renderers/preact/template/cli/Header.stories.jsx
+++ b/code/renderers/preact/template/cli/Header.stories.jsx
@@ -1,3 +1,4 @@
+import { fn } from '@storybook/test';
import { Header } from './Header';
export default {
@@ -9,10 +10,10 @@ export default {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
layout: 'fullscreen',
},
- argTypes: {
- onLogin: { action: 'onLogin' },
- onLogout: { action: 'onLogout' },
- onCreateAccount: { action: 'onCreateAccount' },
+ args: {
+ onLogin: fn(),
+ onLogout: fn(),
+ onCreateAccount: fn(),
},
};
diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json
index a42882c38ebf..08ace69c3cba 100644
--- a/code/renderers/react/package.json
+++ b/code/renderers/react/package.json
@@ -1,6 +1,6 @@
{
"name": "@storybook/react",
- "version": "8.0.0-rc.2",
+ "version": "8.1.0-alpha.1",
"description": "Storybook React renderer",
"keywords": [
"storybook"
diff --git a/code/renderers/react/src/__test__/__snapshots__/portable-stories.test.tsx.snap b/code/renderers/react/src/__test__/__snapshots__/portable-stories.test.tsx.snap
index 2779b21001ab..ce16b3dc224e 100644
--- a/code/renderers/react/src/__test__/__snapshots__/portable-stories.test.tsx.snap
+++ b/code/renderers/react/src/__test__/__snapshots__/portable-stories.test.tsx.snap
@@ -3,17 +3,12 @@
exports[`Renders CSF2Secondary story 1`] = `
-
-
-
+ Children coming from story args!
+
`;
@@ -21,17 +16,12 @@ exports[`Renders CSF2Secondary story 1`] = `
exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = `
-
-
-
+ foo
+
`;
@@ -39,17 +29,12 @@ exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = `
exports[`Renders CSF3Button story 1`] = `
-
-
-
+ foo
+
`;
@@ -57,23 +42,18 @@ exports[`Renders CSF3Button story 1`] = `
exports[`Renders CSF3ButtonWithRender story 1`] = `
-
-
-
- I am a custom render function
-
-
-
+
+
+ I am a custom render function
+
+
@@ -82,14 +62,9 @@ exports[`Renders CSF3ButtonWithRender story 1`] = `
exports[`Renders CSF3InputFieldFilled story 1`] = `
-
-
-
+
`;
@@ -97,17 +72,12 @@ exports[`Renders CSF3InputFieldFilled story 1`] = `
exports[`Renders CSF3Primary story 1`] = `
-
-
-
+ foo
+
`;
@@ -115,21 +85,16 @@ exports[`Renders CSF3Primary story 1`] = `
exports[`Renders LoaderStory story 1`] = `
-
-
-
- loaded data
-
-
- mockFn return value
-
+
+
+ loaded data
+
+
+ mockFn return value
diff --git a/code/renderers/react/src/docs/jsxDecorator.test.tsx b/code/renderers/react/src/docs/jsxDecorator.test.tsx
index bfb20fdd5f0d..6ed0f0eda179 100644
--- a/code/renderers/react/src/docs/jsxDecorator.test.tsx
+++ b/code/renderers/react/src/docs/jsxDecorator.test.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable no-underscore-dangle */
import type { FC, PropsWithChildren } from 'react';
import React, { StrictMode, createElement, Profiler } from 'react';
import type { Mock } from 'vitest';
@@ -5,7 +6,7 @@ import { vi, describe, it, expect, beforeEach } from 'vitest';
import PropTypes from 'prop-types';
import { addons, useEffect } from '@storybook/preview-api';
import { SNIPPET_RENDERED } from '@storybook/docs-tools';
-import { renderJsx, jsxDecorator } from './jsxDecorator';
+import { renderJsx, jsxDecorator, getReactSymbolName } from './jsxDecorator';
vi.mock('@storybook/preview-api');
const mockedAddons = vi.mocked(addons);
@@ -16,6 +17,18 @@ expect.addSnapshotSerializer({
test: (val) => typeof val === 'string',
});
+describe('converts React Symbol to displayName string', () => {
+ const symbolCases = [
+ ['react.suspense', 'React.Suspense'],
+ ['react.strict_mode', 'React.StrictMode'],
+ ['react.server_context.defaultValue', 'React.ServerContext.DefaultValue'],
+ ];
+
+ it.each(symbolCases)('"%s" to "%s"', (symbol, expectedValue) => {
+ expect(getReactSymbolName(Symbol(symbol))).toEqual(expectedValue);
+ });
+});
+
describe('renderJsx', () => {
it('basic', () => {
expect(renderJsx(