-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a feature flag for modern inline rendering
- Loading branch information
Showing
9 changed files
with
206 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import React, { FunctionComponent, ReactNode, ElementType, ComponentProps } from 'react'; | ||
import { MDXProvider } from '@mdx-js/react'; | ||
import { resetComponents, Story as PureStory } from '@storybook/components'; | ||
import { toId, storyNameFromExport } from '@storybook/csf'; | ||
import { Args, BaseAnnotations } from '@storybook/addons'; | ||
import { CURRENT_SELECTION } from './types'; | ||
|
||
import { DocsContext, DocsContextProps } from './DocsContext'; | ||
|
||
export const storyBlockIdFromId = (storyId: string) => `story--${storyId}`; | ||
|
||
type PureStoryProps = ComponentProps<typeof PureStory>; | ||
|
||
type CommonProps = BaseAnnotations<Args, any> & { | ||
height?: string; | ||
inline?: boolean; | ||
}; | ||
|
||
type StoryDefProps = { | ||
name: string; | ||
children: ReactNode; | ||
}; | ||
|
||
type StoryRefProps = { | ||
id?: string; | ||
}; | ||
|
||
type StoryImportProps = { | ||
name: string; | ||
story: ElementType; | ||
}; | ||
|
||
export type StoryProps = (StoryDefProps | StoryRefProps | StoryImportProps) & CommonProps; | ||
|
||
export const lookupStoryId = ( | ||
storyName: string, | ||
{ mdxStoryNameToKey, mdxComponentMeta }: DocsContextProps | ||
) => | ||
toId( | ||
mdxComponentMeta.id || mdxComponentMeta.title, | ||
storyNameFromExport(mdxStoryNameToKey[storyName]) | ||
); | ||
|
||
export const getStoryProps = (props: StoryProps, context: DocsContextProps): PureStoryProps => { | ||
const { id } = props as StoryRefProps; | ||
const { name } = props as StoryDefProps; | ||
const inputId = id === CURRENT_SELECTION ? context.id : id; | ||
const previewId = inputId || lookupStoryId(name, context); | ||
const data = context.storyStore.fromId(previewId) || {}; | ||
|
||
const { height, inline } = props; | ||
const { storyFn = undefined, name: storyName = undefined, parameters = {} } = data; | ||
const { docs = {} } = parameters; | ||
|
||
if (docs.disable) { | ||
return null; | ||
} | ||
|
||
// prefer block props, then story parameters defined by the framework-specific settings and optionally overridden by users | ||
const { inlineStories = false, iframeHeight = 100, prepareForInline } = docs; | ||
const storyIsInline = typeof inline === 'boolean' ? inline : inlineStories; | ||
if (storyIsInline && !prepareForInline) { | ||
throw new Error( | ||
`Story '${storyName}' is set to render inline, but no 'prepareForInline' function is implemented in your docs configuration!` | ||
); | ||
} | ||
|
||
return { | ||
parameters, | ||
inline: storyIsInline, | ||
id: previewId, | ||
storyFn: prepareForInline && storyFn ? () => prepareForInline(storyFn, data) : storyFn, | ||
height: height || (storyIsInline ? undefined : iframeHeight), | ||
title: storyName, | ||
}; | ||
}; | ||
|
||
const Story: FunctionComponent<StoryProps> = (props) => ( | ||
<DocsContext.Consumer> | ||
{(context) => { | ||
const storyProps = getStoryProps(props, context); | ||
|
||
if (!storyProps) { | ||
return null; | ||
} | ||
return ( | ||
<div id={storyBlockIdFromId(storyProps.id)}> | ||
<MDXProvider components={resetComponents}> | ||
<PureStory {...storyProps} /> | ||
</MDXProvider> | ||
</div> | ||
); | ||
}} | ||
</DocsContext.Consumer> | ||
); | ||
|
||
Story.defaultProps = { | ||
children: null, | ||
name: null, | ||
}; | ||
|
||
export { Story }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React, { FunctionComponent, ReactNode, ElementType, useEffect } from 'react'; | ||
import { MDXProvider } from '@mdx-js/react'; | ||
import { resetComponents } from '@storybook/components'; | ||
import { DOCS_TARGETTED_RENDER, DOCS_TARGETTED_DESTROY } from '@storybook/core-events'; | ||
import { toId, storyNameFromExport } from '@storybook/csf'; | ||
import { Args, BaseAnnotations, addons } from '@storybook/addons'; | ||
import { CURRENT_SELECTION } from './types'; | ||
|
||
import { DocsContext, DocsContextProps } from './DocsContext'; | ||
|
||
export const storyBlockIdFromId = (storyId: string) => `story--${storyId}`; | ||
|
||
type CommonProps = BaseAnnotations<Args, any> & { | ||
height?: string; | ||
inline?: boolean; | ||
}; | ||
|
||
type StoryDefProps = { | ||
name: string; | ||
children: ReactNode; | ||
}; | ||
|
||
type StoryRefProps = { | ||
id?: string; | ||
}; | ||
|
||
type StoryImportProps = { | ||
name: string; | ||
story: ElementType; | ||
}; | ||
|
||
export type StoryProps = (StoryDefProps | StoryRefProps | StoryImportProps) & CommonProps; | ||
|
||
export const lookupStoryId = ( | ||
storyName: string, | ||
{ mdxStoryNameToKey, mdxComponentMeta }: DocsContextProps | ||
) => | ||
toId( | ||
mdxComponentMeta.id || mdxComponentMeta.title, | ||
storyNameFromExport(mdxStoryNameToKey[storyName]) | ||
); | ||
|
||
const Placeholder: FunctionComponent<any> = ({ id, name }) => { | ||
const channel = addons.getChannel(); | ||
const identifier = storyBlockIdFromId(id); | ||
useEffect(() => { | ||
channel.emit(DOCS_TARGETTED_RENDER, { identifier, id, name }); | ||
return () => { | ||
channel.emit(DOCS_TARGETTED_DESTROY, { identifier, id, name }); | ||
// TODO this does nothing, should it do something though? | ||
}; | ||
}); | ||
|
||
return ( | ||
<div id={identifier} data-name={name}> | ||
<span data-is-loadering-indicator="true">loading story...</span> | ||
</div> | ||
); | ||
}; | ||
|
||
const Story: FunctionComponent<StoryProps> = (props) => ( | ||
<DocsContext.Consumer> | ||
{(context) => { | ||
const { id } = props as StoryRefProps; | ||
const { name } = props as StoryDefProps; | ||
const inputId = id === CURRENT_SELECTION ? context.id : id; | ||
const previewId = inputId || lookupStoryId(name, context); | ||
|
||
return ( | ||
<MDXProvider components={resetComponents}> | ||
<Placeholder id={previewId} name={name} /> | ||
</MDXProvider> | ||
); | ||
}} | ||
</DocsContext.Consumer> | ||
); | ||
|
||
Story.defaultProps = { | ||
children: null, | ||
name: null, | ||
}; | ||
|
||
export { Story }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,8 @@ | ||
import React, { FunctionComponent, ReactNode, ElementType, useEffect } from 'react'; | ||
import { MDXProvider } from '@mdx-js/react'; | ||
import { resetComponents } from '@storybook/components'; | ||
import { DOCS_TARGETTED_RENDER, DOCS_TARGETTED_DESTROY } from '@storybook/core-events'; | ||
import { toId, storyNameFromExport } from '@storybook/csf'; | ||
import { Args, BaseAnnotations, addons } from '@storybook/addons'; | ||
import { CURRENT_SELECTION } from './types'; | ||
import global from 'global'; | ||
import { Story as LegacyStory } from './LegacyStory'; | ||
import { Story as ModernStory } from './ModernStory'; | ||
|
||
import { DocsContext, DocsContextProps } from './DocsContext'; | ||
export const Story = global?.MODERN_INLINE_RENDER ? ModernStory : LegacyStory; | ||
|
||
export const storyBlockIdFromId = (storyId: string) => `story--${storyId}`; | ||
|
||
type CommonProps = BaseAnnotations<Args, any> & { | ||
height?: string; | ||
inline?: boolean; | ||
}; | ||
|
||
type StoryDefProps = { | ||
name: string; | ||
children: ReactNode; | ||
}; | ||
|
||
type StoryRefProps = { | ||
id?: string; | ||
}; | ||
|
||
type StoryImportProps = { | ||
name: string; | ||
story: ElementType; | ||
}; | ||
|
||
export type StoryProps = (StoryDefProps | StoryRefProps | StoryImportProps) & CommonProps; | ||
|
||
export const lookupStoryId = ( | ||
storyName: string, | ||
{ mdxStoryNameToKey, mdxComponentMeta }: DocsContextProps | ||
) => | ||
toId( | ||
mdxComponentMeta.id || mdxComponentMeta.title, | ||
storyNameFromExport(mdxStoryNameToKey[storyName]) | ||
); | ||
|
||
const Placeholder: FunctionComponent<any> = ({ id, name }) => { | ||
const channel = addons.getChannel(); | ||
const identifier = storyBlockIdFromId(id); | ||
useEffect(() => { | ||
channel.emit(DOCS_TARGETTED_RENDER, { identifier, id, name }); | ||
return () => { | ||
channel.emit(DOCS_TARGETTED_DESTROY, { identifier, id, name }); | ||
// TODO this does nothing, should it do something though? | ||
}; | ||
}); | ||
|
||
return ( | ||
<div id={identifier} data-name={name}> | ||
<span data-is-loadering-indicator="true">loading story...</span> | ||
</div> | ||
); | ||
}; | ||
|
||
const Story: FunctionComponent<StoryProps> = (props) => ( | ||
<DocsContext.Consumer> | ||
{(context) => { | ||
const { id } = props as StoryRefProps; | ||
const { name } = props as StoryDefProps; | ||
const inputId = id === CURRENT_SELECTION ? context.id : id; | ||
const previewId = inputId || lookupStoryId(name, context); | ||
|
||
return ( | ||
<MDXProvider components={resetComponents}> | ||
<Placeholder id={previewId} name={name} /> | ||
</MDXProvider> | ||
); | ||
}} | ||
</DocsContext.Consumer> | ||
); | ||
|
||
Story.defaultProps = { | ||
children: null, | ||
name: null, | ||
}; | ||
|
||
export { Story }; | ||
// FIXME: refactor | ||
export { storyBlockIdFromId, lookupStoryId } from './ModernStory'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters