diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b54804527df..61fb14255fc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 10.2.1 + +- Builder-Webpack5: Fix @vitest/mocker resolution issue - [#33315](https://github.com/storybookjs/storybook/pull/33315), thanks @valentinpalkovic! +- CLI: Add init telemetry for CLI integrations - [#33603](https://github.com/storybookjs/storybook/pull/33603), thanks @shilman! + ## 10.2.0 > Improved UI and story authoring ergonomics diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index 43ca0314a52f..8d79e5edf12b 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,13 @@ +## 10.3.0-alpha.1 + +- Builder-Webpack5: Fix @vitest/mocker resolution issue - [#33315](https://github.com/storybookjs/storybook/pull/33315), thanks @valentinpalkovic! +- CLI: Add init telemetry for CLI integrations - [#33603](https://github.com/storybookjs/storybook/pull/33603), thanks @shilman! +- Core: Fix `previewHref` when current path does not end with a slash - [#33647](https://github.com/storybookjs/storybook/pull/33647), thanks @ghengeveld! +- Core: Fix rendering of View Transitions in Firefox - [#33651](https://github.com/storybookjs/storybook/pull/33651), thanks @ghengeveld! +- Manifest: Add docs entries to debugger - [#33607](https://github.com/storybookjs/storybook/pull/33607), thanks @JReinhold! +- Theming: Export interface declaration for `ThemesGlobals` - [#33343](https://github.com/storybookjs/storybook/pull/33343), thanks @icopp! +- UI: Avoid large animation for reduced motion users - [#33530](https://github.com/storybookjs/storybook/pull/33530), thanks @Sidnioulz! + ## 10.3.0-alpha.0 - CLI: Fix onboarding not opening - [#33609](https://github.com/storybookjs/storybook/pull/33609), thanks @ndelangen! diff --git a/code/addons/themes/src/index.ts b/code/addons/themes/src/index.ts index 428b8e12eb58..f99c1096a117 100644 --- a/code/addons/themes/src/index.ts +++ b/code/addons/themes/src/index.ts @@ -3,7 +3,7 @@ import { definePreviewAddon } from 'storybook/internal/csf'; import * as addonAnnotations from './preview'; import type { ThemesTypes } from './types'; -export type { ThemesTypes } from './types'; +export type { ThemesGlobals, ThemesTypes } from './types'; export default () => definePreviewAddon(addonAnnotations); diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index 1c7438d29eb0..55443bc2e9cc 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -47,7 +47,6 @@ ], "dependencies": { "@storybook/csf-plugin": "workspace:*", - "@vitest/mocker": "3.2.4", "ts-dedent": "^2.0.0" }, "devDependencies": { diff --git a/code/builders/builder-vite/src/plugins/vite-inject-mocker/plugin.ts b/code/builders/builder-vite/src/plugins/vite-inject-mocker/plugin.ts index 8937c9a33bce..d8cc28d6b2b1 100644 --- a/code/builders/builder-vite/src/plugins/vite-inject-mocker/plugin.ts +++ b/code/builders/builder-vite/src/plugins/vite-inject-mocker/plugin.ts @@ -1,63 +1,35 @@ -import { readFileSync } from 'node:fs'; -import { join } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { resolvePackageDir } from 'storybook/internal/common'; +import type { ResolvedConfig } from 'vite'; -import { exactRegex } from '@rolldown/pluginutils'; -import { dedent } from 'ts-dedent'; -import type { ResolvedConfig, ViteDevServer } from 'vite'; - -const entryPath = '/vite-inject-mocker-entry.js'; - -const entryCode = dedent` - - `; - -let server: ViteDevServer; +const ENTRY_PATH = '/vite-inject-mocker-entry.js'; export const viteInjectMockerRuntime = (options: { previewConfigPath?: string | null; }): import('vite').Plugin => { + // Get the actual file path so Vite can resolve relative imports + const mockerRuntimePath = fileURLToPath( + import.meta.resolve('storybook/internal/mocking-utils/mocker-runtime') + ); + let viteConfig: ResolvedConfig; return { name: 'vite:storybook-inject-mocker-runtime', + enforce: 'pre', buildStart() { if (viteConfig.command === 'build') { this.emitFile({ type: 'chunk', - id: join( - resolvePackageDir('storybook'), - 'assets', - 'server', - 'mocker-runtime.template.js' - ), - fileName: entryPath.slice(1), + id: mockerRuntimePath, + fileName: ENTRY_PATH.slice(1), }); } }, - config() { - return { - optimizeDeps: { - include: ['@vitest/mocker', '@vitest/mocker/browser'], - }, - resolve: { - // Aliasing necessary for package managers like pnpm, since resolving modules from a virtual module - // leads to errors, if the imported module is not a dependency of the project. - // By resolving the module to the real path, we can avoid this issue. - alias: { - '@vitest/mocker/browser': fileURLToPath(import.meta.resolve('@vitest/mocker/browser')), - '@vitest/mocker': fileURLToPath(import.meta.resolve('@vitest/mocker')), - }, - }, - }; - }, configResolved(config) { viteConfig = config; }, - configureServer(server_) { - server = server_; + configureServer(server) { if (options.previewConfigPath) { server.watcher.on('change', (file) => { if (file === options.previewConfigPath) { @@ -69,31 +41,17 @@ export const viteInjectMockerRuntime = (options: { }); } }, - resolveId: { - filter: { - id: [exactRegex(entryPath)], - }, - handler(id) { - if (exactRegex(id).test(entryPath)) { - return id; - } - return null; - }, - }, - async load(id) { - if (exactRegex(id).test(entryPath)) { - return readFileSync( - join(resolvePackageDir('storybook'), 'assets', 'server', 'mocker-runtime.template.js'), - 'utf-8' - ); + resolveId(source) { + if (source === ENTRY_PATH) { + return mockerRuntimePath; } - - return null; + return undefined; }, transformIndexHtml(html: string) { const headTag = html.match(/]*>/); if (headTag) { + const entryCode = ``; const headTagIndex = html.indexOf(headTag[0]); const newHtml = html.slice(0, headTagIndex + headTag[0].length) + diff --git a/code/builders/builder-vite/src/plugins/vite-mock/plugin.ts b/code/builders/builder-vite/src/plugins/vite-mock/plugin.ts index 23861a121259..5f60995c05b0 100644 --- a/code/builders/builder-vite/src/plugins/vite-mock/plugin.ts +++ b/code/builders/builder-vite/src/plugins/vite-mock/plugin.ts @@ -3,6 +3,7 @@ import { readFileSync } from 'node:fs'; import { babelParser, extractMockCalls, + findMockRedirect, getAutomockCode, getRealPath, rewriteSbMockImportCalls, @@ -10,7 +11,6 @@ import { import { logger } from 'storybook/internal/node-logger'; import type { CoreConfig } from 'storybook/internal/types'; -import { findMockRedirect } from '@vitest/mocker/redirect'; import { normalize } from 'pathe'; import type { Plugin, ResolvedConfig } from 'vite'; diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index b2e090833673..8dc333960608 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -52,7 +52,6 @@ ], "dependencies": { "@storybook/core-webpack": "workspace:*", - "@vitest/mocker": "3.2.4", "case-sensitive-paths-webpack-plugin": "^2.4.0", "cjs-module-lexer": "^1.2.3", "css-loader": "^7.1.2", diff --git a/code/builders/builder-webpack5/src/plugins/webpack-mock-plugin.ts b/code/builders/builder-webpack5/src/plugins/webpack-mock-plugin.ts index 7a3f4b8f2dfe..dd53310fd231 100644 --- a/code/builders/builder-webpack5/src/plugins/webpack-mock-plugin.ts +++ b/code/builders/builder-webpack5/src/plugins/webpack-mock-plugin.ts @@ -4,12 +4,12 @@ import { fileURLToPath } from 'node:url'; import { babelParser, extractMockCalls, + findMockRedirect, getIsExternal, resolveExternalModule, resolveWithExtensions, } from 'storybook/internal/mocking-utils'; -import { findMockRedirect } from '@vitest/mocker/redirect'; import type { Compiler } from 'webpack'; // --- Type Definitions --- diff --git a/code/core/build-config.ts b/code/core/build-config.ts index ee417c6603aa..3c72209d7694 100644 --- a/code/core/build-config.ts +++ b/code/core/build-config.ts @@ -190,6 +190,16 @@ const config: BuildEntries = { entryPoint: './src/manager/globals-runtime.ts', dts: false, }, + /** + * It is required to be a runtime entry point, because it is used to inject the mocker runtime + * into the preview iframe in builder-vite and builder-webpack5. To guarantee that the mocker + * runtime is transpiled correctly, code splitting needs to be disabled for this entry point. + */ + { + exportEntries: ['./internal/mocking-utils/mocker-runtime'], + entryPoint: './src/mocking-utils/mocker-runtime.js', + dts: false, + }, ], globalizedRuntime: [ { diff --git a/code/core/package.json b/code/core/package.json index 2548446aafec..f05f72381cf7 100644 --- a/code/core/package.json +++ b/code/core/package.json @@ -126,6 +126,7 @@ "types": "./dist/mocking-utils/index.d.ts", "default": "./dist/mocking-utils/index.js" }, + "./internal/mocking-utils/mocker-runtime": "./dist/mocking-utils/mocker-runtime.js", "./internal/node-logger": { "types": "./dist/node-logger/index.d.ts", "default": "./dist/node-logger/index.js" @@ -255,6 +256,7 @@ "@types/react-syntax-highlighter": "11.0.5", "@types/semver": "^7.7.1", "@types/ws": "^8", + "@vitest/mocker": "3.2.4", "@vitest/utils": "^3.2.4", "@yarnpkg/fslib": "2.10.3", "@yarnpkg/libzip": "2.3.0", diff --git a/code/core/src/core-server/utils/manifests/manifests.test.ts b/code/core/src/core-server/utils/manifests/manifests.test.ts index 8111e48b7802..8cbeb17f19f4 100644 --- a/code/core/src/core-server/utils/manifests/manifests.test.ts +++ b/code/core/src/core-server/utils/manifests/manifests.test.ts @@ -99,6 +99,30 @@ describe('manifests', () => { expect(files['/output/manifests/components.html']).toContain(''); }); + it('should write HTML file when docs manifest exists', async () => { + mockManifests = { + docs: { + v: 0, + docs: { + 'intro--docs': { + id: 'intro--docs', + name: 'docs', + path: './Intro.mdx', + title: 'Intro', + content: '# Introduction', + }, + }, + }, + }; + + await writeManifests('/output', mockPresets); + + const files = vol.toJSON(); + expect(files['/output/manifests/components.html']).toBeDefined(); + expect(files['/output/manifests/components.html']).toContain(''); + expect(files['/output/manifests/components.html']).toContain('Unattached Docs'); + }); + it('should handle errors when presets.apply fails', async () => { const error = new Error('Preset application failed'); vi.mocked(mockPresets.apply).mockRejectedValue(error); @@ -360,11 +384,11 @@ describe('manifests', () => { expect(res.end).toHaveBeenCalled(); const html = (res.end as any).mock.calls[0][0]; expect(html).toContain(''); - expect(html).toContain('Components Manifest'); + expect(html).toContain('Manifest Debugger'); expect(res.statusCode).toBeUndefined(); }); - it('should return 404 message when components manifest does not exist', async () => { + it('should return 404 message when no components or docs manifest exist', async () => { mockManifests = { other: { data: 'value' }, }; @@ -383,7 +407,9 @@ describe('manifests', () => { expect(res.statusCode).toBe(404); expect(res.setHeader).toHaveBeenCalledWith('Content-Type', 'text/html; charset=utf-8'); - expect(res.end).toHaveBeenCalledWith('
No components manifest configured.
'); + expect(res.end).toHaveBeenCalledWith( + '
No components or docs manifest configured.
' + ); }); it('should return 404 when manifests is empty', async () => { @@ -402,7 +428,9 @@ describe('manifests', () => { await handler(req, res); expect(res.statusCode).toBe(404); - expect(res.end).toHaveBeenCalledWith('
No components manifest configured.
'); + expect(res.end).toHaveBeenCalledWith( + '
No components or docs manifest configured.
' + ); }); it('should handle errors with 500 status and return error HTML', async () => { diff --git a/code/core/src/core-server/utils/manifests/manifests.ts b/code/core/src/core-server/utils/manifests/manifests.ts index 386c920270ac..04cf2788aaec 100644 --- a/code/core/src/core-server/utils/manifests/manifests.ts +++ b/code/core/src/core-server/utils/manifests/manifests.ts @@ -8,7 +8,7 @@ import type { Polka } from 'polka'; import invariant from 'tiny-invariant'; import { Tag } from '../../../shared/constants/tags'; -import { renderComponentsManifest } from './render-components-manifest'; +import { type DocsManifest, renderComponentsManifest } from './render-components-manifest'; async function getManifests(presets: Presets) { const generator = await presets.apply('storyIndexGenerator'); @@ -37,10 +37,13 @@ export async function writeManifests(outputDir: string, presets: Presets) { writeFile(join(outputDir, 'manifests', `${name}.json`), JSON.stringify(content)) ) ); - if ('components' in manifests) { + if ('components' in manifests || 'docs' in manifests) { await writeFile( join(outputDir, 'manifests', 'components.html'), - renderComponentsManifest(manifests.components as ComponentsManifest) + renderComponentsManifest( + manifests.components as ComponentsManifest | undefined, + manifests.docs as DocsManifest | undefined + ) ); } } catch (e) { @@ -72,17 +75,18 @@ export function registerManifests({ app, presets }: { app: Polka; presets: Prese app.get('/manifests/components.html', async (req, res) => { try { const manifests = await getManifests(presets); - const manifest = manifests.components; + const componentsManifest = manifests.components; + const docsManifest = manifests.docs as DocsManifest | undefined; - if (!manifest) { + if (!componentsManifest && !docsManifest) { res.statusCode = 404; res.setHeader('Content-Type', 'text/html; charset=utf-8'); - res.end(`
No components manifest configured.
`); + res.end(`
No components or docs manifest configured.
`); return; } res.setHeader('Content-Type', 'text/html; charset=utf-8'); - res.end(renderComponentsManifest(manifest)); + res.end(renderComponentsManifest(componentsManifest, docsManifest)); } catch (e) { res.statusCode = 500; res.setHeader('Content-Type', 'text/html; charset=utf-8'); diff --git a/code/core/src/core-server/utils/manifests/render-components-manifest.ts b/code/core/src/core-server/utils/manifests/render-components-manifest.ts index 9a22308e6b23..73d65c1bbf7b 100644 --- a/code/core/src/core-server/utils/manifests/render-components-manifest.ts +++ b/code/core/src/core-server/utils/manifests/render-components-manifest.ts @@ -4,20 +4,56 @@ import { groupBy } from 'storybook/internal/common'; import type { ComponentManifest, ComponentsManifest } from '../../../types'; +/** Minimal docs entry type for rendering in the manifest debugger */ +interface DocsManifestEntry { + id: string; + name: string; + path: string; + title: string; + content?: string; + summary?: string; + error?: { name: string; message: string }; +} + +/** Minimal docs manifest type for rendering in the manifest debugger */ +export interface DocsManifest { + v: number; + docs: Record; +} + +/** Extended component manifest that may include docs from the docs addon */ +interface ComponentManifestWithDocs extends ComponentManifest { + docs?: Record; +} + // AI generated manifests/components.html page // Only HTML/CSS no JS -export function renderComponentsManifest(manifest: ComponentsManifest) { +export function renderComponentsManifest( + manifest: ComponentsManifest | undefined, + docsManifest?: DocsManifest +) { const entries = Object.entries(manifest?.components ?? {}).sort((a, b) => (a[1].name || a[0]).localeCompare(b[1].name || b[0]) ); + // Get unattached docs entries + const docsEntries = Object.entries(docsManifest?.docs ?? {}).sort((a, b) => + (a[1].name || a[0]).localeCompare(b[1].name || b[0]) + ); + const analyses = entries.map(([, c]) => analyzeComponent(c)); + const docsAnalyses = docsEntries.map(([, d]) => analyzeDoc(d)); + const attachedDocs = analyses.reduce((sum, a) => sum + a.totalDocs, 0); + const attachedDocsWithError = analyses.reduce((sum, a) => sum + a.docsErrors, 0); + const unattachedDocsWithError = docsAnalyses.filter((a) => a.hasError).length; const totals = { components: entries.length, componentsWithPropTypeError: analyses.filter((a) => a.hasPropTypeError).length, infos: analyses.filter((a) => a.hasWarns).length, stories: analyses.reduce((sum, a) => sum + a.totalStories, 0), storyErrors: analyses.reduce((sum, a) => sum + a.storyErrors, 0), + docs: docsEntries.length + attachedDocs, + docsWithError: unattachedDocsWithError + attachedDocsWithError, }; // Top filters (clickable), no tags; 1px active ring lives in CSS via :target @@ -25,7 +61,9 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { const compErrorsPill = totals.componentsWithPropTypeError > 0 ? `${totals.componentsWithPropTypeError}/${totals.components} prop type ${plural(totals.componentsWithPropTypeError, 'error')}` - : `${totals.components} components ok`; + : totals.components > 0 + ? `${totals.components} components ok` + : ''; const compInfosPill = totals.infos > 0 ? `${totals.infos}/${totals.components} ${plural(totals.infos, 'info', 'infos')}` @@ -33,9 +71,18 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { const storiesPill = totals.storyErrors > 0 ? `${totals.storyErrors}/${totals.stories} story errors` - : `${totals.stories} ${plural(totals.stories, 'story', 'stories')} ok`; + : totals.stories > 0 + ? `${totals.stories} ${plural(totals.stories, 'story', 'stories')} ok` + : ''; + const docsPill = + totals.docs > 0 + ? totals.docsWithError > 0 + ? `${totals.docsWithError}/${totals.docs} doc ${plural(totals.docsWithError, 'error')}` + : `${totals.docs} ${plural(totals.docs, 'doc')} ok` + : ''; const grid = entries.map(([key, c], idx) => renderComponentCard(key, c, `${idx}`)).join(''); + const docsGrid = docsEntries.map(([key, d], idx) => renderDocCard(key, d, `doc-${idx}`)).join(''); const errorGroups = Object.entries( groupBy( @@ -190,7 +237,9 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { #filter-all:target ~ header .filter-pill[data-k='all'], #filter-errors:target ~ header .filter-pill[data-k='errors'], #filter-infos:target ~ header .filter-pill[data-k='infos'], - #filter-story-errors:target ~ header .filter-pill[data-k='story-errors'] { + #filter-story-errors:target ~ header .filter-pill[data-k='story-errors'], + #filter-doc-errors:target ~ header .filter-pill[data-k='docs'], + #filter-docs:target ~ header .filter-pill[data-k='docs'] { box-shadow: 0 0 0 var(--active-ring) currentColor; border-color: currentColor; } @@ -199,7 +248,9 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { #filter-all, #filter-errors, #filter-infos, - #filter-story-errors { + #filter-story-errors, + #filter-doc-errors, + #filter-docs { display: none; } @@ -312,6 +363,8 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { .tg-err:checked + label.as-toggle, .tg-info:checked + label.as-toggle, .tg-stories:checked + label.as-toggle, + .tg-docs:checked + label.as-toggle, + .tg-content:checked + label.as-toggle, .tg-props:checked + label.as-toggle { box-shadow: 0 0 0 var(--active-ring) currentColor; border-color: currentColor; @@ -341,6 +394,16 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { gap: 8px; } + .tg-docs:checked ~ .panels .panel-docs { + display: grid; + gap: 8px; + } + + .tg-content:checked ~ .panels .panel-content { + display: grid; + gap: 8px; + } + .tg-props:checked ~ .panels .panel-props { display: grid; } @@ -501,6 +564,19 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { display: none; } + #filter-doc-errors:target ~ main .card:not(.has-doc-error) { + display: none; + } + + #filter-docs:target ~ main .card:has(> .tg-docs), + #filter-docs:target ~ main .card.is-doc { + display: block; + } + + #filter-docs:target ~ main .card:not(:has(> .tg-docs)):not(.is-doc) { + display: none; + } + #filter-all:target ~ main .card { display: block; } @@ -515,6 +591,19 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { display: block; } + /* Section titles */ + .section-title { + font-size: 16px; + font-weight: 600; + color: var(--muted); + margin: 24px 0 12px; + padding-bottom: 8px; + border-bottom: 1px solid var(--border); + } + .section-title:first-child { + margin-top: 0; + } + /* When a toggle is checked, show the corresponding panel */ .card > .tg-err:checked ~ .panels .panel-err { display: grid; @@ -528,10 +617,20 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { display: grid; } + .card > .tg-docs:checked ~ .panels .panel-docs { + display: grid; + } + + .card > .tg-content:checked ~ .panels .panel-content { + display: grid; + } + /* Add vertical spacing around panels only when any panel is visible */ .card > .tg-err:checked ~ .panels, .card > .tg-info:checked ~ .panels, .card > .tg-stories:checked ~ .panels, + .card > .tg-docs:checked ~ .panels, + .card > .tg-content:checked ~ .panels, .card > .tg-props:checked ~ .panels { margin: 10px 0; } @@ -541,6 +640,8 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { .card:has(.tg-err:checked) label[for$='-err'], .card:has(.tg-info:checked) label[for$='-info'], .card:has(.tg-stories:checked) label[for$='-stories'], + .card:has(.tg-docs:checked) label[for$='-docs'], + .card:has(.tg-content:checked) label[for$='-content'], .card:has(.tg-props:checked) label[for$='-props'] { box-shadow: 0 0 0 1px currentColor; border-color: currentColor; @@ -565,6 +666,17 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { word-break: inherit; inline-size: min(100%, 120ch); } + + /* MDX content container for docs */ + .mdx-content { + background: #0f131b; + border: 1px solid var(--border); + border-radius: 10px; + padding: 12px; + max-height: 400px; + overflow-y: auto; + margin-top: 8px; + } @@ -573,25 +685,42 @@ export function renderComponentsManifest(manifest: ComponentsManifest) { + +
-

Components Manifest

-
${allPill}${compErrorsPill}${compInfosPill}${storiesPill}
+

Manifest Debugger

+
${allPill}${compErrorsPill}${compInfosPill}${storiesPill}${docsPill}
+ ${ + grid + ? `

Components

- ${ - grid || - `
No components.
` - } -
+ ${grid} +
` + : '' + } ${ errorGroups.length ? `
${errorGroupsHTML}
` : '' } + ${ + docsGrid + ? `

Unattached Docs

+
+ ${docsGrid} +
` + : '' + } + ${ + !grid && !docsGrid + ? `
No components or docs.
` + : '' + }
@@ -605,7 +734,7 @@ const esc = (s: unknown) => ); const plural = (n: number, one: string, many = `${one}s`) => (n === 1 ? one : many); -function analyzeComponent(c: ComponentManifest) { +function analyzeComponent(c: ComponentManifestWithDocs) { const hasPropTypeError = !!c.error; const warns: string[] = []; @@ -623,7 +752,13 @@ function analyzeComponent(c: ComponentManifest) { const storyErrors = (c.stories ?? []).filter((e) => !!e?.error).length; const storyOk = totalStories - storyErrors; - const hasAnyError = hasPropTypeError || storyErrors > 0; // for status dot (red if any errors) + // Analyze attached docs + const docsEntries = c.docs ? Object.values(c.docs) : []; + const totalDocs = docsEntries.length; + const docsErrors = docsEntries.filter((d) => !!d?.error).length; + const docsOk = totalDocs - docsErrors; + + const hasAnyError = hasPropTypeError || storyErrors > 0 || docsErrors > 0; // for status dot (red if any errors) return { hasPropTypeError, @@ -633,6 +768,15 @@ function analyzeComponent(c: ComponentManifest) { totalStories, storyErrors, storyOk, + totalDocs, + docsErrors, + docsOk, + }; +} + +function analyzeDoc(d: DocsManifestEntry) { + return { + hasError: !!d.error, }; } @@ -644,13 +788,82 @@ function note(title: string, bodyHTML: string, kind: 'info' | 'err') { `; } -function renderComponentCard(key: string, c: ComponentManifest, id: string) { +function renderDocCard(key: string, d: DocsManifestEntry, id: string) { + const a = analyzeDoc(d); + const statusDot = a.hasError ? 'dot-err' : 'dot-ok'; + + const slug = `${id}-${(d.id || key) + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, '')}`; + + const errorBadge = a.hasError + ? `` + : ''; + + const contentBadge = d.content + ? `` + : ''; + + return ` +
+
+
+

${esc(d.title || d.name || key)}

+
+ ${errorBadge} + ${contentBadge} +
+
+
${esc(d.id)} ยท ${esc(d.path)}
+ ${d.summary ? `
${esc(d.summary)}
` : ''} +
+ + + ${a.hasError ? `` : ''} + ${d.content ? `` : ''} + +
+ ${ + a.hasError + ? ` +
+
+
${esc(d.error?.name || 'Error')}
+
${esc(d.error?.message || 'Unknown error')}
+
+
` + : '' + } + ${ + d.content + ? ` +
+
+
${esc(d.content)}
+
+
` + : '' + } +
+
`; +} + +function renderComponentCard(key: string, c: ComponentManifestWithDocs, id: string) { const a = analyzeComponent(c); const statusDot = a.hasAnyError ? 'dot-err' : 'dot-ok'; const allStories = c.stories ?? []; const errorStories = allStories.filter((ex) => !!ex?.error); const okStories = allStories.filter((ex) => !ex?.error); + // Get attached docs entries + const allDocs = c.docs ? Object.values(c.docs) : []; + const errorDocs = allDocs.filter((d) => !!d?.error); + const okDocs = allDocs.filter((d) => !d?.error); + const slug = `c-${id}-${(c.id || key) .toLowerCase() .replace(/[^a-z0-9]+/g, '-') @@ -669,6 +882,11 @@ function renderComponentCard(key: string, c: ComponentManifest, id: string) { ? `` : ''; + const docsBadge = + a.totalDocs > 0 + ? `` + : ''; + // When there is no prop type error, try to read prop types from reactDocgen if present const reactDocgen: any = !a.hasPropTypeError && 'reactDocgen' in c && c.reactDocgen; const parsedDocgen = reactDocgen ? parseReactDocgen(reactDocgen) : undefined; @@ -715,7 +933,8 @@ function renderComponentCard(key: string, c: ComponentManifest, id: string) { class="card ${a.hasPropTypeError ? 'has-error' : 'no-error'} ${a.hasWarns ? 'has-info' : 'no-info'} - ${a.storyErrors ? 'has-story-error' : 'no-story-error'}" + ${a.storyErrors ? 'has-story-error' : 'no-story-error'} + ${a.docsErrors ? 'has-doc-error' : 'no-doc-error'}" role="listitem" aria-label="${esc(c.name || key)}">
@@ -725,6 +944,7 @@ function renderComponentCard(key: string, c: ComponentManifest, id: string) { ${primaryBadge} ${infosBadge} ${storiesBadge} + ${docsBadge}
${esc(c.id)} ยท ${esc(c.path)}
@@ -737,6 +957,7 @@ function renderComponentCard(key: string, c: ComponentManifest, id: string) { ${a.hasPropTypeError ? `` : ''} ${a.hasWarns ? `` : ''} ${a.totalStories > 0 ? `` : ''} + ${a.totalDocs > 0 ? `` : ''} ${!a.hasPropTypeError && propEntries.length > 0 ? `` : ''}
@@ -821,6 +1042,41 @@ function renderComponentCard(key: string, c: ComponentManifest, id: string) {
` : '' } + ${ + a.totalDocs > 0 + ? ` +
+ ${errorDocs + .map( + (doc) => ` +
+
+ ${esc(doc.name)} + doc error +
+
${esc(doc.path)}
+ ${doc?.summary ? `
${esc(doc.summary)}
` : ''} + ${doc?.error?.message ? `
${esc(doc.error.message)}
` : ''} +
` + ) + .join('')} + ${okDocs + .map( + (doc) => ` +
+
+ ${esc(doc.name)} + doc ok +
+
${esc(doc.path)}
+ ${doc?.summary ? `
${esc(doc.summary)}
` : ''} + ${doc?.content ? `
${esc(doc.content)}
` : ''} +
` + ) + .join('')} +
` + : '' + } `; } diff --git a/code/core/src/manager-api/modules/url.ts b/code/core/src/manager-api/modules/url.ts index 83633a00de4e..b7f37e179e59 100644 --- a/code/core/src/manager-api/modules/url.ts +++ b/code/core/src/manager-api/modules/url.ts @@ -247,13 +247,14 @@ export const init: ModuleFn = (moduleArgs) => { throw new Error(`Invalid refId: ${refId}`); } - const originAddress = global.window.location.origin + location.pathname; + const pathname = location.pathname || '/'; + const originAddress = global.window.location.origin + pathname; const networkAddress = global.STORYBOOK_NETWORK_ADDRESS ?? originAddress; const managerBase = - base === 'origin' ? originAddress : base === 'network' ? networkAddress : location.pathname; + base === 'origin' ? originAddress : base === 'network' ? networkAddress : pathname; const previewBase = refId ? refs[refId].url + '/iframe.html' - : global.PREVIEW_URL || `${managerBase}iframe.html`; + : global.PREVIEW_URL || `${managerBase.replace(/\/[^/]*$/, '/')}iframe.html`; const refParam = refId ? `&refId=${encodeURIComponent(refId)}` : ''; const { args = '', globals = '', ...otherParams } = queryParams; diff --git a/code/core/src/manager-api/tests/url.test.js b/code/core/src/manager-api/tests/url.test.js index a32e062cbd31..aedbc591d13e 100644 --- a/code/core/src/manager-api/tests/url.test.js +++ b/code/core/src/manager-api/tests/url.test.js @@ -469,5 +469,21 @@ describe('getStoryHrefs', () => { const { managerHref, previewHref } = api.getStoryHrefs('test--story'); expect(managerHref).toEqual('/?path=/story/test--story'); expect(previewHref).toEqual('https://custom.preview.url/?id=test--story&viewMode=story'); + delete global.PREVIEW_URL; + }); + + it('correctly links from /index.html', () => { + const { api, state } = initURL({ + store, + provider: { channel: new EventEmitter() }, + state: { location: { pathname: '/index.html', search: '' } }, + navigate: vi.fn(), + fullAPI: { getCurrentStoryData: () => ({ id: 'test--story' }) }, + }); + store.setState(state); + + const { managerHref, previewHref } = api.getStoryHrefs('test--story'); + expect(managerHref).toEqual('/index.html?path=/story/test--story'); + expect(previewHref).toEqual('/iframe.html?id=test--story&viewMode=story'); }); }); diff --git a/code/core/src/manager/components/layout/useLandmarkIndicator.ts b/code/core/src/manager/components/layout/useLandmarkIndicator.ts index 82f595508968..7226ef483511 100644 --- a/code/core/src/manager/components/layout/useLandmarkIndicator.ts +++ b/code/core/src/manager/components/layout/useLandmarkIndicator.ts @@ -2,6 +2,8 @@ import { useEffect, useRef } from 'react'; import { useTheme } from 'storybook/theming'; +import { useMediaQuery } from '../../hooks/useMedia'; + function findActiveLandmarkElement() { let currentElement: Element | null = document.activeElement; let landmarkElement: HTMLElement | null = null; @@ -23,6 +25,7 @@ function findActiveLandmarkElement() { // which region of the UI they landed into. export function useLandmarkIndicator() { const theme = useTheme(); + const reducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)'); const currentAnimationRef = useRef(null); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { @@ -41,23 +44,25 @@ export function useLandmarkIndicator() { currentAnimationRef.current = null; } - const animation = landmarkElement.animate( - [{ border: `2px solid ${theme.color.primary}` }, { border: `2px solid transparent` }], - { - duration: 1500, - pseudoElement: '::after', - } - ); - currentAnimationRef.current = animation; + if (!reducedMotion) { + const animation = landmarkElement.animate( + [{ border: `2px solid ${theme.color.primary}` }, { border: `2px solid transparent` }], + { + duration: 1500, + pseudoElement: '::after', + } + ); + currentAnimationRef.current = animation; - animation.onfinish = () => { - currentAnimationRef.current = null; - }; + animation.onfinish = () => { + currentAnimationRef.current = null; + }; + } }; document.addEventListener('keydown', handleKeyDown, { capture: true }); return () => { document.removeEventListener('keydown', handleKeyDown, { capture: true }); }; - }, [theme.color.primary]); + }, [reducedMotion, theme.color.primary]); } diff --git a/code/core/src/manager/components/preview/Viewport.tsx b/code/core/src/manager/components/preview/Viewport.tsx index 9c0fa7f46975..78d0e5910878 100644 --- a/code/core/src/manager/components/preview/Viewport.tsx +++ b/code/core/src/manager/components/preview/Viewport.tsx @@ -359,7 +359,7 @@ export const Viewport = ({ style={{ height: `${(1 / scale) * 100}%`, width: `${(1 / scale) * 100}%`, - transform: `scale(${scale})`, + transform: scale !== 1 ? `scale(${scale})` : 'none', transformOrigin: 'top left', }} > diff --git a/code/core/src/mocking-utils/index.ts b/code/core/src/mocking-utils/index.ts index 5d418381446e..f6ef78ec4af5 100644 --- a/code/core/src/mocking-utils/index.ts +++ b/code/core/src/mocking-utils/index.ts @@ -3,3 +3,4 @@ export * from './extract'; export * from './resolve'; export * from './esmWalker'; export * from './runtime'; +export * from './redirect'; diff --git a/code/core/assets/server/mocker-runtime.template.js b/code/core/src/mocking-utils/mocker-runtime.js similarity index 100% rename from code/core/assets/server/mocker-runtime.template.js rename to code/core/src/mocking-utils/mocker-runtime.js diff --git a/code/core/src/mocking-utils/redirect.ts b/code/core/src/mocking-utils/redirect.ts new file mode 100644 index 000000000000..fdeef615419c --- /dev/null +++ b/code/core/src/mocking-utils/redirect.ts @@ -0,0 +1,3 @@ +// Re-export findMockRedirect from @vitest/mocker/redirect +// This allows builders to use it without depending on @vitest/mocker directly +export { findMockRedirect } from '@vitest/mocker/redirect'; diff --git a/code/core/src/mocking-utils/runtime.ts b/code/core/src/mocking-utils/runtime.ts index eca3c51629f4..be8b131ba6f0 100644 --- a/code/core/src/mocking-utils/runtime.ts +++ b/code/core/src/mocking-utils/runtime.ts @@ -1,28 +1,13 @@ -import { resolvePackageDir } from 'storybook/internal/common'; - -import { buildSync } from 'esbuild'; -import { join } from 'pathe'; - -const runtimeTemplatePath = join( - resolvePackageDir('storybook'), - 'assets', - 'server', - 'mocker-runtime.template.js' -); - -export function getMockerRuntime() { - // Use esbuild to bundle the runtime script and its dependencies (`@vitest/mocker`, etc.) - // into a single, self-contained string of code. - const bundleResult = buildSync({ - entryPoints: [runtimeTemplatePath], - bundle: true, - write: false, // Return the result in memory instead of writing to disk - format: 'esm', - target: 'es2020', - external: ['msw/browser', 'msw/core/http'], - }); - - const runtimeScriptContent = bundleResult.outputFiles[0].text; - - return runtimeScriptContent; +import { readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; + +/** + * Returns the bundled mocker runtime script content. This is used by builders (webpack5, vite, + * etc.) to inject the mocker runtime into the preview iframe. + */ +export function getMockerRuntime(): string { + return readFileSync( + fileURLToPath(import.meta.resolve('storybook/internal/mocking-utils/mocker-runtime')), + 'utf-8' + ); } diff --git a/code/core/src/preview-api/modules/store/csf/portable-stories.ts b/code/core/src/preview-api/modules/store/csf/portable-stories.ts index 60fa3d7450bb..35a9ef931d9c 100644 --- a/code/core/src/preview-api/modules/store/csf/portable-stories.ts +++ b/code/core/src/preview-api/modules/store/csf/portable-stories.ts @@ -169,7 +169,7 @@ export function composeStory { }); }); - test.describe('Tool: get-story-urls', () => { + test.describe('Tool: preview-stories', () => { test('should return story URLs for valid stories', async ({ request }) => { + const storyName = 'Primary'; + const expectedPreviewUrl = `${storybookUrl}/?path=/story/example-button--primary`; + // Use a path pattern that works regardless of sandbox location const response = await mcpRequest(request, 'tools/call', { - name: 'get-story-urls', + name: 'preview-stories', arguments: { stories: [ { - exportName: 'Primary', - // Use a relative-style path that the tool should recognize - absoluteStoryPath: '/src/stories/Button.stories.ts', + exportName: storyName, + absoluteStoryPath: path.join(sandboxDir, 'src', 'stories', 'Button.stories.ts'), }, ], }, }); - expect(response.result).toHaveProperty('content'); - expect(response.result.content).toHaveLength(1); - // Should contain either a valid URL or an error message about the story - expect(response.result.content[0]).toHaveProperty('text'); + expect(response.result).toStrictEqual({ + content: [ + { + type: 'text', + text: expectedPreviewUrl, + }, + ], + structuredContent: { + stories: [ + { + name: storyName, + previewUrl: expectedPreviewUrl, + title: 'Example/Button', + }, + ], + }, + }); }); }); diff --git a/code/lib/create-storybook/src/services/VersionService.test.ts b/code/lib/create-storybook/src/services/VersionService.test.ts index 1927fef28334..4f7d06f4e156 100644 --- a/code/lib/create-storybook/src/services/VersionService.test.ts +++ b/code/lib/create-storybook/src/services/VersionService.test.ts @@ -131,6 +131,57 @@ describe('VersionService', () => { expect(integration).toBeUndefined(); }); + + it('should detect create-rsbuild command', () => { + const ancestry = [{ command: 'npx create-rsbuild' }, { command: 'node /usr/local/bin/npm' }]; + + const integration = versionService.getCliIntegrationFromAncestry(ancestry as any); + + expect(integration).toBe('create-rsbuild'); + }); + + it('should detect create rsbuild with version specifier', () => { + const ancestry = [{ command: 'npx create-rsbuild@1.0.0 init' }]; + + const integration = versionService.getCliIntegrationFromAncestry(ancestry as any); + + expect(integration).toBe('create-rsbuild'); + }); + + it('should detect "create rsbuild" with space instead of dash', () => { + const ancestry = [{ command: 'npm create rsbuild -- my-app' }]; + + const integration = versionService.getCliIntegrationFromAncestry(ancestry as any); + + expect(integration).toBe('create-rsbuild'); + }); + + it('should NOT detect creatersbuild without separator', () => { + const ancestry = [{ command: 'npx creatersbuild' }]; + + const integration = versionService.getCliIntegrationFromAncestry(ancestry as any); + + expect(integration).toBeUndefined(); + }); + + it('should detect @tanstack/start command', () => { + const ancestry = [{ command: 'npx @tanstack/start@latest create my-app' }]; + + const integration = versionService.getCliIntegrationFromAncestry(ancestry as any); + + expect(integration).toBe('@tanstack/start'); + }); + + it('should detect @tanstack/start in middle of command chain', () => { + const ancestry = [ + { command: 'pnpm @tanstack/start init' }, + { command: 'node /usr/local/bin/pnpm' }, + ]; + + const integration = versionService.getCliIntegrationFromAncestry(ancestry as any); + + expect(integration).toBe('@tanstack/start'); + }); }); describe('getVersionInfo', () => { diff --git a/code/lib/create-storybook/src/services/VersionService.ts b/code/lib/create-storybook/src/services/VersionService.ts index 019911ecebda..5a5cef89c58e 100644 --- a/code/lib/create-storybook/src/services/VersionService.ts +++ b/code/lib/create-storybook/src/services/VersionService.ts @@ -43,16 +43,26 @@ export class VersionService { } /** - * Extract CLI integration from process ancestry Detects if Storybook was invoked via sv create or - * sv add commands + * Extract CLI integration from process ancestry Detects if Storybook was invoked via sv create, + * sv add, create-rsbuild, or @tanstack/start commands */ getCliIntegrationFromAncestry( ancestry: ReturnType ): string | undefined { for (const ancestor of ancestry.toReversed()) { - const match = ancestor.command?.match(/(?:^|\s)(sv(?:@[^ ]+)? (?:create|add))/i); - if (match) { - return match[1].toLowerCase().includes('add') ? 'sv add' : 'sv create'; + // Check for sv create/add + const svMatch = ancestor.command?.match(/(?:^|\s)(sv(?:@[^ ]+)? (?:create|add))/i); + if (svMatch) { + return svMatch[1].toLowerCase().includes('add') ? 'sv add' : 'sv create'; + } + // Check for create-rsbuild or create rsbuild + const rsbuildMatch = ancestor.command?.match(/(?:^|\s)create[\s\-]rsbuild/i); + if (rsbuildMatch) { + return 'create-rsbuild'; + } + // Check for @tanstack/start + if (ancestor.command?.includes('@tanstack/start')) { + return '@tanstack/start'; } } return undefined; diff --git a/code/lib/eslint-plugin/src/rules/no-uninstalled-addons.ts b/code/lib/eslint-plugin/src/rules/no-uninstalled-addons.ts index 1ddbc63fa3e7..436267459171 100644 --- a/code/lib/eslint-plugin/src/rules/no-uninstalled-addons.ts +++ b/code/lib/eslint-plugin/src/rules/no-uninstalled-addons.ts @@ -163,7 +163,7 @@ export default createStorybookRule({ addonsExpression: TSESTree.ArrayExpression | undefined ) => { if (addonsExpression?.elements) { - // extract all nodes taht are a string inside the addons array + // extract all nodes that are a string inside the addons array const nodesWithAddons = addonsExpression.elements .map((elem) => (isLiteral(elem) ? { value: elem.value, node: elem } : undefined)) .filter(excludeNullable); diff --git a/code/package.json b/code/package.json index 123018bbbc4d..ddb1bab905a0 100644 --- a/code/package.json +++ b/code/package.json @@ -220,5 +220,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "10.3.0-alpha.1" } diff --git a/docs/_snippets/addon-a11y-parameter-example.md b/docs/_snippets/addon-a11y-parameter-example.md index 7920d6d22e0a..f2823b4bd258 100644 --- a/docs/_snippets/addon-a11y-parameter-example.md +++ b/docs/_snippets/addon-a11y-parameter-example.md @@ -146,7 +146,7 @@ export const NoA11yFail = { // Replace your-framework with the framework you are using, e.g. sveltekit or svelte-vite import type { Meta, StoryObj } from '@storybook/your-framework'; -import { Button } from './Button.svelte'; +import Button from './Button.svelte'; const meta = { component: Button, @@ -205,7 +205,7 @@ export const NoA11yFail: Story = { ``` ```js filename="Button.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" -import { Button } from './Button.svelte'; +import Button from './Button.svelte'; export default { component: Button, diff --git a/docs/_snippets/addon-a11y-parameter-remove.md b/docs/_snippets/addon-a11y-parameter-remove.md index 078d2c1ccf8d..8071d7fd2209 100644 --- a/docs/_snippets/addon-a11y-parameter-remove.md +++ b/docs/_snippets/addon-a11y-parameter-remove.md @@ -75,7 +75,7 @@ export default meta; // Replace your-framework with the framework you are using, e.g. sveltekit or svelte-vite import type { Meta } from '@storybook/your-framework'; -import { Button } from './Button.svelte'; +import Button from './Button.svelte'; const meta = { component: Button, @@ -104,7 +104,7 @@ export default meta; ``` ```js filename="Button.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" -import { Button } from './Button.svelte'; +import Button from './Button.svelte'; export default { component: Button, diff --git a/docs/_snippets/addon-a11y-parameter-todo-in-meta.md b/docs/_snippets/addon-a11y-parameter-todo-in-meta.md index 28e22c80c3c7..e6ca6f88cef7 100644 --- a/docs/_snippets/addon-a11y-parameter-todo-in-meta.md +++ b/docs/_snippets/addon-a11y-parameter-todo-in-meta.md @@ -59,14 +59,14 @@ export default { }; ``` -```svelte filename="Button.stories.svelte" renderer="svelte" language="ts" tabTitle="Svelte CSF" +```svelte filename="DataTable.stories.svelte" renderer="svelte" language="ts" tabTitle="Svelte CSF" ``` -```ts filename="Button.stories.ts" renderer="svelte" language="ts" tabTitle="CSF 3" +```ts filename="DataTable.stories.ts" renderer="svelte" language="ts" tabTitle="CSF 3" // Replace your-framework with the framework you are using, e.g. sveltekit or svelte-vite import type { Meta } from '@storybook/your-framework'; -import { Button } from './Button.svelte'; +import DataTable from './DataTable.svelte'; const meta = { - component: Button, + component: DataTable, parameters: { // ๐Ÿ‘‡ This component's accessibility tests will not fail // Instead, they display warnings in the Storybook UI a11y: { test: 'todo' }, }, -} satisfies Meta; +} satisfies Meta; export default meta; ``` -```svelte filename="Button.stories.svelte" renderer="svelte" language="js" tabTitle="Svelte CSF" +```svelte filename="DataTable.stories.svelte" renderer="svelte" language="js" tabTitle="Svelte CSF" ``` -```js filename="Button.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" -import { Button } from './Button.svelte'; +```js filename="DataTable.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" +import DataTable from './DataTable.svelte'; export default { - component: Button, + component: DataTable, parameters: { // ๐Ÿ‘‡ This component's accessibility tests will not fail // Instead, they display warnings in the Storybook UI @@ -193,6 +193,7 @@ const meta = preview.meta({ ```js filename="DataTable.stories.js" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { DataTable } from './DataTable'; const meta = preview.meta({ diff --git a/docs/_snippets/addon-backgrounds-define-globals.md b/docs/_snippets/addon-backgrounds-define-globals.md index 431f6c31257d..9435bcba7ab0 100644 --- a/docs/_snippets/addon-backgrounds-define-globals.md +++ b/docs/_snippets/addon-backgrounds-define-globals.md @@ -281,6 +281,7 @@ export const OnDark = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/addon-backgrounds-disabled.md b/docs/_snippets/addon-backgrounds-disabled.md index 0e9dc6d74e7c..268bcd0f15fa 100644 --- a/docs/_snippets/addon-backgrounds-disabled.md +++ b/docs/_snippets/addon-backgrounds-disabled.md @@ -140,6 +140,7 @@ export const Large = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/addon-backgrounds-grid.md b/docs/_snippets/addon-backgrounds-grid.md index 62cc81532675..8c2d90af17ae 100644 --- a/docs/_snippets/addon-backgrounds-grid.md +++ b/docs/_snippets/addon-backgrounds-grid.md @@ -288,6 +288,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/addon-backgrounds-options-in-meta.md b/docs/_snippets/addon-backgrounds-options-in-meta.md index e4dfa34a7660..266ec8eb12bb 100644 --- a/docs/_snippets/addon-backgrounds-options-in-meta.md +++ b/docs/_snippets/addon-backgrounds-options-in-meta.md @@ -344,6 +344,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/addon-viewport-define-globals.md b/docs/_snippets/addon-viewport-define-globals.md index 8e8846e5c5a4..dd2df1817cf9 100644 --- a/docs/_snippets/addon-viewport-define-globals.md +++ b/docs/_snippets/addon-viewport-define-globals.md @@ -112,7 +112,7 @@ export const OnPhone = { // Replace your-framework with svelte-vite or sveltekit import type { Meta, StoryObj } from '@storybook/your-framework'; -import { Button } from './Button'; +import Button from './Button.svelte'; const meta = { component: Button, @@ -279,6 +279,7 @@ export const OnPhone = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/after-each-in-meta.md b/docs/_snippets/after-each-in-meta.md index 727c37ccf0ce..488d3e24be35 100644 --- a/docs/_snippets/after-each-in-meta.md +++ b/docs/_snippets/after-each-in-meta.md @@ -47,7 +47,7 @@ export const Basic = meta.story({ import Page from './Page.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Page, // ๐Ÿ‘‡ Runs after each story in this file async afterEach(context) { @@ -104,7 +104,7 @@ export const Basic = { import Page from './Page.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Page, // ๐Ÿ‘‡ Runs after each story in this file async afterEach(context) { @@ -264,6 +264,7 @@ export const Basic = meta.story({ ```js filename="Page.stories.js" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Page } from './Page'; const meta = preview.meta({ diff --git a/docs/_snippets/api-doc-block-argtypes-parameter.md b/docs/_snippets/api-doc-block-argtypes-parameter.md index 35141c192b23..af8d83e2e958 100644 --- a/docs/_snippets/api-doc-block-argtypes-parameter.md +++ b/docs/_snippets/api-doc-block-argtypes-parameter.md @@ -36,7 +36,7 @@ const meta = preview.meta({ import Button from './Button.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, parameters: { docs: { @@ -79,7 +79,7 @@ export default { import Button from './Button.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, parameters: { docs: { @@ -197,6 +197,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/api-doc-block-canvas-parameter.md b/docs/_snippets/api-doc-block-canvas-parameter.md index f885229e60ba..3e590a65ec7e 100644 --- a/docs/_snippets/api-doc-block-canvas-parameter.md +++ b/docs/_snippets/api-doc-block-canvas-parameter.md @@ -244,6 +244,7 @@ export const Basic = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/api-doc-block-controls-parameter.md b/docs/_snippets/api-doc-block-controls-parameter.md index f4dd7aa3fee2..9e3a9768ec82 100644 --- a/docs/_snippets/api-doc-block-controls-parameter.md +++ b/docs/_snippets/api-doc-block-controls-parameter.md @@ -36,7 +36,7 @@ const meta = preview.meta({ import Button from './Button.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, parameters: { docs: { @@ -79,7 +79,7 @@ export default { import Button from './Button.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, parameters: { docs: { @@ -201,6 +201,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/api-doc-block-description-example.md b/docs/_snippets/api-doc-block-description-example.md index 2db5926f156f..9b03f07c67c7 100644 --- a/docs/_snippets/api-doc-block-description-example.md +++ b/docs/_snippets/api-doc-block-description-example.md @@ -81,7 +81,7 @@ export const Primary = meta.story({ * Button stories * These stories showcase the button */ - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, parameters: { docs: { @@ -185,7 +185,7 @@ export const Primary = { * Button stories * These stories showcase the button */ - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, parameters: { docs: { @@ -467,6 +467,7 @@ export const Primary = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/api-doc-block-source-parameter.md b/docs/_snippets/api-doc-block-source-parameter.md index cfabd70472bc..3f3c35b6dfb8 100644 --- a/docs/_snippets/api-doc-block-source-parameter.md +++ b/docs/_snippets/api-doc-block-source-parameter.md @@ -43,7 +43,7 @@ export const Basic = meta.story({ import Button from './Button.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, }); @@ -95,7 +95,7 @@ export const Basic = { import Button from './Button.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, }); @@ -240,6 +240,7 @@ export const Basic = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/api-doc-block-story-parameter.md b/docs/_snippets/api-doc-block-story-parameter.md index ae256429c282..c1688f92f3fc 100644 --- a/docs/_snippets/api-doc-block-story-parameter.md +++ b/docs/_snippets/api-doc-block-story-parameter.md @@ -43,7 +43,7 @@ export const Basic = meta.story({ import Button from './Button.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, }); @@ -95,7 +95,7 @@ export const Basic = { import Button from './Button.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Button, }); @@ -240,6 +240,7 @@ export const Basic = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-default-value.md b/docs/_snippets/arg-types-default-value.md index 5b42e7105dbb..926d7ba7ebf8 100644 --- a/docs/_snippets/arg-types-default-value.md +++ b/docs/_snippets/arg-types-default-value.md @@ -262,6 +262,7 @@ const meta = preview.meta({ ```js filename="Example.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Example } from './Example'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-description.md b/docs/_snippets/arg-types-description.md index 30d6ac827fb3..d60a86b28844 100644 --- a/docs/_snippets/arg-types-description.md +++ b/docs/_snippets/arg-types-description.md @@ -197,6 +197,7 @@ const meta = preview.meta({ ```js filename="Example.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Example } from './Example'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-if.md b/docs/_snippets/arg-types-if.md index daf6bb7b10b1..02210d722694 100644 --- a/docs/_snippets/arg-types-if.md +++ b/docs/_snippets/arg-types-if.md @@ -483,6 +483,7 @@ const meta = preview.meta({ ```js filename="Example.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Example } from './Example'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-in-meta.md b/docs/_snippets/arg-types-in-meta.md index 4bb13a963866..d532b7a09b07 100644 --- a/docs/_snippets/arg-types-in-meta.md +++ b/docs/_snippets/arg-types-in-meta.md @@ -223,6 +223,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-in-story.md b/docs/_snippets/arg-types-in-story.md index bb9c7d7b5295..45a0d9bbee15 100644 --- a/docs/_snippets/arg-types-in-story.md +++ b/docs/_snippets/arg-types-in-story.md @@ -261,6 +261,7 @@ export const Basic = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-mapping.md b/docs/_snippets/arg-types-mapping.md index ca7291582e87..750f3dc91b47 100644 --- a/docs/_snippets/arg-types-mapping.md +++ b/docs/_snippets/arg-types-mapping.md @@ -211,6 +211,7 @@ const meta = preview.meta({ ```js filename="Example.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Example } from './Example'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-name.md b/docs/_snippets/arg-types-name.md index 9db1f728ff21..4dd2c741349b 100644 --- a/docs/_snippets/arg-types-name.md +++ b/docs/_snippets/arg-types-name.md @@ -197,6 +197,7 @@ const meta = preview.meta({ ```js filename="Example.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Example } from './Example'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-options.md b/docs/_snippets/arg-types-options.md index 6b6078c7bed2..6c477521d666 100644 --- a/docs/_snippets/arg-types-options.md +++ b/docs/_snippets/arg-types-options.md @@ -197,6 +197,7 @@ const meta = preview.meta({ ```js filename="Example.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Example } from './Example'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-table.md b/docs/_snippets/arg-types-table.md index 1a15adbf0ba9..a8b6b23318ac 100644 --- a/docs/_snippets/arg-types-table.md +++ b/docs/_snippets/arg-types-table.md @@ -112,7 +112,7 @@ export default { // Replace your-framework with svelte-vite or sveltekit import type { Meta } from '@storybook/your-framework'; -import { Example } from './Example'; +import Example from './Example.svelte'; const meta = { component: Example, @@ -236,6 +236,7 @@ const meta = preview.meta({ ```js filename="Example.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Example } from './Example'; const meta = preview.meta({ diff --git a/docs/_snippets/arg-types-type.md b/docs/_snippets/arg-types-type.md index a4fd1823cfd3..28a96463fb15 100644 --- a/docs/_snippets/arg-types-type.md +++ b/docs/_snippets/arg-types-type.md @@ -171,6 +171,7 @@ const meta = preview.meta({ ```js filename="Example.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Example } from './Example'; const meta = preview.meta({ diff --git a/docs/_snippets/automocked-modules-in-story.md b/docs/_snippets/automocked-modules-in-story.md index a8ede4299fe2..b4a0d5088cd1 100644 --- a/docs/_snippets/automocked-modules-in-story.md +++ b/docs/_snippets/automocked-modules-in-story.md @@ -130,7 +130,7 @@ export const LogIn = { import { defineMeta } from '@storybook/addon-svelte-csf'; import { expect, mocked } from 'storybook/test'; - import { AuthButton } from './AuthButton.svelte'; + import AuthButton from './AuthButton.svelte'; import { v4 as uuidv4 } from 'uuid'; import { getUserFromSession } from '../lib/session'; @@ -163,7 +163,7 @@ export const LogIn = { import type { Meta, StoryObj } from '@storybook/your-framework'; import { expect, mocked } from 'storybook/test'; -import { AuthButton } from './AuthButton.svelte'; +import AuthButton from './AuthButton.svelte'; import { v4 as uuidv4 } from 'uuid'; import { getUserFromSession } from '../lib/session'; @@ -228,7 +228,7 @@ export const LogIn: Story = { ```js filename="AuthButton.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" import { expect } from 'storybook/test'; -import { AuthButton } from './AuthButton.svelte'; +import AuthButton from './AuthButton.svelte'; import { v4 as uuidv4 } from 'uuid'; import { getUserFromSession } from '../lib/session'; diff --git a/docs/_snippets/before-each-in-meta-mock-date.md b/docs/_snippets/before-each-in-meta-mock-date.md index 100e8a979435..fa57c8291ad9 100644 --- a/docs/_snippets/before-each-in-meta-mock-date.md +++ b/docs/_snippets/before-each-in-meta-mock-date.md @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/angular'; import MockDate from 'mockdate'; -import { Page } from './Page'; +import { Page } from './Page.component'; const meta: Meta = { component: Page, @@ -33,7 +33,7 @@ import MockDate from 'mockdate'; import preview from '../.storybook/preview'; -import { Page } from './Page'; +import { Page } from './Page.component'; const meta = preview.meta({ component: Page, @@ -63,7 +63,7 @@ export const Basic = meta.story({ import Page from './Page.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Page, // ๐Ÿ‘‡ Set the value of Date for every story in the file async beforeEach() { @@ -141,7 +141,7 @@ export const Basic = { import Page from './Page.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Page, // ๐Ÿ‘‡ Set the value of Date for every story in the file async beforeEach() { diff --git a/docs/_snippets/button-group-story.md b/docs/_snippets/button-group-story.md index 049d81fb2fc2..d3aef1a7ca93 100644 --- a/docs/_snippets/button-group-story.md +++ b/docs/_snippets/button-group-story.md @@ -445,6 +445,7 @@ export const Pair = meta.story({ ```js filename="ButtonGroup.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { ButtonGroup } from '../ButtonGroup'; //๐Ÿ‘‡ Imports the Button stories diff --git a/docs/_snippets/button-story-argtypes-with-categories.md b/docs/_snippets/button-story-argtypes-with-categories.md index 6637773506e4..dec9a6aeae8c 100644 --- a/docs/_snippets/button-story-argtypes-with-categories.md +++ b/docs/_snippets/button-story-argtypes-with-categories.md @@ -375,6 +375,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-argtypes-with-subcategories.md b/docs/_snippets/button-story-argtypes-with-subcategories.md index 10140c72ace3..2ad9013d11d1 100644 --- a/docs/_snippets/button-story-argtypes-with-subcategories.md +++ b/docs/_snippets/button-story-argtypes-with-subcategories.md @@ -411,6 +411,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-component-args-primary.md b/docs/_snippets/button-story-component-args-primary.md index 9dd8ff2498c7..370259da2a35 100644 --- a/docs/_snippets/button-story-component-args-primary.md +++ b/docs/_snippets/button-story-component-args-primary.md @@ -346,6 +346,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-component-decorator.md b/docs/_snippets/button-story-component-decorator.md index 7240f4b8df51..210a60b92f02 100644 --- a/docs/_snippets/button-story-component-decorator.md +++ b/docs/_snippets/button-story-component-decorator.md @@ -320,6 +320,7 @@ const meta = preview.meta({ ```jsx filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-decorator.md b/docs/_snippets/button-story-decorator.md index 5af4660489e8..0a9293745073 100644 --- a/docs/_snippets/button-story-decorator.md +++ b/docs/_snippets/button-story-decorator.md @@ -388,6 +388,7 @@ export const Primary = meta.story({ ```jsx filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-default-export-with-component.md b/docs/_snippets/button-story-default-export-with-component.md index 2841563f9a0a..713f03647c73 100644 --- a/docs/_snippets/button-story-default-export-with-component.md +++ b/docs/_snippets/button-story-default-export-with-component.md @@ -210,6 +210,7 @@ const meta = preview.meta({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-rename-story.md b/docs/_snippets/button-story-rename-story.md index fd8fa6ffc1d3..937e3f0b3824 100644 --- a/docs/_snippets/button-story-rename-story.md +++ b/docs/_snippets/button-story-rename-story.md @@ -406,6 +406,7 @@ export const Primary = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-using-args.md b/docs/_snippets/button-story-using-args.md index ec16735ba7b6..a3e2ff6726a2 100644 --- a/docs/_snippets/button-story-using-args.md +++ b/docs/_snippets/button-story-using-args.md @@ -795,6 +795,7 @@ export const Tertiary = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-with-args.md b/docs/_snippets/button-story-with-args.md index 7db3f5e89117..07283ba493db 100644 --- a/docs/_snippets/button-story-with-args.md +++ b/docs/_snippets/button-story-with-args.md @@ -479,6 +479,7 @@ export const Primary = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/button-story-with-emojis.md b/docs/_snippets/button-story-with-emojis.md index 8f3731ddc5cf..56ffb7c3ca81 100644 --- a/docs/_snippets/button-story-with-emojis.md +++ b/docs/_snippets/button-story-with-emojis.md @@ -660,6 +660,7 @@ export const Tertiary = meta.story({ ```jsx filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/code-panel-in-meta-and-story.md b/docs/_snippets/code-panel-in-meta-and-story.md index bb0b7c8fef41..9adc9fdfcb33 100644 --- a/docs/_snippets/code-panel-in-meta-and-story.md +++ b/docs/_snippets/code-panel-in-meta-and-story.md @@ -622,6 +622,7 @@ export const Secondary = meta.story({ ```js filename="Button.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Button } from './Button'; const meta = preview.meta({ diff --git a/docs/_snippets/component-story-custom-args-complex.md b/docs/_snippets/component-story-custom-args-complex.md index 4d8e7e791fb0..96f181e8a585 100644 --- a/docs/_snippets/component-story-custom-args-complex.md +++ b/docs/_snippets/component-story-custom-args-complex.md @@ -248,6 +248,8 @@ export const ExampleStory: Story = { + + + {#snippet template(args)} + +
+

Example

+
+
+ +
+
+ {/snippet} +
+``` diff --git a/docs/_snippets/foo-bar-baz-story.md b/docs/_snippets/foo-bar-baz-story.md index 1403194e2c69..b2b1cc5aee6b 100644 --- a/docs/_snippets/foo-bar-baz-story.md +++ b/docs/_snippets/foo-bar-baz-story.md @@ -166,6 +166,7 @@ export const Baz = meta.story(); ```js filename="FooBar.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Foo } from './Foo'; const meta = preview.meta({ @@ -201,6 +202,7 @@ export const Baz = meta.story(); ```js filename="FooBar.stories.js" renderer="vue" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import Foo from './Foo.vue'; const meta = preview.meta({ diff --git a/docs/_snippets/highlight-remove.md b/docs/_snippets/highlight-remove.md index 080e2d73b630..49d4560eba66 100644 --- a/docs/_snippets/highlight-remove.md +++ b/docs/_snippets/highlight-remove.md @@ -120,7 +120,6 @@ export const RemoveHighlight: Story = { import { useChannel } from 'storybook/preview-api'; import { HIGHLIGHT, REMOVE_HIGHLIGHT } from 'storybook/highlight'; - import MyComponent from './MyComponent.svelte'; const { Story } = defineMeta({ @@ -176,7 +175,6 @@ export const RemoveHighlight = { import { useChannel } from 'storybook/preview-api'; import { HIGHLIGHT, REMOVE_HIGHLIGHT } from 'storybook/highlight'; - import MyComponent from './MyComponent.svelte'; const { Story } = defineMeta({ diff --git a/docs/_snippets/histogram-story.md b/docs/_snippets/histogram-story.md index 2ff15e04232a..540afca2f097 100644 --- a/docs/_snippets/histogram-story.md +++ b/docs/_snippets/histogram-story.md @@ -506,6 +506,7 @@ export const Basic = meta.story({ ```js filename="Histogram.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { Histogram } from './Histogram'; const meta = preview.meta({ diff --git a/docs/_snippets/interaction-test-complex.md b/docs/_snippets/interaction-test-complex.md index 99747aeaa769..1d8756c9aab8 100644 --- a/docs/_snippets/interaction-test-complex.md +++ b/docs/_snippets/interaction-test-complex.md @@ -179,7 +179,7 @@ export const Submits = { import { fn, expect } from 'storybook/test'; import { users } from '../mocks/users'; - import { EventForm } from './EventForm.svelte'; + import EventForm from './EventForm.svelte'; const { Story } = defineMeta({ component: EventForm, @@ -224,7 +224,7 @@ import type { Meta, StoryObj } from '@storybook/your-framework'; import { fn, expect } from 'storybook/test'; import { users } from '../mocks/users'; -import { EventForm } from './EventForm.svelte'; +import EventForm from './EventForm.svelte'; const meta = { component: EventForm, @@ -270,7 +270,7 @@ export const Submits: Story = { import { fn, expect } from 'storybook/test'; import { users } from '../mocks/users'; - import { EventForm } from './EventForm.svelte'; + import EventForm from './EventForm.svelte'; const { Story } = defineMeta({ component: EventForm, @@ -313,7 +313,7 @@ export const Submits: Story = { import { fn, expect } from 'storybook/test'; import { users } from '../mocks/users'; -import { EventForm } from './EventForm.svelte'; +import EventForm from './EventForm.svelte'; export default { component: EventForm, diff --git a/docs/_snippets/interaction-test-fn-mock-spy.md b/docs/_snippets/interaction-test-fn-mock-spy.md index 948fdaf9951d..1d62bf1f0bdf 100644 --- a/docs/_snippets/interaction-test-fn-mock-spy.md +++ b/docs/_snippets/interaction-test-fn-mock-spy.md @@ -142,7 +142,7 @@ export const FilledForm = { import type { Meta, StoryObj } from '@storybook/your-framework'; import { fn, expect } from 'storybook/test'; -import { LoginForm } from './LoginForm.svelte'; +import LoginForm from './LoginForm.svelte'; const meta = { component: LoginForm, @@ -198,7 +198,7 @@ export const FilledForm: Story = { ```js filename="LoginForm.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" import { fn, expect } from 'storybook/test'; -import { LoginForm } from './LoginForm.svelte'; +import LoginForm from './LoginForm.svelte'; export default { component: LoginForm, diff --git a/docs/_snippets/interaction-test-simple.md b/docs/_snippets/interaction-test-simple.md index 2da522e555e1..8756cdad4aab 100644 --- a/docs/_snippets/interaction-test-simple.md +++ b/docs/_snippets/interaction-test-simple.md @@ -112,7 +112,7 @@ export const Opens = { import type { Meta, StoryObj } from '@storybook/your-framework'; import { expect } from 'storybook/test'; -import { Dialog } from './Dialog.svelte'; +import Dialog from './Dialog.svelte'; const meta = { component: Dialog, @@ -156,7 +156,7 @@ export const Opens: Story = { ```js filename="Dialog.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" import { expect } from 'storybook/test'; -import { Dialog } from './Dialog.svelte'; +import Dialog from './Dialog.svelte'; export default { component: Dialog, diff --git a/docs/_snippets/list-story-expanded.md b/docs/_snippets/list-story-expanded.md index e5dd849f4ccc..367ba32d5b66 100644 --- a/docs/_snippets/list-story-expanded.md +++ b/docs/_snippets/list-story-expanded.md @@ -331,7 +331,7 @@ export const ManyItems: Story = { }; ``` -```svelte filename="List.stories.svelte" renderer="svelte" language="js" tabTitle="Svelte CSF" +```svelte filename="List.stories.svelte" renderer="svelte" language="js" @@ -71,7 +71,7 @@ export const ChristmasUI = meta.story({ /> ``` -```ts filename="LoginForm.stories.ts" renderer="svelte" language="ts" tabTitle="CSF 3" +```ts filename="Page.stories.ts" renderer="svelte" language="ts" tabTitle="CSF 3" import MockDate from 'mockdate'; // ...rest of story file @@ -86,14 +86,14 @@ export const ChristmasUI: Story = { }; ``` -```svelte filename="LoginForm.stories.svelte" renderer="svelte" language="js" tabTitle="Svelte CSF" +```svelte filename="Page.stories.svelte" renderer="svelte" language="js" tabTitle="Svelte CSF" @@ -108,7 +108,7 @@ export const ChristmasUI: Story = { /> ``` -```js filename="LoginForm.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" +```js filename="Page.stories.js" renderer="svelte" language="js" tabTitle="CSF 3" import MockDate from 'mockdate'; // ...rest of story file diff --git a/docs/_snippets/my-component-story-mandatory-export.md b/docs/_snippets/my-component-story-mandatory-export.md index 91cf467e9d4d..7f85bea00ddd 100644 --- a/docs/_snippets/my-component-story-mandatory-export.md +++ b/docs/_snippets/my-component-story-mandatory-export.md @@ -27,7 +27,7 @@ export default meta; import MyComponent from './MyComponent.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ /* ๐Ÿ‘‡ The title prop is optional. * See https://storybook.js.org/docs/configure/#configure-story-loading * to learn how to generate automatic titles @@ -45,7 +45,7 @@ export default meta; ``` ```js filename="MyComponent.story.js" renderer="svelte" language="js" tabTitle="CSF 3" -import { MyComponent } from './MyComponent'; +import MyComponent from './MyComponent.svelte'; export default { /* ๐Ÿ‘‡ The title prop is optional. @@ -88,7 +88,7 @@ export default { import MyComponent from './MyComponent.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ /* ๐Ÿ‘‡ The title prop is optional. * See https://storybook.js.org/docs/configure/#configure-story-loading * to learn how to generate automatic titles diff --git a/docs/_snippets/my-component-story-use-globaltype.md b/docs/_snippets/my-component-story-use-globaltype.md index a4e3b74bdbdf..caff0c961c77 100644 --- a/docs/_snippets/my-component-story-use-globaltype.md +++ b/docs/_snippets/my-component-story-use-globaltype.md @@ -659,6 +659,7 @@ export const StoryWithLocale = meta.story({ ```js filename="MyComponent.stories.js|jsx" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import { MyComponent } from './MyComponent'; const meta = preview.meta({ diff --git a/docs/_snippets/nextjs-app-directory-in-meta.md b/docs/_snippets/nextjs-app-directory-in-meta.md index 565b999547b5..ce5fe7a95544 100644 --- a/docs/_snippets/nextjs-app-directory-in-meta.md +++ b/docs/_snippets/nextjs-app-directory-in-meta.md @@ -47,6 +47,7 @@ const meta = preview.meta({ ```js filename="NavigationBasedComponent.stories.js" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import NavigationBasedComponent from './NavigationBasedComponent'; const meta = preview.meta({ diff --git a/docs/_snippets/nextjs-navigation-override-in-story.md b/docs/_snippets/nextjs-navigation-override-in-story.md index 11f142fc99a2..68f85db8051f 100644 --- a/docs/_snippets/nextjs-navigation-override-in-story.md +++ b/docs/_snippets/nextjs-navigation-override-in-story.md @@ -91,6 +91,7 @@ export const Example = meta.story({ ```js filename="NavigationBasedComponent.stories.js" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import NavigationBasedComponent from './NavigationBasedComponent'; const meta = preview.meta({ diff --git a/docs/_snippets/nextjs-navigation-segments-for-use-params-override-in-meta.md b/docs/_snippets/nextjs-navigation-segments-for-use-params-override-in-meta.md index a2324e16771b..3bb2965c4300 100644 --- a/docs/_snippets/nextjs-navigation-segments-for-use-params-override-in-meta.md +++ b/docs/_snippets/nextjs-navigation-segments-for-use-params-override-in-meta.md @@ -65,6 +65,7 @@ const meta = preview.meta({ ```js filename="NavigationBasedComponent.stories.js" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import NavigationBasedComponent from './NavigationBasedComponent'; const meta = preview.meta({ diff --git a/docs/_snippets/nextjs-navigation-segments-override-in-meta.md b/docs/_snippets/nextjs-navigation-segments-override-in-meta.md index b44e0602dbe0..60cea70f337e 100644 --- a/docs/_snippets/nextjs-navigation-segments-override-in-meta.md +++ b/docs/_snippets/nextjs-navigation-segments-override-in-meta.md @@ -56,6 +56,7 @@ const meta = preview.meta({ ```js filename="NavigationBasedComponent.stories.js" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import NavigationBasedComponent from './NavigationBasedComponent'; const meta = preview.meta({ diff --git a/docs/_snippets/nextjs-router-override-in-story.md b/docs/_snippets/nextjs-router-override-in-story.md index 4c452ae68b5e..96bec3c73afd 100644 --- a/docs/_snippets/nextjs-router-override-in-story.md +++ b/docs/_snippets/nextjs-router-override-in-story.md @@ -79,6 +79,7 @@ export const Example = meta.story({ ```js filename="RouterBasedComponent.stories.js" renderer="react" language="js" tabTitle="CSF Next ๐Ÿงช" import preview from '../.storybook/preview'; + import RouterBasedComponent from './RouterBasedComponent'; const meta = preview.meta({ diff --git a/docs/_snippets/page-story-slots.md b/docs/_snippets/page-story-slots.md index cf59752e0957..51a005727866 100644 --- a/docs/_snippets/page-story-slots.md +++ b/docs/_snippets/page-story-slots.md @@ -166,7 +166,7 @@ export const CustomFooter = { ``` -```svelte filename="Page.stories.svelte" renderer="svelte" language="ts" tabTitle="Svelte CSF" +```svelte filename="Page.stories.svelte" renderer="svelte" language="ts" @@ -110,7 +110,7 @@ export const Basic = { import Page from './Page.svelte'; - const meta = defineMeta({ + const { Story } = defineMeta({ component: Page, }); diff --git a/docs/_snippets/tags-autodocs-in-meta.md b/docs/_snippets/tags-autodocs-in-meta.md index 139dd092fcaa..03c278302542 100644 --- a/docs/_snippets/tags-autodocs-in-meta.md +++ b/docs/_snippets/tags-autodocs-in-meta.md @@ -1,7 +1,7 @@ ```ts filename="Button.stories.ts" renderer="angular" language="ts" tabTitle="CSF 3" import type { Meta } from '@storybook/angular'; -import { Button } from './Button'; +import { Button } from './Button.component'; const meta: Meta