From 30e065b47eff4018c4a8729a0de457cd17809736 Mon Sep 17 00:00:00 2001 From: ASeeto Date: Fri, 5 Jan 2018 14:08:41 -0500 Subject: [PATCH 001/175] Enable groupId option for knobs to be organized into sub panels. --- addons/knobs/README.md | 35 +++++++++++----- addons/knobs/src/KnobStore.js | 1 + addons/knobs/src/base.js | 35 ++++++++-------- addons/knobs/src/components/Panel.js | 40 +++++++++++++++++-- .../stories/addon-knobs.stories.js | 8 ++-- 5 files changed, 84 insertions(+), 35 deletions(-) diff --git a/addons/knobs/README.md b/addons/knobs/README.md index 78b5039f760b..e7eff3e15c66 100644 --- a/addons/knobs/README.md +++ b/addons/knobs/README.md @@ -123,8 +123,9 @@ import { text } from '@storybook/addon-knobs/react'; const label = 'Your Name'; const defaultValue = 'Arunoda Susiripala'; +const groupId = 'GROUP-ID1'; -const value = text(label, defaultValue); +const value = text(label, defaultValue, groupId); ``` ### boolean @@ -136,8 +137,9 @@ import { boolean } from '@storybook/addon-knobs/react'; const label = 'Agree?'; const defaultValue = false; +const groupId = 'GROUP-ID1'; -const value = boolean(label, defaultValue); +const value = boolean(label, defaultValue, groupId); ``` ### number @@ -149,8 +151,9 @@ import { number } from '@storybook/addon-knobs/react'; const label = 'Age'; const defaultValue = 78; +const groupId = 'GROUP-ID1'; -const value = number(label, defaultValue); +const value = number(label, defaultValue, groupId); ``` ### number bound by range @@ -168,8 +171,9 @@ const options = { max: 90, step: 1, }; +const groupId = 'GROUP-ID1'; -const value = number(label, defaultValue, options); +const value = number(label, defaultValue, options, groupId); ``` ### color @@ -181,8 +185,9 @@ import { color } from '@storybook/addon-knobs/react'; const label = 'Color'; const defaultValue = '#ff00ff'; +const groupId = 'GROUP-ID1'; -const value = color(label, defaultValue); +const value = color(label, defaultValue, groupId); ``` ### object @@ -196,8 +201,9 @@ const label = 'Styles'; const defaultValue = { backgroundColor: 'red' }; +const groupId = 'GROUP-ID1'; -const value = object(label, defaultValue); +const value = object(label, defaultValue, groupId); ``` > Make sure to enter valid JSON syntax while editing values inside the knob. @@ -210,7 +216,8 @@ Allows you to get an array of strings from the user. import { array } from '@storybook/addon-knobs/react'; const label = 'Styles'; -const defaultValue = ['Red'] +const defaultValue = ['Red']; +const groupId = 'GROUP-ID1'; const value = array(label, defaultValue); ``` @@ -224,7 +231,8 @@ const value = array(label, defaultValue); > const label = 'Styles'; > const defaultValue = ['Red']; > const separator = ':'; -> const value = array(label, defaultValue, separator); +> const groupId = 'GROUP-ID1'; +> const value = array(label, defaultValue, separator, groupId); > ``` ### select @@ -241,8 +249,9 @@ const options = { yellow: 'Yellow', }; const defaultValue = 'red'; +const groupId = 'GROUP-ID1'; -const value = select(label, options, defaultValue); +const value = select(label, options, defaultValue, groupId); ``` > You can also provide options as an array like this: `['red', 'blue', 'yellow']` @@ -256,7 +265,9 @@ import { date } from '@storybook/addon-knobs/react'; const label = 'Event Date'; const defaultValue = new Date('Jan 20 2017'); -const value = date(label, defaultValue); +const groupId = 'GROUP-ID1'; + +const value = date(label, defaultValue, groupId); ``` > Note: the default value must not change - e.g., do not do `date('Label', new Date())` or `date('Label')` @@ -280,7 +291,9 @@ import { button } from '@storybook/addon-knobs'; const label = 'Do Something'; const handler = () => doSomething('foobar'); -button(label, handler); +const groupId = 'GROUP-ID1'; + +button(label, handler, groupId); ``` ### withKnobs vs withKnobsOptions diff --git a/addons/knobs/src/KnobStore.js b/addons/knobs/src/KnobStore.js index b3a365c6af60..6474abfb79ee 100644 --- a/addons/knobs/src/KnobStore.js +++ b/addons/knobs/src/KnobStore.js @@ -11,6 +11,7 @@ export default class KnobStore { set(key, value) { this.store[key] = value; this.store[key].used = true; + this.store[key].groupId = value.groupId; this.callbacks.forEach(cb => cb()); } diff --git a/addons/knobs/src/base.js b/addons/knobs/src/base.js index 41597325b2b3..e382c625035f 100644 --- a/addons/knobs/src/base.js +++ b/addons/knobs/src/base.js @@ -6,15 +6,15 @@ export function knob(name, options) { return manager.knob(name, options); } -export function text(name, value) { - return manager.knob(name, { type: 'text', value }); +export function text(name, value, groupId) { + return manager.knob(name, { type: 'text', value, groupId }); } -export function boolean(name, value) { - return manager.knob(name, { type: 'boolean', value }); +export function boolean(name, value, groupId) { + return manager.knob(name, { type: 'boolean', value, groupId }); } -export function number(name, value, options = {}) { +export function number(name, value, options = {}, groupId) { const rangeDefaults = { min: 0, max: 10, @@ -32,32 +32,33 @@ export function number(name, value, options = {}) { ...mergedOptions, type: 'number', value, + groupId, }; return manager.knob(name, finalOptions); } -export function color(name, value) { - return manager.knob(name, { type: 'color', value }); +export function color(name, value, groupId) { + return manager.knob(name, { type: 'color', value, groupId }); } -export function object(name, value) { - return manager.knob(name, { type: 'object', value }); +export function object(name, value, groupId) { + return manager.knob(name, { type: 'object', value, groupId }); } -export function select(name, options, value) { - return manager.knob(name, { type: 'select', options, value }); +export function select(name, options, value, groupId) { + return manager.knob(name, { type: 'select', options, value, groupId }); } -export function array(name, value, separator = ',') { - return manager.knob(name, { type: 'array', value, separator }); +export function array(name, value, separator = ',', groupId) { + return manager.knob(name, { type: 'array', value, separator, groupId }); } -export function date(name, value = new Date()) { +export function date(name, value = new Date(), groupId) { const proxyValue = value ? value.getTime() : null; - return manager.knob(name, { type: 'date', value: proxyValue }); + return manager.knob(name, { type: 'date', value: proxyValue, groupId }); } -export function button(name, callback) { - return manager.knob(name, { type: 'button', callback, hideLabel: true }); +export function button(name, callback, groupId) { + return manager.knob(name, { type: 'button', callback, hideLabel: true, groupId }); } diff --git a/addons/knobs/src/components/Panel.js b/addons/knobs/src/components/Panel.js index 062f660c23a1..9a36bb8b5799 100644 --- a/addons/knobs/src/components/Panel.js +++ b/addons/knobs/src/components/Panel.js @@ -5,6 +5,8 @@ import debounce from 'lodash.debounce'; import PropForm from './PropForm'; import Types from './types'; +import AddonPanel from '../../../../lib/ui/src/modules/ui/components/addon_panel/index'; + const getTimestamp = () => +new Date(); const styles = { @@ -50,8 +52,9 @@ export default class Panel extends React.Component { this.setKnobs = this.setKnobs.bind(this); this.reset = this.reset.bind(this); this.setOptions = this.setOptions.bind(this); + this.onPanelSelect = this.onPanelSelect.bind(this); - this.state = { knobs: {} }; + this.state = { knobs: {}, groupId: 'ALL' }; this.options = {}; this.lastEdit = getTimestamp(); @@ -70,6 +73,10 @@ export default class Panel extends React.Component { this.stopListeningOnStory(); } + onPanelSelect(name) { + this.setState({ groupId: name }); + } + setOptions(options = { debounce: false, timestamps: false }) { this.options = options; @@ -139,9 +146,31 @@ export default class Panel extends React.Component { } render() { - const { knobs } = this.state; + const { knobs, groupId } = this.state; + + const groupIds = { + ALL: { + render: () =>
ALL
, + title: 'ALL', + }, + }; + + Object.keys(knobs) + .filter(key => knobs[key].used && knobs[key].groupId) + .forEach(key => { + const keyGroupId = knobs[key].groupId; + groupIds[keyGroupId] = { + render: () =>
{keyGroupId}
, + title: keyGroupId, + }; + }); + const knobsArray = Object.keys(knobs) - .filter(key => knobs[key].used) + .filter(key => { + const filter = + groupId === 'ALL' ? knobs[key].used : knobs[key].used && knobs[key].groupId === groupId; + return filter; + }) .map(key => knobs[key]); if (knobsArray.length === 0) { @@ -150,6 +179,11 @@ export default class Panel extends React.Component { return (
+
{ - const name = text('Name', 'Storyteller'); - const age = number('Age', 70, { range: true, min: 0, max: 90, step: 5 }); + const name = text('Name', 'Storyteller', 'GROUP-1'); + const age = number('Age', 70, { range: true, min: 0, max: 90, step: 5 }, 'GROUP-1'); const fruits = { apple: 'Apple', banana: 'Banana', cherry: 'Cherry', }; - const fruit = select('Fruit', fruits, 'apple'); - const dollars = number('Dollars', 12.5, { min: 0, max: 100, step: 0.01 }); + const fruit = select('Fruit', fruits, 'apple', 'GROUP-1'); + const dollars = number('Dollars', 12.5, { min: 0, max: 100, step: 0.01 }, 'GROUP-2'); const years = number('Years in NY', 9); const backgroundColor = color('background', '#ffff00'); From a57dec8a7384aab46a5a67eebc51aee2b6e033d6 Mon Sep 17 00:00:00 2001 From: ASeeto Date: Fri, 5 Jan 2018 14:30:29 -0500 Subject: [PATCH 002/175] Knobs with optional arguments must have default values passed in for use with groupId. --- addons/knobs/README.md | 4 +-- .../stories/addon-knobs.stories.js | 30 +++++++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/addons/knobs/README.md b/addons/knobs/README.md index e7eff3e15c66..a61ad5b85cfb 100644 --- a/addons/knobs/README.md +++ b/addons/knobs/README.md @@ -153,7 +153,7 @@ const label = 'Age'; const defaultValue = 78; const groupId = 'GROUP-ID1'; -const value = number(label, defaultValue, groupId); +const value = number(label, defaultValue, {}, groupId); ``` ### number bound by range @@ -219,7 +219,7 @@ const label = 'Styles'; const defaultValue = ['Red']; const groupId = 'GROUP-ID1'; -const value = array(label, defaultValue); +const value = array(label, defaultValue, ',', groupId); ``` > While editing values inside the knob, you will need to use a separator. diff --git a/examples/official-storybook/stories/addon-knobs.stories.js b/examples/official-storybook/stories/addon-knobs.stories.js index 306e75e3981e..072239720d74 100644 --- a/examples/official-storybook/stories/addon-knobs.stories.js +++ b/examples/official-storybook/stories/addon-knobs.stories.js @@ -49,27 +49,31 @@ storiesOf('Addons|Knobs.withKnobs', module) .addDecorator(withKnobs) .add('tweaks static values', () => { const name = text('Name', 'Storyteller', 'GROUP-1'); - const age = number('Age', 70, { range: true, min: 0, max: 90, step: 5 }, 'GROUP-1'); + const age = number('Age', 70, { range: true, min: 0, max: 90, step: 5 }, 'GROUP-2'); const fruits = { apple: 'Apple', banana: 'Banana', cherry: 'Cherry', }; - const fruit = select('Fruit', fruits, 'apple', 'GROUP-1'); - const dollars = number('Dollars', 12.5, { min: 0, max: 100, step: 0.01 }, 'GROUP-2'); - const years = number('Years in NY', 9); - - const backgroundColor = color('background', '#ffff00'); - const items = array('Items', ['Laptop', 'Book', 'Whiskey']); - const otherStyles = object('Styles', { - border: '3px solid #ff00ff', - padding: '10px', - }); - const nice = boolean('Nice', true); + const fruit = select('Fruit', fruits, 'apple', 'GROUP-3'); + const dollars = number('Dollars', 12.5, { min: 0, max: 100, step: 0.01 }, 'GROUP-4'); + const years = number('Years in NY', 9, {}, 'GROUP-5'); + + const backgroundColor = color('background', '#ffff00', 'GROUP-6'); + const items = array('Items', ['Laptop', 'Book', 'Whiskey'], ',', 'GROUP-7'); + const otherStyles = object( + 'Styles', + { + border: '3px solid #ff00ff', + padding: '10px', + }, + 'GROUP-8' + ); + const nice = boolean('Nice', true, 'GROUP-9'); // NOTE: the default value must not change - e.g., do not do date('Label', new Date()) or date('Label') const defaultBirthday = new Date('Jan 20 2017 GMT+0'); - const birthday = date('Birthday', defaultBirthday); + const birthday = date('Birthday', defaultBirthday, 'GROUP-10'); const intro = `My name is ${name}, I'm ${age} years old, and my favorite fruit is ${fruit}.`; const style = { backgroundColor, ...otherStyles }; From fbcc281b102e1161f74c926d2563d3f9e9b0a680 Mon Sep 17 00:00:00 2001 From: ASeeto Date: Fri, 5 Jan 2018 15:09:43 -0500 Subject: [PATCH 003/175] Fixed build-storybook. Replicated AddonPanel as GroupTabs component within addons/knobs. --- addons/knobs/package.json | 1 + addons/knobs/src/components/GroupTabs.js | 142 +++++++++++++++++++++++ addons/knobs/src/components/Panel.js | 31 ++--- 3 files changed, 159 insertions(+), 15 deletions(-) create mode 100644 addons/knobs/src/components/GroupTabs.js diff --git a/addons/knobs/package.json b/addons/knobs/package.json index af2d5f233434..626331b198b7 100644 --- a/addons/knobs/package.json +++ b/addons/knobs/package.json @@ -15,6 +15,7 @@ "storybook": "start-storybook -p 9010" }, "dependencies": { + "@storybook/components": "^3.3.3", "babel-runtime": "^6.26.0", "deep-equal": "^1.0.1", "global": "^4.3.2", diff --git a/addons/knobs/src/components/GroupTabs.js b/addons/knobs/src/components/GroupTabs.js new file mode 100644 index 000000000000..3e013f169319 --- /dev/null +++ b/addons/knobs/src/components/GroupTabs.js @@ -0,0 +1,142 @@ +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { baseFonts } from '@storybook/components'; + +const styles = { + empty: { + flex: 1, + display: 'flex', + ...baseFonts, + fontSize: 11, + letterSpacing: '1px', + textTransform: 'uppercase', + alignItems: 'center', + justifyContent: 'center', + }, + + wrapper: { + flex: '1 1 auto', + display: 'flex', + flexDirection: 'column', + background: 'white', + borderRadius: 4, + border: 'solid 1px rgb(236, 236, 236)', + marginTop: 5, + width: '100%', + }, + + tabbar: { + display: 'flex', + flexWrap: 'wrap', + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'center', + borderBottom: 'solid 1px #eaeaea', + }, + + content: { + flex: '1 1 0', + display: 'flex', + overflow: 'auto', + }, + + tablink: { + ...baseFonts, + fontSize: 11, + letterSpacing: '1px', + padding: '10px 15px', + textTransform: 'uppercase', + transition: 'opacity 0.3s', + opacity: 0.5, + maxHeight: 60, + overflow: 'hidden', + cursor: 'pointer', + background: 'transparent', + border: 'none', + }, + + activetab: { + opacity: 1, + }, +}; + +class GroupTabs extends Component { + renderTab(name, group) { + let tabStyle = styles.tablink; + if (this.props.selectedGroup === name) { + tabStyle = Object.assign({}, styles.tablink, styles.activetab); + } + + const onClick = e => { + e.preventDefault(); + this.props.onGroupSelect(name); + }; + + let { title } = group; + if (typeof title === 'function') { + title = title(); + } + + return ( + + ); + } + + renderTabs() { + return Object.keys(this.props.groups).map(name => { + const group = this.props.groups[name]; + return this.renderTab(name, group); + }); + } + + renderGroups() { + return Object.keys(this.props.groups) + .sort() + .map(name => { + const groupStyle = { display: 'none' }; + const group = this.props.groups[name]; + if (name === this.props.selectedGroup) { + Object.assign(groupStyle, { flex: 1, display: 'flex' }); + } + return ( +
+ {group.render()} +
+ ); + }); + } + + renderEmpty() { + return
no groups available
; + } + + render() { + if (!this.props.groups || !Object.keys(this.props.groups).length) { + return this.renderEmpty(); + } + return ( +
+
+ {this.renderTabs()} +
+
{this.renderGroups()}
+
+ ); + } +} + +GroupTabs.defaultProps = { + groups: {}, + onGroupSelect: () => {}, + selectedGroup: null, +}; + +GroupTabs.propTypes = { + groups: PropTypes.object, // eslint-disable-line react/forbid-prop-types + onGroupSelect: PropTypes.func, + selectedGroup: PropTypes.string, +}; + +export default GroupTabs; diff --git a/addons/knobs/src/components/Panel.js b/addons/knobs/src/components/Panel.js index 9a36bb8b5799..fe6738caa394 100644 --- a/addons/knobs/src/components/Panel.js +++ b/addons/knobs/src/components/Panel.js @@ -2,13 +2,14 @@ import React from 'react'; import PropTypes from 'prop-types'; import debounce from 'lodash.debounce'; +import GroupTabs from './GroupTabs'; import PropForm from './PropForm'; import Types from './types'; -import AddonPanel from '../../../../lib/ui/src/modules/ui/components/addon_panel/index'; - const getTimestamp = () => +new Date(); +const DEFAULT_GROUP_ID = 'ALL'; + const styles = { panelWrapper: { width: '100%', @@ -52,9 +53,9 @@ export default class Panel extends React.Component { this.setKnobs = this.setKnobs.bind(this); this.reset = this.reset.bind(this); this.setOptions = this.setOptions.bind(this); - this.onPanelSelect = this.onPanelSelect.bind(this); + this.onGroupSelect = this.onGroupSelect.bind(this); - this.state = { knobs: {}, groupId: 'ALL' }; + this.state = { knobs: {}, groupId: DEFAULT_GROUP_ID }; this.options = {}; this.lastEdit = getTimestamp(); @@ -73,7 +74,7 @@ export default class Panel extends React.Component { this.stopListeningOnStory(); } - onPanelSelect(name) { + onGroupSelect(name) { this.setState({ groupId: name }); } @@ -148,18 +149,18 @@ export default class Panel extends React.Component { render() { const { knobs, groupId } = this.state; - const groupIds = { - ALL: { - render: () =>
ALL
, - title: 'ALL', - }, + const groups = {}; + + groups[DEFAULT_GROUP_ID] = { + render: () =>
{DEFAULT_GROUP_ID}
, + title: DEFAULT_GROUP_ID, }; Object.keys(knobs) .filter(key => knobs[key].used && knobs[key].groupId) .forEach(key => { const keyGroupId = knobs[key].groupId; - groupIds[keyGroupId] = { + groups[keyGroupId] = { render: () =>
{keyGroupId}
, title: keyGroupId, }; @@ -179,10 +180,10 @@ export default class Panel extends React.Component { return (
-
Date: Fri, 5 Jan 2018 16:34:29 -0500 Subject: [PATCH 004/175] Replace string with DEFAULT_GROUP_ID. --- addons/knobs/src/components/Panel.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/knobs/src/components/Panel.js b/addons/knobs/src/components/Panel.js index fe6738caa394..f8527391bdc2 100644 --- a/addons/knobs/src/components/Panel.js +++ b/addons/knobs/src/components/Panel.js @@ -169,7 +169,9 @@ export default class Panel extends React.Component { const knobsArray = Object.keys(knobs) .filter(key => { const filter = - groupId === 'ALL' ? knobs[key].used : knobs[key].used && knobs[key].groupId === groupId; + groupId === DEFAULT_GROUP_ID + ? knobs[key].used + : knobs[key].used && knobs[key].groupId === groupId; return filter; }) .map(key => knobs[key]); From 524de4de6087f7c85f8277ebc7f81697e69cd8bb Mon Sep 17 00:00:00 2001 From: ASeeto Date: Fri, 5 Jan 2018 16:35:05 -0500 Subject: [PATCH 005/175] Added GroupTabs test file. --- .../src/components/__tests__/GroupTabs.js | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 addons/knobs/src/components/__tests__/GroupTabs.js diff --git a/addons/knobs/src/components/__tests__/GroupTabs.js b/addons/knobs/src/components/__tests__/GroupTabs.js new file mode 100644 index 000000000000..9915657b5e1b --- /dev/null +++ b/addons/knobs/src/components/__tests__/GroupTabs.js @@ -0,0 +1,58 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import GroupTabs from '../GroupTabs'; + +describe('GroupTabs', () => { + test('should render only the selected group with display set other than "none"', () => { + const groups = { + test1: { + render() { + return
TEST 1
; + }, + }, + test2: { + render() { + return
TEST 2
; + }, + }, + }; + + const onGroupSelect = () => 'onGroupSelect'; + + const wrapper = shallow( + + ); + + expect(wrapper.find('#test1').parent()).toHaveStyle('display', 'none'); + expect(wrapper.find('#test2').parent()).not.toHaveStyle('display', 'none'); + }); + + test('should set onGroupSelected as onClick handlers of tabs', () => { + const groups = { + test1: { + render() { + return
TEST 1
; + }, + }, + }; + const onGroupSelect = jest.fn(); + const preventDefault = jest.fn(); + const wrapper = shallow( + + ); + wrapper.find('button').simulate('click', { preventDefault }); + + expect(onGroupSelect).toHaveBeenCalled(); + expect(preventDefault).toHaveBeenCalled(); + }); + + describe('when no groups are given', () => { + test('should render "no groups available"', () => { + const groups = {}; + const onGroupSelect = () => 'onGroupSelect'; + const wrapper = shallow(); + + expect(wrapper.contains('no groups available')).toBe(true); + }); + }); +}); From d2c75415325f0a543ee321aca4ea7d7a8280a243 Mon Sep 17 00:00:00 2001 From: Tomek Niezgoda Date: Mon, 29 Jan 2018 17:56:39 +0100 Subject: [PATCH 006/175] Added "key" prop to list items inside test failure message. --- addons/jest/src/components/Result.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/addons/jest/src/components/Result.js b/addons/jest/src/components/Result.js index fa71b0b17d37..8cd4d68ed31a 100644 --- a/addons/jest/src/components/Result.js +++ b/addons/jest/src/components/Result.js @@ -35,7 +35,7 @@ const StackTrace = glamorous(({ trace, className }) => ( .join('') .trim() .split(/\n/) - .map(i =>
{i.trim()}
)} + .map(traceLine, traceLineIndex =>
{traceLine.trim()}
)} ))({ background: 'silver', @@ -80,6 +80,10 @@ const createSubgroup = (acc, item, i, list) => { if (!acc.grouped) { acc.grouped = []; } + if (!('grouperIndex' in acc)) + acc.grouperIndex = 0; + else + acc.grouperIndex++; // start or stop extraction if (acc.startTrigger(item)) { @@ -104,11 +108,11 @@ const createSubgroup = (acc, item, i, list) => { switch (true) { case acc.injectionPoint === 0 && ei === 0: { // at index 0, inject before - return eacc.concat(acc.grouper(acc.grouped)).concat(el); + return eacc.concat(acc.grouper(acc.grouped, acc.grouperIndex)).concat(el); } case acc.injectionPoint > 0 && acc.injectionPoint === ei + 1: { // at index > 0, and next index WOULD BE injectionPoint, inject after - return eacc.concat(el).concat(acc.grouper(acc.grouped)); + return eacc.concat(el).concat(acc.grouper(acc.grouped, acc.grouperIndex)); } default: { // do not inject @@ -131,9 +135,9 @@ const Message = ({ msg }) => { (item, li) => typeof item === 'string' ? item - .split(/\[32m(.*?)\[39m/) - // eslint-disable-next-line react/no-array-index-key - .map((i, index) => (index % 2 ? {i} : i)) + .split(/\[32m(.*?)\[39m/) + // eslint-disable-next-line react/no-array-index-key + .map((i, index) => (index % 2 ? {i} : i)) : item ) .reduce((acc, item) => acc.concat(item), []) @@ -141,16 +145,16 @@ const Message = ({ msg }) => { (item, li) => typeof item === 'string' ? item - .split(/\[31m(.*?)\[39m/) - // eslint-disable-next-line react/no-array-index-key - .map((i, index) => (index % 2 ? {i} : i)) + .split(/\[31m(.*?)\[39m/) + // eslint-disable-next-line react/no-array-index-key + .map((i, index) => (index % 2 ? {i} : i)) : item ) .reduce((acc, item) => acc.concat(item), []) .reduce(createSubgroup, { startTrigger: e => typeof e === 'string' && e.indexOf('Error: ') === 0, endTrigger: e => typeof e === 'string' && e.match('Expected '), - grouper: list =>
, + grouper: (list, key) =>
, }) .reduce( (acc, it) => @@ -161,12 +165,12 @@ const Message = ({ msg }) => { .reduce(createSubgroup, { startTrigger: e => typeof e === 'string' && e.indexOf('Expected ') !== -1, endTrigger: e => typeof e === 'string' && e.match(/^at/), - grouper: list => , + grouper: (list, key) => , }) .reduce(createSubgroup, { startTrigger: e => typeof e === 'string' && e.match(/at(.|\n)+\d+:\d+\)/), endTrigger: () => false, - grouper: list => , + grouper: (list, key) => , }); return
{data}
; From dd1b8791b14a231aadc25ecfa980d855f037d2e4 Mon Sep 17 00:00:00 2001 From: Hypnosphi Date: Wed, 31 Jan 2018 00:23:32 +0300 Subject: [PATCH 007/175] Core: upgrade dotenv to 5.0.0 --- lib/core/package.json | 2 +- yarn.lock | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/core/package.json b/lib/core/package.json index 2efd91542aef..bd37b645dc42 100644 --- a/lib/core/package.json +++ b/lib/core/package.json @@ -24,7 +24,7 @@ "autoprefixer": "^7.2.5", "babel-runtime": "^6.26.0", "css-loader": "^0.28.9", - "dotenv": "^4.0.0", + "dotenv": "^5.0.0", "events": "^1.1.1", "file-loader": "^1.1.6", "global": "^4.3.2", diff --git a/yarn.lock b/yarn.lock index a3906c95a7cc..7c5b7bf252ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4350,6 +4350,10 @@ dotenv@4.0.0, dotenv@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d" +dotenv@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.0.tgz#0206eb5b336639bf377618a2a304ff00c6a1fddb" + duplexer2@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" From a1f54bc6aebfd3155a2055f5543ae4b5fc4ff853 Mon Sep 17 00:00:00 2001 From: igor Date: Wed, 31 Jan 2018 14:54:29 +0200 Subject: [PATCH 008/175] First addon stories integration --- addons/stories/loader.js | 53 +++++++++++++++++++ addons/stories/package.json | 30 +++++++++++ addons/stories/register.js | 1 + addons/stories/src/StoryPanel.js | 35 ++++++++++++ addons/stories/src/index.js | 6 +++ addons/stories/src/manager.js | 14 +++++ addons/stories/src/preview.js | 18 +++++++ examples/official-storybook/addons.js | 1 + examples/official-storybook/config.js | 10 ++-- examples/official-storybook/package.json | 1 + examples/official-storybook/webpack.config.js | 39 +++++++++----- 11 files changed, 193 insertions(+), 15 deletions(-) create mode 100644 addons/stories/loader.js create mode 100644 addons/stories/package.json create mode 100644 addons/stories/register.js create mode 100644 addons/stories/src/StoryPanel.js create mode 100644 addons/stories/src/index.js create mode 100644 addons/stories/src/manager.js create mode 100644 addons/stories/src/preview.js diff --git a/addons/stories/loader.js b/addons/stories/loader.js new file mode 100644 index 000000000000..3a6f07800ab0 --- /dev/null +++ b/addons/stories/loader.js @@ -0,0 +1,53 @@ +const STORY_OF_STATEMENT = 'storiesOf('; +const ADD_STATEMENT = 'add'; +const ADD_DECORATOR_STATEMENT = 'addDecorator(withStorySource(__STORY__)).'; +const ADD_DECORATOR_STATEMENT_LENGTH = ADD_DECORATOR_STATEMENT.length; + +function insertDecorator(source) { + let newSource = source; + let changed = false; + let storyOfIndex = source.indexOf(STORY_OF_STATEMENT); + + while (storyOfIndex > 0) { + const indexOfFirstAdd = newSource.indexOf(ADD_STATEMENT, storyOfIndex); + + const start = newSource.slice(0, indexOfFirstAdd); + const end = newSource.slice(indexOfFirstAdd); + + newSource = `${start}${ADD_DECORATOR_STATEMENT}${end}`; + + storyOfIndex = newSource.indexOf( + STORY_OF_STATEMENT, + indexOfFirstAdd + ADD_DECORATOR_STATEMENT_LENGTH + ); + + changed = true; + } + + return { + newSource, + changed, + }; +} + +module.exports = source => { + this.value = source; + + // Based on https://github.com/webpack-contrib/raw-loader/blob/master/index.js + const json = JSON.stringify(source) + .replace(/\u2028/g, '\\u2028') + .replace(/\u2029/g, '\\u2029'); + + const result = insertDecorator(source); + + if (!result.changed) { + return source; + } + + return ` + var withStorySource = require('@storybook/addon-stories').withStorySource; + var __STORY__ = ${json}; + + ${result.newSource} + `; +}; diff --git a/addons/stories/package.json b/addons/stories/package.json new file mode 100644 index 000000000000..1734e2cfd824 --- /dev/null +++ b/addons/stories/package.json @@ -0,0 +1,30 @@ +{ + "name": "@storybook/addon-stories", + "version": "3.4.0-alpha.6", + "description": "Stories addon for storybook", + "keywords": [ + "storybook" + ], + "homepage": "https://github.com/storybooks/storybook/tree/master/addons/stories", + "bugs": { + "url": "https://github.com/storybooks/storybook/issues" + }, + "license": "MIT", + "main": "dist/index.js", + "jsnext:main": "src/index.js", + "repository": { + "type": "git", + "url": "https://github.com/storybooks/storybook.git" + }, + "scripts": { + "prepare": "node ../../scripts/prepare.js" + }, + "dependencies": { + "prop-types": "^15.5.10" + }, + "peerDependencies": { + "@storybook/addons": "^3.3.0", + "react": "*", + "react-dom": "*" + } +} diff --git a/addons/stories/register.js b/addons/stories/register.js new file mode 100644 index 000000000000..e69edbea3ed1 --- /dev/null +++ b/addons/stories/register.js @@ -0,0 +1 @@ +require('./dist').register(); diff --git a/addons/stories/src/StoryPanel.js b/addons/stories/src/StoryPanel.js new file mode 100644 index 000000000000..05e1beb8f0d2 --- /dev/null +++ b/addons/stories/src/StoryPanel.js @@ -0,0 +1,35 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { EVENT_ID } from './'; + +export default class StoryPanel extends Component { + constructor(props) { + super(props); + + this.state = { source: '' }; + + const { channel } = props; + + channel.on(EVENT_ID, ({ source }) => { + this.setState({ + source, + }); + }); + } + + render() { + return ( +
+        {this.state.source}
+      
+ ); + } +} + +StoryPanel.propTypes = { + channel: PropTypes.shape({ + emit: PropTypes.func, + on: PropTypes.func, + removeListener: PropTypes.func, + }).isRequired, +}; diff --git a/addons/stories/src/index.js b/addons/stories/src/index.js new file mode 100644 index 000000000000..d24b2a4f9853 --- /dev/null +++ b/addons/stories/src/index.js @@ -0,0 +1,6 @@ +export const ADDON_ID = 'storybook/stories'; +export const PANEL_ID = `${ADDON_ID}/stories-panel`; +export const EVENT_ID = `${ADDON_ID}/story-event`; + +export { register } from './manager'; +export { withStorySource } from './preview'; diff --git a/addons/stories/src/manager.js b/addons/stories/src/manager.js new file mode 100644 index 000000000000..bdfd4b4d5db4 --- /dev/null +++ b/addons/stories/src/manager.js @@ -0,0 +1,14 @@ +import React from 'react'; +import addons from '@storybook/addons'; +import StoryPanel from './StoryPanel'; +import { ADDON_ID, PANEL_ID } from './'; + +export function register() { + addons.register(ADDON_ID, () => { + const channel = addons.getChannel(); + addons.addPanel(PANEL_ID, { + title: 'Story', + render: () => , + }); + }); +} diff --git a/addons/stories/src/preview.js b/addons/stories/src/preview.js new file mode 100644 index 000000000000..f866e2f70324 --- /dev/null +++ b/addons/stories/src/preview.js @@ -0,0 +1,18 @@ +import addons from '@storybook/addons'; +import { EVENT_ID } from './'; + +function setStorySource(source, context) { + const channel = addons.getChannel(); + + channel.emit(EVENT_ID, { + source, + context, + }); +} + +export function withStorySource(source) { + return (story, context) => { + setStorySource(source, context); + return story(); + }; +} diff --git a/examples/official-storybook/addons.js b/examples/official-storybook/addons.js index 3d9e060a1226..e6fb08d25399 100644 --- a/examples/official-storybook/addons.js +++ b/examples/official-storybook/addons.js @@ -1,4 +1,5 @@ /* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions */ +import '@storybook/addon-stories/register'; import '@storybook/addon-actions/register'; import '@storybook/addon-links/register'; import '@storybook/addon-events/register'; diff --git a/examples/official-storybook/config.js b/examples/official-storybook/config.js index f2886738d26a..d5bb03603425 100644 --- a/examples/official-storybook/config.js +++ b/examples/official-storybook/config.js @@ -12,16 +12,20 @@ setOptions({ hierarchyRootSeparator: /\|/, }); +function importAll(req) { + req.keys().forEach(filename => req(filename)); +} + function loadStories() { let req; req = require.context('../../lib/ui/src', true, /\.stories\.js$/); - req.keys().forEach(filename => req(filename)); + importAll(req); req = require.context('../../lib/components/src', true, /\.stories\.js$/); - req.keys().forEach(filename => req(filename)); + importAll(req); req = require.context('./stories', true, /\.stories\.js$/); - req.keys().forEach(filename => req(filename)); + importAll(req); } configure(loadStories, module); diff --git a/examples/official-storybook/package.json b/examples/official-storybook/package.json index e0b6a10f4e86..4839de44f86a 100644 --- a/examples/official-storybook/package.json +++ b/examples/official-storybook/package.json @@ -21,6 +21,7 @@ "@storybook/addon-links": "^3.4.0-alpha.6", "@storybook/addon-notes": "^3.4.0-alpha.6", "@storybook/addon-options": "^3.4.0-alpha.6", + "@storybook/addon-stories": "^3.4.0-alpha.6", "@storybook/addon-storyshots": "^3.4.0-alpha.6", "@storybook/addon-viewport": "^3.4.0-alpha.6", "@storybook/addons": "^3.4.0-alpha.6", diff --git a/examples/official-storybook/webpack.config.js b/examples/official-storybook/webpack.config.js index 0a6124501f5b..b6d45be3a581 100644 --- a/examples/official-storybook/webpack.config.js +++ b/examples/official-storybook/webpack.config.js @@ -1,16 +1,31 @@ const path = require('path'); -module.exports = { - module: { - rules: [ - { - test: /\.js/, - loaders: ['babel-loader'], - include: [ - path.resolve(__dirname, '../../lib/ui/src'), - path.resolve(__dirname, '../../lib/components/src'), - ], - }, +module.exports = baseConfig => { + const originJsRule = baseConfig.module.rules.find(rule => rule.test.test('text.js')); + + if (originJsRule) { + originJsRule.exclude.push(/\.stories\.jsx?$/); + } + + baseConfig.module.rules.push({ + test: /\.jsx?$/, + exclude: [/\.stories\.jsx?$/], + loaders: [require.resolve('babel-loader')], + include: [ + path.resolve(__dirname, '../../lib/ui/src'), + path.resolve(__dirname, '../../lib/components/src'), ], - }, + }); + + baseConfig.module.rules.push({ + test: /\.stories\.jsx?$/, + loaders: [require.resolve('babel-loader'), require.resolve('@storybook/addon-stories/loader')], + include: [ + path.resolve(__dirname, './stories'), + path.resolve(__dirname, '../../lib/ui/src'), + path.resolve(__dirname, '../../lib/components/src'), + ], + }); + + return baseConfig; }; From 65e4ea2d5d62c63d36992ecc03183622a1967257 Mon Sep 17 00:00:00 2001 From: igor Date: Wed, 31 Jan 2018 15:21:41 +0200 Subject: [PATCH 009/175] Add stories addon to angular --- examples/angular-cli/.storybook/addons.js | 1 + .../angular-cli/.storybook/webpack.config.js | 23 +++++++++++++++++++ examples/angular-cli/package.json | 1 + examples/official-storybook/webpack.config.js | 6 ++--- 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 examples/angular-cli/.storybook/webpack.config.js diff --git a/examples/angular-cli/.storybook/addons.js b/examples/angular-cli/.storybook/addons.js index c558d2235028..2d5d822c6dcc 100644 --- a/examples/angular-cli/.storybook/addons.js +++ b/examples/angular-cli/.storybook/addons.js @@ -1,5 +1,6 @@ /* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions */ +import '@storybook/addon-stories/register'; import '@storybook/addon-actions/register'; import '@storybook/addon-links/register'; import '@storybook/addon-notes/register'; diff --git a/examples/angular-cli/.storybook/webpack.config.js b/examples/angular-cli/.storybook/webpack.config.js new file mode 100644 index 000000000000..2ee8211ad6c0 --- /dev/null +++ b/examples/angular-cli/.storybook/webpack.config.js @@ -0,0 +1,23 @@ +const path = require('path'); + +module.exports = (baseConfig) => { + debugger; + const originalTsRule = baseConfig.module.rules.find(rule => rule.test.test('text.ts')); + + if (originalTsRule) { + originalTsRule.exclude = [/\.stories\.tsx?$/]; + } + + baseConfig.module.rules.push({ + test: [ + /\.stories\.tsx?$/, + /index\.ts$/ + ], + loaders: [ ...originalTsRule.loaders, require.resolve('@storybook/addon-stories/loader') ], + include: [ + path.resolve(__dirname, '../src') + ], + }); + + return baseConfig; +}; diff --git a/examples/angular-cli/package.json b/examples/angular-cli/package.json index 55c9dadae834..eb710f7b1f94 100644 --- a/examples/angular-cli/package.json +++ b/examples/angular-cli/package.json @@ -33,6 +33,7 @@ "@storybook/addon-actions": "^3.4.0-alpha.6", "@storybook/addon-links": "^3.4.0-alpha.6", "@storybook/addon-notes": "^3.4.0-alpha.6", + "@storybook/addon-stories": "^3.4.0-alpha.6", "@storybook/addon-storyshots": "^3.4.0-alpha.6", "@storybook/addons": "^3.4.0-alpha.6", "@storybook/angular": "^3.4.0-alpha.6", diff --git a/examples/official-storybook/webpack.config.js b/examples/official-storybook/webpack.config.js index b6d45be3a581..6a9ed7cf7828 100644 --- a/examples/official-storybook/webpack.config.js +++ b/examples/official-storybook/webpack.config.js @@ -1,10 +1,10 @@ const path = require('path'); module.exports = baseConfig => { - const originJsRule = baseConfig.module.rules.find(rule => rule.test.test('text.js')); + const originalJsRule = baseConfig.module.rules.find(rule => rule.test.test('text.js')); - if (originJsRule) { - originJsRule.exclude.push(/\.stories\.jsx?$/); + if (originalJsRule) { + originalJsRule.exclude.push(/\.stories\.jsx?$/); } baseConfig.module.rules.push({ From 2bf9a1fb4fadeae69060007bdd0ad138ea167990 Mon Sep 17 00:00:00 2001 From: Filipp Riabchun Date: Thu, 1 Feb 2018 02:56:15 +0300 Subject: [PATCH 010/175] Mention new supported frameworks --- ROADMAP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index cae6888ac4ca..e3ee3605fde6 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -57,7 +57,7 @@ That way you can write your stories how they are best, and preview them how you We believe in the power of react, and think it's the right choice for a lot of projects. But it's up to you and your team to decide your stack. -Unfortunately if you choose anything other then React or React-Native you can not use storybook. +Unfortunately if you choose anything other then React or React-Native or Vue or Angular you can not use storybook. We want you to be able to use storybook with the framework / library of your choice. From c7b07bb38e89dc55babf4b7cb6fd7900070e0ea7 Mon Sep 17 00:00:00 2001 From: igor Date: Thu, 1 Feb 2018 10:13:06 +0200 Subject: [PATCH 011/175] Add react-syntax-highlighter to highlight the story code --- addons/stories/package.json | 3 +- addons/stories/src/StoryPanel.js | 18 +++++-- yarn.lock | 89 ++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/addons/stories/package.json b/addons/stories/package.json index 1734e2cfd824..51bccad6747a 100644 --- a/addons/stories/package.json +++ b/addons/stories/package.json @@ -20,7 +20,8 @@ "prepare": "node ../../scripts/prepare.js" }, "dependencies": { - "prop-types": "^15.5.10" + "prop-types": "^15.5.10", + "react-syntax-highlighter": "^7.0.0" }, "peerDependencies": { "@storybook/addons": "^3.3.0", diff --git a/addons/stories/src/StoryPanel.js b/addons/stories/src/StoryPanel.js index 05e1beb8f0d2..8d69a69f97d1 100644 --- a/addons/stories/src/StoryPanel.js +++ b/addons/stories/src/StoryPanel.js @@ -1,12 +1,17 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light'; +import jsx from 'react-syntax-highlighter/languages/prism/jsx'; +import { darcula } from 'react-syntax-highlighter/styles/prism'; import { EVENT_ID } from './'; +registerLanguage('jsx', jsx); + export default class StoryPanel extends Component { constructor(props) { super(props); - this.state = { source: '' }; + this.state = { source: '// Here will be dragons 🐉' }; const { channel } = props; @@ -19,9 +24,14 @@ export default class StoryPanel extends Component { render() { return ( -
-        {this.state.source}
-      
+ + {this.state.source} + ); } } diff --git a/yarn.lock b/yarn.lock index 5a9cd5edaac5..1bd382b47a4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2950,6 +2950,14 @@ cli@~1.0.0: exit "0.1.2" glob "^7.1.1" +clipboard@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-1.7.1.tgz#360d6d6946e99a7a1fef395e42ba92b5e9b5a16b" + dependencies: + good-listener "^1.2.2" + select "^1.1.2" + tiny-emitter "^2.0.0" + cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" @@ -3124,6 +3132,12 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" +comma-separated-tokens@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.4.tgz#72083e58d4a462f01866f6617f4d98a3cd3b8a46" + dependencies: + trim "0.0.1" + command-join@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/command-join/-/command-join-2.0.0.tgz#52e8b984f4872d952ff1bdc8b98397d27c7144cf" @@ -4121,6 +4135,10 @@ delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" +delegate@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" + delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -6199,6 +6217,12 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" +good-listener@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" + dependencies: + delegate "^3.1.2" + got@^5.0.0: version "5.7.1" resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" @@ -6513,6 +6537,20 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" +hast-util-parse-selector@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.1.0.tgz#b55c0f4bb7bb2040c889c325ef87ab29c38102b4" + +hastscript@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-3.1.0.tgz#66628ba6d7f1ad07d9277dd09028aba7f4934599" + dependencies: + camelcase "^3.0.0" + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^3.0.0" + space-separated-tokens "^1.0.0" + hawk@3.1.3, hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -6535,6 +6573,10 @@ he@1.1.x, he@^1.1.0, he@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" +highlight.js@~9.12.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -9417,6 +9459,12 @@ lowercase-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" +lowlight@~1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.9.1.tgz#ed7c3dffc36f8c1f263735c0fe0c907847c11250" + dependencies: + highlight.js "~9.12.0" + lru-cache@2.2.x: version "2.2.4" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" @@ -11533,6 +11581,12 @@ pretty-format@^4.2.1: version "4.3.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-4.3.1.tgz#530be5c42b3c05b36414a7a2a4337aa80acd0e8d" +prismjs@^1.8.4, prismjs@~1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.10.0.tgz#77e5187c2ae6b3253fcc313029cf25fe53778721" + optionalDependencies: + clipboard "^1.7.1" + private@^0.1.6, private@^0.1.7, private@~0.1.5: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -11606,6 +11660,10 @@ prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, loose-envify "^1.3.1" object-assign "^4.1.1" +property-information@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-3.2.0.tgz#fd1483c8fbac61808f5fe359e7693a1f48a58331" + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -12160,6 +12218,16 @@ react-style-proptype@^3.0.0: dependencies: prop-types "^15.5.4" +react-syntax-highlighter@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-7.0.0.tgz#a522ccf95f272178b8f25de2184383e9bf647155" + dependencies: + babel-runtime "^6.18.0" + highlight.js "~9.12.0" + lowlight "~1.9.1" + prismjs "^1.8.4" + refractor "^2.0.0" + react-test-renderer@^16.0.0-0, react-test-renderer@^16.1.0, react-test-renderer@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.2.0.tgz#bddf259a6b8fcd8555f012afc8eacc238872a211" @@ -12482,6 +12550,13 @@ reflect-metadata@^0.1.10, reflect-metadata@^0.1.2: version "0.1.10" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.10.tgz#b4f83704416acad89988c9b15635d47e03b9344a" +refractor@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.3.0.tgz#b8cade8f88020f8836ca3622c6ef87fd2444d76a" + dependencies: + hastscript "^3.1.0" + prismjs "~1.10.0" + regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" @@ -13203,6 +13278,10 @@ select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" +select@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" + selenium-webdriver@3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" @@ -13734,6 +13813,12 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" +space-separated-tokens@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.1.tgz#9695b9df9e65aec1811d4c3f9ce52520bc2f7e4d" + dependencies: + trim "0.0.1" + sparkles@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" @@ -14406,6 +14491,10 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tiny-emitter@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c" + tinycolor2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" From b96b1dac2f77de4b83f0a9197b9574637ed2f344 Mon Sep 17 00:00:00 2001 From: igor Date: Thu, 1 Feb 2018 11:52:23 +0200 Subject: [PATCH 012/175] Add to vue --- examples/angular-cli/.storybook/addons.js | 2 -- examples/vue-kitchen-sink/.storybook/addons.js | 1 + .../.storybook/webpack.config.js | 17 ++++++++++++----- examples/vue-kitchen-sink/package.json | 1 + 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/examples/angular-cli/.storybook/addons.js b/examples/angular-cli/.storybook/addons.js index 2d5d822c6dcc..2577aa9ee2bb 100644 --- a/examples/angular-cli/.storybook/addons.js +++ b/examples/angular-cli/.storybook/addons.js @@ -1,5 +1,3 @@ -/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions */ - import '@storybook/addon-stories/register'; import '@storybook/addon-actions/register'; import '@storybook/addon-links/register'; diff --git a/examples/vue-kitchen-sink/.storybook/addons.js b/examples/vue-kitchen-sink/.storybook/addons.js index 2d7b52c620bd..a7afc3474ea6 100644 --- a/examples/vue-kitchen-sink/.storybook/addons.js +++ b/examples/vue-kitchen-sink/.storybook/addons.js @@ -1,3 +1,4 @@ +import '@storybook/addon-stories/register'; import '@storybook/addon-actions/register'; import '@storybook/addon-links/register'; import '@storybook/addon-notes/register'; diff --git a/examples/vue-kitchen-sink/.storybook/webpack.config.js b/examples/vue-kitchen-sink/.storybook/webpack.config.js index c96b297ebae5..5d124c0fb8d9 100644 --- a/examples/vue-kitchen-sink/.storybook/webpack.config.js +++ b/examples/vue-kitchen-sink/.storybook/webpack.config.js @@ -1,11 +1,19 @@ +const path = require('path'); const webpack = require('webpack'); module.exports = (storybookBaseConfig, configType, defaultConfig) => { - // configType has a value of 'DEVELOPMENT' or 'PRODUCTION' - // You can change the configuration based on that. - // 'PRODUCTION' is used when building the static version of storybook. - // Make whatever fine-grained changes you need + defaultConfig.module.rules.push({ + test: [ + /\.stories\.js$/, + /index\.js$/ + ], + loaders: [ require.resolve('babel-loader'), require.resolve('@storybook/addon-stories/loader') ], + include: [ + path.resolve(__dirname, '../src') + ], + }); + defaultConfig.plugins.push( new webpack.optimize.CommonsChunkPlugin({ name: "vendor", @@ -17,6 +25,5 @@ module.exports = (storybookBaseConfig, configType, defaultConfig) => { }) ); - // Return the altered config return defaultConfig; }; diff --git a/examples/vue-kitchen-sink/package.json b/examples/vue-kitchen-sink/package.json index 80acd6189727..bb1a2ed8e268 100644 --- a/examples/vue-kitchen-sink/package.json +++ b/examples/vue-kitchen-sink/package.json @@ -18,6 +18,7 @@ "@storybook/addon-knobs": "^3.4.0-alpha.6", "@storybook/addon-links": "^3.4.0-alpha.6", "@storybook/addon-notes": "^3.4.0-alpha.6", + "@storybook/addon-stories": "^3.4.0-alpha.6", "@storybook/addon-storyshots": "^3.4.0-alpha.6", "@storybook/addon-viewport": "^3.4.0-alpha.6", "@storybook/addons": "^3.4.0-alpha.6", From 53d3bf38735d2446ea8ee1b52600c91d2610230e Mon Sep 17 00:00:00 2001 From: igor Date: Thu, 1 Feb 2018 12:07:00 +0200 Subject: [PATCH 013/175] Add to polymer --- examples/polymer-cli/.storybook/addons.js | 1 + .../polymer-cli/.storybook/webpack.config.js | 17 +++++++++++++++++ examples/polymer-cli/package.json | 1 + 3 files changed, 19 insertions(+) create mode 100644 examples/polymer-cli/.storybook/webpack.config.js diff --git a/examples/polymer-cli/.storybook/addons.js b/examples/polymer-cli/.storybook/addons.js index 1191fbebf304..3f64483be7f9 100644 --- a/examples/polymer-cli/.storybook/addons.js +++ b/examples/polymer-cli/.storybook/addons.js @@ -1,3 +1,4 @@ +import '@storybook/addon-stories/register'; import '@storybook/addon-actions/register'; import '@storybook/addon-notes/register'; import '@storybook/addon-knobs/register'; diff --git a/examples/polymer-cli/.storybook/webpack.config.js b/examples/polymer-cli/.storybook/webpack.config.js new file mode 100644 index 000000000000..8419ff0c9883 --- /dev/null +++ b/examples/polymer-cli/.storybook/webpack.config.js @@ -0,0 +1,17 @@ +const path = require('path'); + +module.exports = (storybookBaseConfig, configType, defaultConfig) => { + + defaultConfig.module.rules.push({ + test: [ + /\.stories\.js$/, + /index\.js$/ + ], + loaders: [ require.resolve('babel-loader'), require.resolve('@storybook/addon-stories/loader') ], + include: [ + path.resolve(__dirname, '../src') + ], + }); + + return defaultConfig; +}; \ No newline at end of file diff --git a/examples/polymer-cli/package.json b/examples/polymer-cli/package.json index a354a06d62b7..fa3c6ece0dad 100644 --- a/examples/polymer-cli/package.json +++ b/examples/polymer-cli/package.json @@ -11,6 +11,7 @@ "@storybook/addon-actions": "^3.4.0-alpha.6", "@storybook/addon-knobs": "^3.4.0-alpha.6", "@storybook/addon-notes": "^3.4.0-alpha.6", + "@storybook/addon-stories": "^3.4.0-alpha.6", "@storybook/addon-viewport": "^3.4.0-alpha.6", "@storybook/polymer": "^3.4.0-alpha.6", "@webcomponents/webcomponentsjs": "^1.1.0", From e940e88214f0886d14af0488fbf255ccb5c2e401 Mon Sep 17 00:00:00 2001 From: igor Date: Thu, 1 Feb 2018 18:57:13 +0200 Subject: [PATCH 014/175] Change loader to parse the source with acorn and estraverse --- __mocks__/inject-decorator.no-stories.txt | 3 + __mocks__/inject-decorator.stories.txt | 153 ++++++++++++++++ addons/stories/loader.js | 54 +----- addons/stories/package.json | 4 + .../inject-decorator.test.js.snap | 164 ++++++++++++++++++ addons/stories/src/loader/index.js | 23 +++ addons/stories/src/loader/inject-decorator.js | 52 ++++++ .../src/loader/inject-decorator.test.js | 22 +++ yarn.lock | 73 +++++++- 9 files changed, 493 insertions(+), 55 deletions(-) create mode 100644 __mocks__/inject-decorator.no-stories.txt create mode 100644 __mocks__/inject-decorator.stories.txt create mode 100644 addons/stories/src/loader/__snapshots__/inject-decorator.test.js.snap create mode 100644 addons/stories/src/loader/index.js create mode 100644 addons/stories/src/loader/inject-decorator.js create mode 100644 addons/stories/src/loader/inject-decorator.test.js diff --git a/__mocks__/inject-decorator.no-stories.txt b/__mocks__/inject-decorator.no-stories.txt new file mode 100644 index 000000000000..f0124e61691c --- /dev/null +++ b/__mocks__/inject-decorator.no-stories.txt @@ -0,0 +1,3 @@ +while(true) { + console.log("it's a kind of magic"); +} \ No newline at end of file diff --git a/__mocks__/inject-decorator.stories.txt b/__mocks__/inject-decorator.stories.txt new file mode 100644 index 000000000000..c4f0c4d53e5d --- /dev/null +++ b/__mocks__/inject-decorator.stories.txt @@ -0,0 +1,153 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { withInfo } from '@storybook/addon-info'; +import { action } from '@storybook/addon-actions'; + +import DocgenButton from '../components/DocgenButton'; +import FlowTypeButton from '../components/FlowTypeButton'; +import BaseButton from '../components/BaseButton'; +import TableComponent from '../components/TableComponent'; + +storiesOf('Addons|Info.React Docgen', module) + .add( + 'Comments from PropType declarations', + withInfo( + 'Comments above the PropType declarations should be extracted from the React component file itself and rendered in the Info Addon prop table' + )(() => ) + ) + .add( + 'Comments from Flow declarations', + withInfo( + 'Comments above the Flow declarations should be extracted from the React component file itself and rendered in the Info Addon prop table' + )(() => ) + ) + .add( + 'Comments from component declaration', + withInfo( + 'Comments above the component declaration should be extracted from the React component file itself and rendered below the Info Addon heading' + )(() => ) + ); + +const markdownDescription = ` +#### You can use markdown in your withInfo() description. + +Sometimes you might want to manually include some code examples: +~~~js +const Button = () => @@ -22,19 +22,19 @@ exports[`Storyshots Addon Actions Action and method 1`] = ` `; -exports[`Storyshots Addon Actions Action only 1`] = ` +exports[`Storyshots Addon|Actions Action only 1`] = ` diff --git a/examples/angular-cli/src/stories/__snapshots__/addon-knobs.stories.storyshot b/examples/angular-cli/src/stories/__snapshots__/addon-knobs.stories.storyshot index 59e126d4c6db..c33cc5239ccc 100644 --- a/examples/angular-cli/src/stories/__snapshots__/addon-knobs.stories.storyshot +++ b/examples/angular-cli/src/stories/__snapshots__/addon-knobs.stories.storyshot @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Storyshots Addon Knobs All knobs 1`] = ` +exports[`Storyshots Addon|Knobs All knobs 1`] = ` `; -exports[`Storyshots Addon Knobs Simple 1`] = ` +exports[`Storyshots Addon|Knobs Simple 1`] = ` diff --git a/examples/angular-cli/src/stories/__snapshots__/addon-notes.stories.storyshot b/examples/angular-cli/src/stories/__snapshots__/addon-notes.stories.storyshot index 94b5ff1c35a0..03dd16736718 100644 --- a/examples/angular-cli/src/stories/__snapshots__/addon-notes.stories.storyshot +++ b/examples/angular-cli/src/stories/__snapshots__/addon-notes.stories.storyshot @@ -1,18 +1,18 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Storyshots Addon Notes Note with HTML 1`] = ` +exports[`Storyshots Addon|Notes Note with HTML 1`] = ` @@ -22,19 +22,19 @@ exports[`Storyshots Addon Notes Note with HTML 1`] = ` `; -exports[`Storyshots Addon Notes Simple note 1`] = ` +exports[`Storyshots Addon|Notes Simple note 1`] = ` diff --git a/examples/angular-cli/src/stories/__snapshots__/custom-metadata.stories.storyshot b/examples/angular-cli/src/stories/__snapshots__/custom-metadata.stories.storyshot index d927a530a22b..dc40ccce186f 100644 --- a/examples/angular-cli/src/stories/__snapshots__/custom-metadata.stories.storyshot +++ b/examples/angular-cli/src/stories/__snapshots__/custom-metadata.stories.storyshot @@ -1,34 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Storyshots Custom Pipe Default 1`] = ` - - -

- CustomPipe: foobar -

-
-
-`; - -exports[`Storyshots Custom Pipe/With Knobs NameComponent 1`] = ` - - -

- CustomPipe: foobar -

-
-
-`; - -exports[`Storyshots Custom ngModule metadata simple 1`] = ` +exports[`Storyshots Custom|Metadata simple 1`] = ` `; -exports[`Storyshots Custom ngModule metadata with knobs 1`] = ` +exports[`Storyshots Custom|Metadata with knobs 1`] = ` `; + +exports[`Storyshots Custom|Pipe Default 1`] = ` + + +

+ CustomPipe: foobar +

+
+
+`; + +exports[`Storyshots Custom|Pipe/With Knobs NameComponent 1`] = ` + + +

+ CustomPipe: foobar +

+
+
+`; diff --git a/examples/angular-cli/src/stories/__snapshots__/custom-ng-content.stories.storyshot b/examples/angular-cli/src/stories/__snapshots__/custom-ng-content.stories.storyshot new file mode 100644 index 000000000000..3616eacf80cd --- /dev/null +++ b/examples/angular-cli/src/stories/__snapshots__/custom-ng-content.stories.storyshot @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Custom|ng-content Default 1`] = ` + + + +
+

+ This is rendered in ng-content +

+
+
+
+
+`; diff --git a/examples/angular-cli/src/stories/__snapshots__/custom-styles.stories.storyshot b/examples/angular-cli/src/stories/__snapshots__/custom-styles.stories.storyshot index 454a8bf5b983..0b26e9da8a43 100644 --- a/examples/angular-cli/src/stories/__snapshots__/custom-styles.stories.storyshot +++ b/examples/angular-cli/src/stories/__snapshots__/custom-styles.stories.storyshot @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Storyshots Custom Style Default 1`] = ` +exports[`Storyshots Custom|Style Default 1`] = ` @@ -25,24 +25,24 @@ exports[`Storyshots Custom Style Default 1`] = ` `; -exports[`Storyshots Custom Style With Knobs 1`] = ` +exports[`Storyshots Custom|Style With Knobs 1`] = ` diff --git a/examples/angular-cli/src/stories/__snapshots__/index.storyshot b/examples/angular-cli/src/stories/__snapshots__/index.storyshot index 4b9cce2ec8be..30483889802a 100644 --- a/examples/angular-cli/src/stories/__snapshots__/index.storyshot +++ b/examples/angular-cli/src/stories/__snapshots__/index.storyshot @@ -6,19 +6,22 @@ exports[`Storyshots Button with some emoji 1`] = ` data={[Function Object]} target={[Function ViewContainerRef_]} > - - - - - + + + + - + + `; @@ -29,13 +32,6 @@ exports[`Storyshots Button with text 1`] = ` target={[Function ViewContainerRef_]} > - - -

- This is a template -

- - - - +
+
+`; + +exports[`Storyshots Welcome to Storybook 1`] = ` + +

Welcome to storybook

This is a UI component dev environment for your app.

We've added some basic stories inside the src/stories @@ -90,14 +95,14 @@ exports[`Storyshots Button with text 1`] = ` directory.
A story is a single state of one or more UI components. You can have as many stories as you want.
(Basically a story is like a visual test case.) @@ -106,12 +111,12 @@ exports[`Storyshots Button with text 1`] = `

See these sample @@ -120,7 +125,7 @@ exports[`Storyshots Button with text 1`] = ` for a component called Button @@ -131,24 +136,24 @@ exports[`Storyshots Button with text 1`] = `

Just like that, you can add your own components as stories.
You can also edit those components and see changes right away.
(Try editing the Button @@ -156,7 +161,7 @@ exports[`Storyshots Button with text 1`] = ` stories located at src/stories/index.js @@ -167,17 +172,17 @@ exports[`Storyshots Button with text 1`] = `

Usually we create stories with smaller UI components in the app.
Have a look at the
NOTE:
Have a look at the .storybook/webpack.config.js @@ -225,190 +230,6 @@ exports[`Storyshots Button with text 1`] = ` - - `; - -exports[`Storyshots Welcome to Storybook 1`] = ` - - - - -

- - -

- Welcome to storybook -

- - -

- This is a UI component dev environment for your app. -

- - -

- - We've added some basic stories inside the - - src/stories - - directory. - -
- - A story is a single state of one or more UI components. You can have as many stories as - you want. - -
- - (Basically a story is like a visual test case.) - -

- - -

- - See these sample - - stories - - for a component called - - - Button - - . - -

- - -

- - Just like that, you can add your own components as stories. - -
- - You can also edit those components and see changes right away. - -
- - (Try editing the - - Button - - stories - located at - - src/stories/index.js - - .) - -

- - -

- - Usually we create stories with smaller UI components in the app. -
- - Have a look at the - - - Writing Stories - - - section in our documentation. - -

- - -

- - - - NOTE: - - - -
- - Have a look at the - - .storybook/webpack.config.js - - - to add webpack loaders and plugins you are using in this project. - -

- - -
- - - - -`; diff --git a/examples/angular-cli/src/stories/addon-actions.stories.ts b/examples/angular-cli/src/stories/addon-actions.stories.ts index 6820b38ce4cb..6e20fd02b1ac 100644 --- a/examples/angular-cli/src/stories/addon-actions.stories.ts +++ b/examples/angular-cli/src/stories/addon-actions.stories.ts @@ -2,7 +2,7 @@ import { storiesOf } from '@storybook/angular'; import { action } from '@storybook/addon-actions'; import { Button } from '@storybook/angular/demo'; -storiesOf('Addon Actions', module) +storiesOf('Addon|Actions', module) .add('Action only', () => ({ component: Button, props: { diff --git a/examples/angular-cli/src/stories/addon-knobs.stories.ts b/examples/angular-cli/src/stories/addon-knobs.stories.ts index 29708d2a8bb7..f4a1cd90b38c 100644 --- a/examples/angular-cli/src/stories/addon-knobs.stories.ts +++ b/examples/angular-cli/src/stories/addon-knobs.stories.ts @@ -16,7 +16,7 @@ import { import { SimpleKnobsComponent } from './knobs.component'; import { AllKnobsComponent } from './all-knobs.component'; -storiesOf('Addon Knobs', module) +storiesOf('Addon|Knobs', module) .addDecorator(withKnobs) .add('Simple', () => { const name = text('name', 'John Doe'); diff --git a/examples/angular-cli/src/stories/addon-links.stories.ts b/examples/angular-cli/src/stories/addon-links.stories.ts index c33f82b72565..61c583d620aa 100644 --- a/examples/angular-cli/src/stories/addon-links.stories.ts +++ b/examples/angular-cli/src/stories/addon-links.stories.ts @@ -2,7 +2,7 @@ import { linkTo } from '@storybook/addon-links'; import { storiesOf } from '@storybook/angular'; import { Button } from '@storybook/angular/demo'; -storiesOf('Another Button', module).add('button with link to another story', () => ({ +storiesOf('Addon|Links', module).add('button with link to another story', () => ({ component: Button, props: { text: 'Go to Welcome Story', diff --git a/examples/angular-cli/src/stories/addon-notes.stories.ts b/examples/angular-cli/src/stories/addon-notes.stories.ts index 64468bb5e256..c47e63d39cba 100644 --- a/examples/angular-cli/src/stories/addon-notes.stories.ts +++ b/examples/angular-cli/src/stories/addon-notes.stories.ts @@ -2,7 +2,7 @@ import { storiesOf } from '@storybook/angular'; import { withNotes } from '@storybook/addon-notes'; import { Button } from '@storybook/angular/demo'; -storiesOf('Addon Notes', module) +storiesOf('Addon|Notes', module) .add( 'Simple note', withNotes({ text: 'My notes on some button' })(() => ({ diff --git a/examples/angular-cli/src/stories/component-with-di/__snapshots__/di.component.stories.storyshot b/examples/angular-cli/src/stories/component-with-di/__snapshots__/di.component.stories.storyshot index 84e7b5be377d..eb31a6b0eec5 100644 --- a/examples/angular-cli/src/stories/component-with-di/__snapshots__/di.component.stories.storyshot +++ b/examples/angular-cli/src/stories/component-with-di/__snapshots__/di.component.stories.storyshot @@ -89,3 +89,93 @@ exports[`Storyshots Component dependencies inputs and inject dependencies with k `; + +exports[`Storyshots Custom|Dependencies inputs and inject dependencies 1`] = ` + + +
+ + +
+ All dependencies are defined: true +
+ + +
+ Title: Component dependencies +
+ + +
+ Injector: function Injector_(view, elDef) { + this.view = view; + this.elDef = elDef; + } +
+ + +
+ ElementRef: {"nativeElement":{}} +
+ + +
+ TestToken: 123 +
+ + +
+ + +
+
+`; + +exports[`Storyshots Custom|Dependencies inputs and inject dependencies with knobs 1`] = ` + + +
+ + +
+ All dependencies are defined: true +
+ + +
+ Title: Component dependencies +
+ + +
+ Injector: function Injector_(view, elDef) { + this.view = view; + this.elDef = elDef; + } +
+ + +
+ ElementRef: {"nativeElement":{}} +
+ + +
+ TestToken: 123 +
+ + +
+ + +
+
+`; diff --git a/examples/angular-cli/src/stories/component-with-di/di.component.stories.ts b/examples/angular-cli/src/stories/component-with-di/di.component.stories.ts index e17f46d47c23..f72fd8e040a9 100644 --- a/examples/angular-cli/src/stories/component-with-di/di.component.stories.ts +++ b/examples/angular-cli/src/stories/component-with-di/di.component.stories.ts @@ -2,7 +2,7 @@ import { storiesOf } from '@storybook/angular'; import { withKnobs, text } from '@storybook/addon-knobs/angular'; import { DiComponent } from './di.component'; -storiesOf('Component dependencies', module) +storiesOf('Custom|Dependencies', module) .add('inputs and inject dependencies', () => ({ component: DiComponent, props: { diff --git a/examples/angular-cli/src/stories/component-with-style/__snapshots__/styled.component.stories.storyshot b/examples/angular-cli/src/stories/component-with-style/__snapshots__/styled.component.stories.storyshot index d2a95b1f3523..937109ba6e3b 100644 --- a/examples/angular-cli/src/stories/component-with-style/__snapshots__/styled.component.stories.storyshot +++ b/examples/angular-cli/src/stories/component-with-style/__snapshots__/styled.component.stories.storyshot @@ -37,3 +37,41 @@ exports[`Storyshots Component styles Component with styles 1`] = ` `; + +exports[`Storyshots Custom|styleUrls Component with styles 1`] = ` + + +
+ + +

+ Styled with scoped CSS +

+ + +

+ Styled with scoped SCSS +

+ + +

+ Styled with global CSS +

+ + +
+ + +
+
+`; diff --git a/examples/angular-cli/src/stories/component-with-style/styled.component.stories.ts b/examples/angular-cli/src/stories/component-with-style/styled.component.stories.ts index b1ec85245c3a..6df1a5405b29 100644 --- a/examples/angular-cli/src/stories/component-with-style/styled.component.stories.ts +++ b/examples/angular-cli/src/stories/component-with-style/styled.component.stories.ts @@ -1,6 +1,6 @@ import { storiesOf } from '@storybook/angular'; import { StyledComponent } from './styled.component'; -storiesOf('Component styles', module).add('Component with styles', () => ({ +storiesOf('Custom|styleUrls', module).add('Component with styles', () => ({ component: StyledComponent, })); diff --git a/examples/angular-cli/src/stories/custom-metadata.stories.ts b/examples/angular-cli/src/stories/custom-metadata.stories.ts index 48c03a3ed644..90101db8c68e 100644 --- a/examples/angular-cli/src/stories/custom-metadata.stories.ts +++ b/examples/angular-cli/src/stories/custom-metadata.stories.ts @@ -6,7 +6,7 @@ import { CustomPipePipe } from './moduleMetadata/custom.pipe'; import { DummyService } from './moduleMetadata/dummy.service'; import { ServiceComponent } from './moduleMetadata/service.component'; -storiesOf('Custom Pipe', module).add('Default', () => ({ +storiesOf('Custom|Pipe', module).add('Default', () => ({ component: NameComponent, props: { field: 'foobar', @@ -19,7 +19,7 @@ storiesOf('Custom Pipe', module).add('Default', () => ({ }, })); -storiesOf('Custom Pipe/With Knobs', module) +storiesOf('Custom|Pipe/With Knobs', module) .addDecorator(withKnobs) .add('NameComponent', () => ({ component: NameComponent, @@ -34,7 +34,7 @@ storiesOf('Custom Pipe/With Knobs', module) }, })); -storiesOf('Custom ngModule metadata', module) +storiesOf('Custom|Metadata', module) .add('simple', () => ({ component: ServiceComponent, props: { diff --git a/examples/angular-cli/src/stories/custom-ng-content.stories.ts b/examples/angular-cli/src/stories/custom-ng-content.stories.ts new file mode 100644 index 000000000000..5baa440d797b --- /dev/null +++ b/examples/angular-cli/src/stories/custom-ng-content.stories.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { storiesOf } from '@storybook/angular'; + +@Component({ + selector: 'storybook-with-ng-content', + template: `
`, +}) +class WithNgContentComponent {} + +storiesOf('Custom|ng-content', module).add('Default', () => ({ + template: `

This is rendered in ng-content

`, + moduleMetadata: { + declarations: [WithNgContentComponent], + }, +})); diff --git a/examples/angular-cli/src/stories/custom-styles.stories.ts b/examples/angular-cli/src/stories/custom-styles.stories.ts index 7bf4e59958c0..6d8cabd8f2df 100644 --- a/examples/angular-cli/src/stories/custom-styles.stories.ts +++ b/examples/angular-cli/src/stories/custom-styles.stories.ts @@ -3,7 +3,7 @@ import { action } from '@storybook/addon-actions'; import { withKnobs, text } from '@storybook/addon-knobs/angular'; import { Button } from '@storybook/angular/demo'; -storiesOf('Custom Style', module) +storiesOf('Custom|Style', module) .add('Default', () => ({ template: ``, moduleMetadata: { diff --git a/examples/angular-cli/src/stories/customControlValueAccessor/__snapshots__/custom-cva-component.stories.storyshot b/examples/angular-cli/src/stories/customControlValueAccessor/__snapshots__/custom-cva-component.stories.storyshot index 63c11a12c5e8..1efc604e67ad 100644 --- a/examples/angular-cli/src/stories/customControlValueAccessor/__snapshots__/custom-cva-component.stories.storyshot +++ b/examples/angular-cli/src/stories/customControlValueAccessor/__snapshots__/custom-cva-component.stories.storyshot @@ -1,5 +1,30 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Storyshots Custom|ngModel custom ControlValueAccessor 1`] = ` + + + + +
+ Type anything +
+ + + + + +
+
+`; + exports[`Storyshots ngModel custom ControlValueAccessor 1`] = ` ({ component: CustomCvaComponent, diff --git a/examples/angular-cli/src/stories/index.ts b/examples/angular-cli/src/stories/index.ts index 08fc7eac3698..625a86f6bc64 100644 --- a/examples/angular-cli/src/stories/index.ts +++ b/examples/angular-cli/src/stories/index.ts @@ -2,14 +2,18 @@ import { storiesOf } from '@storybook/angular'; import { Welcome, Button } from '@storybook/angular/demo'; storiesOf('Welcome', module).add('to Storybook', () => ({ - component: Welcome, + template: ``, props: {}, + moduleMetadata: { + declarations: [Welcome], + }, })); storiesOf('Button', module) .add('with text', () => ({ + template: ``, moduleMetadata: { - declarations: [Button, Welcome], + declarations: [Button], }, props: { text: 'Hello Button', @@ -18,14 +22,12 @@ storiesOf('Button', module) console.log(event); }, }, - template: ` -

This is a template

- - - `, })) .add('with some emoji', () => ({ - component: Button, + template: ``, + moduleMetadata: { + declarations: [Button], + }, props: { text: '😀 😎 👍 💯', onClick: () => {}, diff --git a/examples/angular-cli/src/stories/inheritance/__snapshots__/inheritance.stories.storyshot b/examples/angular-cli/src/stories/inheritance/__snapshots__/inheritance.stories.storyshot index 67e21a5c1f77..720d41b34c54 100644 --- a/examples/angular-cli/src/stories/inheritance/__snapshots__/inheritance.stories.storyshot +++ b/examples/angular-cli/src/stories/inheritance/__snapshots__/inheritance.stories.storyshot @@ -1,5 +1,41 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Storyshots Custom|Inheritance base button 1`] = ` + + + + + + + + + +`; + +exports[`Storyshots Custom|Inheritance icon button 1`] = ` + + + + + + + + + +`; + exports[`Storyshots Inheritance base button 1`] = ` ({ component: IconButtonComponent, props: { From 956ed1823bee623489e241296ab7fd6622cbab61 Mon Sep 17 00:00:00 2001 From: igor Date: Mon, 5 Feb 2018 17:49:55 +0200 Subject: [PATCH 026/175] Separate pipes and providers --- .../custom-pipes.stories.storyshot | 29 ++++++++ ...hot => custom-providers.stories.storyshot} | 32 +-------- .../src/stories/custom-metadata.stories.ts | 66 ------------------- .../src/stories/custom-pipes.stories.ts | 32 +++++++++ .../src/stories/custom-providers.stories.ts | 36 ++++++++++ 5 files changed, 99 insertions(+), 96 deletions(-) create mode 100644 examples/angular-cli/src/stories/__snapshots__/custom-pipes.stories.storyshot rename examples/angular-cli/src/stories/__snapshots__/{custom-metadata.stories.storyshot => custom-providers.stories.storyshot} (52%) delete mode 100644 examples/angular-cli/src/stories/custom-metadata.stories.ts create mode 100644 examples/angular-cli/src/stories/custom-pipes.stories.ts create mode 100644 examples/angular-cli/src/stories/custom-providers.stories.ts diff --git a/examples/angular-cli/src/stories/__snapshots__/custom-pipes.stories.storyshot b/examples/angular-cli/src/stories/__snapshots__/custom-pipes.stories.storyshot new file mode 100644 index 000000000000..b2a69015ad53 --- /dev/null +++ b/examples/angular-cli/src/stories/__snapshots__/custom-pipes.stories.storyshot @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Custom|Pipes Simple 1`] = ` + + +

+ CustomPipe: foobar +

+
+
+`; + +exports[`Storyshots Custom|Pipes With Knobs 1`] = ` + + +

+ CustomPipe: foobar +

+
+
+`; diff --git a/examples/angular-cli/src/stories/__snapshots__/custom-metadata.stories.storyshot b/examples/angular-cli/src/stories/__snapshots__/custom-providers.stories.storyshot similarity index 52% rename from examples/angular-cli/src/stories/__snapshots__/custom-metadata.stories.storyshot rename to examples/angular-cli/src/stories/__snapshots__/custom-providers.stories.storyshot index dc40ccce186f..97aa11aaed47 100644 --- a/examples/angular-cli/src/stories/__snapshots__/custom-metadata.stories.storyshot +++ b/examples/angular-cli/src/stories/__snapshots__/custom-providers.stories.storyshot @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Storyshots Custom|Metadata simple 1`] = ` +exports[`Storyshots Custom|Providers Simple 1`] = ` `; -exports[`Storyshots Custom|Metadata with knobs 1`] = ` +exports[`Storyshots Custom|Providers With knobs 1`] = ` `; - -exports[`Storyshots Custom|Pipe Default 1`] = ` - - -

- CustomPipe: foobar -

-
-
-`; - -exports[`Storyshots Custom|Pipe/With Knobs NameComponent 1`] = ` - - -

- CustomPipe: foobar -

-
-
-`; diff --git a/examples/angular-cli/src/stories/custom-metadata.stories.ts b/examples/angular-cli/src/stories/custom-metadata.stories.ts deleted file mode 100644 index 90101db8c68e..000000000000 --- a/examples/angular-cli/src/stories/custom-metadata.stories.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { storiesOf } from '@storybook/angular'; -import { withKnobs, text } from '@storybook/addon-knobs/angular'; - -import { NameComponent } from './moduleMetadata/name.component'; -import { CustomPipePipe } from './moduleMetadata/custom.pipe'; -import { DummyService } from './moduleMetadata/dummy.service'; -import { ServiceComponent } from './moduleMetadata/service.component'; - -storiesOf('Custom|Pipe', module).add('Default', () => ({ - component: NameComponent, - props: { - field: 'foobar', - }, - moduleMetadata: { - imports: [], - schemas: [], - declarations: [CustomPipePipe], - providers: [], - }, -})); - -storiesOf('Custom|Pipe/With Knobs', module) - .addDecorator(withKnobs) - .add('NameComponent', () => ({ - component: NameComponent, - props: { - field: text('field', 'foobar'), - }, - moduleMetadata: { - imports: [], - schemas: [], - declarations: [CustomPipePipe], - providers: [], - }, - })); - -storiesOf('Custom|Metadata', module) - .add('simple', () => ({ - component: ServiceComponent, - props: { - name: 'Static name', - }, - moduleMetadata: { - imports: [], - schemas: [], - declarations: [], - providers: [DummyService], - }, - })) - .addDecorator(withKnobs) - .add('with knobs', () => { - const name = text('name', 'Dynamic knob'); - - return { - component: ServiceComponent, - props: { - name, - }, - moduleMetadata: { - imports: [], - schemas: [], - declarations: [], - providers: [DummyService], - }, - }; - }); diff --git a/examples/angular-cli/src/stories/custom-pipes.stories.ts b/examples/angular-cli/src/stories/custom-pipes.stories.ts new file mode 100644 index 000000000000..45b84c68ff0e --- /dev/null +++ b/examples/angular-cli/src/stories/custom-pipes.stories.ts @@ -0,0 +1,32 @@ +import { storiesOf } from '@storybook/angular'; +import { withKnobs, text } from '@storybook/addon-knobs/angular'; + +import { NameComponent } from './moduleMetadata/name.component'; +import { CustomPipePipe } from './moduleMetadata/custom.pipe'; + +storiesOf('Custom|Pipes', module) + .add('Simple', () => ({ + component: NameComponent, + props: { + field: 'foobar', + }, + moduleMetadata: { + imports: [], + schemas: [], + declarations: [CustomPipePipe], + providers: [], + }, + })) + .addDecorator(withKnobs) + .add('With Knobs', () => ({ + component: NameComponent, + props: { + field: text('field', 'foobar'), + }, + moduleMetadata: { + imports: [], + schemas: [], + declarations: [CustomPipePipe], + providers: [], + }, + })); diff --git a/examples/angular-cli/src/stories/custom-providers.stories.ts b/examples/angular-cli/src/stories/custom-providers.stories.ts new file mode 100644 index 000000000000..420c2f1c64a2 --- /dev/null +++ b/examples/angular-cli/src/stories/custom-providers.stories.ts @@ -0,0 +1,36 @@ +import { storiesOf } from '@storybook/angular'; +import { withKnobs, text } from '@storybook/addon-knobs/angular'; + +import { DummyService } from './moduleMetadata/dummy.service'; +import { ServiceComponent } from './moduleMetadata/service.component'; + +storiesOf('Custom|Providers', module) + .add('Simple', () => ({ + component: ServiceComponent, + props: { + name: 'Static name', + }, + moduleMetadata: { + imports: [], + schemas: [], + declarations: [], + providers: [DummyService], + }, + })) + .addDecorator(withKnobs) + .add('With knobs', () => { + const name = text('name', 'Dynamic knob'); + + return { + component: ServiceComponent, + props: { + name, + }, + moduleMetadata: { + imports: [], + schemas: [], + declarations: [], + providers: [DummyService], + }, + }; + }); From fe35a3009f63a3dc479f6d7d43a783969ace40e3 Mon Sep 17 00:00:00 2001 From: igor Date: Tue, 6 Feb 2018 10:02:29 +0200 Subject: [PATCH 027/175] Separate vue examples --- examples/angular-cli/.storybook/config.js | 4 +- .../vue-kitchen-sink/.storybook/addons.js | 1 + .../vue-kitchen-sink/.storybook/config.js | 9 +- examples/vue-kitchen-sink/package.json | 1 + .../addon-actions.stories.storyshot | 19 ++ .../addon-centered.stories.storyshot | 18 ++ .../addon-knobs.stories.storyshot | 45 ++++ .../addon-notes.stories.storyshot | 19 ++ .../custom-decorators.stories.storyshot | 34 +++ .../custom-rendering.stories.storyshot | 95 +++++++ .../src/stories/__snapshots__/index.storyshot | 231 +---------------- .../src/stories/addon-actions.stories.js | 19 ++ .../src/stories/addon-centered.stories.js | 11 + .../src/stories/addon-knobs.stories.js | 69 ++++++ .../src/stories/addon-notes.stories.js | 25 ++ .../src/stories/custom-decorators.stories.js | 33 +++ .../src/stories/custom-rendering.stories.js | 92 +++++++ .../vue-kitchen-sink/src/stories/index.js | 233 ------------------ 18 files changed, 495 insertions(+), 463 deletions(-) create mode 100644 examples/vue-kitchen-sink/src/stories/__snapshots__/addon-actions.stories.storyshot create mode 100644 examples/vue-kitchen-sink/src/stories/__snapshots__/addon-centered.stories.storyshot create mode 100644 examples/vue-kitchen-sink/src/stories/__snapshots__/addon-knobs.stories.storyshot create mode 100644 examples/vue-kitchen-sink/src/stories/__snapshots__/addon-notes.stories.storyshot create mode 100644 examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot create mode 100644 examples/vue-kitchen-sink/src/stories/__snapshots__/custom-rendering.stories.storyshot create mode 100644 examples/vue-kitchen-sink/src/stories/addon-actions.stories.js create mode 100644 examples/vue-kitchen-sink/src/stories/addon-centered.stories.js create mode 100644 examples/vue-kitchen-sink/src/stories/addon-knobs.stories.js create mode 100644 examples/vue-kitchen-sink/src/stories/addon-notes.stories.js create mode 100644 examples/vue-kitchen-sink/src/stories/custom-decorators.stories.js create mode 100644 examples/vue-kitchen-sink/src/stories/custom-rendering.stories.js diff --git a/examples/angular-cli/.storybook/config.js b/examples/angular-cli/.storybook/config.js index 29275bdbc9e0..b7d5eaf2e962 100644 --- a/examples/angular-cli/.storybook/config.js +++ b/examples/angular-cli/.storybook/config.js @@ -13,8 +13,8 @@ function loadStories() { require('../src/stories'); // automatically import all story ts files that end with *.stories.ts - const req = require.context('../src/stories', true, /\.stories\.ts$/) - req.keys().forEach((filename) => req(filename)) + const req = require.context('../src/stories', true, /\.stories\.ts$/); + req.keys().forEach((filename) => req(filename)); } configure(loadStories, module); diff --git a/examples/vue-kitchen-sink/.storybook/addons.js b/examples/vue-kitchen-sink/.storybook/addons.js index 2d7b52c620bd..8f0c06885db4 100644 --- a/examples/vue-kitchen-sink/.storybook/addons.js +++ b/examples/vue-kitchen-sink/.storybook/addons.js @@ -3,3 +3,4 @@ import '@storybook/addon-links/register'; import '@storybook/addon-notes/register'; import '@storybook/addon-knobs/register'; import '@storybook/addon-viewport/register'; +import '@storybook/addon-options/register'; \ No newline at end of file diff --git a/examples/vue-kitchen-sink/.storybook/config.js b/examples/vue-kitchen-sink/.storybook/config.js index 385320a351f4..697f131b66da 100644 --- a/examples/vue-kitchen-sink/.storybook/config.js +++ b/examples/vue-kitchen-sink/.storybook/config.js @@ -1,5 +1,5 @@ import { configure } from '@storybook/vue'; - +import { setOptions } from '@storybook/addon-options'; import Vue from 'vue' import Vuex from 'vuex' @@ -8,8 +8,15 @@ import MyButton from '../src/stories/Button.vue' Vue.component('my-button', MyButton); Vue.use(Vuex); +setOptions({ + hierarchyRootSeparator: /\|/, +}); + function loadStories() { require('../src/stories'); + + const req = require.context('../src/stories', true, /\.stories\.js$/); + req.keys().forEach((filename) => req(filename)); } configure(loadStories, module); diff --git a/examples/vue-kitchen-sink/package.json b/examples/vue-kitchen-sink/package.json index 2382600e3949..623434036a8c 100644 --- a/examples/vue-kitchen-sink/package.json +++ b/examples/vue-kitchen-sink/package.json @@ -18,6 +18,7 @@ "@storybook/addon-knobs": "^3.4.0-alpha.7", "@storybook/addon-links": "^3.4.0-alpha.7", "@storybook/addon-notes": "^3.4.0-alpha.7", + "@storybook/addon-options": "^3.4.0-alpha.7", "@storybook/addon-storyshots": "^3.4.0-alpha.7", "@storybook/addon-viewport": "^3.4.0-alpha.7", "@storybook/addons": "^3.4.0-alpha.7", diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-actions.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-actions.stories.storyshot new file mode 100644 index 000000000000..7691db827094 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-actions.stories.storyshot @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Addon|Actions Action and method 1`] = ` + +`; + +exports[`Storyshots Addon|Actions Action only 1`] = ` + +`; diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-centered.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-centered.stories.storyshot new file mode 100644 index 000000000000..4838600b62f3 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-centered.stories.storyshot @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Addon|Centered rounded 1`] = ` +
+
+ +
+
+`; diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-knobs.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-knobs.stories.storyshot new file mode 100644 index 000000000000..f2a13b0fcadf --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-knobs.stories.storyshot @@ -0,0 +1,45 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Addon|Knobs All knobs 1`] = ` +
+

+ My name is Jane, +

+ +

+ today is January 20, 2017 +

+ +

+ I have a stock of 20 apple, costing $2.25 each. +

+ +

+ Also, I have: +

+ +
    +
  • + Laptop +
  • +
  • + Book +
  • +
  • + Whiskey +
  • +
+ +

+ Nice to meet you! +

+
+`; + +exports[`Storyshots Addon|Knobs Simple 1`] = ` +
+ I am John Doe and I'm 44 years old. +
+`; diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-notes.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-notes.stories.storyshot new file mode 100644 index 000000000000..a005840d537d --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/addon-notes.stories.storyshot @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Addon|Notes Note with HTML 1`] = ` +

+ 🤔😳😯😮 +
+ 😄😩😓😱 +
+ 🤓😑😶😊 +

+`; + +exports[`Storyshots Addon|Notes Simple note 1`] = ` +

+ + Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna. + +

+`; diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot new file mode 100644 index 000000000000..eb88673228af --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-decorators.stories.storyshot @@ -0,0 +1,34 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Custom|Decorator for Vue render 1`] = ` +
+
+ +
+
+`; + +exports[`Storyshots Custom|Decorator for Vue template 1`] = ` +
+
+ +
+
+`; diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-rendering.stories.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-rendering.stories.storyshot new file mode 100644 index 000000000000..b2c1b397beba --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/custom-rendering.stories.storyshot @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Custom|Method for rendering Vue JSX 1`] = ` + +`; + +exports[`Storyshots Custom|Method for rendering Vue pre-registered component 1`] = ` +

