diff --git a/CHANGELOG.md b/CHANGELOG.md index 5143f97018fe..7b3dd726dbd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.2.4 + +- CLI: Add diagnostic when the `storybook` package is missing - [#28604](https://github.com/storybookjs/storybook/pull/28604), thanks @kasperpeulen! +- CLI: Make a few automigrations run on all version upgrades - [#28601](https://github.com/storybookjs/storybook/pull/28601), thanks @yannbf! +- CPC: Direct dependencies on shim packages in renderers - [#28599](https://github.com/storybookjs/storybook/pull/28599), thanks @ndelangen! + ## 8.2.3 - Bug: Fix invalid docs links in Configure.mdx template page - [#28560](https://github.com/storybookjs/storybook/pull/28560), thanks @kylegach! diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index 452768602a10..c77cec1c61b7 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,16 @@ +## 8.3.0-alpha.2 + +- Addon-Interactions: Fix status in panel tab - [#28580](https://github.com/storybookjs/storybook/pull/28580), thanks @yannbf! +- Build: Remove external overrides, use package.json as source of truth - [#28632](https://github.com/storybookjs/storybook/pull/28632), thanks @kasperpeulen! +- CLI: Add conditional logging for manager and preview start - [#28603](https://github.com/storybookjs/storybook/pull/28603), thanks @tobiasdiez! +- CPC: Add the globals export for manager - [#28650](https://github.com/storybookjs/storybook/pull/28650), thanks @ndelangen! +- CPC: Correct path to the `@storybook/theming/create` alias - [#28643](https://github.com/storybookjs/storybook/pull/28643), thanks @Averethel! +- Core: Fix manager-builder `tsconfig` to emit `react-jsx` - [#28541](https://github.com/storybookjs/storybook/pull/28541), thanks @williamhelmrath! +- Fix: Add header for MountMustBeDestructuredError message - [#28590](https://github.com/storybookjs/storybook/pull/28590), thanks @0916dhkim! +- Fix: Prevent iframe from capturing mouse events in composed Storybooks - [#28568](https://github.com/storybookjs/storybook/pull/28568), thanks @Vincentdevreede! +- Onboarding: Fix code snippet when story name differs from export name - [#28649](https://github.com/storybookjs/storybook/pull/28649), thanks @ghengeveld! +- Vue: Fix out of memory error when using vue-component-meta - [#28589](https://github.com/storybookjs/storybook/pull/28589), thanks @larsrickert! + ## 8.3.0-alpha.1 - Bug: Fix invalid docs links in Configure.mdx template page - [#28560](https://github.com/storybookjs/storybook/pull/28560), thanks @kylegach! diff --git a/code/addons/docs/src/preset.ts b/code/addons/docs/src/preset.ts index 0ad19b34bd58..8d359204c227 100644 --- a/code/addons/docs/src/preset.ts +++ b/code/addons/docs/src/preset.ts @@ -68,11 +68,11 @@ async function webpack( * * In the future the `@storybook/theming` and `@storybook/components` can be removed, as they should be singletons in the future due to the peerDependency on `storybook` package. */ - const cliPath = require.resolve('storybook/package.json'); - const themingPath = join(cliPath, '..', 'core', 'theming', 'index.js'); + const cliPath = dirname(require.resolve('storybook/package.json')); + const themingPath = join(cliPath, 'core', 'theming', 'index.js'); const themingCreatePath = join(cliPath, 'core', 'theming', 'create.js'); - const componentsPath = join(cliPath, '..', 'core', 'components', 'index.js'); + const componentsPath = join(cliPath, 'core', 'components', 'index.js'); const blocksPath = dirname(require.resolve('@storybook/blocks/package.json')); if (Array.isArray(webpackConfig.resolve?.alias)) { alias = [...webpackConfig.resolve?.alias]; diff --git a/code/addons/interactions/src/Panel.tsx b/code/addons/interactions/src/Panel.tsx index 490d1df1564c..f6e1b06b8619 100644 --- a/code/addons/interactions/src/Panel.tsx +++ b/code/addons/interactions/src/Panel.tsx @@ -180,13 +180,13 @@ export const Panel = memo<{ storyId: string }>(function PanelMemoized({ storyId }); }, [STORY_THREW_EXCEPTION]: () => { - set((s) => ({ ...s, isErrored: true })); + set((s) => ({ ...s, isErrored: true, hasException: true })); }, [PLAY_FUNCTION_THREW_EXCEPTION]: (e) => { - set((s) => ({ ...s, caughtException: e })); + set((s) => ({ ...s, caughtException: e, hasException: true })); }, [UNHANDLED_ERRORS_WHILE_PLAYING]: (e) => { - set((s) => ({ ...s, unhandledErrors: e })); + set((s) => ({ ...s, unhandledErrors: e, hasException: true })); }, }, [collapsed] diff --git a/code/addons/interactions/src/components/TabStatus.tsx b/code/addons/interactions/src/components/TabStatus.tsx deleted file mode 100644 index fc2390b5c823..000000000000 --- a/code/addons/interactions/src/components/TabStatus.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { styled } from 'storybook/internal/theming'; - -import { StatusIcon } from './StatusIcon'; - -export const TabIcon = styled(StatusIcon)({ - marginLeft: 5, -}); diff --git a/code/addons/interactions/src/manager.tsx b/code/addons/interactions/src/manager.tsx index 88b20d1d8bb1..2de5d48d8fa6 100644 --- a/code/addons/interactions/src/manager.tsx +++ b/code/addons/interactions/src/manager.tsx @@ -2,10 +2,8 @@ import React, { useCallback } from 'react'; import type { Combo } from 'storybook/internal/manager-api'; import { addons, Consumer, types, useAddonState } from 'storybook/internal/manager-api'; import { AddonPanel, Badge, Spaced } from 'storybook/internal/components'; -import { CallStates } from '@storybook/instrumenter'; import { ADDON_ID, PANEL_ID } from './constants'; import { Panel } from './Panel'; -import { TabIcon } from './components/TabStatus'; function Title() { const [addonState = {}] = useAddonState(ADDON_ID); @@ -18,7 +16,7 @@ function Title() { {interactionsCount && !hasException ? ( {interactionsCount} ) : null} - {hasException ? : null} + {hasException ? {interactionsCount} : null} ); diff --git a/code/addons/onboarding/src/Onboarding.tsx b/code/addons/onboarding/src/Onboarding.tsx index e387659cf7ce..fde1526aa483 100644 --- a/code/addons/onboarding/src/Onboarding.tsx +++ b/code/addons/onboarding/src/Onboarding.tsx @@ -75,6 +75,7 @@ export default function Onboarding({ api }: { api: API }) { const [createNewStoryForm, setCreateNewStoryForm] = useState(); const [createdStory, setCreatedStory] = useState<{ newStoryName: string; + newStoryExportName: string; sourceFileContent: string; sourceFileName: string; } | null>(); @@ -158,8 +159,8 @@ export default function Onboarding({ api }: { api: API }) { } const source = createdStory?.sourceFileContent; - const startIndex = source?.lastIndexOf(`export const ${createdStory?.newStoryName}`); - const snippet = source?.slice(startIndex); + const startIndex = source?.lastIndexOf(`export const ${createdStory?.newStoryExportName}`); + const snippet = source?.slice(startIndex).trim(); const startingLineNumber = source?.slice(0, startIndex).split('\n').length; const steps: StepDefinition[] = [ diff --git a/code/core/assets/server/addon.tsconfig.json b/code/core/assets/server/addon.tsconfig.json index 38452bcdfa20..9161d5ff8254 100644 --- a/code/core/assets/server/addon.tsconfig.json +++ b/code/core/assets/server/addon.tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "jsx": "react", + "jsx": "react-jsx", "jsxImportSource": "react" } } diff --git a/code/core/package.json b/code/core/package.json index 5fd58d2a95fc..3b545da0b3e0 100644 --- a/code/core/package.json +++ b/code/core/package.json @@ -142,6 +142,11 @@ "import": "./dist/manager/globals-module-info.js", "require": "./dist/manager/globals-module-info.cjs" }, + "./manager/globals": { + "types": "./dist/manager/globals.d.ts", + "import": "./dist/manager/globals.js", + "require": "./dist/manager/globals.cjs" + }, "./preview/globals": { "types": "./dist/preview/globals.d.ts", "import": "./dist/preview/globals.js", @@ -229,6 +234,9 @@ "manager/globals-module-info": [ "./dist/manager/globals-module-info.d.ts" ], + "manager/globals": [ + "./dist/manager/globals.d.ts" + ], "preview/globals": [ "./dist/preview/globals.d.ts" ] diff --git a/code/core/scripts/entries.ts b/code/core/scripts/entries.ts index 85297c1b0c56..a618dac3b623 100644 --- a/code/core/scripts/entries.ts +++ b/code/core/scripts/entries.ts @@ -28,17 +28,13 @@ export const getEntries = (cwd: string) => { define('src/preview-api/index.ts', ['browser', 'node'], true), define('src/manager-api/index.ts', ['browser', 'node'], true, ['react']), define('src/router/index.ts', ['browser', 'node'], true, ['react']), - define('src/components/index.ts', ['browser', 'node'], true, [ - 'react', - 'react-dom', - '@storybook/csf', - '@storybook/global', - ]), + define('src/components/index.ts', ['browser', 'node'], true, ['react', 'react-dom']), define('src/theming/index.ts', ['browser', 'node'], true, ['react']), define('src/theming/create.ts', ['browser', 'node'], true, ['react']), define('src/docs-tools/index.ts', ['browser', 'node'], true), define('src/manager/globals-module-info.ts', ['node'], true), + define('src/manager/globals.ts', ['node'], true), define('src/preview/globals.ts', ['node'], true), ]; }; diff --git a/code/core/src/builder-manager/index.ts b/code/core/src/builder-manager/index.ts index c6b5840fb3ff..01755fbdef2c 100644 --- a/code/core/src/builder-manager/index.ts +++ b/code/core/src/builder-manager/index.ts @@ -126,7 +126,9 @@ const starter: StarterFunction = async function* starterGeneratorFn({ options, router, }) { - logger.info('=> Starting manager..'); + if (!options.quiet) { + logger.info('=> Starting manager..'); + } const { config, diff --git a/code/core/src/core-events/data/save-story.ts b/code/core/src/core-events/data/save-story.ts index 8bb4091e513e..0162ecdb0819 100644 --- a/code/core/src/core-events/data/save-story.ts +++ b/code/core/src/core-events/data/save-story.ts @@ -9,7 +9,9 @@ export interface SaveStoryResponsePayload { csfId: string; newStoryId?: string; newStoryName?: string; + newStoryExportName?: string; sourceFileContent?: string; sourceFileName?: string; sourceStoryName?: string; + sourceStoryExportName?: string; } diff --git a/code/core/src/core-server/dev-server.ts b/code/core/src/core-server/dev-server.ts index 1a8935d19a3a..1639e754fe04 100644 --- a/code/core/src/core-server/dev-server.ts +++ b/code/core/src/core-server/dev-server.ts @@ -95,7 +95,9 @@ export async function storybookDevServer(options: Options) { let previewStarted: Promise = Promise.resolve(); if (!options.ignorePreview) { - logger.info('=> Starting preview..'); + if (!options.quiet) { + logger.info('=> Starting preview..'); + } previewStarted = previewBuilder .start({ startTime: process.hrtime(), diff --git a/code/core/src/core-server/utils/save-story/save-story.ts b/code/core/src/core-server/utils/save-story/save-story.ts index 8ad7ef738ff3..5369d99a4cba 100644 --- a/code/core/src/core-server/utils/save-story/save-story.ts +++ b/code/core/src/core-server/utils/save-story/save-story.ts @@ -111,9 +111,11 @@ export function initializeSaveStory(channel: Channel, options: Options, coreConf csfId, newStoryId, newStoryName, + newStoryExportName: name, sourceFileContent: code, sourceFileName, sourceStoryName, + sourceStoryExportName: storyName, }, error: null, } satisfies ResponseData); diff --git a/code/core/src/manager/components/layout/useDragging.ts b/code/core/src/manager/components/layout/useDragging.ts index 4711354153b3..1c00f516c234 100644 --- a/code/core/src/manager/components/layout/useDragging.ts +++ b/code/core/src/manager/components/layout/useDragging.ts @@ -37,7 +37,7 @@ export function useDragging({ useEffect(() => { const panelResizer = panelResizerRef.current; const sidebarResizer = sidebarResizerRef.current; - const previewIframe = document.querySelector('#storybook-preview-iframe') as HTMLIFrameElement; + const previewIframe = document.querySelector('#storybook-preview-wrapper') as HTMLIFrameElement; let draggedElement: typeof panelResizer | typeof sidebarResizer | null = null; const onDragStart = (e: MouseEvent) => { diff --git a/code/core/src/preview-errors.ts b/code/core/src/preview-errors.ts index 31341bb6132c..c1d070f7c10a 100644 --- a/code/core/src/preview-errors.ts +++ b/code/core/src/preview-errors.ts @@ -214,6 +214,7 @@ export class MountMustBeDestructuredError extends StorybookError { category: Category.PREVIEW_API, code: 12, message: dedent` + Incorrect use of mount in the play function. To use mount in the play function, you must satisfy the following two requirements: diff --git a/code/deprecated/manager/globals.js b/code/deprecated/manager/globals.js new file mode 100644 index 000000000000..d6ee8ec2d144 --- /dev/null +++ b/code/deprecated/manager/globals.js @@ -0,0 +1 @@ +module.exports = require('storybook/internal/manager/globals'); diff --git a/code/deprecated/preview/globals.js b/code/deprecated/preview/globals.js new file mode 100644 index 000000000000..91340ce6505b --- /dev/null +++ b/code/deprecated/preview/globals.js @@ -0,0 +1 @@ +module.exports = require('storybook/internal/preview/globals'); diff --git a/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts b/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts index 54ac30cbb9dd..a263635a44f8 100644 --- a/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts +++ b/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts @@ -50,6 +50,26 @@ export async function vueComponentMeta(tsconfigPath = 'tsconfig.json'): Promise< const exportName = exportNames[index]; + // we remove nested object schemas here since they are not used inside Storybook (we don't generate controls for object properties) + // and they can cause "out of memory" issues for large/complex schemas (e.g. HTMLElement) + // it also reduced the bundle size when running "Storybook build" when such schemas are used + (['props', 'exposed'] as const).forEach((key) => { + meta[key].forEach((value) => { + if (typeof value.schema !== 'object') return; + + // we need to use Object.defineProperty here since schema is a getter so we can not set it directly + Object.defineProperty(value, 'schema', { + configurable: true, + enumerable: true, + value: { + kind: value.schema.kind, + type: value.schema.type, + // note that value.schema.schema is not included here (see comment above) + }, + }); + }); + }); + const exposed = // the meta also includes duplicated entries in the "exposed" array with "on" // prefix (e.g. onClick instead of click), so we need to filter them out here diff --git a/code/lib/cli/core/manager/globals.cjs b/code/lib/cli/core/manager/globals.cjs new file mode 100644 index 000000000000..3dc797bf4cd7 --- /dev/null +++ b/code/lib/cli/core/manager/globals.cjs @@ -0,0 +1 @@ +module.exports = require('@storybook/core/manager/globals'); diff --git a/code/lib/cli/core/manager/globals.d.ts b/code/lib/cli/core/manager/globals.d.ts new file mode 100644 index 000000000000..47746a38ada4 --- /dev/null +++ b/code/lib/cli/core/manager/globals.d.ts @@ -0,0 +1,2 @@ +export * from '@storybook/core/manager/globals'; +export type * from '@storybook/core/manager/globals'; diff --git a/code/lib/cli/core/manager/globals.js b/code/lib/cli/core/manager/globals.js new file mode 100644 index 000000000000..779828900cda --- /dev/null +++ b/code/lib/cli/core/manager/globals.js @@ -0,0 +1 @@ +export * from '@storybook/core/manager/globals'; diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 7f78b60ee29b..dbe07f1e4de8 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -167,6 +167,11 @@ "types": "./core/preview/globals.d.ts", "import": "./core/preview/globals.js", "require": "./core/preview/globals.cjs" + }, + "./internal/manager/globals": { + "types": "./core/manager/globals.d.ts", + "import": "./core/manager/globals.js", + "require": "./core/manager/globals.cjs" } }, "main": "dist/index.cjs", @@ -219,6 +224,9 @@ "internal/manager-errors": [ "./core/manager-errors.d.ts" ], + "internal/manager/globals": [ + "./core/manager/globals.d.ts" + ], "internal/manager/globals-module-info": [ "./core/manager/globals-module-info.d.ts" ], diff --git a/code/package.json b/code/package.json index 8b3f199748e1..8512ebb34cde 100644 --- a/code/package.json +++ b/code/package.json @@ -278,5 +278,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.3.0-alpha.2" } diff --git a/code/renderers/vue3/src/docs/__snapshots__/extractArgTypes.test.ts.snap b/code/renderers/vue3/src/docs/__snapshots__/extractArgTypes.test.ts.snap index cbe74a47b7d6..39e2654bcff4 100644 --- a/code/renderers/vue3/src/docs/__snapshots__/extractArgTypes.test.ts.snap +++ b/code/renderers/vue3/src/docs/__snapshots__/extractArgTypes.test.ts.snap @@ -157,12 +157,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1 "value": { "name": "object", "required": false, - "value": { - "nestedProp": { - "name": "string", - "required": true, - }, - }, + "value": {}, }, }, }, @@ -183,12 +178,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1 "value": { "name": "object", "required": false, - "value": { - "nestedProp": { - "name": "string", - "required": true, - }, - }, + "value": {}, }, }, }, @@ -279,12 +269,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1 "type": { "name": "object", "required": true, - "value": { - "foo": { - "name": "string", - "required": true, - }, - }, + "value": {}, }, }, "literalFromContext": { @@ -325,12 +310,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1 "type": { "name": "object", "required": true, - "value": { - "nestedProp": { - "name": "string", - "required": true, - }, - }, + "value": {}, }, }, "nestedIntersection": { @@ -347,16 +327,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1 "type": { "name": "object", "required": true, - "value": { - "additionalProp": { - "name": "string", - "required": true, - }, - "nestedProp": { - "name": "string", - "required": true, - }, - }, + "value": {}, }, }, "nestedOptional": { @@ -377,22 +348,12 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1 { "name": "object", "required": false, - "value": { - "nestedProp": { - "name": "string", - "required": true, - }, - }, + "value": {}, }, { "name": "object", "required": false, - "value": { - "nestedProp": { - "name": "string", - "required": true, - }, - }, + "value": {}, }, ], }, @@ -411,13 +372,7 @@ exports[`extractArgTypes (vue-docgen-api) > should extract props for component 1 "type": { "name": "object", "required": false, - "value": { - "recursive": { - "name": "other", - "required": true, - "value": "MyNestedRecursiveProps", - }, - }, + "value": {}, }, }, "stringArray": { diff --git a/code/renderers/vue3/src/docs/extractArgTypes.ts b/code/renderers/vue3/src/docs/extractArgTypes.ts index 76c52cc755a7..31f4d19dc163 100644 --- a/code/renderers/vue3/src/docs/extractArgTypes.ts +++ b/code/renderers/vue3/src/docs/extractArgTypes.ts @@ -1,3 +1,4 @@ +import type { VueDocgenInfo, VueDocgenInfoEntry, VueDocgenPlugin } from '@storybook/vue3-vite'; import type { ExtractedProp } from 'storybook/internal/docs-tools'; import { convert, @@ -6,7 +7,6 @@ import { type ArgTypesExtractor, } from 'storybook/internal/docs-tools'; import type { SBType, StrictArgTypes, StrictInputType } from 'storybook/internal/types'; -import type { VueDocgenInfo, VueDocgenInfoEntry, VueDocgenPlugin } from '@storybook/vue3-vite'; type PropertyMetaSchema = VueDocgenInfoEntry<'vue-component-meta', 'props'>['schema']; @@ -283,17 +283,12 @@ export const convertVueComponentMetaProp = ( }; } - // recursively/deeply convert all properties of the object case 'object': return { name: 'object', - value: Object.entries(schema.schema ?? {}).reduce>( - (obj, [propName, propSchema]) => { - obj[propName] = convertVueComponentMetaProp(propSchema); - return obj; - }, - {} - ), + // while Storybook generates simple JSON object controls, nested schemas don't have specialized controls + // so we don't need to recursively map the object schema here + value: {}, required, }; diff --git a/docs/versions/next.json b/docs/versions/next.json index 6a3a45eedc89..f2daa3fb9b6b 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.3.0-alpha.1","info":{"plain":"- Bug: Fix invalid docs links in Configure.mdx template page - [#28560](https://github.com/storybookjs/storybook/pull/28560), thanks @kylegach!\n- CLI: Add \\\"missing-storybook-dependencies\\\" automigration - [#28579](https://github.com/storybookjs/storybook/pull/28579), thanks @yannbf!\n- CLI: Add diagnostic when the `storybook` package is missing - [#28604](https://github.com/storybookjs/storybook/pull/28604), thanks @kasperpeulen!\n- CLI: Make a few automigrations run on all version upgrades - [#28601](https://github.com/storybookjs/storybook/pull/28601), thanks @yannbf!\n- CPC: Add `theming/create` aliases in docs preset - [#28570](https://github.com/storybookjs/storybook/pull/28570), thanks @ndelangen!\n- CPC: Direct dependencies on shim packages in renderers - [#28599](https://github.com/storybookjs/storybook/pull/28599), thanks @ndelangen!\n- CPC: Fix Vite builder had wrong conditions - [#28581](https://github.com/storybookjs/storybook/pull/28581), thanks @ndelangen!\n- CPC: Fix incorrect re-export in `core-events` - [#28573](https://github.com/storybookjs/storybook/pull/28573), thanks @ndelangen!\n- CSF: Fix small typing issue - [#28587](https://github.com/storybookjs/storybook/pull/28587), thanks @valentinpalkovic!\n- Core: Upgrade docs-mdx for smaller install - [#28552](https://github.com/storybookjs/storybook/pull/28552), thanks @shilman!\n- Portable stories: Remove unused types - [#28548](https://github.com/storybookjs/storybook/pull/28548), thanks @kasperpeulen!\n- Webpack: Fix sourceMap generation in csf-tools - [#28585](https://github.com/storybookjs/storybook/pull/28585), thanks @valentinpalkovic!"}} +{"version":"8.3.0-alpha.2","info":{"plain":"- Addon-Interactions: Fix status in panel tab - [#28580](https://github.com/storybookjs/storybook/pull/28580), thanks @yannbf!\n- Build: Remove external overrides, use package.json as source of truth - [#28632](https://github.com/storybookjs/storybook/pull/28632), thanks @kasperpeulen!\n- CLI: Add conditional logging for manager and preview start - [#28603](https://github.com/storybookjs/storybook/pull/28603), thanks @tobiasdiez!\n- CPC: Add the globals export for manager - [#28650](https://github.com/storybookjs/storybook/pull/28650), thanks @ndelangen!\n- CPC: Correct path to the `@storybook/theming/create` alias - [#28643](https://github.com/storybookjs/storybook/pull/28643), thanks @Averethel!\n- Core: Fix manager-builder `tsconfig` to emit `react-jsx` - [#28541](https://github.com/storybookjs/storybook/pull/28541), thanks @williamhelmrath!\n- Fix: Add header for MountMustBeDestructuredError message - [#28590](https://github.com/storybookjs/storybook/pull/28590), thanks @0916dhkim!\n- Fix: Prevent iframe from capturing mouse events in composed Storybooks - [#28568](https://github.com/storybookjs/storybook/pull/28568), thanks @Vincentdevreede!\n- Onboarding: Fix code snippet when story name differs from export name - [#28649](https://github.com/storybookjs/storybook/pull/28649), thanks @ghengeveld!\n- Vue: Fix out of memory error when using vue-component-meta - [#28589](https://github.com/storybookjs/storybook/pull/28589), thanks @larsrickert!"}}