Skip to content

Commit

Permalink
Merge pull request #25459 from storybookjs/yann/remove-deprecated-sou…
Browse files Browse the repository at this point in the history
…rce-block-props

Doc blocks: Remove deprecated props from Source block
  • Loading branch information
valentinpalkovic authored Jan 11, 2024
2 parents 91f1bb8 + 0bdf657 commit 97bfaab
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 502 deletions.
18 changes: 18 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
- [Description Doc block properties](#description-doc-block-properties)
- [Story Doc block properties](#story-doc-block-properties)
- [Manager API expandAll and collapseAll methods](#manager-api-expandall-and-collapseall-methods)
- [Source Doc block properties](#source-doc-block-properties)
- [Canvas Doc block properties](#canvas-doc-block-properties)
- [`Primary` Doc block properties](#primary-doc-block-properties)
- [`createChannel` from `@storybook/postmessage` and `@storybook/channel-websocket`](#createchannel-from-storybookpostmessage-and--storybookchannel-websocket)
- [From version 7.5.0 to 7.6.0](#from-version-750-to-760)
Expand Down Expand Up @@ -950,6 +952,22 @@ api.collapseAll() // becomes api.emit(STORIES_COLLAPSE_ALL)
api.expandAll() // becomes api.emit(STORIES_EXPAND_ALL)
```

#### Source Doc block properties

`id` and `ids` are now removed in favor of the `of` property. [More info](#doc-blocks).

#### Canvas Doc block properties

The following properties were removed from the Canvas Doc block:

- children
- isColumn
- columns
- withSource
- mdxSource

[More info](#doc-blocks).

#### `Primary` Doc block properties

The `name` prop is now removed in favor of the `of` property. [More info](#doc-blocks).
Expand Down
163 changes: 10 additions & 153 deletions code/ui/blocks/src/blocks/Canvas.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,17 @@
/* eslint-disable react/destructuring-assignment */
import React, { Children, useContext } from 'react';
import type { FC, ReactElement, ReactNode } from 'react';
import type { ModuleExport, ModuleExports, PreparedStory, Renderer } from '@storybook/types';
import { deprecate } from '@storybook/client-logger';
import dedent from 'ts-dedent';
import React, { useContext } from 'react';
import type { FC } from 'react';
import type { ModuleExport, ModuleExports } from '@storybook/types';
import type { Layout, PreviewProps as PurePreviewProps } from '../components';
import { Preview as PurePreview, PreviewSkeleton } from '../components';
import type { DocsContextProps } from './DocsContext';
import { Preview as PurePreview } from '../components';
import { DocsContext } from './DocsContext';
import type { SourceContextProps } from './SourceContainer';
import { SourceContext } from './SourceContainer';
import type { SourceProps } from './Source';
import { useSourceProps, SourceState as DeprecatedSourceState, SourceState } from './Source';
import { useStories } from './useStory';
import { useSourceProps } from './Source';
import type { StoryProps } from './Story';
import { getStoryId, Story } from './Story';
import { Story } from './Story';
import { useOf } from './useOf';

export { DeprecatedSourceState as SourceState };

type DeprecatedCanvasProps = {
/**
* @deprecated multiple stories are not supported
*/
isColumn?: boolean;
/**
* @deprecated multiple stories are not supported
*/
columns?: number;
/**
* @deprecated use `sourceState` instead
*/
withSource?: DeprecatedSourceState;
/**
* @deprecated use `source.code` instead
*/
mdxSource?: string;
/**
* @deprecated reference stories with the `of` prop instead
*/
children?: ReactNode;
};

type CanvasProps = Pick<PurePreviewProps, 'withToolbar' | 'additionalActions' | 'className'> & {
/**
* Pass the export defining a story to render that story
Expand Down Expand Up @@ -92,129 +62,16 @@ type CanvasProps = Pick<PurePreviewProps, 'withToolbar' | 'additionalActions' |
story?: Pick<StoryProps, 'inline' | 'height' | 'autoplay' | '__forceInitialArgs' | '__primary'>;
};

const useDeprecatedPreviewProps = (
{
withSource,
mdxSource,
children,
layout: layoutProp,
...props
}: DeprecatedCanvasProps & { of?: ModuleExport; layout?: Layout },
docsContext: DocsContextProps<Renderer>,
sourceContext: SourceContextProps
) => {
/*
get all story IDs by traversing through the children,
filter out any non-story children (e.g. text nodes)
and then get the id from each story depending on available props
*/
const storyIds = (Children.toArray(children) as ReactElement[])
.filter((c) => c.props && (c.props.id || c.props.name || c.props.of))
.map((c) => getStoryId(c.props, docsContext));

const stories = useStories(storyIds, docsContext);
const isLoading = stories.some((s) => !s);
const sourceProps = useSourceProps(
{
...(mdxSource ? { code: decodeURI(mdxSource) } : { ids: storyIds }),
...(props.of && { of: props.of }),
},
docsContext,
sourceContext
);
if (withSource === SourceState.NONE) {
return { isLoading, previewProps: props };
}

// if the user has specified a layout prop, use that...
let layout = layoutProp;
// ...otherwise, try to infer it from the story parameters
stories.forEach((story) => {
if (layout || !story) {
return;
}
layout = story?.parameters.layout ?? story.parameters.docs?.canvas?.layout;
});

return {
isLoading,
previewProps: {
...props, // pass through columns etc.
layout: layout ?? 'padded',
withSource: sourceProps,
isExpanded: (withSource || sourceProps.state) === SourceState.OPEN,
},
};
};

export const Canvas: FC<CanvasProps & DeprecatedCanvasProps> = (props) => {
export const Canvas: FC<CanvasProps> = (props) => {
const docsContext = useContext(DocsContext);
const sourceContext = useContext(SourceContext);
const { children, of, source } = props;
const { 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;
let sourceProps;
/**
* useOf and useSourceProps will throw if they can't find the story, in the scenario where
* the doc is unattached (no primary story) and 'of' is undefined.
* That scenario is valid in the deprecated API, where children is used as story refs rather than 'of'.
* So if children is passed we allow the error to be swallowed and we'll use them instead.
* We use two separate try blocks and throw the error afterwards to not break the rules of hooks.
*/
let hookError;
try {
({ story } = useOf(of || 'story', ['story']));
} catch (error) {
if (!children) {
hookError = error;
}
}
try {
sourceProps = useSourceProps({ ...source, ...(of && { of }) }, docsContext, sourceContext);
} catch (error) {
if (!children) {
hookError = error;
}
}
if (hookError) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw hookError;
}

if (props.withSource) {
deprecate(dedent`Setting source state with \`withSource\` is deprecated, please use \`sourceState\` with 'hidden', 'shown' or 'none' instead.
Please refer to the migration guide: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#canvas-block
`);
}
if (props.mdxSource) {
deprecate(dedent`Setting source code with \`mdxSource\` is deprecated, please use source={{code: '...'}} instead.
Please refer to the migration guide: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#canvas-block
`);
}
if (props.isColumn !== undefined || props.columns !== undefined) {
deprecate(dedent`\`isColumn\` and \`columns\` props are deprecated as the Canvas block now only supports showing a single story.
Please refer to the migration guide: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#canvas-block
`);
}
if (children) {
deprecate(dedent`Passing children to Canvas is deprecated, please use the \`of\` prop instead to reference a story.
Please refer to the migration guide: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#canvas-block
`);
return isLoading ? (
<PreviewSkeleton />
) : (
<PurePreview {...previewProps}>{children}</PurePreview>
);
}
const { story } = useOf(of || 'story', ['story']);
const sourceProps = useSourceProps({ ...source, ...(of && { of }) }, docsContext, sourceContext);

const layout =
props.layout ?? story.parameters.layout ?? story.parameters.docs?.canvas?.layout ?? 'padded';
Expand Down
Loading

0 comments on commit 97bfaab

Please sign in to comment.