-
-
Notifications
You must be signed in to change notification settings - Fork 9.1k
/
Canvas.tsx
80 lines (71 loc) · 2.67 KB
/
Canvas.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import React, { FC, ReactElement, ReactNode, ReactNodeArray, useContext } from 'react';
import { AnyFramework } from '@storybook/csf';
import {
Preview as PurePreview,
PreviewProps as PurePreviewProps,
PreviewSkeleton,
} from '../components';
import { DocsContext, DocsContextProps } from './DocsContext';
import { SourceContext, SourceContextProps } from './SourceContainer';
import { getSourceProps, SourceState } from './Source';
import { useStories } from './useStory';
import { CURRENT_SELECTION, currentSelectionWarning } from './types';
export { SourceState };
type CanvasProps = PurePreviewProps & {
withSource?: SourceState;
mdxSource?: string;
};
const getPreviewProps = (
{ withSource, mdxSource, children, ...props }: CanvasProps & { children?: ReactNode },
docsContext: DocsContextProps<AnyFramework>,
sourceContext: SourceContextProps
) => {
let sourceState = withSource;
let isLoading = false;
if (sourceState === SourceState.NONE) {
return { isLoading, previewProps: props };
}
if (mdxSource) {
return {
isLoading,
previewProps: {
...props,
withSource: getSourceProps({ code: decodeURI(mdxSource) }, docsContext, sourceContext),
isExpanded: sourceState === SourceState.OPEN,
},
};
}
const childArray: ReactNodeArray = Array.isArray(children) ? children : [children];
const storyChildren = childArray.filter(
(c: ReactElement) => c.props && (c.props.id || c.props.name || c.props.of)
) as ReactElement[];
const targetIds = storyChildren.map(({ props: { id, of, name } }) => {
if (id) return id;
if (of) return docsContext.storyIdByModuleExport(of);
return docsContext.storyIdByName(name);
});
const sourceProps = getSourceProps({ ids: targetIds }, docsContext, sourceContext);
if (!sourceState) sourceState = sourceProps.state;
const storyIds = targetIds.map((targetId) => {
if (targetId === CURRENT_SELECTION) currentSelectionWarning();
return targetId === CURRENT_SELECTION ? docsContext.storyById().id : targetId;
});
const stories = useStories(storyIds, docsContext);
isLoading = stories.some((s) => !s);
return {
isLoading,
previewProps: {
...props, // pass through columns etc.
withSource: sourceProps,
isExpanded: sourceState === SourceState.OPEN,
},
};
};
export const Canvas: FC<CanvasProps> = (props) => {
const docsContext = useContext(DocsContext);
const sourceContext = useContext(SourceContext);
const { isLoading, previewProps } = getPreviewProps(props, docsContext, sourceContext);
const { children } = props;
if (isLoading) return <PreviewSkeleton />;
return <PurePreview {...previewProps}>{children}</PurePreview>;
};