import React from 'react'; import PropTypes from 'prop-types'; import { storiesOf } from '@storybook/react'; import { withKnobs, withKnobsOptions, text, number, boolean, color, select, radios, array, date, button, object, files, } from '@storybook/addon-knobs'; const ItemLoader = ({ isLoading, items }) => { if (isLoading) { return

Loading data

; } if (!items.length) { return

No items loaded

; } return ( ); }; ItemLoader.propTypes = { isLoading: PropTypes.bool.isRequired, items: PropTypes.arrayOf(PropTypes.string).isRequired, }; let injectedItems = []; let injectedIsLoading = false; storiesOf('Addons|Knobs.withKnobs', module) .addDecorator(withKnobs) .add('tweaks static values', () => { const name = text('Name', 'Storyteller'); const age = number('Age', 70, { range: true, min: 0, max: 90, step: 5 }); const fruits = { Apple: 'apple', Banana: 'banana', Cherry: 'cherry', }; const fruit = select('Fruit', fruits, 'apple'); const otherFruits = { Kiwi: 'kiwi', Guava: 'guava', Watermelon: 'watermelon', }; const otherFruit = radios('Other Fruit', otherFruits, 'watermelon'); const dollars = number('Dollars', 12.5, { min: 0, max: 100, step: 0.01 }); const years = number('Years in NY', 9); const backgroundColor = color('background', '#dedede'); const items = array('Items', ['Laptop', 'Book', 'Whiskey']); const otherStyles = object('Styles', { border: '2px dashed silver', borderRadius: 10, padding: '10px', }); const nice = boolean('Nice', true); const images = files('Happy Picture', 'image/*', [ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII=', ]); // 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 intro = `My name is ${name}, I'm ${age} years old, and my favorite fruit is ${fruit}. I also enjoy ${otherFruit}.`; const style = { backgroundColor, ...otherStyles }; const salutation = nice ? 'Nice to meet you!' : 'Leave me alone!'; const dateOptions = { year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' }; return (

{intro}

My birthday is: {new Date(birthday).toLocaleDateString('en-US', dateOptions)}

I live in NY for {years} years.

My wallet contains: ${dollars.toFixed(2)}

In my backpack, I have:

{salutation}

When I am happy I look like this: happy

); }) .add('tweaks static values organized in groups', () => { const GROUP_IDS = { DISPLAY: 'DISPLAY', GENERAL: 'GENERAL', FAVORITES: 'FAVORITES', }; const fruits = { Apple: 'apple', Banana: 'banana', Cherry: 'cherry', }; const otherFruits = { Kiwi: 'kiwi', Guava: 'guava', Watermelon: 'watermelon', }; // 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'); // General const name = text('Name', 'Storyteller', GROUP_IDS.GENERAL); const age = number('Age', 70, { range: true, min: 0, max: 90, step: 5 }, GROUP_IDS.GENERAL); const birthday = date('Birthday', defaultBirthday, GROUP_IDS.GENERAL); const dollars = number( 'Account Balance', 12.5, { min: 0, max: 100, step: 0.01 }, GROUP_IDS.GENERAL ); const years = number('Years in NY', 9, {}, GROUP_IDS.GENERAL); // Favorites const nice = boolean('Nice', true, GROUP_IDS.FAVORITES); const fruit = select('Fruit', fruits, 'apple', GROUP_IDS.FAVORITES); const otherFruit = radios('Other Fruit', otherFruits, 'watermelon', GROUP_IDS.FAVORITES); const items = array('Items', ['Laptop', 'Book', 'Whiskey'], ',', GROUP_IDS.FAVORITES); // Display const backgroundColor = color('Color', 'rgba(126, 211, 33, 0.22)', GROUP_IDS.DISPLAY); const otherStyles = object( 'Styles', { border: '2px dashed silver', borderRadius: 10, padding: '10px', }, GROUP_IDS.DISPLAY ); const style = { backgroundColor, ...otherStyles }; const salutation = nice ? 'Nice to meet you!' : 'Leave me alone!'; const dateOptions = { year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' }; return (

General Information

Name: {name}

Age: {age}

Birthday: {new Date(birthday).toLocaleDateString('en-US', dateOptions)}

Account Balance: {dollars}

Years in NY: {years}


Favorites

Catchphrase: {salutation}

Fruit: {fruit}

Other Fruit: {otherFruit}

Items:

); }) .add('dynamic knobs', () => { const showOptional = select('Show optional', ['yes', 'no'], 'yes'); return (
{text('compulsary', 'I must be here')}
{showOptional === 'yes' ?
{text('optional', 'I can disapear')}
: null}
); }) .add('triggers actions via button', () => { button('Toggle item list state', () => { if (!injectedIsLoading && injectedItems.length === 0) { injectedIsLoading = true; } else if (injectedIsLoading && injectedItems.length === 0) { injectedIsLoading = false; injectedItems = ['pencil', 'pen', 'eraser']; } else if (injectedItems.length > 0) { injectedItems = []; } }); return (

Hit the knob button and it will toggle the items list into multiple states.

); }) .add('XSS safety', () => (
'), }} /> )) .add('accepts story parameters', () =>
{text('Rendered string', '

Hello

')}
, { knobs: { escapeHTML: false }, }); storiesOf('Addons|Knobs.withKnobs using options', module) .addDecorator( withKnobs({ escapeHTML: false, }) ) .add('accepts options', () =>
{text('Rendered string', '

Hello

')}
); storiesOf('Addons|Knobs.withKnobsOptions', module) .addDecorator( withKnobsOptions({ escapeHTML: false, }) ) .add('displays HTML code', () =>
{text('Rendered string', '

Hello

')}
);