diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 638e1aade6f2..5235cf76da43 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -327,9 +327,7 @@ First we are going to install storybook, then we are going to link `@storybook/r You should now have a working storybook dev environment up and running. -> TODO: update this section (is already incorrect) - -Save and go to `http://localhost:9009` (or wherever storybook is running) +Save and go to `http://localhost:9011` (or wherever storybook is running) If you don't see the changes rerun `yarn storybook` again in your sandbox app diff --git a/addons/knobs/README.md b/addons/knobs/README.md index 2da7666da27d..b00b25b4f366 100644 --- a/addons/knobs/README.md +++ b/addons/knobs/README.md @@ -307,8 +307,37 @@ const groupId = 'GROUP-ID1'; const value = select(label, options, defaultValue, groupId); ``` -> You can also provide options as an array like this: `['red', 'blue', 'yellow']`. +Options can also be an array: +```js +import { select } from '@storybook/addon-knobs'; +const label = 'Cats'; +const options = ['linus', 'eleanor', 'lover'] +const defaultValue = 'eleanor'; +const groupId = 'GROUP-ID2'; +const value = select(label, options, defaultValue, groupId); +``` + +Options can also be an array OF objects: + +```js +const label = 'Dogs'; +const arrayOfObjects = [ + { + label: 'Sparky', + dogParent: 'Matthew', + location: 'Austin', + }, + { + label: 'Juniper', + dogParent: 'Joshua', + location: 'Austin', + }, +]; +const defaultValue = arrayOfObjects[0]; +const groupId = 'GROUP-ID3'; +const value = select(label, options, defaultValue, groupId); +``` ### radio buttons diff --git a/addons/knobs/src/components/types/Select.tsx b/addons/knobs/src/components/types/Select.tsx index 8a7f387859f4..50a5d52b5648 100644 --- a/addons/knobs/src/components/types/Select.tsx +++ b/addons/knobs/src/components/types/Select.tsx @@ -30,15 +30,23 @@ const SelectType: FunctionComponent & { deserialize: typeof deserialize; } = ({ knob, onChange }) => { const { options } = knob; - const entries = Array.isArray(options) - ? options.reduce>((acc, k) => ({ ...acc, [k]: k }), {}) - : (options as Record); - const selectedKey = Object.keys(entries).find(k => { - if (Array.isArray(knob.value)) { - return JSON.stringify(entries[k]) === JSON.stringify(knob.value); + const callbackReduceArrayOptions = (acc: any, option: any, i: number) => { + if (typeof option !== 'object') return { ...acc, [option]: option }; + const label = option.label || option.key || i; + return { ...acc, [label]: option }; + }; + + const entries = Array.isArray(options) ? options.reduce(callbackReduceArrayOptions, {}) : options; + + const selectedKey = Object.keys(entries).find(key => { + const { value: knobVal } = knob; + const entryVal = entries[key]; + + if (Array.isArray(knobVal)) { + return JSON.stringify(entryVal) === JSON.stringify(knobVal); } - return entries[k] === knob.value; + return entryVal === knobVal; }); return ( diff --git a/examples/official-storybook/stories/addon-knobs/with-knobs.stories.js b/examples/official-storybook/stories/addon-knobs/with-knobs.stories.js index ee7330922dd7..7882dc8c9c9c 100644 --- a/examples/official-storybook/stories/addon-knobs/with-knobs.stories.js +++ b/examples/official-storybook/stories/addon-knobs/with-knobs.stories.js @@ -75,12 +75,27 @@ export const tweaksStaticValues = () => { const images = files('Happy Picture', 'image/*', [ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII=', ]); + // array of objects + const arrayOfObjects = [ + { + label: 'Sparky', + dogParent: 'Matthew', + location: 'Austin', + }, + { + label: 'Juniper', + dogParent: 'Joshua', + location: 'Austin', + }, + ]; + + const dog = select('Dogs', arrayOfObjects, arrayOfObjects[0]); // 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 intro = `My name is ${name}, I'm ${age} years old, and my favorite fruit is ${fruit}. I also enjoy ${otherFruit}, and hanging out with my dog ${dog.label}`; const style = { backgroundColor, ...otherStyles }; const salutation = nice ? 'Nice to meet you!' : 'Leave me alone!'; const dateOptions = { year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' };