Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

files knob #2860

Merged
merged 10 commits into from
Mar 27, 2018
15 changes: 15 additions & 0 deletions addons/knobs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,21 @@ const groupId = 'GROUP-ID1';
const value = selectV2(label, options, defaultValue, groupId);
```

### files

Allows you to get a value from a file input from the user.

```js
import { files } from '@storybook/addon-knobs/react';

const label = 'Images';
const defaultValue = [];

const value = files(label, accept, defaultValue);
```

> Multiple files can be selected, and will be returned as an array of [Data URLs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs)

### date

Allow you to get date (and time) from the user.
Expand Down
5 changes: 4 additions & 1 deletion addons/knobs/example/stories/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import moment from 'moment';
import { withKnobs, number, object, boolean, text, select, date, array, color } from '../../src';
import { withKnobs, number, object, boolean, text, select, date, array, color, files } from '../../src';

const stories = storiesOf('Example of Knobs', module);

Expand All @@ -20,6 +20,8 @@ stories.add('with all knobs', () => {

const passions = array('Passions', ['Fishing', 'Skiing']);

const images = files('Happy Picture', 'image/*', ['data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII=']);

const customStyle = object('Style', {
fontFamily: 'Arial',
padding: 20,
Expand All @@ -38,6 +40,7 @@ stories.add('with all knobs', () => {
<ul>{passions.map(p => <li key={p}>{p}</li>)}</ul>
<p>My favorite number is {favoriteNumber}.</p>
<p>My most comfortable room temperature is {comfortTemp} degrees Fahrenheit.</p>
<p>When I am happy I look like this: <img src={images[0]} /></p>
</div>
);
});
Expand Down
3 changes: 2 additions & 1 deletion addons/knobs/src/angular/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import {
select,
selectV2,
button,
files,
manager,
} from '../base';

export { knob, text, boolean, number, color, object, array, date, select, selectV2, button };
export { knob, text, boolean, number, color, object, array, date, select, selectV2, button, files };

export const angularHandler = (channel, knobStore) => getStory => context =>
prepareComponent({ getStory, context, channel, knobStore });
Expand Down
4 changes: 4 additions & 0 deletions addons/knobs/src/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,7 @@ export function date(name, value = new Date(), groupId) {
export function button(name, callback, groupId) {
return manager.knob(name, { type: 'button', callback, hideLabel: true, groupId });
}

export function files(name, accept, value = []) {
return manager.knob(name, { type: 'files', accept, value });
}
38 changes: 38 additions & 0 deletions addons/knobs/src/components/types/Files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FileReader } from 'global';
import PropTypes from 'prop-types';
import React from 'react';

function fileReaderPromise(file) {
return new Promise(resolve => {
const fileReader = new FileReader();
fileReader.onload = e => resolve(e.currentTarget.result);
fileReader.readAsDataURL(file);
});
}

const FilesType = ({ knob, onChange }) => (
<input
id={knob.name}
type="file"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

multiple
onChange={e => Promise.all(Array.from(e.target.files).map(fileReaderPromise)).then(onChange)}
accept={knob.accept}
/>
);

FilesType.defaultProps = {
knob: {},
onChange: value => value,
};

FilesType.propTypes = {
knob: PropTypes.shape({
name: PropTypes.string,
}),
onChange: PropTypes.func,
};

FilesType.serialize = () => undefined;
FilesType.deserialize = () => undefined;

export default FilesType;
2 changes: 2 additions & 0 deletions addons/knobs/src/components/types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import SelectType from './Select';
import ArrayType from './Array';
import DateType from './Date';
import ButtonType from './Button';
import FilesType from './Files';

export default {
text: TextType,
Expand All @@ -18,4 +19,5 @@ export default {
array: ArrayType,
date: DateType,
button: ButtonType,
files: FilesType,
};
3 changes: 2 additions & 1 deletion addons/knobs/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
array,
boolean,
button,
files,
color,
date,
knob,
Expand All @@ -20,7 +21,7 @@ import {
text,
} from './base';

export { knob, text, boolean, number, color, object, array, date, button, select, selectV2 };
export { knob, text, boolean, number, color, object, array, date, button, select, selectV2, files };

deprecate(() => {},
'Using @storybook/addon-knobs directly is discouraged, please use @storybook/addon-knobs/{{framework}}');
Expand Down
18 changes: 15 additions & 3 deletions addons/knobs/src/polymer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@ import addons from '@storybook/addons';
import window from 'global';
import './WrapStory.html';

import { knob, text, boolean, number, color, object, array, date, select, manager } from '../base';

export { knob, text, boolean, number, color, object, array, date, select };
import {
knob,
text,
boolean,
number,
color,
object,
array,
date,
select,
files,
manager,
} from '../base';

export { knob, text, boolean, number, color, object, array, date, select, files };

export function button(name, callback) {
return manager.knob(name, { type: 'button', value: Date.now(), callback, hideLabel: true });
Expand Down
3 changes: 2 additions & 1 deletion addons/knobs/src/react/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import {
select,
selectV2,
button,
files,
manager,
} from '../base';

export { knob, text, boolean, number, color, object, array, date, select, selectV2, button };
export { knob, text, boolean, number, color, object, array, date, select, selectV2, button, files };

export const reactHandler = (channel, knobStore) => getStory => context => {
const initialContent = getStory(context);
Expand Down
3 changes: 2 additions & 1 deletion addons/knobs/src/vue/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import {
select,
selectV2,
button,
files,
manager,
} from '../base';

export { knob, text, boolean, number, color, object, array, date, select, selectV2, button };
export { knob, text, boolean, number, color, object, array, date, select, selectV2, button, files };

export const vueHandler = (channel, knobStore) => getStory => context => ({
data() {
Expand Down
13 changes: 13 additions & 0 deletions examples/official-storybook/stories/addon-knobs.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
date,
button,
object,
files,
} from '@storybook/addon-knobs/react';

class AsyncItemLoader extends React.Component {
Expand Down Expand Up @@ -73,6 +74,9 @@ storiesOf('Addons|Knobs.withKnobs', module)
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');
Expand All @@ -92,6 +96,9 @@ storiesOf('Addons|Knobs.withKnobs', module)
<p>In my backpack, I have:</p>
<ul>{items.map(item => <li key={item}>{item}</li>)}</ul>
<p>{salutation}</p>
<p>
When I am happy I look like this: <img src={images[0]} alt="happy" />
</p>
<hr />
<p>PS. My shirt pocket contains: </p>
</div>
Expand Down Expand Up @@ -206,6 +213,9 @@ storiesOf('Addons|Knobs.withKnobsOptions', module)
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');
Expand All @@ -228,6 +238,9 @@ storiesOf('Addons|Knobs.withKnobsOptions', module)
<p>In my backpack, I have:</p>
<ul>{items.map(item => <li key={item}>{item}</li>)}</ul>
<p>{salutation}</p>
<p>
When I am happy I look like this: <img src={images[0]} alt="happy" />
</p>
<hr />
<p>PS. My shirt pocket contains: </p>
</div>
Expand Down