Skip to content

Commit

Permalink
Merge pull request #14652 from lauracarballo/fix-source-dynamic-snipp…
Browse files Browse the repository at this point in the history
…et-includes-decorators

Addon-docs: Exclude decorators in dynamic source snippets
  • Loading branch information
shilman authored May 24, 2021
2 parents ac1188b + a5c667f commit f54339f
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 3 deletions.
29 changes: 28 additions & 1 deletion addons/docs/src/frameworks/react/jsxDecorator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,13 @@ describe('renderJsx', () => {
});

// @ts-ignore
const makeContext = (name: string, parameters: any, args: any): StoryContext => ({
const makeContext = (name: string, parameters: any, args: any, extra?: object): StoryContext => ({
id: `jsx-test--${name}`,
kind: 'js-text',
name,
parameters,
args,
...extra,
});

describe('jsxDecorator', () => {
Expand All @@ -183,6 +184,32 @@ describe('jsxDecorator', () => {
);
});

it('should not render decorators when provided excludeDecorators parameter', () => {
const storyFn = (args: any) => <div>args story</div>;
const decoratedStoryFn = (args: any) => (
<div style={{ padding: 25, border: '3px solid red' }}>{storyFn(args)}</div>
);
const context = makeContext(
'args',
{
__isArgsStory: true,
docs: {
source: {
excludeDecorators: true,
},
},
},
{},
{ originalStoryFn: storyFn }
);
jsxDecorator(decoratedStoryFn, context);
expect(mockChannel.emit).toHaveBeenCalledWith(
SNIPPET_RENDERED,
'jsx-test--args',
'<div>\n args story\n</div>'
);
});

it('should skip dynamic rendering for no-args stories', () => {
const storyFn = () => <div>classic story</div>;
const context = makeContext('classic', {}, {});
Expand Down
7 changes: 6 additions & 1 deletion addons/docs/src/frameworks/react/jsxDecorator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,13 @@ export const jsxDecorator = (storyFn: any, context: StoryContext) => {
...(context?.parameters.jsx || {}),
} as Required<JSXOptions>;

// Exclude decorators from source code snippet by default
const sourceJsx = context?.parameters.docs?.source?.excludeDecorators
? context.originalStoryFn(context.args)
: story;

let jsx = '';
const rendered = renderJsx(story, options);
const rendered = renderJsx(sourceJsx, options);
if (rendered) {
jsx = applyTransformSource(rendered, options, context);
}
Expand Down
5 changes: 5 additions & 0 deletions examples/cra-kitchen-sink/.storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ addParameters({
storySort: (a, b) =>
a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, undefined, { numeric: true }),
},
docs: {
source: {
excludeDecorators: true,
},
},
});
36 changes: 36 additions & 0 deletions examples/cra-kitchen-sink/src/stories/decorators.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { action } from '@storybook/addon-actions';
import { Button } from '@storybook/react/demo';
import PropTypes from 'prop-types';

const Bold = ({ children }) => {
return <b>{children}</b>;
};

Bold.propTypes = {
children: PropTypes.string.isRequired,
};

export default {
title: 'Decorators',
component: Button,
decorators: [
(Story) => (
<div style={{ padding: 25, border: '3px solid red' }}>
<Story />
</div>
),
],
};

export const WithArgs = (args) => <Button {...args} />;
WithArgs.args = { onClick: action('clicked', { depth: 1 }), children: 'With args' };

export const Basic = () => <Button onClick={action('clicked', { depth: 1 })}>Basic</Button>;

export const Nested = (args) => (
<Button {...args}>
<Bold>Hello</Bold>
</Button>
);
Nested.args = { onClick: action('clicked', { depth: 1 }) };
27 changes: 26 additions & 1 deletion examples/official-storybook/stories/hooks.stories.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import React from 'react';
import React, { useContext, createContext } from 'react';
import { useEffect, useRef, useState } from '@storybook/client-api';

const Consumer = () => {
// testing hooks in the component itself,
// rendering JSX for the component without decorators
// per https://github.com/storybookjs/storybook/pull/14652/
const value = useContext(DummyContext);
return <div>value: {value}</div>;
};

export default {
title: 'Core/Hooks',
component: Consumer,
};

export const Checkbox = () => {
Expand Down Expand Up @@ -44,3 +53,19 @@ export const ReactHookCheckbox = () => {
</label>
);
};

const DummyContext = createContext({});

export const Context = (args) => {
// testing hooks in the story
const storyContext = useContext(DummyContext);
return <Consumer />;
};

Context.decorators = [
(Story) => (
<DummyContext.Provider value="hello">
<Story />
</DummyContext.Provider>
),
];
1 change: 1 addition & 0 deletions lib/addons/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export type StoryContext = StoryIdentifier & {
globals: Args;
hooks?: HooksContext;
viewMode?: ViewMode;
originalStoryFn?: ArgsStoryFn;
};

export interface WrapperSettings {
Expand Down
4 changes: 4 additions & 0 deletions lib/client-api/src/story_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ export default class StoryStore {
args: {},
argTypes: {},
globals: {},
originalStoryFn: getOriginal(),
}),
}),
{ __isArgsStory, ...combinedParameters }
Expand All @@ -506,6 +507,7 @@ export default class StoryStore {
argTypes,
globals: this._globals,
viewMode: this._selection?.viewMode,
originalStoryFn: getOriginal(),
});
};

Expand All @@ -521,6 +523,7 @@ export default class StoryStore {
argTypes,
globals: this._globals,
viewMode: this._selection?.viewMode,
originalStoryFn: getOriginal(),
};
const loadResults = await Promise.all(loaders.map((loader) => loader(context)));
const loaded = Object.assign({}, ...loadResults);
Expand Down Expand Up @@ -554,6 +557,7 @@ export default class StoryStore {
args: initialArgsBeforeEnhancers,
argTypes,
globals: {},
originalStoryFn: getOriginal(),
}),
}),
initialArgsBeforeEnhancers
Expand Down

0 comments on commit f54339f

Please sign in to comment.