diff --git a/addons/controls/README.md b/addons/controls/README.md index d394925f99c3..169d5cbeb01f 100644 --- a/addons/controls/README.md +++ b/addons/controls/README.md @@ -279,17 +279,22 @@ export const VeryLongLabel = (args) => +export const ButtonStory = (args) => ; + + + {ButtonStory.bind({})} diff --git a/addons/docs/src/mdx/__testfixtures__/story-args.output.snapshot b/addons/docs/src/mdx/__testfixtures__/story-args.output.snapshot index ef73decd1034..e22ef3db8561 100644 --- a/addons/docs/src/mdx/__testfixtures__/story-args.output.snapshot +++ b/addons/docs/src/mdx/__testfixtures__/story-args.output.snapshot @@ -6,7 +6,7 @@ import { assertIsFn, AddContext } from '@storybook/addon-docs/blocks'; import { Button } from '@storybook/react/demo'; import { Story, Meta } from '@storybook/addon-docs/blocks'; - +export const ButtonStory = (args) => ; const makeShortcode = (name) => function MDXDefaultShortcode(props) { console.warn( @@ -17,13 +17,16 @@ const makeShortcode = (name) => return
; }; -const layoutProps = {}; +const layoutProps = { + ButtonStory, +}; const MDXLayout = 'wrapper'; function MDXContent({ components, ...props }) { return (

{\`Args\`}

+ - + {ButtonStory.bind({})}
); @@ -48,7 +51,7 @@ function MDXContent({ components, ...props }) { MDXContent.isMDXComponent = true; -export const componentNotes = () => ; +export const componentNotes = ButtonStory.bind({}); componentNotes.storyName = 'component notes'; componentNotes.argTypes = { a: { @@ -62,7 +65,7 @@ componentNotes.args = { a: 1, b: 2, }; -componentNotes.parameters = { storySource: { source: '' } }; +componentNotes.parameters = { storySource: { source: 'ButtonStory.bind({})' } }; const componentMeta = { title: 'Button', includeStories: ['componentNotes'] }; diff --git a/addons/docs/src/mdx/mdx-compiler-plugin.js b/addons/docs/src/mdx/mdx-compiler-plugin.js index be7d6952ba29..8abe68dd3539 100644 --- a/addons/docs/src/mdx/mdx-compiler-plugin.js +++ b/addons/docs/src/mdx/mdx-compiler-plugin.js @@ -84,20 +84,25 @@ function genStoryExport(ast, context) { const storyReactCode = bodyParts.length > 1 ? `<>\n${storyCode}\n` : storyCode; // keep track if an indentifier or function call // avoid breaking change for 5.3 - switch (bodyParts.length === 1 && bodyParts[0].body.type) { - // We don't know what type the identifier is, but this code - // assumes it's a function from CSF. Let's see who complains! - case 'Identifier': - storyVal = `assertIsFn(${storyCode})`; - break; - case 'ArrowFunctionExpression': - storyVal = `(${storyCode})`; - break; - default: - storyVal = `() => ( + const BIND_REGEX = /\.bind\(.*\)/; + if (bodyParts.length === 1 && BIND_REGEX.test(bodyParts[0].code)) { + storyVal = bodyParts[0].code; + } else { + switch (bodyParts.length === 1 && bodyParts[0].body.type) { + // We don't know what type the identifier is, but this code + // assumes it's a function from CSF. Let's see who complains! + case 'Identifier': + storyVal = `assertIsFn(${storyCode})`; + break; + case 'ArrowFunctionExpression': + storyVal = `(${storyCode})`; + break; + default: + storyVal = `() => ( ${storyReactCode} )`; - break; + break; + } } } diff --git a/examples/angular-cli/src/stories/addon-controls.stories.ts b/examples/angular-cli/src/stories/addon-controls.stories.ts new file mode 100644 index 000000000000..86f0d915e7a4 --- /dev/null +++ b/examples/angular-cli/src/stories/addon-controls.stories.ts @@ -0,0 +1,18 @@ +import { ButtonComponent } from './doc-button/doc-button.component'; + +export default { + title: 'Addon/Controls', + component: ButtonComponent, + parameters: { docs: { iframeHeight: 120 } }, +}; + +const ButtonStory = (args) => ({ + component: ButtonComponent, + props: args, +}); + +export const Basic = ButtonStory.bind({}); +Basic.args = { label: 'Args test', isDisabled: false }; + +export const Disabled = ButtonStory.bind({}); +Disabled.args = { label: 'Disabled', isDisabled: true }; diff --git a/examples/ember-cli/.storybook/main.js b/examples/ember-cli/.storybook/main.js index 20ab5838242f..d1f25bb46dc5 100644 --- a/examples/ember-cli/.storybook/main.js +++ b/examples/ember-cli/.storybook/main.js @@ -8,6 +8,7 @@ module.exports = { '@storybook/addon-storysource', '@storybook/addon-actions', '@storybook/addon-docs', + '@storybook/addon-controls', '@storybook/addon-links', '@storybook/addon-knobs', '@storybook/addon-viewport', diff --git a/examples/ember-cli/package.json b/examples/ember-cli/package.json index 3e715d3dec46..d7e1e5d2879e 100644 --- a/examples/ember-cli/package.json +++ b/examples/ember-cli/package.json @@ -19,6 +19,7 @@ "@storybook/addon-a11y": "6.0.0-beta.29", "@storybook/addon-actions": "6.0.0-beta.29", "@storybook/addon-backgrounds": "6.0.0-beta.29", + "@storybook/addon-controls": "6.0.0-beta.29", "@storybook/addon-docs": "6.0.0-beta.29", "@storybook/addon-knobs": "6.0.0-beta.29", "@storybook/addon-links": "6.0.0-beta.29", diff --git a/examples/ember-cli/stories/addon-a11y.stories.js b/examples/ember-cli/stories/addon-a11y.stories.js index 5ef46b92224b..92cb2a614cfd 100644 --- a/examples/ember-cli/stories/addon-a11y.stories.js +++ b/examples/ember-cli/stories/addon-a11y.stories.js @@ -2,7 +2,6 @@ import { hbs } from 'ember-cli-htmlbars'; export default { title: 'Addon/a11y', - parameters: { options: { selectedPanel: '@storybook/a11y/panel' }, }, diff --git a/examples/ember-cli/stories/addon-actions.stories.js b/examples/ember-cli/stories/addon-actions.stories.js index 4151467114ab..ce4b67a59eec 100644 --- a/examples/ember-cli/stories/addon-actions.stories.js +++ b/examples/ember-cli/stories/addon-actions.stories.js @@ -3,7 +3,6 @@ import { action } from '@storybook/addon-actions'; export default { title: 'Addon/Actions', - parameters: { options: { selectedPanel: 'storybook/actions/panel', diff --git a/examples/ember-cli/stories/addon-backgrounds.stories.js b/examples/ember-cli/stories/addon-backgrounds.stories.js index 70ea6f30c4ca..39d5848ce98b 100644 --- a/examples/ember-cli/stories/addon-backgrounds.stories.js +++ b/examples/ember-cli/stories/addon-backgrounds.stories.js @@ -2,7 +2,6 @@ import { hbs } from 'ember-cli-htmlbars'; export default { title: 'Addon/Backgrounds', - parameters: { backgrounds: { default: 'dark', diff --git a/examples/ember-cli/stories/addon-controls.stories.js b/examples/ember-cli/stories/addon-controls.stories.js new file mode 100644 index 000000000000..db2a1d8e5247 --- /dev/null +++ b/examples/ember-cli/stories/addon-controls.stories.js @@ -0,0 +1,19 @@ +import { hbs } from 'ember-cli-htmlbars'; + +export default { + title: 'Addon/Controls', + argTypes: { + label: { type: { name: 'string' } }, + }, +}; + +const ButtonStory = (args) => ({ + template: hbs``, + context: args, +}); + +export const Hello = ButtonStory.bind({}); +Hello.args = { label: 'Hello!' }; + +export const Bonjour = ButtonStory.bind({}); +Bonjour.args = { label: 'Bonjour!' }; diff --git a/examples/ember-cli/stories/addon-knobs.stories.js b/examples/ember-cli/stories/addon-knobs.stories.js index 29c9e12b595c..6aff81be1dbc 100644 --- a/examples/ember-cli/stories/addon-knobs.stories.js +++ b/examples/ember-cli/stories/addon-knobs.stories.js @@ -5,7 +5,6 @@ import { action } from '@storybook/addon-actions'; export default { title: 'Addon/Knobs', decorators: [withKnobs], - parameters: { options: { selectedPanel: 'storybookjs/knobs/panel' }, }, diff --git a/examples/ember-cli/stories/index.stories.js b/examples/ember-cli/stories/index.stories.js index f2b461b43eac..547a286c29a5 100644 --- a/examples/ember-cli/stories/index.stories.js +++ b/examples/ember-cli/stories/index.stories.js @@ -2,7 +2,6 @@ import { hbs } from 'ember-cli-htmlbars'; export default { title: 'Welcome', - parameters: { options: { showPanel: false }, }, diff --git a/examples/html-kitchen-sink/.storybook/main.js b/examples/html-kitchen-sink/.storybook/main.js index 059d11ddb6cc..efa6344c6473 100644 --- a/examples/html-kitchen-sink/.storybook/main.js +++ b/examples/html-kitchen-sink/.storybook/main.js @@ -7,6 +7,7 @@ module.exports = { '@storybook/addon-a11y', '@storybook/addon-actions', '@storybook/addon-backgrounds', + '@storybook/addon-controls', '@storybook/addon-events', '@storybook/addon-jest', '@storybook/addon-knobs', diff --git a/examples/html-kitchen-sink/package.json b/examples/html-kitchen-sink/package.json index c4935c8485ca..945cbff1901a 100644 --- a/examples/html-kitchen-sink/package.json +++ b/examples/html-kitchen-sink/package.json @@ -16,6 +16,7 @@ "@storybook/addon-a11y": "6.0.0-beta.29", "@storybook/addon-actions": "6.0.0-beta.29", "@storybook/addon-backgrounds": "6.0.0-beta.29", + "@storybook/addon-controls": "6.0.0-beta.29", "@storybook/addon-docs": "6.0.0-beta.29", "@storybook/addon-events": "6.0.0-beta.29", "@storybook/addon-jest": "6.0.0-beta.29", diff --git a/examples/html-kitchen-sink/stories/addon-controls.stories.js b/examples/html-kitchen-sink/stories/addon-controls.stories.js new file mode 100644 index 000000000000..78f9b1d57a6c --- /dev/null +++ b/examples/html-kitchen-sink/stories/addon-controls.stories.js @@ -0,0 +1,16 @@ +export default { + title: 'Addons/Controls', + argTypes: { + label: { type: { name: 'string' } }, + }, +}; + +const ButtonStory = ({ label }) => { + return `
${label}
`; +}; + +export const Hello = ButtonStory.bind({}); +Hello.args = { label: 'Hello!' }; + +export const Bonjour = ButtonStory.bind({}); +Bonjour.args = { label: 'Bonjour!' }; diff --git a/examples/official-storybook/stories/addon-docs/props.stories.mdx b/examples/official-storybook/stories/addon-docs/props.stories.mdx index ad44ee97ccc4..1afb27de05d2 100644 --- a/examples/official-storybook/stories/addon-docs/props.stories.mdx +++ b/examples/official-storybook/stories/addon-docs/props.stories.mdx @@ -11,7 +11,7 @@ import { MemoButton } from '../../components/MemoButton'; parameters={{ controls: { expanded: false } }} /> -export const ArgsDisplay = (args = {}) => ( +export const ArgsStory = (args = {}) => ( {Object.entries(args).map(([key, val]) => ( @@ -68,7 +68,7 @@ export const ArgsDisplay = (args = {}) => ( }, }} > - {(args) => } + {ArgsStory.bind({})} @@ -88,7 +88,7 @@ export const ArgsDisplay = (args = {}) => ( bar: '', }} > - {(args) => } + {ArgsStory.bind({})} diff --git a/examples/svelte-kitchen-sink/.storybook/main.js b/examples/svelte-kitchen-sink/.storybook/main.js index aef7a04f9872..0c0d14858f48 100644 --- a/examples/svelte-kitchen-sink/.storybook/main.js +++ b/examples/svelte-kitchen-sink/.storybook/main.js @@ -12,6 +12,7 @@ module.exports = { configureJSX: true, }, }, + '@storybook/addon-controls', '@storybook/addon-links', '@storybook/addon-knobs', '@storybook/addon-backgrounds', diff --git a/examples/svelte-kitchen-sink/package.json b/examples/svelte-kitchen-sink/package.json index b947393df55d..555d02374976 100644 --- a/examples/svelte-kitchen-sink/package.json +++ b/examples/svelte-kitchen-sink/package.json @@ -13,6 +13,7 @@ "@storybook/addon-a11y": "6.0.0-beta.29", "@storybook/addon-actions": "6.0.0-beta.29", "@storybook/addon-backgrounds": "6.0.0-beta.29", + "@storybook/addon-controls": "6.0.0-beta.29", "@storybook/addon-docs": "6.0.0-beta.29", "@storybook/addon-knobs": "6.0.0-beta.29", "@storybook/addon-links": "6.0.0-beta.29", diff --git a/examples/svelte-kitchen-sink/src/stories/addon-controls.stories.js b/examples/svelte-kitchen-sink/src/stories/addon-controls.stories.js new file mode 100644 index 000000000000..08ce74e25268 --- /dev/null +++ b/examples/svelte-kitchen-sink/src/stories/addon-controls.stories.js @@ -0,0 +1,26 @@ +import ButtonView from './views/ButtonView.svelte'; + +export default { + title: 'Addon/Controls', + argTypes: { + rounded: { type: { name: 'boolean' } }, + message: { type: { name: 'string' } }, + }, +}; + +const ButtonStory = (args) => ({ + Component: ButtonView, + props: args, +}); + +export const Rounded = ButtonStory.bind({}); +Rounded.args = { + rounded: true, + message: 'Rounded text', +}; + +export const Square = ButtonStory.bind({}); +Square.args = { + rounded: false, + message: 'Squared text', +}; diff --git a/examples/vue-kitchen-sink/src/stories/addon-controls.stories.js b/examples/vue-kitchen-sink/src/stories/addon-controls.stories.js new file mode 100644 index 000000000000..f7e695e05c23 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/addon-controls.stories.js @@ -0,0 +1,29 @@ +import MyButton from './Button.vue'; + +export default { + title: 'Addon/Controls', + component: MyButton, + argTypes: { + color: { control: { type: 'color' } }, + }, +}; + +const ButtonStory = (args) => ({ + props: Object.keys(args), + components: { MyButton }, + template: '{{label}}', +}); + +export const Rounded = ButtonStory.bind({}); +Rounded.args = { + rounded: true, + color: '#f00', + label: 'A Button with rounded edges', +}; + +export const Square = ButtonStory.bind({}); +Square.args = { + rounded: false, + color: '#00f', + label: 'A Button with square edges', +}; diff --git a/examples/vue-kitchen-sink/src/stories/addon-controls.stories.mdx b/examples/vue-kitchen-sink/src/stories/addon-controls.stories.mdx new file mode 100644 index 000000000000..c67666637489 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/addon-controls.stories.mdx @@ -0,0 +1,50 @@ +import { Meta, Preview, Story } from '@storybook/addon-docs/blocks'; +import MyButton from './Button.vue'; + + + +export const ButtonStory = (args) => ({ + props: Object.keys(args), + components: { MyButton }, + template: '{{label}}', +}); + +# Addon-controls in MDX + +Controls can also be defined and used in MDX stories. + +## Rounded + + + + {ButtonStory.bind({})} + + + +## Square + + + + {ButtonStory.bind({})} + + diff --git a/examples/web-components-kitchen-sink/stories/addon-controls.stories.js b/examples/web-components-kitchen-sink/stories/addon-controls.stories.js new file mode 100644 index 000000000000..181b2255156f --- /dev/null +++ b/examples/web-components-kitchen-sink/stories/addon-controls.stories.js @@ -0,0 +1,33 @@ +/* eslint-disable import/extensions */ +import { html } from 'lit-html'; +import '../demo-wc-card.js'; + +export default { + title: 'Addons/Controls', + component: 'demo-wc-card', +}; + +const CardStory = ({ backSide, header, rows }) => + html` + A simple card + `; + +export const Front = CardStory.bind({}); +Front.args = { backSide: false, header: undefined, rows: [] }; + +export const Back = CardStory.bind({}); +Back.args = { ...Front.args, backSide: true }; + +export const FrontOwnHeader = CardStory.bind({}); +FrontOwnHeader.args = { ...Front.args, header: 'My own Header' }; + +export const BackWithData = CardStory.bind({}); +BackWithData.args = { + ...Back.args, + rows: [ + { header: 'health', value: '200' }, + { header: 'mana', value: '100' }, + ], +}; diff --git a/lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx b/lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx index c3434ba8b966..f5fae762926e 100644 --- a/lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgRow.stories.tsx @@ -122,53 +122,55 @@ const withArgs = { updateArgs: action('updateArgs'), }; -export const String = (args) => ; +const ArgRowStory = (args) => ; + +export const String = ArgRowStory.bind({}); String.args = { row: stringType, }; -export const LongName = (args) => ; +export const LongName = ArgRowStory.bind({}); LongName.args = { row: longNameType, }; -export const LongDesc = (args) => ; +export const LongDesc = ArgRowStory.bind({}); LongDesc.args = { row: longDescType, }; -export const Number = (args) => ; +export const Number = ArgRowStory.bind({}); Number.args = { row: numberType, }; -export const ObjectOf = (args) => ; +export const ObjectOf = ArgRowStory.bind({}); ObjectOf.args = { row: objectType, }; -export const ArrayOf = (args) => ; +export const ArrayOf = ArgRowStory.bind({}); ArrayOf.args = { row: arrayType, }; -export const ComplexObject = (args) => ; +export const ComplexObject = ArgRowStory.bind({}); ComplexObject.args = { row: complexType, }; -export const Func = (args) => ; +export const Func = ArgRowStory.bind({}); Func.args = { row: funcType, }; -export const Markdown = (args) => ; +export const Markdown = ArgRowStory.bind({}); Markdown.args = { row: markdownType, }; -export const StringCompact = (args) => ; +export const StringCompact = ArgRowStory.bind({}); StringCompact.args = { ...String.args, compact: true, }; -export const Args = (args) => ; +export const Args = ArgRowStory.bind({}); Args.args = { ...String.args, ...withArgs, }; -export const ArgsCompact = (args) => ; +export const ArgsCompact = ArgRowStory.bind({}); ArgsCompact.args = { ...Args.args, compact: true, diff --git a/lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx b/lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx index 466994002b9b..e2752a9b9394 100644 --- a/lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx +++ b/lib/components/src/blocks/ArgsTable/ArgsTable.stories.tsx @@ -13,7 +13,9 @@ const eventsSection = { category: 'events ' }; const stringType = ArgRow.String.args.row; const numberType = ArgRow.Number.args.row; -export const Normal = (args) => ; +const ArgsTableStory = (args) => ; + +export const Normal = ArgsTableStory.bind({}); Normal.args = { rows: { stringType, @@ -21,7 +23,7 @@ Normal.args = { }, }; -export const Compact = (args) => ; +export const Compact = ArgsTableStory.bind({}); Compact.args = { ...Normal.args, compact: true, @@ -33,21 +35,21 @@ const sectionRows = { c: { ...stringType, table: { ...stringType.table, ...eventsSection } }, }; -export const Sections = (args) => ; +export const Sections = ArgsTableStory.bind({}); Sections.args = { rows: sectionRows, }; -export const SectionsCompact = (args) => ; +export const SectionsCompact = ArgsTableStory.bind({}); SectionsCompact.args = { ...Sections.args, compact: true, }; -export const Error = (args) => ; +export const Error = ArgsTableStory.bind({}); Error.args = { error: ArgsTableError.NO_COMPONENT, }; -export const Empty = (args) => ; +export const Empty = ArgsTableStory.bind({}); Empty.args = { rows: {} }; diff --git a/lib/components/src/blocks/ArgsTable/TabbedArgsTable.stories.tsx b/lib/components/src/blocks/ArgsTable/TabbedArgsTable.stories.tsx index 86618e3ff17f..6bbe5e71bf99 100644 --- a/lib/components/src/blocks/ArgsTable/TabbedArgsTable.stories.tsx +++ b/lib/components/src/blocks/ArgsTable/TabbedArgsTable.stories.tsx @@ -7,10 +7,9 @@ export default { title: 'Docs/TabbedArgsTable', }; -const propsSection = { category: 'props ' }; -const eventsSection = { category: 'events ' }; +const Story = (args) => ; -export const Tabs = (args) => ; +export const Tabs = Story.bind({}); Tabs.args = { tabs: { Normal: Normal.args, @@ -19,7 +18,7 @@ Tabs.args = { }, }; -export const Empty = Tabs.bind(); +export const Empty = Story.bind({}); Empty.args = { tabs: {}, };