Skip to content

Commit

Permalink
Merge pull request #2860 from kn0ll/files-knob
Browse files Browse the repository at this point in the history
files knob
  • Loading branch information
Hypnosphi authored Mar 27, 2018
2 parents 4f5d7f9 + b57e8e7 commit 2994fc1
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 8 deletions.
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
20 changes: 19 additions & 1 deletion addons/knobs/example/stories/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
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 +31,10 @@ 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 +53,9 @@ 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]} alt="happy" />
</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"
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ exports[`Storyshots Addons|Knobs.withKnobs tweaks static values 1`] = `
<p>
Nice to meet you!
</p>
<p>
When I am happy I look like this:
<img
alt="happy"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII="
/>
</p>
<hr />
<p>
PS. My shirt pocket contains:
Expand Down Expand Up @@ -147,6 +154,13 @@ exports[`Storyshots Addons|Knobs.withKnobsOptions tweaks static values with debo
<p>
Nice to meet you!
</p>
<p>
When I am happy I look like this:
<img
alt="happy"
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII="
/>
</p>
<hr />
<p>
PS. My shirt pocket contains:
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

0 comments on commit 2994fc1

Please sign in to comment.