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 (
{items.map(i => (
- {i}
))}
);
};
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:
{items.map(item => (
- {item}
))}
{salutation}
When I am happy I look like this:
);
})
.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:
{items.map(item => (
- {item}
))}
);
})
.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
')});