diff --git a/CHANGELOG.md b/CHANGELOG.md
index ef1c0ad4edbf..d93c3b996486 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 8.0.9
+
+- Addon-docs: Fix MDX compilation when using `@vitejs/plugin-react-swc` with plugins - [#26837](https://github.com/storybookjs/storybook/pull/26837), thanks @JReinhold!
+- CSF: Fix typings for control and other properties of argTypes - [#26824](https://github.com/storybookjs/storybook/pull/26824), thanks @kasperpeulen!
+- Controls: Fix crashing when docgen extraction partially fails - [#26862](https://github.com/storybookjs/storybook/pull/26862), thanks @yannbf!
+- Doc Tools: Signature Type Error Handling - [#26774](https://github.com/storybookjs/storybook/pull/26774), thanks @ethriel3695!
+- Next.js: Move sharp into optional deps - [#26787](https://github.com/storybookjs/storybook/pull/26787), thanks @shuta13!
+- Nextjs: Support next 14.2 useParams functionality - [#26874](https://github.com/storybookjs/storybook/pull/26874), thanks @yannbf!
+- Test: Remove chai as dependency of @storybook/test - [#26852](https://github.com/storybookjs/storybook/pull/26852), thanks @kasperpeulen!
+- UI: Fix sidebar search hanging when selecting a story in touch mode - [#26807](https://github.com/storybookjs/storybook/pull/26807), thanks @JReinhold!
+
## 8.0.8
- Automigration: Fix name of VTA addon - [#26816](https://github.com/storybookjs/storybook/pull/26816), thanks @valentinpalkovic!
diff --git a/MIGRATION.md b/MIGRATION.md
index eecaf94950a2..34c0ca87c685 100644
--- a/MIGRATION.md
+++ b/MIGRATION.md
@@ -1,5 +1,8 @@
Migration
+- [From version 8.0 to 8.1.0](#from-version-80-to-810)
+ - [Subtitle block and `parameters.componentSubtitle`](#subtitle-block-and-parameterscomponentsubtitle)
+ - [Title block](#title-block)
- [From version 7.x to 8.0.0](#from-version-7x-to-800)
- [Portable stories](#portable-stories)
- [Project annotations are now merged instead of overwritten in composeStory](#project-annotations-are-now-merged-instead-of-overwritten-in-composestory)
@@ -90,17 +93,17 @@
- [Tab addons cannot manually route, Tool addons can filter their visibility via tabId](#tab-addons-cannot-manually-route-tool-addons-can-filter-their-visibility-via-tabid)
- [Removed `config` preset](#removed-config-preset-1)
- [From version 7.5.0 to 7.6.0](#from-version-750-to-760)
- - [CommonJS with Vite is deprecated](#commonjs-with-vite-is-deprecated)
- - [Using implicit actions during rendering is deprecated](#using-implicit-actions-during-rendering-is-deprecated)
- - [typescript.skipBabel deprecated](#typescriptskipbabel-deprecated)
- - [Primary doc block accepts of prop](#primary-doc-block-accepts-of-prop)
- - [Addons no longer need a peer dependency on React](#addons-no-longer-need-a-peer-dependency-on-react)
+ - [CommonJS with Vite is deprecated](#commonjs-with-vite-is-deprecated)
+ - [Using implicit actions during rendering is deprecated](#using-implicit-actions-during-rendering-is-deprecated)
+ - [typescript.skipBabel deprecated](#typescriptskipbabel-deprecated)
+ - [Primary doc block accepts of prop](#primary-doc-block-accepts-of-prop)
+ - [Addons no longer need a peer dependency on React](#addons-no-longer-need-a-peer-dependency-on-react)
- [From version 7.4.0 to 7.5.0](#from-version-740-to-750)
- - [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated)
- - [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers)
+ - [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated)
+ - [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers)
- [From version 7.0.0 to 7.2.0](#from-version-700-to-720)
- - [Addon API is more type-strict](#addon-api-is-more-type-strict)
- - [Addon-controls hideNoControlsWarning parameter is deprecated](#addon-controls-hidenocontrolswarning-parameter-is-deprecated)
+ - [Addon API is more type-strict](#addon-api-is-more-type-strict)
+ - [Addon-controls hideNoControlsWarning parameter is deprecated](#addon-controls-hidenocontrolswarning-parameter-is-deprecated)
- [From version 6.5.x to 7.0.0](#from-version-65x-to-700)
- [7.0 breaking changes](#70-breaking-changes)
- [Dropped support for Node 15 and below](#dropped-support-for-node-15-and-below)
@@ -126,7 +129,7 @@
- [Deploying build artifacts](#deploying-build-artifacts)
- [Dropped support for file URLs](#dropped-support-for-file-urls)
- [Serving with nginx](#serving-with-nginx)
- - [Ignore story files from node_modules](#ignore-story-files-from-node_modules)
+ - [Ignore story files from node\_modules](#ignore-story-files-from-node_modules)
- [7.0 Core changes](#70-core-changes)
- [7.0 feature flags removed](#70-feature-flags-removed)
- [Story context is prepared before for supporting fine grained updates](#story-context-is-prepared-before-for-supporting-fine-grained-updates)
@@ -140,7 +143,7 @@
- [Addon-interactions: Interactions debugger is now default](#addon-interactions-interactions-debugger-is-now-default)
- [7.0 Vite changes](#70-vite-changes)
- [Vite builder uses Vite config automatically](#vite-builder-uses-vite-config-automatically)
- - [Vite cache moved to node_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook)
+ - [Vite cache moved to node\_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook)
- [7.0 Webpack changes](#70-webpack-changes)
- [Webpack4 support discontinued](#webpack4-support-discontinued)
- [Babel mode v7 exclusively](#babel-mode-v7-exclusively)
@@ -190,7 +193,7 @@
- [Dropped addon-docs manual babel configuration](#dropped-addon-docs-manual-babel-configuration)
- [Dropped addon-docs manual configuration](#dropped-addon-docs-manual-configuration)
- [Autoplay in docs](#autoplay-in-docs)
- - [Removed STORYBOOK_REACT_CLASSES global](#removed-storybook_react_classes-global)
+ - [Removed STORYBOOK\_REACT\_CLASSES global](#removed-storybook_react_classes-global)
- [7.0 Deprecations and default changes](#70-deprecations-and-default-changes)
- [storyStoreV7 enabled by default](#storystorev7-enabled-by-default)
- [`Story` type deprecated](#story-type-deprecated)
@@ -403,6 +406,20 @@
- [Packages renaming](#packages-renaming)
- [Deprecated embedded addons](#deprecated-embedded-addons)
+## From version 8.0 to 8.1.0
+
+### Subtitle block and `parameters.componentSubtitle`
+
+The `Subtitle` block now accepts an `of` prop, which can be a reference to a CSF file or a default export (meta).
+
+`parameters.componentSubtitle` has been deprecated to be consistent with other parameters related to autodocs, instead use `parameters.docs.subtitle`.
+
+##### Title block
+
+The `Title` block now accepts an `of` prop, which can be a reference to a CSF file or a default export (meta).
+
+It still accepts being passed `children`.
+
## From version 7.x to 8.0.0
### Portable stories
diff --git a/code/addons/links/template/stories/decorator.stories.ts b/code/addons/links/template/stories/decorator.stories.ts
index 218833a75800..53a05f380e74 100644
--- a/code/addons/links/template/stories/decorator.stories.ts
+++ b/code/addons/links/template/stories/decorator.stories.ts
@@ -9,29 +9,44 @@ export default {
decorators: [withLinks],
};
-export const Basic = {
+export const Target = {
args: {
content: `
- go to other
+ This is just a story to target with the links
- `,
- },
-};
diff --git a/code/e2e-tests/addon-docs.spec.ts b/code/e2e-tests/addon-docs.spec.ts
index db7b7b7d5e05..2713892fd042 100644
--- a/code/e2e-tests/addon-docs.spec.ts
+++ b/code/e2e-tests/addon-docs.spec.ts
@@ -67,7 +67,7 @@ test.describe('addon-docs', () => {
await new Promise(resolve => resolve('Play function'));
}
}`;
- await expect(sourceCode.textContent()).resolves.toContain(expectedSource);
+ await expect(sourceCode).toHaveText(expectedSource);
});
test('should render errors', async ({ page }) => {
diff --git a/code/e2e-tests/framework-nextjs.spec.ts b/code/e2e-tests/framework-nextjs.spec.ts
index 61233dd5ac25..c1a15c2632ef 100644
--- a/code/e2e-tests/framework-nextjs.spec.ts
+++ b/code/e2e-tests/framework-nextjs.spec.ts
@@ -10,7 +10,7 @@ test.describe('Next.js', () => {
// TODO: improve these E2E tests given that we have more version of Next.js to test
// and this only tests nextjs/default-js
test.skip(
- !templateName?.includes('nextjs/default-js'),
+ !templateName?.includes('nextjs/default-ts'),
'Only run this test for the Frameworks that support next/navigation'
);
@@ -66,7 +66,7 @@ test.describe('Next.js', () => {
sbPage = new SbPage(page);
await sbPage.navigateToStory(
- 'stories/frameworks/nextjs-nextjs-default-js/Navigation',
+ 'stories/frameworks/nextjs-nextjs-default-ts/Navigation',
'default'
);
root = sbPage.previewRoot();
@@ -100,7 +100,7 @@ test.describe('Next.js', () => {
test.beforeEach(async ({ page }) => {
sbPage = new SbPage(page);
- await sbPage.navigateToStory('stories/frameworks/nextjs-nextjs-default-js/Router', 'default');
+ await sbPage.navigateToStory('stories/frameworks/nextjs-nextjs-default-ts/Router', 'default');
root = sbPage.previewRoot();
});
diff --git a/code/e2e-tests/framework-svelte.spec.ts b/code/e2e-tests/framework-svelte.spec.ts
index 7d2efe7db6f3..ba42745c6172 100644
--- a/code/e2e-tests/framework-svelte.spec.ts
+++ b/code/e2e-tests/framework-svelte.spec.ts
@@ -41,7 +41,7 @@ test.describe('Svelte', () => {
await showCodeButton.click();
const sourceCode = root.locator('pre.prismjs');
const expectedSource = '';
- await expect(sourceCode.textContent()).resolves.toContain(expectedSource);
+ await expect(sourceCode).toHaveText(expectedSource);
});
test('Decorators runs only once', async ({ page }) => {
diff --git a/code/ui/blocks/src/blocks/Subtitle.stories.tsx b/code/ui/blocks/src/blocks/Subtitle.stories.tsx
new file mode 100644
index 000000000000..4fe4a2ef6a19
--- /dev/null
+++ b/code/ui/blocks/src/blocks/Subtitle.stories.tsx
@@ -0,0 +1,104 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import React from 'react';
+import { Subtitle } from './Subtitle';
+import * as DefaultButtonStories from '../examples/Button.stories';
+import * as ButtonStoriesWithMetaSubtitleAsBoth from '../examples/ButtonWithMetaSubtitleAsBoth.stories';
+import * as ButtonStoriesWithMetaSubtitleAsComponentSubtitle from '../examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories';
+import * as ButtonStoriesWithMetaSubtitleAsDocsSubtitle from '../examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories';
+
+const meta: Meta = {
+ component: Subtitle,
+ parameters: {
+ controls: {
+ include: [],
+ hideNoControlsWarning: true,
+ },
+ // workaround for https://github.com/storybookjs/storybook/issues/20505
+ docs: { source: { type: 'code' } },
+ attached: false,
+ docsStyles: true,
+ },
+};
+export default meta;
+
+type Story = StoryObj;
+
+export const OfCSFFileAsBoth: Story = {
+ args: {
+ of: ButtonStoriesWithMetaSubtitleAsBoth,
+ },
+ parameters: {
+ relativeCsfPaths: ['../examples/ButtonWithMetaSubtitleAsBoth.stories'],
+ },
+};
+export const OfCSFFileAsComponentSubtitle: Story = {
+ name: 'Of CSF File As parameters.componentSubtitle',
+ args: {
+ of: ButtonStoriesWithMetaSubtitleAsComponentSubtitle,
+ },
+ parameters: {
+ relativeCsfPaths: ['../examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories'],
+ },
+};
+export const OfCSFFileAsDocsSubtitle: Story = {
+ name: 'Of CSF File As parameters.docs.subtitle',
+ args: {
+ of: ButtonStoriesWithMetaSubtitleAsDocsSubtitle,
+ },
+ parameters: {
+ relativeCsfPaths: ['../examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories'],
+ },
+};
+export const OfMetaAsBoth: Story = {
+ args: {
+ of: ButtonStoriesWithMetaSubtitleAsBoth.default,
+ },
+ parameters: {
+ relativeCsfPaths: ['../examples/ButtonWithMetaSubtitleAsBoth.stories'],
+ },
+};
+export const OfMetaAsComponentSubtitle: Story = {
+ name: 'Of Meta As parameters.componentSubtitle',
+ args: {
+ of: ButtonStoriesWithMetaSubtitleAsComponentSubtitle.default,
+ },
+ parameters: {
+ relativeCsfPaths: ['../examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories'],
+ },
+};
+export const OfMetaAsDocsSubtitle: Story = {
+ name: 'Of Meta As parameters.docs.subtitle',
+ args: {
+ of: ButtonStoriesWithMetaSubtitleAsDocsSubtitle.default,
+ },
+ parameters: {
+ relativeCsfPaths: ['../examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories'],
+ },
+};
+export const DefaultAttached: Story = {
+ parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: true },
+};
+export const OfUndefinedAttached: Story = {
+ args: {
+ // @ts-expect-error this is supposed to be undefined
+ // eslint-disable-next-line import/namespace
+ of: DefaultButtonStories.NotDefined,
+ },
+ parameters: {
+ chromatic: { disableSnapshot: true },
+ relativeCsfPaths: ['../examples/Button.stories'],
+ attached: true,
+ },
+ decorators: [(s) => (window?.navigator.userAgent.match(/StorybookTestRunner/) ? : s())],
+};
+export const OfStringMetaAttached: Story = {
+ name: 'Of "meta" Attached',
+ args: {
+ of: 'meta',
+ },
+ parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: true },
+};
+export const Children: Story = {
+ parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: true },
+ render: () => This subtitle is a string passed as a children,
+};
diff --git a/code/ui/blocks/src/blocks/Subtitle.tsx b/code/ui/blocks/src/blocks/Subtitle.tsx
index 143543cb27fb..9b7556e9c7c6 100644
--- a/code/ui/blocks/src/blocks/Subtitle.tsx
+++ b/code/ui/blocks/src/blocks/Subtitle.tsx
@@ -1,15 +1,40 @@
import type { FunctionComponent, ReactNode } from 'react';
-import React, { useContext } from 'react';
+import React from 'react';
+import { deprecate } from '@storybook/client-logger';
+
import { Subtitle as PureSubtitle } from '../components';
-import { DocsContext } from './DocsContext';
+import type { Of } from './useOf';
+import { useOf } from './useOf';
interface SubtitleProps {
children?: ReactNode;
+ /**
+ * Specify where to get the subtitle from.
+ * If not specified, the subtitle will be extracted from the meta of the attached CSF file.
+ */
+ of?: Of;
}
-export const Subtitle: FunctionComponent = ({ children }) => {
- const docsContext = useContext(DocsContext);
- const content = children || docsContext.storyById().parameters?.componentSubtitle;
+const DEPRECATION_MIGRATION_LINK =
+ 'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#subtitle-block-and-parameterscomponentsubtitle';
+
+export const Subtitle: FunctionComponent = (props) => {
+ const { of, children } = props;
+
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
+
+ const { preparedMeta } = useOf(of || 'meta', ['meta']);
+ const { componentSubtitle, docs } = preparedMeta.parameters || {};
+
+ if (componentSubtitle) {
+ deprecate(
+ `Using 'parameters.componentSubtitle' property to subtitle stories is deprecated. See ${DEPRECATION_MIGRATION_LINK}`
+ );
+ }
+
+ const content = children || docs?.subtitle || componentSubtitle;
return content ? (
{content}
diff --git a/code/ui/blocks/src/blocks/Title.stories.tsx b/code/ui/blocks/src/blocks/Title.stories.tsx
new file mode 100644
index 000000000000..a75b6ef72d98
--- /dev/null
+++ b/code/ui/blocks/src/blocks/Title.stories.tsx
@@ -0,0 +1,55 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import { Title } from './Title';
+import * as DefaultButtonStories from '../examples/Button.stories';
+
+const meta: Meta = {
+ component: Title,
+ title: 'Blocks/Title',
+ parameters: {
+ controls: {
+ include: [],
+ hideNoControlsWarning: true,
+ },
+ // workaround for https://github.com/storybookjs/storybook/issues/20505
+ docs: { source: { type: 'code' } },
+ attached: false,
+ docsStyles: true,
+ },
+};
+export default meta;
+
+type Story = StoryObj;
+
+export const OfCSFFile: Story = {
+ args: {
+ of: DefaultButtonStories,
+ },
+ parameters: { relativeCsfPaths: ['../examples/Button.stories'] },
+};
+
+export const OfMeta: Story = {
+ args: {
+ of: DefaultButtonStories,
+ },
+ parameters: { relativeCsfPaths: ['../examples/Button.stories'] },
+};
+
+export const OfStringMetaAttached: Story = {
+ name: 'Of attached "meta"',
+ args: {
+ of: 'meta',
+ },
+ parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: true },
+};
+
+export const Children: Story = {
+ args: {
+ children: 'Title as children',
+ },
+ parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: false },
+};
+
+export const DefaultAttached: Story = {
+ args: {},
+ parameters: { relativeCsfPaths: ['../examples/Button.stories'], attached: true },
+};
diff --git a/code/ui/blocks/src/blocks/Title.tsx b/code/ui/blocks/src/blocks/Title.tsx
index 1f52fb2cc179..55b85ebad717 100644
--- a/code/ui/blocks/src/blocks/Title.tsx
+++ b/code/ui/blocks/src/blocks/Title.tsx
@@ -1,10 +1,20 @@
import type { ComponentTitle } from '@storybook/types';
import type { FunctionComponent, ReactNode } from 'react';
-import React, { useContext } from 'react';
+import React from 'react';
import { Title as PureTitle } from '../components';
-import { DocsContext } from './DocsContext';
+import type { Of } from './useOf';
+import { useOf } from './useOf';
interface TitleProps {
+ /**
+ * Specify where to get the title from. Must be a CSF file's default export.
+ * If not specified, the title will be read from children, or extracted from the meta of the attached CSF file.
+ */
+ of?: Of;
+
+ /**
+ * Specify content to display as the title.
+ */
children?: ReactNode;
}
@@ -12,12 +22,27 @@ const STORY_KIND_PATH_SEPARATOR = /\s*\/\s*/;
export const extractTitle = (title: ComponentTitle) => {
const groups = title.trim().split(STORY_KIND_PATH_SEPARATOR);
- return (groups && groups[groups.length - 1]) || title;
+ return groups?.[groups?.length - 1] || title;
};
-export const Title: FunctionComponent = ({ children }) => {
- const context = useContext(DocsContext);
- const content = children || extractTitle(context.storyById().title);
+export const Title: FunctionComponent = (props) => {
+ const { children, of } = props;
+
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
+
+ let preparedMeta;
+ try {
+ preparedMeta = useOf(of || 'meta', ['meta']).preparedMeta;
+ } catch (error) {
+ if (children && !error.message.includes('did you forget to use ?')) {
+ // ignore error about unattached CSF since we can still render children
+ throw error;
+ }
+ }
+
+ const content = children || extractTitle(preparedMeta.title);
return content ? {content} : null;
};
diff --git a/code/ui/blocks/src/examples/Button.stories.tsx b/code/ui/blocks/src/examples/Button.stories.tsx
index e5fc5b2e3457..a49f88f5d8f8 100644
--- a/code/ui/blocks/src/examples/Button.stories.tsx
+++ b/code/ui/blocks/src/examples/Button.stories.tsx
@@ -17,6 +17,9 @@ const meta = {
notes: 'These are notes for the Button stories',
info: 'This is info for the Button stories',
jsx: { useBooleanShorthandSyntax: false },
+ docs: {
+ subtitle: 'This is the subtitle for the Button stories',
+ },
},
} satisfies Meta;
diff --git a/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsBoth.stories.tsx b/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsBoth.stories.tsx
new file mode 100644
index 000000000000..5b4235c07c57
--- /dev/null
+++ b/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsBoth.stories.tsx
@@ -0,0 +1,29 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import { Button } from './Button';
+
+const meta = {
+ title: 'examples/Button with Meta Subtitle in Both',
+ component: Button,
+ argTypes: {
+ backgroundColor: { control: 'color' },
+ },
+ parameters: {
+ // Stop *this* story from being stacked in Chromatic
+ theme: 'default',
+ // this is to test the deprecated features of the Subtitle block
+ componentSubtitle: 'This subtitle is set in parameters.componentSubtitle',
+ docs: {
+ subtitle: 'This subtitle is set in parameters.docs.subtitle',
+ },
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const WithMetaSubtitleAsBoth: Story = {
+ args: {
+ primary: true,
+ label: 'Button',
+ },
+};
diff --git a/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories.tsx b/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories.tsx
new file mode 100644
index 000000000000..57a106340421
--- /dev/null
+++ b/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsComponentSubtitle.stories.tsx
@@ -0,0 +1,26 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import { Button } from './Button';
+
+const meta = {
+ title: 'examples/Button with Meta Subtitle in componentSubtitle',
+ component: Button,
+ argTypes: {
+ backgroundColor: { control: 'color' },
+ },
+ parameters: {
+ // Stop *this* story from being stacked in Chromatic
+ theme: 'default',
+ // this is to test the deprecated features of the Subtitle block
+ componentSubtitle: 'This subtitle is set in parameters.componentSubtitle',
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const WithMetaSubtitleInComponentSubtitle: Story = {
+ args: {
+ primary: true,
+ label: 'Button',
+ },
+};
diff --git a/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories.tsx b/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories.tsx
new file mode 100644
index 000000000000..3df3110baf6c
--- /dev/null
+++ b/code/ui/blocks/src/examples/ButtonWithMetaSubtitleAsDocsSubtitle.stories.tsx
@@ -0,0 +1,27 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import { Button } from './Button';
+
+const meta = {
+ title: 'examples/Button with Meta Subtitle in docs.subtitle',
+ component: Button,
+ argTypes: {
+ backgroundColor: { control: 'color' },
+ },
+ parameters: {
+ // Stop *this* story from being stacked in Chromatic
+ theme: 'default',
+ docs: {
+ subtitle: 'This subtitle is set in parameters.docs.subtitle',
+ },
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const WithMetaSubtitleInDocsSubtitle: Story = {
+ args: {
+ primary: true,
+ label: 'Button',
+ },
+};
diff --git a/code/ui/blocks/src/examples/EmptyExample.tsx b/code/ui/blocks/src/examples/EmptyExample.tsx
index d9ad80b7a120..a1b48922f303 100644
--- a/code/ui/blocks/src/examples/EmptyExample.tsx
+++ b/code/ui/blocks/src/examples/EmptyExample.tsx
@@ -2,7 +2,7 @@ import React from 'react';
export const EmptyExample = ({}) => (
- This component is not intended to render anything, it simply serves a something to hang
+ This component is not intended to render anything, it simply serves as something to hang
parameters off