diff --git a/.nvmrc b/.nvmrc index 017faf90e766..ddeb00c1678b 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1,2 +1,2 @@ -22.21.1 +22.22.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f72d8afe58d..41efbe690ea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 10.2.17 + +- Next.js: Add support for v16.2 - [#34046](https://github.com/storybookjs/storybook/pull/34046), thanks @valentinpalkovic! + ## 10.2.16 - CSF-Factories: Fix ConfigFile parser false warning on `definePreview({...}).type()` export default - [#33885](https://github.com/storybookjs/storybook/pull/33885), thanks @copilot-swe-agent! diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index d1454b01be1f..05649bbb88da 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,12 @@ +## 10.3.0-alpha.16 + +- A11y: Underline MDX links for WCAG SC 1.4.1 compliance - [#33139](https://github.com/storybookjs/storybook/pull/33139), thanks @NikhilChowdhury27! +- Angular: Add moduleResolution: bundler to tsconfig - [#34085](https://github.com/storybookjs/storybook/pull/34085), thanks @valentinpalkovic! +- Angular: only load webpack dependencies on demand - [#34043](https://github.com/storybookjs/storybook/pull/34043), thanks @sod! +- CLI: Show multiple favicons warning as debug message - [#34069](https://github.com/storybookjs/storybook/pull/34069), thanks @remino! +- Core: Fix error reporting in ManagerErrorBoundary - [#33915](https://github.com/storybookjs/storybook/pull/33915), thanks @ghengeveld! +- Vite: Support Vite 8 - [#33788](https://github.com/storybookjs/storybook/pull/33788), thanks @valentinpalkovic! + ## 10.3.0-alpha.15 - Actions: Add expandLevel parameter to configure tree depth - [#33977](https://github.com/storybookjs/storybook/pull/33977), thanks @mixelburg! diff --git a/code/addons/docs/src/blocks/components/DocsPage.test.tsx b/code/addons/docs/src/blocks/components/DocsPage.test.tsx new file mode 100644 index 000000000000..fcf3fcbbe402 --- /dev/null +++ b/code/addons/docs/src/blocks/components/DocsPage.test.tsx @@ -0,0 +1,101 @@ +// @vitest-environment happy-dom +import { cleanup, render } from '@testing-library/react'; +import { afterEach, describe, expect, it } from 'vitest'; + +import React from 'react'; + +import { ThemeProvider, convert, themes } from 'storybook/theming'; + +import { DocsContent } from './DocsPage'; + +function ThemedDocsContent({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + +describe('DocsContent', () => { + afterEach(() => { + cleanup(); + }); + + describe('accessibility', () => { + it('should render links with underline text decoration for accessibility', () => { + const { container } = render( + +

+ This is a paragraph with a link inside. +

+
+ ); + + const link = container.querySelector('a'); + expect(link).toBeTruthy(); + + const styles = window.getComputedStyle(link!); + expect(styles.textDecoration).toContain('underline'); + }); + + it('should render links with underline in dark theme', () => { + const { container } = render( + + +

+ This is a paragraph with a link inside. +

+
+
+ ); + + const link = container.querySelector('a'); + expect(link).toBeTruthy(); + + const styles = window.getComputedStyle(link!); + expect(styles.textDecoration).toContain('underline'); + }); + + it('should render multiple links with underlines in text blocks', () => { + const { container } = render( + +
+

+ Check out this link and also{' '} + this other link. +

+

+ Here is a third link in another paragraph. +

+
+
+ ); + + const links = container.querySelectorAll('a'); + expect(links).toHaveLength(3); + + links.forEach((link) => { + const styles = window.getComputedStyle(link); + expect(styles.textDecoration).toContain('underline'); + }); + }); + + it('should not underline anchor position markers (a.anchor)', () => { + const { container } = render( + +

+ + Heading + +

+
+ ); + + const anchor = container.querySelector('a.anchor'); + expect(anchor).toBeTruthy(); + + const styles = window.getComputedStyle(anchor!); + expect(styles.textDecoration).not.toContain('underline'); + }); + }); +}); diff --git a/code/addons/docs/src/blocks/components/DocsPage.tsx b/code/addons/docs/src/blocks/components/DocsPage.tsx index 11e01c2c5765..d2f1537c2ab4 100644 --- a/code/addons/docs/src/blocks/components/DocsPage.tsx +++ b/code/addons/docs/src/blocks/components/DocsPage.tsx @@ -114,7 +114,10 @@ export const DocsContent = styled.div(({ theme }) => { lineHeight: '24px', color: theme.color.secondary, - textDecoration: 'none', + // Ensure WCAG Level A compliance (SC 1.4.1), see https://www.w3.org/WAI/WCAG22/Techniques/failures/F73 + textDecoration: 'underline', + textDecorationThickness: '0.03125rem', + textUnderlineOffset: '0.11em', '&.absent': { color: '#cc0000', }, @@ -127,6 +130,10 @@ export const DocsContent = styled.div(({ theme }) => { top: 0, left: 0, bottom: 0, + textDecoration: 'none', + }, + '&.anchor:hover, &.anchor:focus': { + textDecoration: 'underline', }, }, [toGlobalSelector('blockquote')]: { diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index 9eb15518646b..b0b9b6579783 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -63,7 +63,7 @@ }, "peerDependencies": { "storybook": "workspace:^", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "publishConfig": { "access": "public" diff --git a/code/builders/builder-vite/src/build.ts b/code/builders/builder-vite/src/build.ts index 46f1a22e1fb8..3a0891fae7aa 100644 --- a/code/builders/builder-vite/src/build.ts +++ b/code/builders/builder-vite/src/build.ts @@ -7,6 +7,7 @@ import type { InlineConfig } from 'vite'; import { createViteLogger } from './logger'; import type { WebpackStatsPlugin } from './plugins'; import { hasVitePlugins } from './utils/has-vite-plugins'; +import { bundlerOptionsKey } from './utils/vite-features'; import { withoutVitePlugins } from './utils/without-vite-plugins'; import { commonConfig } from './vite-config'; @@ -19,11 +20,13 @@ export async function build(options: Options) { const { presets } = options; const config = await commonConfig(options, 'build'); + config.build = mergeConfig(config, { build: { outDir: options.outputDir, emptyOutDir: false, // do not clean before running Vite build - Storybook has already added assets in there! - rollupOptions: { + // TODO: Remove bundlerOptionsKey and use 'rolldownOptions' directly once support for Vite < 8 is dropped + [bundlerOptionsKey]: { external: [/\.\/sb-common-assets\/.*\.woff2/], }, ...(options.test diff --git a/code/builders/builder-vite/src/plugins/code-generator-plugin.ts b/code/builders/builder-vite/src/plugins/code-generator-plugin.ts index 50a163e9ff9c..91afe7da7f0c 100644 --- a/code/builders/builder-vite/src/plugins/code-generator-plugin.ts +++ b/code/builders/builder-vite/src/plugins/code-generator-plugin.ts @@ -11,6 +11,7 @@ import { generateImportFnScriptCode } from '../codegen-importfn-script'; import { generateModernIframeScriptCode } from '../codegen-modern-iframe-script'; import { generateAddonSetupCode } from '../codegen-set-addon-channel'; import { transformIframeHtml } from '../transform-iframe-html'; +import { bundlerOptionsKey, ensureRolldownOptions } from '../utils/vite-features'; import { SB_VIRTUAL_FILES, SB_VIRTUAL_FILE_IDS, @@ -45,10 +46,17 @@ export function codeGeneratorPlugin(options: Options) { if (!config.build) { config.build = {}; } - config.build.rollupOptions = { - ...config.build.rollupOptions, + // TODO: Remove bundlerOptionsKey and use 'rolldownOptions' directly once support for Vite < 8 is dropped + const build = config.build as Record; + + // shared options between rollup/rolldown + build[bundlerOptionsKey] = { + ...build[bundlerOptionsKey], input: iframePath, }; + + // necessary rolldown specific overrides + ensureRolldownOptions(config); } }, configResolved(config) { diff --git a/code/builders/builder-vite/src/utils/vite-features.ts b/code/builders/builder-vite/src/utils/vite-features.ts new file mode 100644 index 000000000000..47a855174e63 --- /dev/null +++ b/code/builders/builder-vite/src/utils/vite-features.ts @@ -0,0 +1,30 @@ +import type { UserConfig } from 'vite'; +import { version } from 'vite'; + +// TODO: Remove once support for Vite < 8 is dropped +const shouldUseRolldownOptions = () => { + try { + return Number(version.split('.')[0]) >= 8; + } catch { + return false; + } +}; + +/** + * Returns the correct bundler options key based on the installed Vite version. Vite 8 renamed + * `build.rollupOptions` to `build.rolldownOptions`. + */ +// TODO: Remove once support for Vite < 8 is dropped, and use 'rolldownOptions' directly +export const bundlerOptionsKey = shouldUseRolldownOptions() ? 'rolldownOptions' : 'rollupOptions'; + +export function ensureRolldownOptions(config: UserConfig) { + if (!shouldUseRolldownOptions()) { + return; + } + + config.build ??= {}; + // @ts-expect-error - rolldownOptions will only exist with Vite 8+ + const rolldown = (config.build.rolldownOptions ??= {}); + const output = (rolldown.output ??= {}); + output.strictExecutionOrder = true; +} diff --git a/code/core/src/components/components/typography/DocumentWrapper.test.tsx b/code/core/src/components/components/typography/DocumentWrapper.test.tsx new file mode 100644 index 000000000000..3c15119bff92 --- /dev/null +++ b/code/core/src/components/components/typography/DocumentWrapper.test.tsx @@ -0,0 +1,83 @@ +// @vitest-environment happy-dom +import { cleanup, render } from '@testing-library/react'; +import { afterEach, describe, expect, it } from 'vitest'; + +import React from 'react'; + +import { ThemeProvider, convert, themes } from 'storybook/theming'; + +import { DocumentWrapper } from './DocumentWrapper'; + +function ThemedDocumentWrapper({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + +describe('DocumentWrapper', () => { + afterEach(() => { + cleanup(); + }); + + describe('accessibility', () => { + it('should render links with underline text decoration for accessibility', () => { + const { container } = render( + +

+ This is a paragraph with a link inside. +

+
+ ); + + const link = container.querySelector('a'); + expect(link).toBeTruthy(); + + const styles = window.getComputedStyle(link!); + expect(styles.textDecoration).toContain('underline'); + }); + + it('should render links with underline in dark theme', () => { + const { container } = render( + + +

+ This is a paragraph with a link inside. +

+
+
+ ); + + const link = container.querySelector('a'); + expect(link).toBeTruthy(); + + const styles = window.getComputedStyle(link!); + expect(styles.textDecoration).toContain('underline'); + }); + + it('should render multiple links with underlines in text blocks', () => { + const { container } = render( + +
+

+ Check out this link and also{' '} + this other link. +

+

+ Here is a third link in another paragraph. +

+
+
+ ); + + const links = container.querySelectorAll('a'); + expect(links).toHaveLength(3); + + links.forEach((link) => { + const styles = window.getComputedStyle(link); + expect(styles.textDecoration).toContain('underline'); + }); + }); + }); +}); diff --git a/code/core/src/components/components/typography/DocumentWrapper.tsx b/code/core/src/components/components/typography/DocumentWrapper.tsx index b5b4cca5eccb..25a91f33b3b7 100644 --- a/code/core/src/components/components/typography/DocumentWrapper.tsx +++ b/code/core/src/components/components/typography/DocumentWrapper.tsx @@ -64,7 +64,10 @@ export const DocumentWrapper = styled.div(({ theme }) => ({ }, a: { color: theme.color.secondary, - textDecoration: 'none', + // Ensure WCAG Level A compliance (SC 1.4.1), see https://www.w3.org/WAI/WCAG22/Techniques/failures/F73 + textDecoration: 'underline', + textDecorationThickness: '0.03125rem', + textUnderlineOffset: '0.11em', }, 'a.absent': { color: '#cc0000', @@ -78,6 +81,10 @@ export const DocumentWrapper = styled.div(({ theme }) => ({ top: 0, left: 0, bottom: 0, + textDecoration: 'none', + }, + '&.anchor:hover, &.anchor:focus': { + textDecoration: 'underline', }, 'h1, h2, h3, h4, h5, h6': { margin: '20px 0 10px', diff --git a/code/core/src/components/components/typography/elements/A.test.tsx b/code/core/src/components/components/typography/elements/A.test.tsx new file mode 100644 index 000000000000..cbb638ca8d5c --- /dev/null +++ b/code/core/src/components/components/typography/elements/A.test.tsx @@ -0,0 +1,75 @@ +// @vitest-environment happy-dom +import { cleanup, render } from '@testing-library/react'; +import { afterEach, describe, expect, it } from 'vitest'; + +import React from 'react'; + +import { ThemeProvider, convert, themes } from 'storybook/theming'; + +import { A } from './A'; + +function ThemedA({ children, ...props }: React.ComponentProps) { + return ( + + {children} + + ); +} + +describe('A', () => { + afterEach(() => { + cleanup(); + }); + + describe('accessibility', () => { + it('should render with underline text decoration for accessibility', () => { + const { container } = render(Test Link); + + const link = container.querySelector('a'); + expect(link).toBeTruthy(); + + const styles = window.getComputedStyle(link!); + expect(styles.textDecoration).toContain('underline'); + }); + + it('should render with underline in dark theme', () => { + const { container } = render( + + Test Link + + ); + + const link = container.querySelector('a'); + expect(link).toBeTruthy(); + + const styles = window.getComputedStyle(link!); + expect(styles.textDecoration).toContain('underline'); + }); + + it('should not underline anchor position markers (a.anchor)', () => { + const { container } = render( + + Anchor Link + + ); + + const link = container.querySelector('a.anchor'); + expect(link).toBeTruthy(); + + const styles = window.getComputedStyle(link!); + expect(styles.textDecoration).not.toContain('underline'); + }); + + it('should render with correct color and styling', () => { + const { container } = render(Link Text); + + const link = container.querySelector('a'); + expect(link).toBeTruthy(); + expect(link?.textContent).toBe('Link Text'); + + const styles = window.getComputedStyle(link!); + expect(styles.textDecoration).toContain('underline'); + expect(styles.fontSize).toBe('inherit'); + }); + }); +}); diff --git a/code/core/src/components/components/typography/elements/A.tsx b/code/core/src/components/components/typography/elements/A.tsx index e91833da6cfc..9ab4e9bf03b2 100644 --- a/code/core/src/components/components/typography/elements/A.tsx +++ b/code/core/src/components/components/typography/elements/A.tsx @@ -8,7 +8,10 @@ export const A = styled(Link)(withReset, ({ theme }) => ({ lineHeight: '24px', color: theme.color.secondary, - textDecoration: 'none', + // Ensure WCAG Level A compliance (SC 1.4.1), see https://www.w3.org/WAI/WCAG22/Techniques/failures/F73 + textDecoration: 'underline', + textDecorationThickness: '0.03125rem', + textUnderlineOffset: '0.11em', '&.absent': { color: '#cc0000', }, @@ -21,5 +24,9 @@ export const A = styled(Link)(withReset, ({ theme }) => ({ top: 0, left: 0, bottom: 0, + textDecoration: 'none', + }, + '&.anchor:hover, &.anchor:focus': { + textDecoration: 'underline', }, })); diff --git a/code/core/src/core-server/presets/common-preset.ts b/code/core/src/core-server/presets/common-preset.ts index 22387945616a..f1004214dc8b 100644 --- a/code/core/src/core-server/presets/common-preset.ts +++ b/code/core/src/core-server/presets/common-preset.ts @@ -93,7 +93,7 @@ export const favicon = async ( .reduce((l1, l2) => l1.concat(l2), []); if (faviconPaths.length > 1) { - logger.warn(dedent` + logger.debug(dedent` Looks like multiple favicons were detected. Using the first one. ${faviconPaths.join(', ')} diff --git a/code/core/src/core-server/presets/favicon.test.ts b/code/core/src/core-server/presets/favicon.test.ts index e6be6ebb054f..b35a99d6f602 100644 --- a/code/core/src/core-server/presets/favicon.test.ts +++ b/code/core/src/core-server/presets/favicon.test.ts @@ -49,7 +49,7 @@ const createOptions = (locations: string[]): Parameters[1] => vi.mock('storybook/internal/node-logger', () => { return { logger: { - warn: vi.fn(() => {}), + debug: vi.fn(() => {}), }, }; }); @@ -125,7 +125,7 @@ it('with staticDirs containing a single favicon.svg should return the found favi ); }); -it('with staticDirs containing a multiple favicons should return the first favicon and warn', async () => { +it('with staticDirs containing a multiple favicons should return the first favicon and show a debug message', async () => { const location = 'static'; existsSyncMock.mockImplementation((p) => { if (normalize(String(p)) === normalize(createPath(location))) { @@ -145,10 +145,10 @@ it('with staticDirs containing a multiple favicons should return the first favic normalize(createPath(location, 'favicon.svg')) ); - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('multiple favicons')); + expect(logger.debug).toHaveBeenCalledWith(expect.stringContaining('multiple favicons')); }); -it('with multiple staticDirs containing a multiple favicons should return the first favicon and warn', async () => { +it('with multiple staticDirs containing a multiple favicons should return the first favicon and show a debug message', async () => { const locationA = 'static-a'; const locationB = 'static-b'; existsSyncMock.mockImplementation((p) => { @@ -172,5 +172,5 @@ it('with multiple staticDirs containing a multiple favicons should return the fi normalize(createPath(locationA, 'favicon.ico')) ); - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('multiple favicons')); + expect(logger.debug).toHaveBeenCalledWith(expect.stringContaining('multiple favicons')); }); diff --git a/code/core/src/manager/components/error-boundary/ManagerErrorBoundary.stories.tsx b/code/core/src/manager/components/error-boundary/ManagerErrorBoundary.stories.tsx index 3d1cea253671..f12578d8c6f2 100644 --- a/code/core/src/manager/components/error-boundary/ManagerErrorBoundary.stories.tsx +++ b/code/core/src/manager/components/error-boundary/ManagerErrorBoundary.stories.tsx @@ -1,10 +1,33 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; -import { spyOn } from 'storybook/test'; +import { expect, fn, spyOn } from 'storybook/test'; import preview from '../../../../../.storybook/preview'; import { ManagerErrorBoundary } from './ManagerErrorBoundary'; +// Mocks for play assertions: set by decorator, asserted in play functions +let consoleErrorSpy: ReturnType; +const sendTelemetryErrorMock = fn(); + +// Stable wrapper: only cleanup in useEffect so teardown runs correctly with React Strict Mode. +// Setup must run synchronously in the decorator so the spy is in place before Story renders. +const RestoreGlobals = ({ + children, + originalSendTelemetryError, +}: { + children: React.ReactNode; + originalSendTelemetryError: typeof globalThis.sendTelemetryError; +}) => { + useEffect( + () => () => { + consoleErrorSpy.mockRestore(); + globalThis.sendTelemetryError = originalSendTelemetryError; + }, + [originalSendTelemetryError] + ); + return <>{children}; +}; + // Component that throws an error immediately when rendered const ThrowingComponent = ({ shouldThrow = true }: { shouldThrow?: boolean }) => { if (shouldThrow) { @@ -59,9 +82,15 @@ const meta = preview.meta({ }, decorators: [ (Story) => { - // Suppress console.error in stories to prevent noisy test output - spyOn(console, 'error').mockImplementation(() => {}); - return ; + consoleErrorSpy = spyOn(console, 'error').mockImplementation(() => {}); + sendTelemetryErrorMock.mockClear(); + const originalSendTelemetryError = globalThis.sendTelemetryError; + globalThis.sendTelemetryError = sendTelemetryErrorMock; + return ( + + + + ); }, ], }); @@ -74,6 +103,26 @@ export const WithError = meta.story({ ), + play: async ({ canvas }) => { + await expect(canvas.getByTestId('manager-error-boundary')).toBeInTheDocument(); + await expect(canvas.getByText('Something went wrong')).toBeInTheDocument(); + await expect( + canvas.getByText('This is a test error thrown by ThrowingComponent') + ).toBeInTheDocument(); + + await expect(consoleErrorSpy).toHaveBeenCalledWith( + 'Storybook Manager UI Error:', + expect.any(Error) + ); + await expect(consoleErrorSpy).toHaveBeenCalledWith('Component Stack:', expect.any(String)); + + await expect(sendTelemetryErrorMock).toHaveBeenCalledTimes(1); + await expect(sendTelemetryErrorMock).toHaveBeenCalledWith( + expect.objectContaining({ + message: 'This is a test error thrown by ThrowingComponent', + }) + ); + }, }); export const WithDeepStackTrace = meta.story({ @@ -93,6 +142,13 @@ export const WithoutError = meta.story({ ), + play: async ({ canvas }) => { + await expect(canvas.getByText('Everything is fine!')).toBeInTheDocument(); + await expect( + canvas.getByText('This content should render normally when there is no error.') + ).toBeInTheDocument(); + await expect(canvas.queryByTestId('manager-error-boundary')).not.toBeInTheDocument(); + }, }); export const InteractiveError = meta.story({ @@ -121,4 +177,19 @@ export const CustomErrorMessage = meta.story({ ); }, + play: async ({ canvas }) => { + await expect(canvas.getByTestId('manager-error-boundary')).toBeInTheDocument(); + await expect( + canvas.getByText( + 'Custom error: Unable to load addons configuration. Please check your manager.ts file.' + ) + ).toBeInTheDocument(); + + await expect(sendTelemetryErrorMock).toHaveBeenCalledWith( + expect.objectContaining({ + message: + 'Custom error: Unable to load addons configuration. Please check your manager.ts file.', + }) + ); + }, }); diff --git a/code/core/src/manager/components/error-boundary/ManagerErrorBoundary.tsx b/code/core/src/manager/components/error-boundary/ManagerErrorBoundary.tsx index 6aa356f2ca8c..cf4dd5605baa 100644 --- a/code/core/src/manager/components/error-boundary/ManagerErrorBoundary.tsx +++ b/code/core/src/manager/components/error-boundary/ManagerErrorBoundary.tsx @@ -196,6 +196,10 @@ export class ManagerErrorBoundary extends Component< console.error('Storybook Manager UI Error:', error); console.error('Component Stack:', errorInfo.componentStack); this.setState({ errorInfo }); + + if (typeof globalThis.sendTelemetryError === 'function') { + globalThis.sendTelemetryError(error); + } } render() { diff --git a/code/frameworks/angular/src/server/framework-preset-angular-cli.ts b/code/frameworks/angular/src/server/framework-preset-angular-cli.ts index 62ff798d118d..e27e897bf23a 100644 --- a/code/frameworks/angular/src/server/framework-preset-angular-cli.ts +++ b/code/frameworks/angular/src/server/framework-preset-angular-cli.ts @@ -1,6 +1,5 @@ import { logger } from 'storybook/internal/node-logger'; import { AngularLegacyBuildOptionsError } from 'storybook/internal/server-errors'; -import { WebpackDefinePlugin, WebpackIgnorePlugin } from '@storybook/builder-webpack5'; import type { BuilderContext } from '@angular-devkit/architect'; import { targetFromTargetString } from '@angular-devkit/architect'; @@ -9,7 +8,6 @@ import { logging } from '@angular-devkit/core'; import * as find from 'empathic/find'; import type webpack from 'webpack'; -import { getWebpackConfig as getCustomWebpackConfig } from './angular-cli-webpack'; import type { PresetOptions } from './preset-options'; import { getProjectRoot, resolvePackageDir } from 'storybook/internal/common'; import { relative } from 'pathe'; @@ -20,6 +18,9 @@ export async function webpackFinal(baseConfig: webpack.Configuration, options: P return baseConfig; } + const { WebpackDefinePlugin, WebpackIgnorePlugin } = await import('@storybook/builder-webpack5'); + const { getWebpackConfig: getCustomWebpackConfig } = await import('./angular-cli-webpack'); + checkForLegacyBuildOptions(options); const builderContext = getBuilderContext(options); diff --git a/code/frameworks/nextjs-vite/package.json b/code/frameworks/nextjs-vite/package.json index 88e7b0c5cbf1..b308569942e4 100644 --- a/code/frameworks/nextjs-vite/package.json +++ b/code/frameworks/nextjs-vite/package.json @@ -102,7 +102,7 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "workspace:^", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { diff --git a/code/frameworks/nextjs-vite/template/cli/js/Configure.mdx b/code/frameworks/nextjs-vite/template/cli/js/Configure.mdx index 70fcc2a9777c..923c1a47dc93 100644 --- a/code/frameworks/nextjs-vite/template/cli/js/Configure.mdx +++ b/code/frameworks/nextjs-vite/template/cli/js/Configure.mdx @@ -52,6 +52,7 @@ export const RightArrow = () => Add styling and CSS

Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.

Learn more @@ -67,6 +68,7 @@ export const RightArrow = () => Provide context and mocking

Often when a story doesn't render, it's because your component is expecting a specific environment or context (like a theme provider) to be available.

Learn more @@ -85,6 +87,7 @@ export const RightArrow = () => Learn more @@ -113,6 +116,7 @@ export const RightArrow = () => Auto-generate living, interactive reference documentation from your components and stories.

Learn more @@ -128,6 +132,7 @@ export const RightArrow = () => Publish to Chromatic

Publish your Storybook to review and collaborate with your entire team.

Learn more @@ -144,6 +149,7 @@ export const RightArrow = () => Embed your stories into Figma to cross-reference the design and live implementation in one place.

Learn more @@ -160,6 +166,7 @@ export const RightArrow = () => Use stories to test a component in all its variations, no matter how complex.

Learn more @@ -175,6 +182,7 @@ export const RightArrow = () => Accessibility

Automatically test your components for a11y issues as you develop.

Learn more @@ -190,6 +198,7 @@ export const RightArrow = () => Theming

Theme Storybook's UI to personalize it to your project.

Learn more @@ -202,6 +211,7 @@ export const RightArrow = () => Addons

Integrate your tools with Storybook to connect workflows.

Discover all addons @@ -229,6 +239,7 @@ export const RightArrow = () => Star on GitHub @@ -246,6 +257,7 @@ export const RightArrow = () => Join Discord server @@ -264,6 +276,7 @@ export const RightArrow = () => Watch on YouTube @@ -281,6 +294,7 @@ export const RightArrow = () => Follow guided walkthroughs on for key workflows.

Discover tutorials @@ -328,6 +342,16 @@ export const RightArrow = () => Add styling and CSS

Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.

Learn more @@ -67,6 +68,7 @@ export const RightArrow = () => Provide context and mocking

Often when a story doesn't render, it's because your component is expecting a specific environment or context (like a theme provider) to be available.

Learn more @@ -85,6 +87,7 @@ export const RightArrow = () => Learn more @@ -113,6 +116,7 @@ export const RightArrow = () => Auto-generate living, interactive reference documentation from your components and stories.

Learn more @@ -128,6 +132,7 @@ export const RightArrow = () => Publish to Chromatic

Publish your Storybook to review and collaborate with your entire team.

Learn more @@ -144,6 +149,7 @@ export const RightArrow = () => Embed your stories into Figma to cross-reference the design and live implementation in one place.

Learn more @@ -160,6 +166,7 @@ export const RightArrow = () => Use stories to test a component in all its variations, no matter how complex.

Learn more @@ -175,6 +182,7 @@ export const RightArrow = () => Accessibility

Automatically test your components for a11y issues as you develop.

Learn more @@ -190,6 +198,7 @@ export const RightArrow = () => Theming

Theme Storybook's UI to personalize it to your project.

Learn more @@ -202,6 +211,7 @@ export const RightArrow = () => Addons

Integrate your tools with Storybook to connect workflows.

Discover all addons @@ -229,6 +239,7 @@ export const RightArrow = () => Star on GitHub @@ -246,6 +257,7 @@ export const RightArrow = () => Join Discord server @@ -264,6 +276,7 @@ export const RightArrow = () => Watch on YouTube @@ -281,6 +294,7 @@ export const RightArrow = () => Follow guided walkthroughs on for key workflows.

Discover tutorials @@ -328,6 +342,16 @@ export const RightArrow = () => Add styling and CSS

Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.

Learn more @@ -67,6 +68,7 @@ export const RightArrow = () => Provide context and mocking

Often when a story doesn't render, it's because your component is expecting a specific environment or context (like a theme provider) to be available.

Learn more @@ -85,6 +87,7 @@ export const RightArrow = () => Learn more @@ -113,6 +116,7 @@ export const RightArrow = () => Auto-generate living, interactive reference documentation from your components and stories.

Learn more @@ -128,6 +132,7 @@ export const RightArrow = () => Publish to Chromatic

Publish your Storybook to review and collaborate with your entire team.

Learn more @@ -144,6 +149,7 @@ export const RightArrow = () => Embed your stories into Figma to cross-reference the design and live implementation in one place.

Learn more @@ -160,6 +166,7 @@ export const RightArrow = () => Use stories to test a component in all its variations, no matter how complex.

Learn more @@ -175,6 +182,7 @@ export const RightArrow = () => Accessibility

Automatically test your components for a11y issues as you develop.

Learn more @@ -190,6 +198,7 @@ export const RightArrow = () => Theming

Theme Storybook's UI to personalize it to your project.

Learn more @@ -202,6 +211,7 @@ export const RightArrow = () => Addons

Integrate your tools with Storybook to connect workflows.

Discover all addons @@ -229,6 +239,7 @@ export const RightArrow = () => Star on GitHub @@ -246,6 +257,7 @@ export const RightArrow = () => Join Discord server @@ -264,6 +276,7 @@ export const RightArrow = () => Watch on YouTube @@ -281,6 +294,7 @@ export const RightArrow = () => Follow guided walkthroughs on for key workflows.

Discover tutorials @@ -328,6 +342,16 @@ export const RightArrow = () => =0.74.5", "react-native-web": "^0.19.12 || ^0.20.0 || ^0.21.0", "storybook": "workspace:^", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "publishConfig": { "access": "public" diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index c50d9ce1a37a..e1d1939c0189 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -71,7 +71,7 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "workspace:^", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "publishConfig": { "access": "public" diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index 2ffa912fbe54..9ecc584baf26 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -70,7 +70,7 @@ "@sveltejs/vite-plugin-svelte": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "storybook": "workspace:^", "svelte": "^5.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "publishConfig": { "access": "public" diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index f242b60ac811..94a66e0fdf52 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -69,7 +69,7 @@ "peerDependencies": { "storybook": "workspace:^", "svelte": "^5.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "publishConfig": { "access": "public" diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index f7afb60afa3c..f11fc6c6a4d8 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -63,7 +63,7 @@ }, "peerDependencies": { "storybook": "workspace:^", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "publishConfig": { "access": "public" diff --git a/code/lib/create-storybook/rendererAssets/common/Configure.mdx b/code/lib/create-storybook/rendererAssets/common/Configure.mdx index 948e410a08b0..76966acfead3 100644 --- a/code/lib/create-storybook/rendererAssets/common/Configure.mdx +++ b/code/lib/create-storybook/rendererAssets/common/Configure.mdx @@ -48,6 +48,7 @@ export const RightArrow = () => Add styling and CSS

Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.

Learn more @@ -60,6 +61,7 @@ export const RightArrow = () => Provide context and mocking

Often when a story doesn't render, it's because your component is expecting a specific environment or context (like a theme provider) to be available.

Learn more @@ -72,6 +74,7 @@ export const RightArrow = () => Learn more @@ -94,6 +97,7 @@ export const RightArrow = () => Auto-generate living, interactive reference documentation from your components and stories.

Learn more @@ -103,6 +107,7 @@ export const RightArrow = () => Publish to Chromatic

Publish your Storybook to review and collaborate with your entire team.

Learn more @@ -113,6 +118,7 @@ export const RightArrow = () => Embed your stories into Figma to cross-reference the design and live implementation in one place.

Learn more @@ -123,6 +129,7 @@ export const RightArrow = () => Use stories to test a component in all its variations, no matter how complex.

Learn more @@ -132,6 +139,7 @@ export const RightArrow = () => Accessibility

Automatically test your components for a11y issues as you develop.

Learn more @@ -141,6 +149,7 @@ export const RightArrow = () => Theming

Theme Storybook's UI to personalize it to your project.

Learn more @@ -153,6 +162,7 @@ export const RightArrow = () => Addons

Integrate your tools with Storybook to connect workflows.

Discover all addons @@ -168,6 +178,7 @@ export const RightArrow = () => Star on GitHub @@ -178,6 +189,7 @@ export const RightArrow = () => Join Discord server @@ -189,6 +201,7 @@ export const RightArrow = () => Watch on YouTube @@ -199,6 +212,7 @@ export const RightArrow = () => Follow guided walkthroughs on for key workflows.

Discover tutorials @@ -246,6 +260,16 @@ export const RightArrow = () =>

Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.

Learn more @@ -60,6 +61,7 @@ export const RightArrow = () => Provide context and mocking

Often when a story doesn't render, it's because your component is expecting a specific environment or context (like a theme provider) to be available.

Learn more @@ -72,6 +74,7 @@ export const RightArrow = () => Learn more @@ -94,6 +97,7 @@ export const RightArrow = () => Auto-generate living, interactive reference documentation from your components and stories.

Learn more @@ -103,6 +107,7 @@ export const RightArrow = () => Publish to Chromatic

Publish your Storybook to review and collaborate with your entire team.

Learn more @@ -113,6 +118,7 @@ export const RightArrow = () => Embed your stories into Figma to cross-reference the design and live implementation in one place.

Learn more @@ -123,6 +129,7 @@ export const RightArrow = () => Use stories to test a component in all its variations, no matter how complex.

Learn more @@ -132,6 +139,7 @@ export const RightArrow = () => Accessibility

Automatically test your components for a11y issues as you develop.

Learn more @@ -141,6 +149,7 @@ export const RightArrow = () => Theming

Theme Storybook's UI to personalize it to your project.

Learn more @@ -153,6 +162,7 @@ export const RightArrow = () => Addons

Integrate your tools with Storybook to connect workflows.

Discover all addons @@ -168,6 +178,7 @@ export const RightArrow = () => Star on GitHub @@ -178,6 +189,7 @@ export const RightArrow = () => Join Discord server @@ -189,6 +201,7 @@ export const RightArrow = () => Watch on YouTube @@ -199,6 +212,7 @@ export const RightArrow = () => Follow guided walkthroughs on for key workflows.

Discover tutorials @@ -246,6 +260,16 @@ export const RightArrow = () => =0.74.5" react-native-web: ^0.19.12 || ^0.20.0 || ^0.21.0 storybook: "workspace:^" - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 languageName: unknown linkType: soft @@ -8387,7 +8387,7 @@ __metadata: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 storybook: "workspace:^" - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 languageName: unknown linkType: soft @@ -8650,7 +8650,7 @@ __metadata: "@sveltejs/vite-plugin-svelte": ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 storybook: "workspace:^" svelte: ^5.0.0 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 languageName: unknown linkType: soft @@ -8686,7 +8686,7 @@ __metadata: peerDependencies: storybook: "workspace:^" svelte: ^5.0.0 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 languageName: unknown linkType: soft @@ -8704,7 +8704,7 @@ __metadata: vue-docgen-api: "npm:^4.75.1" peerDependencies: storybook: "workspace:^" - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 languageName: unknown linkType: soft