diff --git a/CHANGELOG.md b/CHANGELOG.md
index c78e29fa62ae..2de9a1f7882f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 8.0.5
+
+- Addon-docs: Fix `react-dom/server` imports breaking stories and docs - [#26557](https://github.com/storybookjs/storybook/pull/26557), thanks @JReinhold!
+- Automigrations: Fix missing support for mts vite config - [#26441](https://github.com/storybookjs/storybook/pull/26441), thanks @drik98!
+- CLI: Improve Yarn berry error parsing - [#26616](https://github.com/storybookjs/storybook/pull/26616), thanks @yannbf!
+- React-Docgen: Make sure to be able to handle empty unions - [#26639](https://github.com/storybookjs/storybook/pull/26639), thanks @kasperpeulen!
+- Viewport: Fix missing style - [#26530](https://github.com/storybookjs/storybook/pull/26530), thanks @jpzwarte!
+
## 8.0.4
- Addon Docs: Support Stencil based display names in source snippets - [#26592](https://github.com/storybookjs/storybook/pull/26592), thanks @yannbf!
diff --git a/code/addons/docs/src/preset.ts b/code/addons/docs/src/preset.ts
index 68c7efb39f8b..31248e7af990 100644
--- a/code/addons/docs/src/preset.ts
+++ b/code/addons/docs/src/preset.ts
@@ -1,4 +1,4 @@
-import { dirname, join } from 'path';
+import { dirname, join, isAbsolute } from 'path';
import rehypeSlug from 'rehype-slug';
import rehypeExternalLinks from 'rehype-external-links';
@@ -147,6 +147,8 @@ export const viteFinal = async (config: any, options: Options) => {
resolve: {
alias: {
react,
+ // Vite doesn't respect export maps when resolving an absolute path, so we need to do that manually here
+ ...(isAbsolute(reactDom) && { 'react-dom/server': `${reactDom}/server.browser.js` }),
'react-dom': reactDom,
'@mdx-js/react': mdx,
/**
diff --git a/code/addons/docs/template/stories/docs2/ResolvedReact.jsx b/code/addons/docs/template/stories/docs2/ResolvedReact.jsx
new file mode 100644
index 000000000000..f16c20f04fce
--- /dev/null
+++ b/code/addons/docs/template/stories/docs2/ResolvedReact.jsx
@@ -0,0 +1,28 @@
+import React, * as ReactExport from 'react';
+import * as ReactDom from 'react-dom';
+import * as ReactDomServer from 'react-dom/server';
+
+export const ResolvedReact = () => {
+ return (
+ <>
+
+ react:{' '}
+
+ {ReactExport.version ?? 'no version export found'}
+
+
+
+ react-dom:{' '}
+
+ {ReactDom.version ?? 'no version export found'}
+
+
+
+ react-dom/server:{' '}
+
+ {ReactDomServer.version ?? 'no version export found'}
+
+
+ >
+ );
+};
diff --git a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx
index 7a5f04ab6bc8..bd3ad01c2e08 100644
--- a/code/addons/docs/template/stories/docs2/ResolvedReact.mdx
+++ b/code/addons/docs/template/stories/docs2/ResolvedReact.mdx
@@ -1,13 +1,29 @@
-import { version as reactVersion } from 'react';
-import { version as reactDomVersion } from 'react-dom';
-import { ResolvedReactVersion } from './ResolvedReactVersion';
+import { Meta } from '@storybook/blocks';
+import * as ReactExport from 'react';
+import * as ReactDom from 'react-dom';
+import * as ReactDomServer from 'react-dom/server';
+import { ResolvedReact } from './ResolvedReact';
+
+
+
+This doc is used to display the resolved version of React and its related packages.
+As long as `@storybook/addon-docs` is installed, `react` and `react-dom` should be available to import from and should resolve to the same version.
+
+The MDX here ensures that it works in an MDX file.
+
+- See the [autodocs](/docs/addons-docs-docs2-resolvedreact--docs) for how it resolves in autodocs.
+- See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story.
+
+**Note: There appears to be a bug in the _production_ build of `react-dom`, where it reports version `18.2.0-next-9e3b772b8-20220608` while in fact version `18.2.0` is installed.**
## In MDX
-react: {reactVersion}
+react: {ReactExport.version ?? 'no version export found'}
+
+react-dom: {ReactDom.version ?? 'no version export found'}
-react-dom: {reactDomVersion}
+react-dom/server: {ReactDomServer.version ?? 'no version export found'}
-## In `ResolvedReactVersion` component
+## In `ResolvedReact` component
-
+
diff --git a/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx b/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx
deleted file mode 100644
index 6e094c1e64d0..000000000000
--- a/code/addons/docs/template/stories/docs2/ResolvedReactVersion.jsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React, { version as reactVersion } from 'react';
-import { version as reactDomVersion } from 'react-dom';
-
-export const ResolvedReactVersion = () => {
- return (
- <>
-
- react: {reactVersion}
-
-
- react-dom: {reactDomVersion}
-
- >
- );
-};
diff --git a/code/addons/docs/template/stories/docs2/resolved-react.stories.ts b/code/addons/docs/template/stories/docs2/resolved-react.stories.ts
new file mode 100644
index 000000000000..91f12041962b
--- /dev/null
+++ b/code/addons/docs/template/stories/docs2/resolved-react.stories.ts
@@ -0,0 +1,70 @@
+import { within, expect } from '@storybook/test';
+import * as ReactExport from 'react';
+import * as ReactDom from 'react-dom';
+import * as ReactDomServer from 'react-dom/server';
+
+/**
+ * This component is used to display the resolved version of React and its related packages.
+ * As long as `@storybook/addon-docs` is installed, `react` and `react-dom` should be available to import from and should resolve to the same version.
+ *
+ * The autodocs here ensures that it also works in the generated documentation.
+ *
+ * - See the [MDX docs](/docs/addons-docs-docs2-resolvedreact--mdx) for how it resolves in MDX.
+ * - See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story.
+ *
+ * **Note: There appears to be a bug in the _production_ build of `react-dom`, where it reports version `18.2.0-next-9e3b772b8-20220608` while in fact version `18.2.0` is installed.**
+ */
+export default {
+ title: 'Docs2/ResolvedReact',
+ component: globalThis.Components.Html,
+ tags: ['autodocs'],
+ argTypes: {
+ content: { table: { disable: true } },
+ },
+ args: {
+ content: `
+
+ react: ${
+ ReactExport.version ?? 'no version export found'
+ }
+
+
+ react-dom: ${
+ ReactDom.version ?? 'no version export found'
+ }
+
+
+ react-dom/server: ${
+ ReactDomServer.version ?? 'no version export found'
+ }
+
+ `,
+ },
+ parameters: {
+ docs: {
+ name: 'ResolvedReact',
+ },
+ },
+};
+
+export const Story = {
+ // This test is more or less the same as the E2E test we have for MDX and autodocs entries in addon-docs.spec.ts
+ play: async ({ canvasElement, step, parameters }: any) => {
+ const canvas = await within(canvasElement);
+
+ const actualReactVersion = (await canvas.findByTestId('react')).textContent;
+ const actualReactDomVersion = (await canvas.findByTestId('react-dom')).textContent;
+ const actualReactDomServerVersion = (await canvas.findByTestId('react-dom-server')).textContent;
+
+ step('Expect React packages to all resolve to the same version', () => {
+ // react-dom has a bug in its production build, reporting version 18.2.0-next-9e3b772b8-20220608 even though version 18.2.0 is installed.
+ expect(actualReactDomVersion!.startsWith(actualReactVersion!)).toBeTruthy();
+
+ if (parameters.renderer === 'preact') {
+ // the preact/compat alias doesn't have a version export in react-dom/server
+ return;
+ }
+ expect(actualReactDomServerVersion).toBe(actualReactVersion);
+ });
+ },
+};
diff --git a/code/addons/viewport/src/Tool.tsx b/code/addons/viewport/src/Tool.tsx
index 37bc22500e9b..da600e576675 100644
--- a/code/addons/viewport/src/Tool.tsx
+++ b/code/addons/viewport/src/Tool.tsx
@@ -74,6 +74,7 @@ const flip = ({ width, height, ...styles }: ViewportStyles) => ({
const ActiveViewportSize = styled.div(() => ({
display: 'inline-flex',
+ alignItems: 'center',
}));
const ActiveViewportLabel = styled.div(({ theme }) => ({
diff --git a/code/e2e-tests/addon-docs.spec.ts b/code/e2e-tests/addon-docs.spec.ts
index 72470acb62ab..db7b7b7d5e05 100644
--- a/code/e2e-tests/addon-docs.spec.ts
+++ b/code/e2e-tests/addon-docs.spec.ts
@@ -185,30 +185,71 @@ test.describe('addon-docs', () => {
});
test('should resolve react to the correct version', async ({ page }) => {
+ // Arrange - Navigate to MDX docs
const sbPage = new SbPage(page);
- await sbPage.navigateToUnattachedDocs('addons/docs/docs2', 'ResolvedReact');
+ await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'mdx', 'docs');
const root = sbPage.previewRoot();
- let expectedReactVersion = /^18/;
+ // Arrange - Setup expectations
+ let expectedReactVersionRange = /^18/;
if (
templateName.includes('preact') ||
templateName.includes('react-webpack/17') ||
templateName.includes('react-vite/17')
) {
- expectedReactVersion = /^17/;
+ expectedReactVersionRange = /^17/;
} else if (templateName.includes('react16')) {
- expectedReactVersion = /^16/;
+ expectedReactVersionRange = /^16/;
}
+ // Arrange - Get the actual versions
const mdxReactVersion = await root.getByTestId('mdx-react');
const mdxReactDomVersion = await root.getByTestId('mdx-react-dom');
+ const mdxReactDomServerVersion = await root.getByTestId('mdx-react-dom-server');
const componentReactVersion = await root.getByTestId('component-react');
const componentReactDomVersion = await root.getByTestId('component-react-dom');
+ const componentReactDomServerVersion = await root.getByTestId('component-react-dom-server');
+
+ // Assert - The versions are in the expected range
+ await expect(mdxReactVersion).toHaveText(expectedReactVersionRange);
+ await expect(componentReactVersion).toHaveText(expectedReactVersionRange);
+ await expect(mdxReactDomVersion).toHaveText(expectedReactVersionRange);
+ await expect(componentReactDomVersion).toHaveText(expectedReactVersionRange);
+ if (!templateName.includes('preact')) {
+ // preact/compat alias doesn't have a version export in react-dom/server
+ await expect(mdxReactDomServerVersion).toHaveText(expectedReactVersionRange);
+ await expect(componentReactDomServerVersion).toHaveText(expectedReactVersionRange);
+ }
+
+ // Arrange - Navigate to autodocs
+ await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'docs');
+
+ // Arrange - Get the actual versions
+ const autodocsReactVersion = await root.getByTestId('react');
+ const autodocsReactDomVersion = await root.getByTestId('react-dom');
+ const autodocsReactDomServerVersion = await root.getByTestId('react-dom-server');
+
+ // Assert - The versions are in the expected range
+ await expect(autodocsReactVersion).toHaveText(expectedReactVersionRange);
+ await expect(autodocsReactDomVersion).toHaveText(expectedReactVersionRange);
+ if (!templateName.includes('preact')) {
+ await expect(autodocsReactDomServerVersion).toHaveText(expectedReactVersionRange);
+ }
+
+ // Arrange - Navigate to story
+ await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'story');
- await expect(mdxReactVersion).toHaveText(expectedReactVersion);
- await expect(mdxReactDomVersion).toHaveText(expectedReactVersion);
- await expect(componentReactVersion).toHaveText(expectedReactVersion);
- await expect(componentReactDomVersion).toHaveText(expectedReactVersion);
+ // Arrange - Get the actual versions
+ const storyReactVersion = await root.getByTestId('react');
+ const storyReactDomVersion = await root.getByTestId('react-dom');
+ const storyReactDomServerVersion = await root.getByTestId('react-dom-server');
+
+ // Assert - The versions are in the expected range
+ await expect(storyReactVersion).toHaveText(expectedReactVersionRange);
+ await expect(storyReactDomVersion).toHaveText(expectedReactVersionRange);
+ if (!templateName.includes('preact')) {
+ await expect(storyReactDomServerVersion).toHaveText(expectedReactVersionRange);
+ }
});
test('should have stories from multiple CSF files in autodocs', async ({ page }) => {
diff --git a/code/e2e-tests/util.ts b/code/e2e-tests/util.ts
index df5ca4ff59a8..f97894075f5b 100644
--- a/code/e2e-tests/util.ts
+++ b/code/e2e-tests/util.ts
@@ -40,7 +40,7 @@ export class SbPage {
/**
* Visit a story by selecting it from the sidebar.
*/
- async navigateToStory(title: string, name: string) {
+ async navigateToStory(title: string, name: string, viewMode?: 'docs' | 'story') {
await this.openComponent(title);
const titleId = toId(title);
@@ -50,11 +50,10 @@ export class SbPage {
const storyLink = this.page.locator('*', { has: this.page.locator(`> ${storyLinkId}`) });
await storyLink.click({ force: true });
- // assert url changes
- const viewMode = name === 'docs' ? 'docs' : 'story';
-
await this.page.waitForURL((url) =>
- url.search.includes(`path=/${viewMode}/${titleId}--${storyId}`)
+ url.search.includes(
+ `path=/${viewMode ?? name === 'docs' ? 'docs' : 'story'}/${titleId}--${storyId}`
+ )
);
const selected = await storyLink.getAttribute('data-selected');
diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json
index d9c345d0cfbc..770a8dae006c 100644
--- a/code/frameworks/vue3-vite/package.json
+++ b/code/frameworks/vue3-vite/package.json
@@ -53,7 +53,7 @@
"find-package-json": "^1.2.0",
"magic-string": "^0.30.0",
"typescript": "^5.0.0",
- "vue-component-meta": "^1.8.27",
+ "vue-component-meta": "^2.0.7",
"vue-docgen-api": "^4.75.1"
},
"devDependencies": {
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 7ec671bddf62..7ebeac95e2ed 100644
--- a/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts
+++ b/code/frameworks/vue3-vite/src/plugins/vue-component-meta.ts
@@ -5,8 +5,8 @@ import path from 'path';
import type { PluginOption } from 'vite';
import {
TypeMeta,
- createComponentMetaChecker,
- createComponentMetaCheckerByJsonConfig,
+ createChecker,
+ createCheckerByJson,
type ComponentMeta,
type MetaCheckerOptions,
} from 'vue-component-meta';
@@ -28,7 +28,7 @@ export async function vueComponentMeta(): Promise {
const include = /\.(vue|ts|js|tsx|jsx)$/;
const filter = createFilter(include, exclude);
- const checker = await createChecker();
+ const checker = await createCheckerWithWorkaround();
return {
name: 'storybook:vue-component-meta-plugin',
@@ -127,8 +127,10 @@ export async function vueComponentMeta(): Promise {
/**
* Creates the vue-component-meta checker to use for extracting component meta/docs.
+ * Includes a workaround for projects using references in their tsconfig.json which
+ * is currently not supported by vue-component-meta.
*/
-async function createChecker() {
+async function createCheckerWithWorkaround() {
const checkerOptions: MetaCheckerOptions = {
forceUseTs: true,
noDeclarations: true,
@@ -138,11 +140,7 @@ async function createChecker() {
const projectRoot = getProjectRoot();
const projectTsConfigPath = path.join(projectRoot, 'tsconfig.json');
- const defaultChecker = createComponentMetaCheckerByJsonConfig(
- projectRoot,
- { include: ['**/*'] },
- checkerOptions
- );
+ const defaultChecker = createCheckerByJson(projectRoot, { include: ['**/*'] }, checkerOptions);
// prefer the tsconfig.json file of the project to support alias resolution etc.
if (await fileExists(projectTsConfigPath)) {
@@ -155,7 +153,7 @@ async function createChecker() {
// TODO: paths/aliases are not resolvable, find workaround for this
return defaultChecker;
}
- return createComponentMetaChecker(projectTsConfigPath, checkerOptions);
+ return createChecker(projectTsConfigPath, checkerOptions);
}
return defaultChecker;
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 9203b45f225f..aee8a1ed985e 100644
--- a/code/lib/cli/src/automigrate/fixes/vite-config-file.ts
+++ b/code/lib/cli/src/automigrate/fixes/vite-config-file.ts
@@ -20,7 +20,7 @@ export const viteConfigFile = {
async check({ mainConfig, packageManager, mainConfigPath }) {
let isViteConfigFileFound = !!(await findUp(
- ['vite.config.js', 'vite.config.mjs', 'vite.config.cjs', 'vite.config.ts'],
+ ['vite.config.js', 'vite.config.mjs', 'vite.config.cjs', 'vite.config.ts', 'vite.config.mts'],
{ cwd: mainConfigPath ? path.join(mainConfigPath, '..') : process.cwd() }
));
diff --git a/code/lib/cli/src/sandbox-templates.ts b/code/lib/cli/src/sandbox-templates.ts
index b28021be7049..9d8a839bfcce 100644
--- a/code/lib/cli/src/sandbox-templates.ts
+++ b/code/lib/cli/src/sandbox-templates.ts
@@ -429,6 +429,9 @@ const baseTemplates = {
renderer: '@storybook/preact',
builder: '@storybook/builder-vite',
},
+ modifications: {
+ extraDependencies: ['preact-render-to-string'],
+ },
skipTasks: ['e2e-tests-dev', 'bench'],
},
'preact-vite/default-ts': {
@@ -439,6 +442,9 @@ const baseTemplates = {
renderer: '@storybook/preact',
builder: '@storybook/builder-vite',
},
+ modifications: {
+ extraDependencies: ['preact-render-to-string'],
+ },
skipTasks: ['e2e-tests-dev', 'bench'],
},
'qwik-vite/default-ts': {
diff --git a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.test.ts b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.test.ts
index 8cd9822a8c35..985d0dbecf83 100644
--- a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.test.ts
+++ b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.test.ts
@@ -1,5 +1,4 @@
import { describe, beforeEach, it, expect, vi } from 'vitest';
-import dedent from 'ts-dedent';
import { Yarn2Proxy } from './Yarn2Proxy';
describe('Yarn 2 Proxy', () => {
@@ -276,35 +275,65 @@ describe('Yarn 2 Proxy', () => {
});
describe('parseErrors', () => {
- it('should parse yarn2 errors', () => {
+ it('should single yarn2 error message', () => {
const YARN2_ERROR_SAMPLE = `
➤ YN0000: ┌ Resolution step
➤ YN0001: │ Error: react@npm:28.2.0: No candidates found
- at ge (/Users/yannbraga/.cache/node/corepack/yarn/3.5.1/yarn.js:439:8124)
+ at ge (/Users/xyz/.cache/node/corepack/yarn/3.5.1/yarn.js:439:8124)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Promise.allSettled (index 8)
- at async io (/Users/yannbraga/.cache/node/corepack/yarn/3.5.1/yarn.js:390:10398)
+ at async io (/Users/xyz/.cache/node/corepack/yarn/3.5.1/yarn.js:390:10398)
➤ YN0000: └ Completed in 2s 369ms
➤ YN0000: Failed with errors in 2s 372ms
➤ YN0032: fsevents@npm:2.3.2: Implicit dependencies on node-gyp are discouraged
➤ YN0061: @npmcli/move-file@npm:2.0.1 is deprecated: This functionality has been moved to @npmcli/fs
`;
- expect(yarn2Proxy.parseErrorFromLogs(YARN2_ERROR_SAMPLE)).toEqual(
- 'YARN2 error YN0001 - EXCEPTION: react@npm:28.2.0: No candidates found'
+ expect(yarn2Proxy.parseErrorFromLogs(YARN2_ERROR_SAMPLE)).toMatchInlineSnapshot(
+ `
+ "YARN2 error
+ YN0001: EXCEPTION
+ -> Error: react@npm:28.2.0: No candidates found
+ "
+ `
);
});
- it('should show unknown yarn2 error', () => {
- const YARN2_ERROR_SAMPLE = dedent`
+ it('shows multiple yarn2 error messages', () => {
+ const YARN2_ERROR_SAMPLE = `
+ ➤ YN0000: · Yarn 4.1.1
➤ YN0000: ┌ Resolution step
- ➤ YN0000: └ Completed in 2s 369ms
- ➤ YN0000: Failed with errors in 2s 372ms
- ➤ YN0032: fsevents@npm:2.3.2: Implicit dependencies on node-gyp are discouraged
- ➤ YN0061: @npmcli/move-file@npm:2.0.1 is deprecated: This functionality has been moved to @npmcli/fs
+ ➤ YN0085: │ + @chromatic-com/storybook@npm:1.2.25, and 300 more.
+ ➤ YN0000: └ Completed in 0s 763ms
+ ➤ YN0000: ┌ Post-resolution validation
+ ➤ YN0002: │ before-storybook@workspace:. doesn't provide @testing-library/dom (p1ac37), requested by @testing-library/user-event.
+ ➤ YN0002: │ before-storybook@workspace:. doesn't provide eslint (p1f657), requested by eslint-plugin-storybook.
+ ➤ YN0086: │ Some peer dependencies are incorrectly met; run yarn explain peer-requirements for details, where is the six-letter p-prefixed code.
+ ➤ YN0000: └ Completed
+ ➤ YN0000: ┌ Fetch step
+ ➤ YN0000: └ Completed
+ ➤ YN0000: ┌ Link step
+ ➤ YN0014: │ Failed to import certain dependencies
+ ➤ YN0071: │ Cannot link @storybook/test into before-storybook@workspace:. dependency @testing-library/jest-dom@npm:6.4.2 [ae73b] conflicts with parent dependency @testing-library/jest-dom@npm:5.17.0
+ ➤ YN0071: │ Cannot link @storybook/test into before-storybook@workspace:. dependency @testing-library/user-event@npm:14.5.2 [ae73b] conflicts with parent dependency @testing-library/user-event@npm:13.5.0 [1b0ac]
+ ➤ YN0000: └ Completed in 0s 262ms
+ ➤ YN0000: · Failed with errors in 1s 301ms
`;
- expect(yarn2Proxy.parseErrorFromLogs(YARN2_ERROR_SAMPLE)).toEqual(`YARN2 error`);
+ expect(yarn2Proxy.parseErrorFromLogs(YARN2_ERROR_SAMPLE)).toMatchInlineSnapshot(
+ `
+ "YARN2 error
+ YN0014: YARN_IMPORT_FAILED
+ -> Failed to import certain dependencies
+
+ YN0071: NM_CANT_INSTALL_EXTERNAL_SOFT_LINK
+ -> Cannot link @storybook/test into before-storybook@workspace:. dependency @testing-library/jest-dom@npm:6.4.2 [ae73b] conflicts with parent dependency @testing-library/jest-dom@npm:5.17.0
+
+ YN0071: NM_CANT_INSTALL_EXTERNAL_SOFT_LINK
+ -> Cannot link @storybook/test into before-storybook@workspace:. dependency @testing-library/user-event@npm:14.5.2 [ae73b] conflicts with parent dependency @testing-library/user-event@npm:13.5.0 [1b0ac]
+ "
+ `
+ );
});
});
});
diff --git a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts
index 09f535e2dfa5..08062cf4081c 100644
--- a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts
+++ b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts
@@ -10,10 +10,36 @@ import type { PackageJson } from './PackageJson';
import type { InstallationMetadata, PackageMetadata } from './types';
import { parsePackageData } from './util';
-const YARN2_ERROR_REGEX = /(YN\d{4}):.*?Error:\s+(.*)/i;
+const CRITICAL_YARN2_ERROR_CODES = {
+ YN0001: 'EXCEPTION',
+ YN0009: 'BUILD_FAILED',
+ YN0010: 'RESOLVER_NOT_FOUND',
+ YN0011: 'FETCHER_NOT_FOUND',
+ YN0012: 'LINKER_NOT_FOUND',
+ YN0014: 'YARN_IMPORT_FAILED',
+ YN0015: 'REMOTE_INVALID',
+ YN0016: 'REMOTE_NOT_FOUND',
+ YN0020: 'MISSING_LOCKFILE_ENTRY',
+ YN0021: 'WORKSPACE_NOT_FOUND',
+ YN0028: 'FROZEN_LOCKFILE_EXCEPTION',
+ YN0030: 'FETCH_FAILED',
+ YN0046: 'AUTOMERGE_FAILED_TO_PARSE',
+ YN0062: 'INCOMPATIBLE_OS',
+ YN0063: 'INCOMPATIBLE_CPU',
+ YN0071: 'NM_CANT_INSTALL_EXTERNAL_SOFT_LINK',
+ YN0072: 'NM_PRESERVE_SYMLINKS_REQUIRED',
+ YN0075: 'PROLOG_INSTANTIATION_ERROR',
+ YN0076: 'INCOMPATIBLE_ARCHITECTURE',
+ YN0078: 'RESOLUTION_MISMATCH',
+ YN0081: 'NETWORK_UNSAFE_HTTP',
+ YN0082: 'RESOLUTION_FAILED',
+ YN0083: 'AUTOMERGE_GIT_ERROR',
+};
+
+// @ts-expect-error Might be useful to have this in the future
const YARN2_ERROR_CODES = {
+ ...CRITICAL_YARN2_ERROR_CODES,
YN0000: 'UNNAMED',
- YN0001: 'EXCEPTION',
YN0002: 'MISSING_PEER_DEPENDENCY',
YN0003: 'CYCLIC_DEPENDENCIES',
YN0004: 'DISABLED_BUILD_SCRIPTS',
@@ -21,31 +47,19 @@ const YARN2_ERROR_CODES = {
YN0006: 'SOFT_LINK_BUILD',
YN0007: 'MUST_BUILD',
YN0008: 'MUST_REBUILD',
- YN0009: 'BUILD_FAILED',
- YN0010: 'RESOLVER_NOT_FOUND',
- YN0011: 'FETCHER_NOT_FOUND',
- YN0012: 'LINKER_NOT_FOUND',
YN0013: 'FETCH_NOT_CACHED',
- YN0014: 'YARN_IMPORT_FAILED',
- YN0015: 'REMOTE_INVALID',
- YN0016: 'REMOTE_NOT_FOUND',
YN0017: 'RESOLUTION_PACK',
YN0018: 'CACHE_CHECKSUM_MISMATCH',
YN0019: 'UNUSED_CACHE_ENTRY',
- YN0020: 'MISSING_LOCKFILE_ENTRY',
- YN0021: 'WORKSPACE_NOT_FOUND',
YN0022: 'TOO_MANY_MATCHING_WORKSPACES',
YN0023: 'CONSTRAINTS_MISSING_DEPENDENCY',
YN0024: 'CONSTRAINTS_INCOMPATIBLE_DEPENDENCY',
YN0025: 'CONSTRAINTS_EXTRANEOUS_DEPENDENCY',
YN0026: 'CONSTRAINTS_INVALID_DEPENDENCY',
YN0027: 'CANT_SUGGEST_RESOLUTIONS',
- YN0028: 'FROZEN_LOCKFILE_EXCEPTION',
YN0029: 'CROSS_DRIVE_VIRTUAL_LOCAL',
- YN0030: 'FETCH_FAILED',
YN0031: 'DANGEROUS_NODE_MODULES',
YN0032: 'NODE_GYP_INJECTED',
- YN0046: 'AUTOMERGE_FAILED_TO_PARSE',
YN0047: 'AUTOMERGE_IMMUTABLE',
YN0048: 'AUTOMERGE_SUCCESS',
YN0049: 'AUTOMERGE_REQUIRED',
@@ -53,16 +67,17 @@ const YARN2_ERROR_CODES = {
YN0059: 'INVALID_RANGE_PEER_DEPENDENCY',
YN0060: 'INCOMPATIBLE_PEER_DEPENDENCY',
YN0061: 'DEPRECATED_PACKAGE',
- YN0062: 'INCOMPATIBLE_OS',
- YN0063: 'INCOMPATIBLE_CPU',
YN0068: 'UNUSED_PACKAGE_EXTENSION',
YN0069: 'REDUNDANT_PACKAGE_EXTENSION',
- YN0071: 'NM_CANT_INSTALL_EXTERNAL_SOFT_LINK',
- YN0072: 'NM_PRESERVE_SYMLINKS_REQUIRED',
YN0074: 'NM_HARDLINKS_MODE_DOWNGRADED',
- YN0075: 'PROLOG_INSTANTIATION_ERROR',
- YN0076: 'INCOMPATIBLE_ARCHITECTURE',
YN0077: 'GHOST_ARCHITECTURE',
+ YN0080: 'NETWORK_DISABLED',
+ YN0085: 'UPDATED_RESOLUTION_RECORD',
+ YN0086: 'EXPLAIN_PEER_DEPENDENCIES_CTA',
+ YN0087: 'MIGRATION_SUCCESS',
+ YN0088: 'VERSION_NOTICE',
+ YN0089: 'TIPS_NOTICE',
+ YN0090: 'OFFLINE_MODE_ENABLED',
};
// This encompasses both yarn 2 and yarn 3
@@ -284,26 +299,27 @@ export class Yarn2Proxy extends JsPackageManager {
}
public parseErrorFromLogs(logs: string): string {
- let finalMessage = 'YARN2 error';
- const match = logs.match(YARN2_ERROR_REGEX);
-
- if (match) {
- const errorCode = match[1] as keyof typeof YARN2_ERROR_CODES;
- if (errorCode) {
- finalMessage = `${finalMessage} ${errorCode}`;
- }
-
- const errorType = YARN2_ERROR_CODES[errorCode];
- if (errorType) {
- finalMessage = `${finalMessage} - ${errorType}`;
- }
-
- const errorMessage = match[2];
- if (errorMessage) {
- finalMessage = `${finalMessage}: ${errorMessage}`;
+ const finalMessage = 'YARN2 error';
+ const errorCodesWithMessages: { code: string; message: string }[] = [];
+ const regex = /(YN\d{4}): (.+)/g;
+ let match: RegExpExecArray | null;
+
+ while ((match = regex.exec(logs)) !== null) {
+ const code = match[1];
+ const message = match[2].replace(/[┌│└]/g, '').trim();
+ if (code in CRITICAL_YARN2_ERROR_CODES) {
+ errorCodesWithMessages.push({
+ code,
+ message: `${
+ CRITICAL_YARN2_ERROR_CODES[code as keyof typeof CRITICAL_YARN2_ERROR_CODES]
+ }\n-> ${message}\n`,
+ });
}
}
- return finalMessage.trim();
+ return [
+ finalMessage,
+ errorCodesWithMessages.map(({ code, message }) => `${code}: ${message}`).join('\n'),
+ ].join('\n');
}
}
diff --git a/code/lib/docs-tools/src/argTypes/convert/flow/convert.ts b/code/lib/docs-tools/src/argTypes/convert/flow/convert.ts
index 5886babe7301..b950be171bee 100644
--- a/code/lib/docs-tools/src/argTypes/convert/flow/convert.ts
+++ b/code/lib/docs-tools/src/argTypes/convert/flow/convert.ts
@@ -41,13 +41,13 @@ export const convert = (type: FlowType): SBType | void => {
case 'signature':
return { ...base, ...convertSig(type) };
case 'union':
- if (type.elements.every(isLiteral)) {
- return { ...base, name: 'enum', value: type.elements.map(toEnumOption) };
+ if (type.elements?.every(isLiteral)) {
+ return { ...base, name: 'enum', value: type.elements?.map(toEnumOption) };
}
- return { ...base, name, value: type.elements.map(convert) };
+ return { ...base, name, value: type.elements?.map(convert) };
case 'intersection':
- return { ...base, name, value: type.elements.map(convert) };
+ return { ...base, name, value: type.elements?.map(convert) };
default:
return { ...base, name: 'other', value: name };
}
diff --git a/code/lib/docs-tools/src/argTypes/convert/typescript/convert.ts b/code/lib/docs-tools/src/argTypes/convert/typescript/convert.ts
index 2bf1fe65e552..95436dfcb567 100644
--- a/code/lib/docs-tools/src/argTypes/convert/typescript/convert.ts
+++ b/code/lib/docs-tools/src/argTypes/convert/typescript/convert.ts
@@ -38,19 +38,19 @@ export const convert = (type: TSType): SBType | void => {
return { ...base, ...convertSig(type) };
case 'union':
let result;
- if (type.elements.every((element) => element.name === 'literal')) {
+ if (type.elements?.every((element) => element.name === 'literal')) {
result = {
...base,
name: 'enum',
// @ts-expect-error fix types
- value: type.elements.map((v) => parseLiteral(v.value)),
+ value: type.elements?.map((v) => parseLiteral(v.value)),
};
} else {
- result = { ...base, name, value: type.elements.map(convert) };
+ result = { ...base, name, value: type.elements?.map(convert) };
}
return result;
case 'intersection':
- return { ...base, name, value: type.elements.map(convert) };
+ return { ...base, name, value: type.elements?.map(convert) };
default:
return { ...base, name: 'other', value: name };
}
diff --git a/code/lib/docs-tools/src/argTypes/convert/typescript/types.ts b/code/lib/docs-tools/src/argTypes/convert/typescript/types.ts
index aed18f3f4160..79df2e812c00 100644
--- a/code/lib/docs-tools/src/argTypes/convert/typescript/types.ts
+++ b/code/lib/docs-tools/src/argTypes/convert/typescript/types.ts
@@ -9,7 +9,7 @@ type TSArgType = TSType;
type TSCombinationType = TSBaseType & {
name: 'union' | 'intersection';
- elements: TSType[];
+ elements?: TSType[];
};
type TSFuncSigType = TSBaseType & {
diff --git a/code/lib/react-dom-shim/src/preset.ts b/code/lib/react-dom-shim/src/preset.ts
index 63b2889ba93b..e863a53262b6 100644
--- a/code/lib/react-dom-shim/src/preset.ts
+++ b/code/lib/react-dom-shim/src/preset.ts
@@ -1,5 +1,5 @@
import type { Options } from '@storybook/types';
-import { join, dirname } from 'path';
+import { join, dirname, isAbsolute } from 'path';
import { readFile } from 'fs/promises';
/**
@@ -17,6 +17,12 @@ const getIsReactVersion18 = async (options: Options) => {
const resolvedReact = await options.presets.apply<{ reactDom?: string }>('resolvedReact', {});
const reactDom = resolvedReact.reactDom || dirname(require.resolve('react-dom/package.json'));
+ if (!isAbsolute(reactDom)) {
+ // if react-dom is not resolved to a file we can't be sure if the version in package.json is correct or even if package.json exists
+ // this happens when react-dom is resolved to 'preact/compat' for example
+ return false;
+ }
+
const { version } = JSON.parse(await readFile(join(reactDom, 'package.json'), 'utf-8'));
return version.startsWith('18') || version.startsWith('0.0.0');
};
diff --git a/code/package.json b/code/package.json
index 3295a1306430..f9f386daa07f 100644
--- a/code/package.json
+++ b/code/package.json
@@ -295,5 +295,6 @@
"Dependency Upgrades"
]
]
- }
+ },
+ "deferredNextVersion": "8.0.5"
}
diff --git a/code/renderers/preact/src/preset.ts b/code/renderers/preact/src/preset.ts
index 03b11e7e6097..28e5a428af0a 100644
--- a/code/renderers/preact/src/preset.ts
+++ b/code/renderers/preact/src/preset.ts
@@ -13,3 +13,19 @@ export const previewAnnotations: PresetProperty<'previewAnnotations'> = async (
.concat([join(__dirname, 'entry-preview.mjs')])
.concat(docsEnabled ? [join(__dirname, 'entry-preview-docs.mjs')] : []);
};
+
+/**
+ * Alias react and react-dom to preact/compat similar to the preact vite preset
+ * https://github.com/preactjs/preset-vite/blob/main/src/index.ts#L238-L239
+ */
+export const resolvedReact = async (existing: any) => {
+ try {
+ return {
+ ...existing,
+ react: 'preact/compat',
+ reactDom: 'preact/compat',
+ };
+ } catch (e) {
+ return existing;
+ }
+};
diff --git a/code/renderers/preact/template/stories/React.js b/code/renderers/preact/template/stories/React.jsx
similarity index 100%
rename from code/renderers/preact/template/stories/React.js
rename to code/renderers/preact/template/stories/React.jsx
diff --git a/code/renderers/preact/template/stories/react-compat.stories.js b/code/renderers/preact/template/stories/react-compat.stories.jsx
similarity index 96%
rename from code/renderers/preact/template/stories/react-compat.stories.js
rename to code/renderers/preact/template/stories/react-compat.stories.jsx
index 33f1078d3154..b43a0650e748 100644
--- a/code/renderers/preact/template/stories/react-compat.stories.js
+++ b/code/renderers/preact/template/stories/react-compat.stories.jsx
@@ -1,4 +1,4 @@
-import { ReactFunctionalComponent, ReactClassComponent } from './React';
+import { ReactFunctionalComponent, ReactClassComponent } from './React.jsx';
export default {
component: ReactFunctionalComponent,
diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/DefineModel.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/DefineModel.stories.ts
new file mode 100644
index 000000000000..be2f612287a5
--- /dev/null
+++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/DefineModel.stories.ts
@@ -0,0 +1,16 @@
+import type { Meta, StoryObj } from '@storybook/vue3';
+import Component from './define-model/component.vue';
+
+const meta = {
+ component: Component,
+ tags: ['autodocs'],
+} satisfies Meta;
+
+type Story = StoryObj;
+export default meta;
+
+export const Default: Story = {
+ args: {
+ modelValue: 'Test value',
+ },
+};
diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/DefineSlots.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/DefineSlots.stories.ts
new file mode 100644
index 000000000000..1a06ce6bb504
--- /dev/null
+++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/DefineSlots.stories.ts
@@ -0,0 +1,18 @@
+import type { Meta, StoryObj } from '@storybook/vue3';
+import Component from './define-slots/component.vue';
+
+const meta = {
+ component: Component,
+ tags: ['autodocs'],
+} satisfies Meta;
+
+type Story = StoryObj;
+export default meta;
+
+export const Default: Story = {
+ args: {
+ default: ({ num }) => `Default slot { num=${num} }`,
+ named: ({ str }) => `Named slot { str=${str} }`,
+ vbind: ({ num, str }) => `Named v-bind slot { num=${num}, str=${str} }`,
+ },
+};
diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/define-model/component.vue b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/define-model/component.vue
new file mode 100644
index 000000000000..0b1ea4b3a3d6
--- /dev/null
+++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/define-model/component.vue
@@ -0,0 +1,7 @@
+
+
+
+ {{ model }}
+
diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/define-slots/component.vue b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/define-slots/component.vue
new file mode 100644
index 000000000000..94533f010bdb
--- /dev/null
+++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/component-meta/define-slots/component.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code/yarn.lock b/code/yarn.lock
index 2fb0fb333137..d38001944e61 100644
--- a/code/yarn.lock
+++ b/code/yarn.lock
@@ -6854,7 +6854,7 @@ __metadata:
magic-string: "npm:^0.30.0"
typescript: "npm:^5.3.2"
vite: "npm:^4.0.0"
- vue-component-meta: "npm:^1.8.27"
+ vue-component-meta: "npm:^2.0.7"
vue-docgen-api: "npm:^4.75.1"
peerDependencies:
vite: ^4.0.0 || ^5.0.0
@@ -8689,12 +8689,12 @@ __metadata:
languageName: node
linkType: hard
-"@volar/language-core@npm:1.11.1, @volar/language-core@npm:~1.11.1":
- version: 1.11.1
- resolution: "@volar/language-core@npm:1.11.1"
+"@volar/language-core@npm:2.1.4, @volar/language-core@npm:~2.1.3":
+ version: 2.1.4
+ resolution: "@volar/language-core@npm:2.1.4"
dependencies:
- "@volar/source-map": "npm:1.11.1"
- checksum: 92c4439e3a9ccc534c970031388c318740f6fa032283d03e136c6c8c0228f549c68a7c363af1a28252617a0dca6069e14028329ac906d5acf1912931d0cdcb69
+ "@volar/source-map": "npm:2.1.4"
+ checksum: b1817f479b7ac396a173de9bc1432cfb6ea64555901e3ea8004d6ae585430f0f2dfd83fbe1413ec003e64cb3769ea79f55fccc9784d87f27f0e40eff1b2bab5c
languageName: node
linkType: hard
@@ -8707,12 +8707,12 @@ __metadata:
languageName: node
linkType: hard
-"@volar/source-map@npm:1.11.1, @volar/source-map@npm:~1.11.1":
- version: 1.11.1
- resolution: "@volar/source-map@npm:1.11.1"
+"@volar/source-map@npm:2.1.4":
+ version: 2.1.4
+ resolution: "@volar/source-map@npm:2.1.4"
dependencies:
- muggle-string: "npm:^0.3.1"
- checksum: 0bfc639889802705f8036ea8b2052a95a4d691a68bc2b6744ba8b9d312d887393dd3278101180a5ee5304972899d493972a483afafd41e097968746c77d724cb
+ muggle-string: "npm:^0.4.0"
+ checksum: 246f2ddc41cf47950f7e6c9da5f78a0f87142ee85823379a574d2beed4a048bc8dd87d3f95debe78a3bb52efbca4fe1625edc3d0bbb7c5313d23651fc6f7b035
languageName: node
linkType: hard
@@ -8725,13 +8725,13 @@ __metadata:
languageName: node
linkType: hard
-"@volar/typescript@npm:~1.11.1":
- version: 1.11.1
- resolution: "@volar/typescript@npm:1.11.1"
+"@volar/typescript@npm:~2.1.3":
+ version: 2.1.4
+ resolution: "@volar/typescript@npm:2.1.4"
dependencies:
- "@volar/language-core": "npm:1.11.1"
+ "@volar/language-core": "npm:2.1.4"
path-browserify: "npm:^1.0.1"
- checksum: 86fe153db3a14d8eb3632784a1d7fcbfbfb51fa5517c3878bfdd49ee8d15a83b1a09f9c589454b7396454c104d3a8e2db3a987dc99b37c33816772fc3e292bf2
+ checksum: 62158d6e3cd1b29d06fe519ae676f47f61b685127ed09f97c9365c37647cce236e7f6f4b0259456da4b735fd4e355f71e1efc298dbec08677bafd8b02ac37b36
languageName: node
linkType: hard
@@ -8760,6 +8760,19 @@ __metadata:
languageName: node
linkType: hard
+"@vue/compiler-core@npm:3.4.21":
+ version: 3.4.21
+ resolution: "@vue/compiler-core@npm:3.4.21"
+ dependencies:
+ "@babel/parser": "npm:^7.23.9"
+ "@vue/shared": "npm:3.4.21"
+ entities: "npm:^4.5.0"
+ estree-walker: "npm:^2.0.2"
+ source-map-js: "npm:^1.0.2"
+ checksum: 3ee871b95e17948d10375093c8dd3265923f844528a24ac67512c201ddb9b628021c010565f3e50f2e551b217c502e80a7901384f616a977a04f81e68c64a37c
+ languageName: node
+ linkType: hard
+
"@vue/compiler-core@npm:3.4.5, @vue/compiler-core@npm:^3.0.0":
version: 3.4.5
resolution: "@vue/compiler-core@npm:3.4.5"
@@ -8803,6 +8816,16 @@ __metadata:
languageName: node
linkType: hard
+"@vue/compiler-dom@npm:^3.4.0":
+ version: 3.4.21
+ resolution: "@vue/compiler-dom@npm:3.4.21"
+ dependencies:
+ "@vue/compiler-core": "npm:3.4.21"
+ "@vue/shared": "npm:3.4.21"
+ checksum: b4a1099eddacded2663d12388b48088ca0be0d8969a070476f49e4e65da9b22851fc897cc693662b178e7e7fdee98fcf9ea3617a1f626c3a1b2089815cb1264e
+ languageName: node
+ linkType: hard
+
"@vue/compiler-sfc@npm:3.0.0":
version: 3.0.0
resolution: "@vue/compiler-sfc@npm:3.0.0"
@@ -8915,17 +8938,15 @@ __metadata:
languageName: node
linkType: hard
-"@vue/language-core@npm:1.8.27":
- version: 1.8.27
- resolution: "@vue/language-core@npm:1.8.27"
+"@vue/language-core@npm:2.0.7":
+ version: 2.0.7
+ resolution: "@vue/language-core@npm:2.0.7"
dependencies:
- "@volar/language-core": "npm:~1.11.1"
- "@volar/source-map": "npm:~1.11.1"
- "@vue/compiler-dom": "npm:^3.3.0"
- "@vue/shared": "npm:^3.3.0"
+ "@volar/language-core": "npm:~2.1.3"
+ "@vue/compiler-dom": "npm:^3.4.0"
+ "@vue/shared": "npm:^3.4.0"
computeds: "npm:^0.0.1"
minimatch: "npm:^9.0.3"
- muggle-string: "npm:^0.3.1"
path-browserify: "npm:^1.0.1"
vue-template-compiler: "npm:^2.7.14"
peerDependencies:
@@ -8933,7 +8954,7 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 2018214d8ce2643d19e8e84eddaeacddca28b2980984d7916d97f97556c3716be184cf9f8c4f506d072a11f265401e3bc0391117cf7cfcc1e4a25048f4432dc7
+ checksum: c4da8e077c50cbc2d3bfb112d63ed6112aa0fd834ca63fbc3e2b6f2fdd58fdb3dbd5ad9e3332e373c330f049fac2f8465e4063790e24efafd95572087f896b74
languageName: node
linkType: hard
@@ -9036,6 +9057,13 @@ __metadata:
languageName: node
linkType: hard
+"@vue/shared@npm:3.4.21, @vue/shared@npm:^3.4.0":
+ version: 3.4.21
+ resolution: "@vue/shared@npm:3.4.21"
+ checksum: 79cba4228c3c1769ba8024302d7dbebf6ed1b77fb2e7a69e635cdebaa1c18b409e9c27ce27ccbe3a98e702a7e2dae1b87754d87f0b29adfe2a8f9e1e7c7899d5
+ languageName: node
+ linkType: hard
+
"@vue/shared@npm:3.4.5, @vue/shared@npm:^3.3.0":
version: 3.4.5
resolution: "@vue/shared@npm:3.4.5"
@@ -21277,6 +21305,13 @@ __metadata:
languageName: node
linkType: hard
+"muggle-string@npm:^0.4.0":
+ version: 0.4.1
+ resolution: "muggle-string@npm:0.4.1"
+ checksum: e914b63e24cd23f97e18376ec47e4ba3aa24365e4776212b666add2e47bb158003212980d732c49abf3719568900af7861873844a6e2d3a7ca7e86952c0e99e9
+ languageName: node
+ linkType: hard
+
"multicast-dns@npm:^7.2.5":
version: 7.2.5
resolution: "multicast-dns@npm:7.2.5"
@@ -29382,27 +29417,20 @@ __metadata:
languageName: node
linkType: hard
-"vue-component-meta@npm:^1.8.27":
- version: 1.8.27
- resolution: "vue-component-meta@npm:1.8.27"
+"vue-component-meta@npm:^2.0.7":
+ version: 2.0.7
+ resolution: "vue-component-meta@npm:2.0.7"
dependencies:
- "@volar/typescript": "npm:~1.11.1"
- "@vue/language-core": "npm:1.8.27"
+ "@volar/typescript": "npm:~2.1.3"
+ "@vue/language-core": "npm:2.0.7"
path-browserify: "npm:^1.0.1"
- vue-component-type-helpers: "npm:1.8.27"
+ vue-component-type-helpers: "npm:2.0.7"
peerDependencies:
typescript: "*"
peerDependenciesMeta:
typescript:
optional: true
- checksum: 40884b316940e6995a6e7f9e5cbe5536b5c6e380acfd5b1d24914511972a241550c04474f4fffdf6305b1c9962b1137b5fd6183dc309127d3a268fe7d8d85df9
- languageName: node
- linkType: hard
-
-"vue-component-type-helpers@npm:1.8.27":
- version: 1.8.27
- resolution: "vue-component-type-helpers@npm:1.8.27"
- checksum: 3403d70951e422162321e810f54f23f11ee5d2642631d2ca2cb1de18e5d35a0b7b05dd1f9bd02a0ae77dfa0b80751d826865d98f928ae6d6fbce9303406c9820
+ checksum: 1c7fce41afc2cafe85b7477763da069e06091b4a30bb7fb09e8479f9a4c2bb5b8aa7a5c805a8af68b4bed54fbb435485f91a1a2dfa1332377dfa98acef03ca4d
languageName: node
linkType: hard
@@ -29413,6 +29441,13 @@ __metadata:
languageName: node
linkType: hard
+"vue-component-type-helpers@npm:2.0.7":
+ version: 2.0.7
+ resolution: "vue-component-type-helpers@npm:2.0.7"
+ checksum: c350a06e2dec5a3856ac9ef7cc4fd00c1a59a13b812f885dcab8636cf6dd3951d0f66fd8adbee8b49445294f65b48848f115699a8dc654e0b5b09611739df420
+ languageName: node
+ linkType: hard
+
"vue-component-type-helpers@npm:latest":
version: 1.8.15
resolution: "vue-component-type-helpers@npm:1.8.15"
diff --git a/docs/builders/vite.md b/docs/builders/vite.md
index a254e7b5f7a0..2acc59769c1a 100644
--- a/docs/builders/vite.md
+++ b/docs/builders/vite.md
@@ -109,7 +109,7 @@ If you need, you can also configure Storybook's Vite builder using TypeScript. R
### Working directory not being detected
-By default, the Vite builder enables Vite's [`server.fs.strict`](https://vitejs.dev/config/#server-fs-strict) option for increased security, defining the project's `root` to Storybook's configuration directory
+By default, the Vite builder enables Vite's [`server.fs.strict`](https://vitejs.dev/config/#server-fs-strict) option for increased security, defining the project's `root` to Storybook's configuration directory.
If you need to override it, you can use the `viteFinal` function and adjust it.
### ArgTypes are not generated automatically
diff --git a/docs/get-started/whats-a-story.md b/docs/get-started/whats-a-story.md
index 9ef527d5d6c3..af516341df3e 100644
--- a/docs/get-started/whats-a-story.md
+++ b/docs/get-started/whats-a-story.md
@@ -8,7 +8,7 @@ The CLI created example components that demonstrate the types of components you
Each example component has a set of stories that show the states it supports. You can browse the stories in the UI and see the code behind them in files that end with `.stories.js` or `.stories.ts`. The stories are written in Component Story Format (CSF)--an ES6 modules-based standard--for writing component examples.
-Let’s start with the `Button` component. A story is a function that describes how to render the component in question. Here’s how to render `Button` in the “primary” state and export a story called `Primary`.
+Let’s start with the `Button` component. A story is an object that describes how to render the component in question. Here’s how to render `Button` in the “primary” state and export a story called `Primary`.
diff --git a/docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx b/docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx
index fdb2e942e377..1058c451d943 100644
--- a/docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx
+++ b/docs/snippets/common/storybook-migrate-mdx-to-csf.npm.js.mdx
@@ -1,4 +1,4 @@
```shell
# Convert stories in MDX to CSF
-npx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx”
+npx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx"
```
diff --git a/docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx b/docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx
index 48f8f5fb5ec7..21b956b0fd2a 100644
--- a/docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx
+++ b/docs/snippets/common/storybook-migrate-mdx-to-csf.pnpm.js.mdx
@@ -1,4 +1,4 @@
```sh
# Convert stories in MDX to CSF
-pnpm dlx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx”
+pnpm dlx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx"
```
diff --git a/docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx b/docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx
index ce45b320d7de..93dca5ba3158 100644
--- a/docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx
+++ b/docs/snippets/common/storybook-migrate-mdx-to-csf.yarn.js.mdx
@@ -1,4 +1,4 @@
```sh
# Convert stories in MDX to CSF
-yarn dlx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx”
+yarn dlx storybook@latest migrate mdx-to-csf --glob "src/**/*.stories.mdx"
```
diff --git a/docs/versions/latest.json b/docs/versions/latest.json
index 7b7e0fcf84ca..34455f2dd966 100644
--- a/docs/versions/latest.json
+++ b/docs/versions/latest.json
@@ -1 +1 @@
-{"version":"8.0.4","info":{"plain":"- Addon Docs: Support Stencil based display names in source snippets - [#26592](https://github.com/storybookjs/storybook/pull/26592), thanks @yannbf!\n- CLI: Instruct the correct auto-migration command - [#26515](https://github.com/storybookjs/storybook/pull/26515), thanks @ndelangen!\n- CLI: Throw an error when running upgrade command in incorrect cwd - [#26585](https://github.com/storybookjs/storybook/pull/26585), thanks @yannbf!"}}
+{"version":"8.0.5","info":{"plain":"- Addon-docs: Fix `react-dom/server` imports breaking stories and docs - [#26557](https://github.com/storybookjs/storybook/pull/26557), thanks @JReinhold!\n- Automigrations: Fix missing support for mts vite config - [#26441](https://github.com/storybookjs/storybook/pull/26441), thanks @drik98!\n- CLI: Improve Yarn berry error parsing - [#26616](https://github.com/storybookjs/storybook/pull/26616), thanks @yannbf!\n- React-Docgen: Make sure to be able to handle empty unions - [#26639](https://github.com/storybookjs/storybook/pull/26639), thanks @kasperpeulen!\n- Viewport: Fix missing style - [#26530](https://github.com/storybookjs/storybook/pull/26530), thanks @jpzwarte!"}}
diff --git a/docs/versions/next.json b/docs/versions/next.json
index 41825fb5bf44..5bca2714437b 100644
--- a/docs/versions/next.json
+++ b/docs/versions/next.json
@@ -1 +1 @@
-{"version":"8.1.0-alpha.3","info":{"plain":"- Addon Docs: Fix [Object object] displayName in some JSX components - [#26566](https://github.com/storybookjs/storybook/pull/26566), thanks @yannbf!\n- CLI: Introduce package manager fallback for initializing Storybook in an empty directory with yarn1 - [#26500](https://github.com/storybookjs/storybook/pull/26500), thanks @valentinpalkovic!\n- CSF: Make sure loaders/decorators can be used as array - [#26514](https://github.com/storybookjs/storybook/pull/26514), thanks @kasperpeulen!\n- Controls: Fix disable condition in ArgControl component - [#26567](https://github.com/storybookjs/storybook/pull/26567), thanks @valentinpalkovic!\n- Portable stories: Introduce experimental Playwright CT API and Support for more renderers - [#26063](https://github.com/storybookjs/storybook/pull/26063), thanks @yannbf!\n- UI: Fix theming of elements inside bars - [#26527](https://github.com/storybookjs/storybook/pull/26527), thanks @valentinpalkovic!\n- UI: Improve empty state of addon panel - [#26481](https://github.com/storybookjs/storybook/pull/26481), thanks @yannbf!"}}
+{"version":"8.1.0-alpha.4","info":{"plain":"- Addon Docs: Support Stencil based display names in source snippets - [#26592](https://github.com/storybookjs/storybook/pull/26592), thanks @yannbf!\n- Angular: Add type support for Angular's input signals - [#26413](https://github.com/storybookjs/storybook/pull/26413), thanks @valentinpalkovic!\n- Angular: Add type support for Angular's output signals - [#26546](https://github.com/storybookjs/storybook/pull/26546), thanks @valentinpalkovic!\n- CLI: Instruct the correct auto-migration command - [#26515](https://github.com/storybookjs/storybook/pull/26515), thanks @ndelangen!\n- CLI: Throw an error when running upgrade command in incorrect cwd - [#26585](https://github.com/storybookjs/storybook/pull/26585), thanks @yannbf!\n- CSF: Allow default export without title or component attributes - [#26516](https://github.com/storybookjs/storybook/pull/26516), thanks @kasperpeulen!\n- Core: Fix preloading too early - [#26442](https://github.com/storybookjs/storybook/pull/26442), thanks @ndelangen!\n- UI: Replace the icon prop in the Manager API - [#26477](https://github.com/storybookjs/storybook/pull/26477), thanks @cdedreuille!"}}
diff --git a/docs/writing-stories/index.md b/docs/writing-stories/index.md
index 28aa1cfeee5a..abc6632d90f8 100644
--- a/docs/writing-stories/index.md
+++ b/docs/writing-stories/index.md
@@ -4,7 +4,8 @@ title: 'How to write stories'
-A story captures the rendered state of a UI component. It’s a function that returns a component’s state given a set of arguments.
+A story captures the rendered state of a UI component. It's an object with annotations that describe the component's behavior and appearance given a set
+of arguments.
Storybook uses the generic term arguments (args for short) when talking about React’s `props`, Vue’s `props`, Angular’s `@Input`, and other similar concepts.
@@ -169,7 +170,7 @@ Your story will now be shown in the sidebar with the given text.
## How to write stories
-A story is a function that describes how to render a component. You can have multiple stories per component, and the simplest way to create stories is to render a component with different arguments multiple times.
+A story is an object that describes how to render a component. You can have multiple stories per component, and the simplest way to create stories is to render a component with different arguments multiple times.