Skip to content

Commit

Permalink
Add some template exampes to external docs
Browse files Browse the repository at this point in the history
And make sure doc blocks use the "primary" story by id when possible.
  • Loading branch information
tmeasday committed Jul 6, 2022
1 parent 5b6e508 commit 7d6a4d8
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 32 deletions.
2 changes: 2 additions & 0 deletions examples/external-docs/.storybook/main.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const config = {
stories: [
'../Introduction.mdx',
{
directory: '../components',
titlePrefix: 'Demo',
files: '**/!(Template).(stories.tsx|mdx)',
},
],
logLevel: 'debug',
Expand Down
8 changes: 8 additions & 0 deletions examples/external-docs/components/Template.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Title, Description, ArgsTable, Stories, PRIMARY_STORY } from '@storybook/addon-docs';

# This is a template!

<Title />
<Description />
<ArgsTable story={PRIMARY_STORY} />
<Stories />
7 changes: 7 additions & 0 deletions examples/external-docs/components/button.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Meta } from '@storybook/blocks';
import * as ButtonStories from './button.stories.tsx';
import Template from './Template.mdx';

<Meta of={ButtonStories} />

<Template />
7 changes: 7 additions & 0 deletions examples/external-docs/components/emoji-button.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Meta } from '@storybook/addon-docs';
import * as EmojiButtonStories from './emoji-button.stories.tsx';
import Template from './Template.mdx';

<Meta of={EmojiButtonStories} />

<Template />
1 change: 1 addition & 0 deletions examples/external-docs/pages/button.mdx
1 change: 1 addition & 0 deletions examples/external-docs/pages/emoji-button.mdx
30 changes: 9 additions & 21 deletions lib/blocks/src/blocks/ArgsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,12 @@ type StoryProps = BaseProps & {

type ArgsTableProps = BaseProps | OfProps | ComponentsProps | StoryProps;

const getContext = (storyId: string, context: DocsContextProps) => {
const story = context.storyById(storyId);
if (!story) {
throw new Error(`Unknown story: ${storyId}`);
}
return context.getStoryContext(story);
};

const useArgs = (
storyId: string,
context: DocsContextProps
): [Args, (args: Args) => void, (argNames?: string[]) => void] => {
const channel = addons.getChannel();
const storyContext = getContext(storyId, context);
const storyContext = context.getStoryContext(context.storyById());

const [args, setArgs] = useState(storyContext.args);
useEffect(() => {
Expand All @@ -79,7 +71,7 @@ const useArgs = (

const useGlobals = (storyId: string, context: DocsContextProps): [Globals] => {
const channel = addons.getChannel();
const storyContext = getContext(storyId, context);
const storyContext = context.getStoryContext(context.storyById());
const [globals, setGlobals] = useState(storyContext.globals);

useEffect(() => {
Expand All @@ -95,11 +87,11 @@ const useGlobals = (storyId: string, context: DocsContextProps): [Globals] => {

export const extractComponentArgTypes = (
component: Component,
{ id, storyById }: DocsContextProps,
context: DocsContextProps,
include?: PropDescriptor,
exclude?: PropDescriptor
): StrictArgTypes => {
const { parameters } = storyById(id);
const { parameters } = context.storyById();
const { extractArgTypes }: { extractArgTypes: ArgTypesExtractor } = parameters.docs || {};
if (!extractArgTypes) {
throw new Error(ArgsTableError.ARGS_UNSUPPORTED);
Expand All @@ -114,13 +106,10 @@ const isShortcut = (value?: string) => {
return value && [CURRENT_SELECTION, PRIMARY_STORY].includes(value);
};

export const getComponent = (
props: ArgsTableProps = {},
{ id, storyById }: DocsContextProps
): Component => {
export const getComponent = (props: ArgsTableProps = {}, context: DocsContextProps): Component => {
const { of } = props as OfProps;
const { story } = props as StoryProps;
const { component } = storyById(id);
const { component } = context.storyById();
if (isShortcut(of) || isShortcut(story)) {
return component || null;
}
Expand Down Expand Up @@ -149,7 +138,7 @@ export const StoryTable: FC<
StoryProps & { component: Component; subcomponents: Record<string, Component> }
> = (props) => {
const context = useContext(DocsContext);
const { id: currentId, componentStories } = context;
const { id: currentId } = context;
const {
story: storyName,
component,
Expand All @@ -167,7 +156,7 @@ export const StoryTable: FC<
break;
}
case PRIMARY_STORY: {
const primaryStory = componentStories()[0];
const primaryStory = context.storyById();
storyId = primaryStory.id;
break;
}
Expand Down Expand Up @@ -228,11 +217,10 @@ export const ComponentsTable: FC<ComponentsProps> = (props) => {

export const ArgsTable: FC<ArgsTableProps> = (props) => {
const context = useContext(DocsContext);
const { id, storyById } = context;
const {
parameters: { controls },
subcomponents,
} = storyById(id);
} = context.storyById();

const { include, exclude, components, sort: sortProp } = props as ComponentsProps;
const { story: storyName } = props as StoryProps;
Expand Down
4 changes: 2 additions & 2 deletions lib/blocks/src/blocks/Description.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ const noDescription = (component?: Component): string | null => null;

export const getDescriptionProps = (
{ of, type, markdown, children }: DescriptionProps,
{ id, storyById }: DocsContextProps<any>
{ storyById }: DocsContextProps<any>
): PureDescriptionProps => {
const { component, parameters } = storyById(id);
const { component, parameters } = storyById();
if (children || markdown) {
return { markdown: children || markdown };
}
Expand Down
7 changes: 1 addition & 6 deletions lib/blocks/src/blocks/Source.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,7 @@ export const getSourceProps = (
sourceContext: SourceContextProps
): PureSourceProps & SourceStateProps => {
const { id: currentId, storyById } = docsContext;
let parameters = {} as Parameters;
try {
({ parameters } = storyById(currentId));
} catch (err) {
// TODO: in external mode, there is no "current"
}
const { parameters } = storyById();

const codeProps = props as CodeProps;
const singleProps = props as SingleSourceProps;
Expand Down
18 changes: 15 additions & 3 deletions lib/preview-web/src/docs-context/DocsContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export class DocsContext<TFramework extends AnyFramework> implements DocsContext

private nameToStoryId: Map<StoryName, StoryId>;

private primaryStory?: Story<TFramework>;

constructor(
public readonly id: StoryId,
public readonly title: ComponentTitle,
Expand Down Expand Up @@ -48,7 +50,9 @@ export class DocsContext<TFramework extends AnyFramework> implements DocsContext

if (addToComponentStories) {
this.nameToStoryId.set(annotation.name, annotation.id);
this.componentStoriesValue.push(this.storyById(annotation.id));
const story = this.storyById(annotation.id);
this.componentStoriesValue.push(story);
if (!this.primaryStory) this.primaryStory = story;
}
});
}
Expand All @@ -75,8 +79,16 @@ export class DocsContext<TFramework extends AnyFramework> implements DocsContext
return this.componentStoriesValue;
};

storyById = (inputStoryId?: StoryId) => {
const storyId = inputStoryId || this.id;
storyById = (storyId?: StoryId) => {
if (!storyId) {
if (!this.primaryStory)
throw new Error(
`No primary story defined for docs entry. Did you forget to use \`<Meta>\`?`
);

return this.primaryStory;
}

const csfFile = this.storyIdToCSFFile.get(storyId);
if (!csfFile)
throw new Error(`Called \`storyById\` for story that was never loaded: ${storyId}`);
Expand Down

0 comments on commit 7d6a4d8

Please sign in to comment.