+ + This component was pre-registered in .storybook/config.js + +
+ + +

+`; + +exports[`Storyshots Custom|Method for rendering Vue render + component 1`] = ` + +`; + +exports[`Storyshots Custom|Method for rendering Vue render 1`] = ` +
+ renders a div with some text in it.. +
+`; + +exports[`Storyshots Custom|Method for rendering Vue template + component 1`] = ` + +`; + +exports[`Storyshots Custom|Method for rendering Vue template + methods 1`] = ` +

+ + Clicking the button will navigate to another story using the 'addon-links' + +
+ + +

+`; + +exports[`Storyshots Custom|Method for rendering Vue template 1`] = ` +
+

+ A template +

+ +

+ rendered in vue in storybook +

+
+`; + +exports[`Storyshots Custom|Method for rendering Vue vuex + actions 1`] = ` + +`; + +exports[`Storyshots Custom|Method for rendering Vue whatever you want 1`] = ` + +`; diff --git a/examples/vue-kitchen-sink/src/stories/__snapshots__/index.storyshot b/examples/vue-kitchen-sink/src/stories/__snapshots__/index.storyshot index 8f065230c187..4ba02911bcbc 100644 --- a/examples/vue-kitchen-sink/src/stories/__snapshots__/index.storyshot +++ b/examples/vue-kitchen-sink/src/stories/__snapshots__/index.storyshot @@ -1,85 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Storyshots Addon Actions Action and method 1`] = ` - -`; - -exports[`Storyshots Addon Actions Action only 1`] = ` - -`; - -exports[`Storyshots Addon Knobs All knobs 1`] = ` -
-

- My name is Jane, -

- -

- today is January 20, 2017 -

- -

- I have a stock of 20 apple, costing $2.25 each. -

- -

- Also, I have: -

- -
    -
  • - Laptop -
  • -
  • - Book -
  • -
  • - Whiskey -
  • -
- -

- Nice to meet you! -

-
-`; - -exports[`Storyshots Addon Knobs Simple 1`] = ` -
- I am John Doe and I'm 44 years old. -
-`; - -exports[`Storyshots Addon Notes Note with HTML 1`] = ` -

- 🤔😳😯😮 -
- 😄😩😓😱 -
- 🤓😑😶😊 -

-`; - -exports[`Storyshots Addon Notes Simple note 1`] = ` -

- - Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna. - -

-`; - exports[`Storyshots App App 1`] = `
-
- -
-
-`; - -exports[`Storyshots Button square 1`] = ` -
-
- -
-
-`; - -exports[`Storyshots Decorator for Vue render 1`] = ` -
-
- -
-
-`; - -exports[`Storyshots Decorator for Vue template 1`] = ` -
-
- -
-
-`; - -exports[`Storyshots Method for rendering Vue JSX 1`] = ` - -`; - -exports[`Storyshots Method for rendering Vue pre-registered component 1`] = ` -

- - This component was pre-registered in .storybook/config.js - -
- - -

-`; - -exports[`Storyshots Method for rendering Vue render + component 1`] = ` - -`; - -exports[`Storyshots Method for rendering Vue render 1`] = ` -
- renders a div with some text in it.. -
-`; - -exports[`Storyshots Method for rendering Vue template + component 1`] = ` `; -exports[`Storyshots Method for rendering Vue template + methods 1`] = ` -

- - Clicking the button will navigate to another story using the 'addon-links' - -
- - -

-`; - -exports[`Storyshots Method for rendering Vue template 1`] = ` -
-

- A template -

- -

- rendered in vue in storybook -

-
-`; - -exports[`Storyshots Method for rendering Vue vuex + actions 1`] = ` - -`; - -exports[`Storyshots Method for rendering Vue whatever you want 1`] = ` +exports[`Storyshots Button square 1`] = ` `; diff --git a/examples/vue-kitchen-sink/src/stories/addon-actions.stories.js b/examples/vue-kitchen-sink/src/stories/addon-actions.stories.js new file mode 100644 index 000000000000..e7c24137dda3 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/addon-actions.stories.js @@ -0,0 +1,19 @@ +import { storiesOf } from '@storybook/vue'; +import { action } from '@storybook/addon-actions'; + +storiesOf('Addon|Actions', module) + .add('Action only', () => ({ + template: 'Click me to log the action', + methods: { + log: action('log1'), + }, + })) + .add('Action and method', () => ({ + template: 'Click me to log the action', + methods: { + log: e => { + e.preventDefault(); + action('log2')(e.target); + }, + }, + })); diff --git a/examples/vue-kitchen-sink/src/stories/addon-centered.stories.js b/examples/vue-kitchen-sink/src/stories/addon-centered.stories.js new file mode 100644 index 000000000000..d202fc947c07 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/addon-centered.stories.js @@ -0,0 +1,11 @@ +import { storiesOf } from '@storybook/vue'; +import Centered from '@storybook/addon-centered'; + +import MyButton from './Button.vue'; + +storiesOf('Addon|Centered', module) + .addDecorator(Centered) + .add('rounded', () => ({ + components: { MyButton }, + template: 'A Button with rounded edges', + })); diff --git a/examples/vue-kitchen-sink/src/stories/addon-knobs.stories.js b/examples/vue-kitchen-sink/src/stories/addon-knobs.stories.js new file mode 100644 index 000000000000..a63f1646792f --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/addon-knobs.stories.js @@ -0,0 +1,69 @@ +import { storiesOf } from '@storybook/vue'; +import { action } from '@storybook/addon-actions'; +import { + withKnobs, + text, + number, + boolean, + array, + select, + color, + date, + button, +} from '@storybook/addon-knobs/vue'; + +storiesOf('Addon|Knobs', module) + .addDecorator(withKnobs) + .add('Simple', () => { + const name = text('Name', 'John Doe'); + const age = number('Age', 44); + const content = `I am ${name} and I'm ${age} years old.`; + + return { + template: `
${content}
`, + }; + }) + .add('All knobs', () => { + const name = text('Name', 'Jane'); + const stock = number('Stock', 20, { + range: true, + min: 0, + max: 30, + step: 5, + }); + const fruits = { + apples: 'Apple', + bananas: 'Banana', + cherries: 'Cherry', + }; + const fruit = select('Fruit', fruits, 'apple'); + const price = number('Price', 2.25); + + const colour = color('Border', 'deeppink'); + const today = date('Today', new Date('Jan 20 2017 GMT+0')); + const items = array('Items', ['Laptop', 'Book', 'Whiskey']); + const nice = boolean('Nice', true); + + const stockMessage = stock + ? `I have a stock of ${stock} ${fruit}, costing $${price} each.` + : `I'm out of ${fruit}${nice ? ', Sorry!' : '.'}`; + const salutation = nice ? 'Nice to meet you!' : 'Leave me alone!'; + const dateOptions = { year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' }; + + button('Arbitrary action', action('You clicked it!')); + + return { + template: ` +
+

My name is ${name},

+

today is ${new Date(today).toLocaleDateString('en-US', dateOptions)}

+

${stockMessage}

+

Also, I have:

+
    + ${items.map(item => `
  • ${item}
  • `).join('')} +
+

${salutation}

+
+ `, + }; + }); diff --git a/examples/vue-kitchen-sink/src/stories/addon-notes.stories.js b/examples/vue-kitchen-sink/src/stories/addon-notes.stories.js new file mode 100644 index 000000000000..a35213b8ff2e --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/addon-notes.stories.js @@ -0,0 +1,25 @@ +import { storiesOf } from '@storybook/vue'; +import { withNotes } from '@storybook/addon-notes'; + +storiesOf('Addon|Notes', module) + .add( + 'Simple note', + withNotes({ text: 'My notes on some bold text' })(() => ({ + template: + '

Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna.

', + })) + ) + .add( + 'Note with HTML', + withNotes({ + text: ` +

My notes on emojies

+ + It's not all that important to be honest, but.. + + Emojis are great, I love emojis, in fact I like using them in my Component notes too! 😇 + `, + })(() => ({ + template: '

🤔😳😯😮
😄😩😓😱
🤓😑😶😊

', + })) + ); diff --git a/examples/vue-kitchen-sink/src/stories/custom-decorators.stories.js b/examples/vue-kitchen-sink/src/stories/custom-decorators.stories.js new file mode 100644 index 000000000000..3ff256088776 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/custom-decorators.stories.js @@ -0,0 +1,33 @@ +import { storiesOf } from '@storybook/vue'; + +import MyButton from './Button.vue'; + +storiesOf('Custom|Decorator for Vue', module) + .addDecorator(story => { + // Decorated with story function + const WrapButton = story(); + return { + components: { WrapButton }, + template: '
', + data() { + return { borderStyle: 'medium solid red' }; + }, + }; + }) + .addDecorator(() => ({ + // Decorated with `story` component + template: '
', + data() { + return { + borderStyle: 'medium solid blue', + }; + }, + })) + .add('template', () => ({ + template: 'MyButton with template', + })) + .add('render', () => ({ + render(h) { + return h(MyButton, { props: { color: 'pink' } }, ['renders component: MyButton']); + }, + })); diff --git a/examples/vue-kitchen-sink/src/stories/custom-rendering.stories.js b/examples/vue-kitchen-sink/src/stories/custom-rendering.stories.js new file mode 100644 index 000000000000..cfbde6349393 --- /dev/null +++ b/examples/vue-kitchen-sink/src/stories/custom-rendering.stories.js @@ -0,0 +1,92 @@ +import Vuex from 'vuex'; +import { storiesOf } from '@storybook/vue'; +import { action } from '@storybook/addon-actions'; +import { linkTo } from '@storybook/addon-links'; + +import MyButton from './Button.vue'; + +storiesOf('Custom|Method for rendering Vue', module) + .add('render', () => ({ + render: h => h('div', ['renders a div with some text in it..']), + })) + .add('render + component', () => ({ + render(h) { + return h(MyButton, { props: { color: 'pink' } }, ['renders component: MyButton']); + }, + })) + .add('template', () => ({ + template: ` +
+

A template

+

rendered in vue in storybook

+
`, + })) + .add('template + component', () => ({ + components: { MyButton }, + template: 'MyButton rendered in a template', + })) + .add('template + methods', () => ({ + components: { MyButton }, + template: ` +

+ Clicking the button will navigate to another story using the 'addon-links'
+ MyButton rendered in a template + props & methods +

`, + methods: { + action: linkTo('Button'), + }, + })) + .add('JSX', () => ({ + components: { MyButton }, + render() { + // eslint-disable-next-line react/react-in-jsx-scope + return MyButton rendered with JSX; + }, + })) + .add('vuex + actions', () => ({ + components: { MyButton }, + template: 'with vuex: {{ $store.state.count }}', + store: new Vuex.Store({ + state: { count: 0 }, + mutations: { + increment(state) { + state.count += 1; // eslint-disable-line + action('vuex state')(state); + }, + }, + }), + methods: { + log() { + this.$store.commit('increment'); + }, + }, + })) + .add('whatever you want', () => ({ + components: { MyButton }, + template: + 'with awesomeness: {{ $store.state.count }}', + store: new Vuex.Store({ + state: { count: 0 }, + mutations: { + increment(state) { + state.count += 1; // eslint-disable-line + action('vuex state')(state); + }, + }, + }), + methods: { + log() { + this.$store.commit('increment'); + }, + }, + })) + .add('pre-registered component', () => ({ + /* By pre-registering component in config.js, + * the need to register all components with each story is removed. + * You'll only need the template */ + template: ` +

+ This component was pre-registered in .storybook/config.js
+ MyButton rendered in a template +

`, + })); diff --git a/examples/vue-kitchen-sink/src/stories/index.js b/examples/vue-kitchen-sink/src/stories/index.js index 645a4b23cc32..1a6eb3db1688 100644 --- a/examples/vue-kitchen-sink/src/stories/index.js +++ b/examples/vue-kitchen-sink/src/stories/index.js @@ -1,24 +1,5 @@ -/* eslint-disable react/react-in-jsx-scope */ - -import Vuex from 'vuex'; import { storiesOf } from '@storybook/vue'; -import { action } from '@storybook/addon-actions'; -import { linkTo } from '@storybook/addon-links'; -import { withNotes } from '@storybook/addon-notes'; -import { - withKnobs, - text, - number, - boolean, - array, - select, - color, - date, - button, -} from '@storybook/addon-knobs/vue'; -import Centered from '@storybook/addon-centered'; -import MyButton from './Button.vue'; import Welcome from './Welcome.vue'; import App from '../App.vue'; @@ -31,7 +12,6 @@ storiesOf('App', module).add('App', () => ({ })); storiesOf('Button', module) - .addDecorator(Centered) // Works if Vue.component is called in the config.js in .storybook .add('rounded', () => ({ template: 'A Button with rounded edges', @@ -39,216 +19,3 @@ storiesOf('Button', module) .add('square', () => ({ template: 'A Button with square edges', })); - -storiesOf('Method for rendering Vue', module) - .add('render', () => ({ - render: h => h('div', ['renders a div with some text in it..']), - })) - .add('render + component', () => ({ - render(h) { - return h(MyButton, { props: { color: 'pink' } }, ['renders component: MyButton']); - }, - })) - .add('template', () => ({ - template: ` -
-

A template

-

rendered in vue in storybook

-
`, - })) - .add('template + component', () => ({ - components: { MyButton }, - template: 'MyButton rendered in a template', - })) - .add('template + methods', () => ({ - components: { MyButton }, - template: ` -

- Clicking the button will navigate to another story using the 'addon-links'
- MyButton rendered in a template + props & methods -

`, - methods: { - action: linkTo('Button'), - }, - })) - .add('JSX', () => ({ - components: { MyButton }, - render() { - return MyButton rendered with JSX; - }, - })) - .add('vuex + actions', () => ({ - components: { MyButton }, - template: 'with vuex: {{ $store.state.count }}', - store: new Vuex.Store({ - state: { count: 0 }, - mutations: { - increment(state) { - state.count += 1; // eslint-disable-line - action('vuex state')(state); - }, - }, - }), - methods: { - log() { - this.$store.commit('increment'); - }, - }, - })) - .add('whatever you want', () => ({ - components: { MyButton }, - template: - 'with awesomeness: {{ $store.state.count }}', - store: new Vuex.Store({ - state: { count: 0 }, - mutations: { - increment(state) { - state.count += 1; // eslint-disable-line - action('vuex state')(state); - }, - }, - }), - methods: { - log() { - this.$store.commit('increment'); - }, - }, - })) - .add('pre-registered component', () => ({ - /* By pre-registering component in config.js, - * the need to register all components with each story is removed. - * You'll only need the template */ - template: ` -

- This component was pre-registered in .storybook/config.js
- MyButton rendered in a template -

`, - })); - -storiesOf('Decorator for Vue', module) - .addDecorator(story => { - // Decorated with story function - const WrapButton = story(); - return { - components: { WrapButton }, - template: '
', - data() { - return { borderStyle: 'medium solid red' }; - }, - }; - }) - .addDecorator(() => ({ - // Decorated with `story` component - template: '
', - data() { - return { - borderStyle: 'medium solid blue', - }; - }, - })) - .add('template', () => ({ - template: 'MyButton with template', - })) - .add('render', () => ({ - render(h) { - return h(MyButton, { props: { color: 'pink' } }, ['renders component: MyButton']); - }, - })); - -storiesOf('Addon Actions', module) - .add('Action only', () => ({ - template: 'Click me to log the action', - methods: { - log: action('log1'), - }, - })) - .add('Action and method', () => ({ - template: 'Click me to log the action', - methods: { - log: e => { - e.preventDefault(); - action('log2')(e.target); - }, - }, - })); - -storiesOf('Addon Notes', module) - .add( - 'Simple note', - withNotes({ text: 'My notes on some bold text' })(() => ({ - template: - '

Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna.

', - })) - ) - .add( - 'Note with HTML', - withNotes({ - text: ` -

My notes on emojies

- - It's not all that important to be honest, but.. - - Emojis are great, I love emojis, in fact I like using them in my Component notes too! 😇 - `, - })(() => ({ - template: '

🤔😳😯😮
😄😩😓😱
🤓😑😶😊

', - })) - ); - -storiesOf('Addon Knobs', module) - .addDecorator(withKnobs) - .add('Simple', () => { - const name = text('Name', 'John Doe'); - const age = number('Age', 44); - const content = `I am ${name} and I'm ${age} years old.`; - - return { - template: `
${content}
`, - }; - }) - .add('All knobs', () => { - const name = text('Name', 'Jane'); - const stock = number('Stock', 20, { - range: true, - min: 0, - max: 30, - step: 5, - }); - const fruits = { - apples: 'Apple', - bananas: 'Banana', - cherries: 'Cherry', - }; - const fruit = select('Fruit', fruits, 'apple'); - const price = number('Price', 2.25); - - const colour = color('Border', 'deeppink'); - const today = date('Today', new Date('Jan 20 2017 GMT+0')); - const items = array('Items', ['Laptop', 'Book', 'Whiskey']); - const nice = boolean('Nice', true); - - const stockMessage = stock - ? `I have a stock of ${stock} ${fruit}, costing $${price} each.` - : `I'm out of ${fruit}${nice ? ', Sorry!' : '.'}`; - const salutation = nice ? 'Nice to meet you!' : 'Leave me alone!'; - const dateOptions = { year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' }; - - button('Arbitrary action', action('You clicked it!')); - - return { - template: ` -
-

My name is ${name},

-

today is ${new Date(today).toLocaleDateString('en-US', dateOptions)}

-

${stockMessage}

-

Also, I have:

-
    - ${items.map(item => `
  • ${item}
  • `).join('')} -
-

${salutation}

-
- `, - }; - }); - -/* eslint-enable react/react-in-jsx-scope */ From afc895d57a051f63ac3a42b8ea9e9f7b3f70acb9 Mon Sep 17 00:00:00 2001 From: igor Date: Tue, 6 Feb 2018 10:33:08 +0200 Subject: [PATCH 028/175] Separate polymer examples --- examples/polymer-cli/.storybook/addons.js | 1 + examples/polymer-cli/.storybook/config.js | 11 +- examples/polymer-cli/package.json | 1 + .../polymer-cli/src/playground-button.html | 12 +- .../src/stories/addon-actions.stories.js | 15 +++ .../src/stories/addon-knobs.stories.js | 56 ++++++++++ .../src/stories/addon-notes.stories.js | 23 ++++ .../src/stories/advanced.stories.js | 105 ------------------ .../src/stories/custom-decorators.stories.js | 14 +++ .../src/stories/custom-rendering.stories.js | 15 +++ .../polymer-cli/src/stories/index.stories.js | 25 +---- 11 files changed, 148 insertions(+), 130 deletions(-) create mode 100644 examples/polymer-cli/src/stories/addon-actions.stories.js create mode 100644 examples/polymer-cli/src/stories/addon-knobs.stories.js create mode 100644 examples/polymer-cli/src/stories/addon-notes.stories.js delete mode 100644 examples/polymer-cli/src/stories/advanced.stories.js create mode 100644 examples/polymer-cli/src/stories/custom-decorators.stories.js create mode 100644 examples/polymer-cli/src/stories/custom-rendering.stories.js diff --git a/examples/polymer-cli/.storybook/addons.js b/examples/polymer-cli/.storybook/addons.js index 1191fbebf304..40db03219095 100644 --- a/examples/polymer-cli/.storybook/addons.js +++ b/examples/polymer-cli/.storybook/addons.js @@ -2,3 +2,4 @@ import '@storybook/addon-actions/register'; import '@storybook/addon-notes/register'; import '@storybook/addon-knobs/register'; import '@storybook/addon-viewport/register'; +import '@storybook/addon-options/register'; diff --git a/examples/polymer-cli/.storybook/config.js b/examples/polymer-cli/.storybook/config.js index 37ff65014786..ae9f20d8481b 100644 --- a/examples/polymer-cli/.storybook/config.js +++ b/examples/polymer-cli/.storybook/config.js @@ -1,10 +1,15 @@ -/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions */ - import { configure } from '@storybook/polymer'; +import { setOptions } from '@storybook/addon-options'; + +setOptions({ + hierarchyRootSeparator: /\|/, +}); function loadStories() { require('../src/stories/index.stories'); - require('../src/stories/advanced.stories'); + + const req = require.context('../src/stories', true, /\.stories\.js$/); + req.keys().forEach((filename) => req(filename)); } configure(loadStories, module); diff --git a/examples/polymer-cli/package.json b/examples/polymer-cli/package.json index c91e7010e13d..a94adc2a3caa 100644 --- a/examples/polymer-cli/package.json +++ b/examples/polymer-cli/package.json @@ -11,6 +11,7 @@ "@storybook/addon-actions": "^3.4.0-alpha.7", "@storybook/addon-knobs": "^3.4.0-alpha.7", "@storybook/addon-notes": "^3.4.0-alpha.7", + "@storybook/addon-options": "^3.4.0-alpha.7", "@storybook/addon-viewport": "^3.4.0-alpha.7", "@storybook/polymer": "^3.4.0-alpha.7", "@webcomponents/webcomponentsjs": "^1.1.0", diff --git a/examples/polymer-cli/src/playground-button.html b/examples/polymer-cli/src/playground-button.html index 272d6b2acc0d..51a4b0ed5daa 100644 --- a/examples/polymer-cli/src/playground-button.html +++ b/examples/polymer-cli/src/playground-button.html @@ -4,7 +4,15 @@