diff --git a/code/ui/blocks/src/blocks/ArgTypes.stories.tsx b/code/ui/blocks/src/blocks/ArgTypes.stories.tsx
index 5176d59621bb..a177868ba92a 100644
--- a/code/ui/blocks/src/blocks/ArgTypes.stories.tsx
+++ b/code/ui/blocks/src/blocks/ArgTypes.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { ArgTypes } from './ArgTypes';
@@ -35,6 +36,16 @@ export const OfStory: Story = {
},
};
+export const OfUndefined: Story = {
+ args: {
+ // @ts-expect-error this is supposed to be undefined
+ // eslint-disable-next-line import/namespace
+ of: ExampleStories.NotDefined,
+ },
+ parameters: { chromatic: { disableSnapshot: true } },
+ decorators: [(s) => (window?.navigator.userAgent.match(/StorybookTestRunner/) ?
: s())],
+};
+
// NOTE: this will throw with no of prop
export const OfStoryUnattached: Story = {
parameters: { attached: false },
diff --git a/code/ui/blocks/src/blocks/ArgTypes.tsx b/code/ui/blocks/src/blocks/ArgTypes.tsx
index 009d66cd8198..3515af129bbc 100644
--- a/code/ui/blocks/src/blocks/ArgTypes.tsx
+++ b/code/ui/blocks/src/blocks/ArgTypes.tsx
@@ -60,6 +60,9 @@ function getArgTypesFromResolved(resolved: ReturnType, props: ArgT
export const ArgTypes: FC = (props) => {
const { of } = props;
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
const resolved = useOf(of || 'meta');
const { argTypes, parameters } = getArgTypesFromResolved(resolved, props);
const argTypesParameters = parameters.docs?.argTypes || ({} as ArgTypesParameters);
diff --git a/code/ui/blocks/src/blocks/ArgsTable.tsx b/code/ui/blocks/src/blocks/ArgsTable.tsx
index 378610a8a40b..8322254e8791 100644
--- a/code/ui/blocks/src/blocks/ArgsTable.tsx
+++ b/code/ui/blocks/src/blocks/ArgsTable.tsx
@@ -226,6 +226,9 @@ export const ArgsTable: FC = (props) => {
({ parameters, component, subcomponents } = context.storyById());
} catch (err) {
const { of } = props as OfProps;
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
({
projectAnnotations: { parameters },
} = context.resolveOf(of, ['component']));
diff --git a/code/ui/blocks/src/blocks/Canvas.stories.tsx b/code/ui/blocks/src/blocks/Canvas.stories.tsx
index 4a6d75b4ea86..4022cb110043 100644
--- a/code/ui/blocks/src/blocks/Canvas.stories.tsx
+++ b/code/ui/blocks/src/blocks/Canvas.stories.tsx
@@ -33,26 +33,36 @@ export default meta;
type Story = StoryObj;
-export const DefaultAttached: Story = {
+export const OfAttached: Story = {
args: {
of: ButtonStories.Primary,
},
};
-export const DefaultUnattached: Story = {
+export const OfUnattached: Story = {
args: {
of: ButtonStories.Primary,
},
parameters: { attached: false },
};
-export const DefaultError: Story = {
+export const OfError: Story = {
args: {
of: ButtonStories.ErrorStory,
},
};
-export const UndefinedOf: Story = {};
+export const DefaultAttached: Story = {};
+
+export const OfUndefined: Story = {
+ args: {
+ // @ts-expect-error this is supposed to be undefined
+ // eslint-disable-next-line import/namespace
+ of: ButtonStories.NotDefined,
+ },
+ parameters: { chromatic: { disableSnapshot: true } },
+ decorators: [(s) => (window?.navigator.userAgent.match(/StorybookTestRunner/) ? : s())],
+};
export const PropWithToolbar: Story = {
name: 'Prop withToolbar = true',
diff --git a/code/ui/blocks/src/blocks/Canvas.tsx b/code/ui/blocks/src/blocks/Canvas.tsx
index d354fe775ad3..2245629b438d 100644
--- a/code/ui/blocks/src/blocks/Canvas.tsx
+++ b/code/ui/blocks/src/blocks/Canvas.tsx
@@ -115,7 +115,10 @@ const useDeprecatedPreviewProps = (
const stories = useStories(storyIds, docsContext);
const isLoading = stories.some((s) => !s);
const sourceProps = useSourceProps(
- mdxSource ? { code: decodeURI(mdxSource), of: props.of } : { ids: storyIds, of: props.of },
+ {
+ ...(mdxSource ? { code: decodeURI(mdxSource) } : { ids: storyIds }),
+ ...(props.of && { of: props.of }),
+ },
docsContext,
sourceContext
);
@@ -155,6 +158,10 @@ export const Canvas: FC = (props) => {
const docsContext = useContext(DocsContext);
const sourceContext = useContext(SourceContext);
const { children, of, source } = props;
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
+
const { isLoading, previewProps } = useDeprecatedPreviewProps(props, docsContext, sourceContext);
let story: PreparedStory;
@@ -175,7 +182,7 @@ export const Canvas: FC = (props) => {
}
}
try {
- sourceProps = useSourceProps({ ...source, of }, docsContext, sourceContext);
+ sourceProps = useSourceProps({ ...source, ...(of && { of }) }, docsContext, sourceContext);
} catch (error) {
if (!children) {
hookError = error;
diff --git a/code/ui/blocks/src/blocks/Controls.stories.tsx b/code/ui/blocks/src/blocks/Controls.stories.tsx
index d8da8fabb0bd..7bde517b7bfa 100644
--- a/code/ui/blocks/src/blocks/Controls.stories.tsx
+++ b/code/ui/blocks/src/blocks/Controls.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Controls } from './Controls';
@@ -30,6 +31,16 @@ export const OfStoryUnattached: Story = {
},
};
+export const OfUndefined: Story = {
+ args: {
+ // @ts-expect-error this is supposed to be undefined
+ // eslint-disable-next-line import/namespace
+ of: ExampleStories.NotDefined,
+ },
+ parameters: { chromatic: { disableSnapshot: true } },
+ decorators: [(s) => (window?.navigator.userAgent.match(/StorybookTestRunner/) ? : s())],
+};
+
export const IncludeProp: Story = {
args: {
of: ExampleStories.NoParameters,
diff --git a/code/ui/blocks/src/blocks/Controls.tsx b/code/ui/blocks/src/blocks/Controls.tsx
index 8a70a4a29520..9712aeda130e 100644
--- a/code/ui/blocks/src/blocks/Controls.tsx
+++ b/code/ui/blocks/src/blocks/Controls.tsx
@@ -24,6 +24,10 @@ type ControlsProps = ControlsParameters & {
export const Controls: FC = (props) => {
const { of } = props;
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
+
const context = useContext(DocsContext);
const { story } = context.resolveOf(of || 'story', ['story']);
const { parameters, argTypes } = story;
diff --git a/code/ui/blocks/src/blocks/Description.stories.tsx b/code/ui/blocks/src/blocks/Description.stories.tsx
index 0e940c37cf54..a8f6bac08fd5 100644
--- a/code/ui/blocks/src/blocks/Description.stories.tsx
+++ b/code/ui/blocks/src/blocks/Description.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Description } from './Description';
import { Button as ButtonComponent } from '../examples/Button';
@@ -107,9 +108,22 @@ export const OfStoryAsStoryCommentAndParameter: Story = {
},
parameters: { relativeCsfPaths: ['../examples/Button.stories'] },
};
-export const OfUndefinedAttached: Story = {
+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 OfStringComponentAttached: Story = {
name: 'Of "component" Attached',
args: {
diff --git a/code/ui/blocks/src/blocks/Description.tsx b/code/ui/blocks/src/blocks/Description.tsx
index 645a4d95f54c..a6cda58ca930 100644
--- a/code/ui/blocks/src/blocks/Description.tsx
+++ b/code/ui/blocks/src/blocks/Description.tsx
@@ -125,6 +125,10 @@ const getDescriptionFromDeprecatedProps = (
const DescriptionContainer: FC = (props) => {
const { of, type, markdown: markdownProp, children } = props;
+
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
const context = useContext(DocsContext);
const resolvedOf = useOf(of || 'meta');
let markdown;
diff --git a/code/ui/blocks/src/blocks/Source.stories.tsx b/code/ui/blocks/src/blocks/Source.stories.tsx
index ad70eafedf80..ef0b85c3dce7 100644
--- a/code/ui/blocks/src/blocks/Source.stories.tsx
+++ b/code/ui/blocks/src/blocks/Source.stories.tsx
@@ -53,6 +53,16 @@ export const Of: Story = {
},
};
+export const OfUndefined: Story = {
+ args: {
+ // @ts-expect-error this is supposed to be undefined
+ // eslint-disable-next-line import/namespace
+ of: ParametersStories.NotDefined,
+ },
+ parameters: { chromatic: { disableSnapshot: true } },
+ decorators: [(s) => (window?.navigator.userAgent.match(/StorybookTestRunner/) ? : s())],
+};
+
export const OfTypeProp: Story = {
args: {
of: ParametersStories.NoParameters,
diff --git a/code/ui/blocks/src/blocks/Source.tsx b/code/ui/blocks/src/blocks/Source.tsx
index 335c338dc611..5b43a4828537 100644
--- a/code/ui/blocks/src/blocks/Source.tsx
+++ b/code/ui/blocks/src/blocks/Source.tsx
@@ -126,8 +126,13 @@ export const useSourceProps = (
// The check didn't actually change the type.
let stories: PreparedStory[] = storiesFromIds as PreparedStory[];
- if (props.of) {
- const resolved = docsContext.resolveOf(props.of, ['story']);
+ const { of } = props;
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
+
+ if (of) {
+ const resolved = docsContext.resolveOf(of, ['story']);
stories = [resolved.story];
} else if (stories.length === 0) {
try {
diff --git a/code/ui/blocks/src/blocks/Story.stories.tsx b/code/ui/blocks/src/blocks/Story.stories.tsx
index 5f416e055724..dce6292a643c 100644
--- a/code/ui/blocks/src/blocks/Story.stories.tsx
+++ b/code/ui/blocks/src/blocks/Story.stories.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Story as StoryBlock } from './Story';
@@ -45,6 +46,16 @@ export const OfError: Story = {
},
};
+export const OfUndefined: Story = {
+ args: {
+ // @ts-expect-error this is supposed to be undefined
+ // eslint-disable-next-line import/namespace
+ of: ButtonStories.NotDefined,
+ },
+ parameters: { chromatic: { disableSnapshot: true } },
+ decorators: [(s) => (window?.navigator.userAgent.match(/StorybookTestRunner/) ? : s())],
+};
+
export const Inline: Story = {
args: {
of: StoryParametersStories.NoParameters,
diff --git a/code/ui/blocks/src/blocks/Story.tsx b/code/ui/blocks/src/blocks/Story.tsx
index 42d84ff90947..42f7e5935ae3 100644
--- a/code/ui/blocks/src/blocks/Story.tsx
+++ b/code/ui/blocks/src/blocks/Story.tsx
@@ -89,6 +89,10 @@ export type StoryProps = (StoryDefProps | StoryRefProps) & StoryParameters;
export const getStoryId = (props: StoryProps, context: DocsContextProps): StoryId => {
const { id, of, meta, story } = props as StoryRefProps;
+ if ('of' in props && of === undefined) {
+ throw new Error('Unexpected `of={undefined}`, did you mistype a CSF file reference?');
+ }
+
if (id) {
deprecate(dedent`Referencing stories by \`id\` is deprecated, please use \`of\` instead.