From a12d5c5462f7ee27d6fa24f2118da826b1f2ed80 Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Sat, 30 Dec 2017 07:14:33 +1100 Subject: [PATCH 1/8] key and value for select knob match key/value of options fixes #799 add selectV2 for backwards compatibility --- addons/knobs/README.md | 21 +++++++++- addons/knobs/src/angular/index.js | 3 +- addons/knobs/src/base.js | 4 ++ .../knobs/src/components/__tests__/Select.js | 40 +++++++++++++++++++ addons/knobs/src/components/types/Select.js | 23 +++++++---- addons/knobs/src/index.js | 9 +++-- addons/knobs/src/react/index.js | 3 +- addons/knobs/src/vue/index.js | 3 +- 8 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 addons/knobs/src/components/__tests__/Select.js diff --git a/addons/knobs/README.md b/addons/knobs/README.md index 78b5039f760b..0459c2bb6935 100644 --- a/addons/knobs/README.md +++ b/addons/knobs/README.md @@ -3,7 +3,7 @@ [![Build Status on CircleCI](https://circleci.com/gh/storybooks/storybook.svg?style=shield)](https://circleci.com/gh/storybooks/storybook) [![CodeFactor](https://www.codefactor.io/repository/github/storybooks/storybook/badge)](https://www.codefactor.io/repository/github/storybooks/storybook) [![Known Vulnerabilities](https://snyk.io/test/github/storybooks/storybook/8f36abfd6697e58cd76df3526b52e4b9dc894847/badge.svg)](https://snyk.io/test/github/storybooks/storybook/8f36abfd6697e58cd76df3526b52e4b9dc894847) -[![BCH compliance](https://bettercodehub.com/edge/badge/storybooks/storybook)](https://bettercodehub.com/results/storybooks/storybook) [![codecov](https://codecov.io/gh/storybooks/storybook/branch/master/graph/badge.svg)](https://codecov.io/gh/storybooks/storybook) +[![BCH compliance](https://bettercodehub.com/edge/badge/storybooks/storybook)](https://bettercodehub.com/results/storybooks/storybook) [![codecov](https://codecov.io/gh/storybooks/storybook/branch/master/graph/badge.svg)](https://codecov.io/gh/storybooks/storybook) [![Storybook Slack](https://now-examples-slackin-rrirkqohko.now.sh/badge.svg)](https://now-examples-slackin-rrirkqohko.now.sh/) [![Backers on Open Collective](https://opencollective.com/storybook/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/storybook/sponsors/badge.svg)](#sponsors) @@ -247,6 +247,25 @@ const value = select(label, options, defaultValue); > You can also provide options as an array like this: `['red', 'blue', 'yellow']` +### selectV2 + +In v4 this will replace `select`. The value from the select now uses the values from the `options` object. + +```js +import { selectV2 } from '@storybook/addon-knobs'; + +const label = 'Colors'; +const options = { + Red: 'red', + Blue: 'blue', + Yellow: 'yellow', + Rainbow: ['red', 'orange', 'etc'], + None: null, +}; +const defaultValue = 'Red'; + +const value = selectV2(label, options, defaultValue) + ### date Allow you to get date (and time) from the user. diff --git a/addons/knobs/src/angular/index.js b/addons/knobs/src/angular/index.js index 03b581dfd110..3d5666ea205a 100644 --- a/addons/knobs/src/angular/index.js +++ b/addons/knobs/src/angular/index.js @@ -12,11 +12,12 @@ import { array, date, select, + selectV2, button, manager, } from '../base'; -export { knob, text, boolean, number, color, object, array, date, select, button }; +export { knob, text, boolean, number, color, object, array, date, select, selectV2, button }; export const angularHandler = (channel, knobStore) => getStory => context => prepareComponent({ getStory, context, channel, knobStore }); diff --git a/addons/knobs/src/base.js b/addons/knobs/src/base.js index 41597325b2b3..ef378209f0bc 100644 --- a/addons/knobs/src/base.js +++ b/addons/knobs/src/base.js @@ -49,6 +49,10 @@ export function select(name, options, value) { return manager.knob(name, { type: 'select', options, value }); } +export function selectV2(name, options, value) { + return manager.knob(name, { type: 'select', selectV2: true, options, value }); +} + export function array(name, value, separator = ',') { return manager.knob(name, { type: 'array', value, separator }); } diff --git a/addons/knobs/src/components/__tests__/Select.js b/addons/knobs/src/components/__tests__/Select.js new file mode 100644 index 000000000000..ce77519ec8ea --- /dev/null +++ b/addons/knobs/src/components/__tests__/Select.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { shallow } from 'enzyme'; // eslint-disable-line +import SelectType from '../types/Select'; + +describe('Select', () => { + let knob; + + beforeEach(() => { + knob = { + name: 'Colors', + value: '#00ff00', + options: { + Green: '#00ff00', + Red: '#ff0000', + }, + }; + }); + + it('displays value', () => { + const wrapper = shallow(); + + const green = wrapper.find('option').first(); + expect(green.text()).toEqual('#00ff00'); + expect(green.prop('value')).toEqual('Green'); + }); + + describe('selectV2', () => { + beforeEach(() => { + knob.selectV2 = true; + }); + + it('correctly maps option keys and values', () => { + const wrapper = shallow(); + + const green = wrapper.find('option').first(); + expect(green.text()).toEqual('Green'); + expect(green.prop('value')).toEqual('#00ff00'); + }); + }); +}); diff --git a/addons/knobs/src/components/types/Select.js b/addons/knobs/src/components/types/Select.js index a0a5366af625..bad3d398ce65 100644 --- a/addons/knobs/src/components/types/Select.js +++ b/addons/knobs/src/components/types/Select.js @@ -18,20 +18,27 @@ const styles = { }; class SelectType extends React.Component { - _makeOpt(key, val) { + _makeOpt(key, value, selectV2) { const opts = { key, value: key, }; - return ; + let display = value; + + if (selectV2) { + opts.value = value; + display = key; + } + + return ; } - _options(values) { + _options({ options, selectV2 }) { let data = []; - if (Array.isArray(values)) { - data = values.map(val => this._makeOpt(val, val)); + if (Array.isArray(options)) { + data = options.map(val => this._makeOpt(val, val)); } else { - data = Object.keys(values).map(key => this._makeOpt(key, values[key])); + data = Object.keys(options).map(key => this._makeOpt(key, options[key], selectV2)); } return data; @@ -49,7 +56,7 @@ class SelectType extends React.Component { value={knob.value} onChange={e => onChange(e.target.value)} > - {this._options(knob.options)} + {this._options(knob)} ); } @@ -64,6 +71,8 @@ SelectType.propTypes = { knob: PropTypes.shape({ name: PropTypes.string, value: PropTypes.string, + options: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), + selectV2: PropTypes.bool, }), onChange: PropTypes.func, }; diff --git a/addons/knobs/src/index.js b/addons/knobs/src/index.js index 7a4109270d06..f144aac24aec 100644 --- a/addons/knobs/src/index.js +++ b/addons/knobs/src/index.js @@ -16,13 +16,16 @@ import { number, object, select, + selectV2, text, } from './base'; -export { knob, text, boolean, number, color, object, array, date, button, select }; +export { knob, text, boolean, number, color, object, array, date, button, select, selectV2 }; -deprecate(() => {}, -'Using @storybook/addon-knobs directly is discouraged, please use @storybook/addon-knobs/{{framework}}'); +deprecate( + () => {}, + 'Using @storybook/addon-knobs directly is discouraged, please use @storybook/addon-knobs/{{framework}}' +); // generic higher-order component decorator for all platforms - usage is discouraged // This file Should be removed with 4.0 release diff --git a/addons/knobs/src/react/index.js b/addons/knobs/src/react/index.js index f4f2ddccc0b4..71c0b7d792f1 100644 --- a/addons/knobs/src/react/index.js +++ b/addons/knobs/src/react/index.js @@ -13,11 +13,12 @@ import { array, date, select, + selectV2, button, manager, } from '../base'; -export { knob, text, boolean, number, color, object, array, date, select, button }; +export { knob, text, boolean, number, color, object, array, date, select, selectV2, button }; export const reactHandler = (channel, knobStore) => getStory => context => { const initialContent = getStory(context); diff --git a/addons/knobs/src/vue/index.js b/addons/knobs/src/vue/index.js index d5cddbf0f790..df66a1036db3 100644 --- a/addons/knobs/src/vue/index.js +++ b/addons/knobs/src/vue/index.js @@ -10,11 +10,12 @@ import { array, date, select, + selectV2, button, manager, } from '../base'; -export { knob, text, boolean, number, color, object, array, date, select, button }; +export { knob, text, boolean, number, color, object, array, date, select, selectV2, button }; export const vueHandler = (channel, knobStore) => getStory => context => ({ data() { From c19a44576c13312832de2dc854789bb6dd482ef9 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 1 Jan 2018 23:03:33 +0100 Subject: [PATCH 2/8] Update README.md --- addons/knobs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/knobs/README.md b/addons/knobs/README.md index 0459c2bb6935..cb51e157f63f 100644 --- a/addons/knobs/README.md +++ b/addons/knobs/README.md @@ -3,7 +3,7 @@ [![Build Status on CircleCI](https://circleci.com/gh/storybooks/storybook.svg?style=shield)](https://circleci.com/gh/storybooks/storybook) [![CodeFactor](https://www.codefactor.io/repository/github/storybooks/storybook/badge)](https://www.codefactor.io/repository/github/storybooks/storybook) [![Known Vulnerabilities](https://snyk.io/test/github/storybooks/storybook/8f36abfd6697e58cd76df3526b52e4b9dc894847/badge.svg)](https://snyk.io/test/github/storybooks/storybook/8f36abfd6697e58cd76df3526b52e4b9dc894847) -[![BCH compliance](https://bettercodehub.com/edge/badge/storybooks/storybook)](https://bettercodehub.com/results/storybooks/storybook) [![codecov](https://codecov.io/gh/storybooks/storybook/branch/master/graph/badge.svg)](https://codecov.io/gh/storybooks/storybook) +[![BCH compliance](https://bettercodehub.com/edge/badge/storybooks/storybook)](https://bettercodehub.com/results/storybooks/storybook) [![codecov](https://codecov.io/gh/storybooks/storybook/branch/master/graph/badge.svg)](https://codecov.io/gh/storybooks/storybook) [![Storybook Slack](https://now-examples-slackin-rrirkqohko.now.sh/badge.svg)](https://now-examples-slackin-rrirkqohko.now.sh/) [![Backers on Open Collective](https://opencollective.com/storybook/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/storybook/sponsors/badge.svg)](#sponsors) From 81864f817d9b9a3136b9c31d146b80a4d81a898d Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Mon, 15 Jan 2018 22:52:29 +1100 Subject: [PATCH 3/8] add deprecation messages for select and selectV2 --- addons/knobs/src/base.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/addons/knobs/src/base.js b/addons/knobs/src/base.js index ef378209f0bc..f72d7ed081b4 100644 --- a/addons/knobs/src/base.js +++ b/addons/knobs/src/base.js @@ -1,3 +1,4 @@ +import deprecate from 'util-deprecate'; import KnobManager from './KnobManager'; export const manager = new KnobManager(); @@ -46,11 +47,17 @@ export function object(name, value) { } export function select(name, options, value) { - return manager.knob(name, { type: 'select', options, value }); + return deprecate( + manager.knob(name, { type: 'select', options, value }), + 'in v4 keys/values of the options argument are reversed' + ); } export function selectV2(name, options, value) { - return manager.knob(name, { type: 'select', selectV2: true, options, value }); + return deprecate( + manager.knob(name, { type: 'select', selectV2: true, options, value }), + 'in v4 selectV2 will be renamed to select' + ); } export function array(name, value, separator = ',') { From 571069b4ecebd43fc4ce23141968523ca3e61810 Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Thu, 18 Jan 2018 17:51:34 +1100 Subject: [PATCH 4/8] don't deprecate selectV2 until v5 --- addons/knobs/src/base.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/addons/knobs/src/base.js b/addons/knobs/src/base.js index f72d7ed081b4..b7dde4e83410 100644 --- a/addons/knobs/src/base.js +++ b/addons/knobs/src/base.js @@ -54,10 +54,7 @@ export function select(name, options, value) { } export function selectV2(name, options, value) { - return deprecate( - manager.knob(name, { type: 'select', selectV2: true, options, value }), - 'in v4 selectV2 will be renamed to select' - ); + return manager.knob(name, { type: 'select', selectV2: true, options, value }); } export function array(name, value, separator = ',') { From c0c8f3c737644c35e197a7d363fda1cf21875c47 Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Tue, 30 Jan 2018 13:25:53 +1100 Subject: [PATCH 5/8] fix deprecate message, add example for select v2 --- addons/knobs/src/base.js | 4 ++-- .../stories/addon-knobs.stories.js | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/addons/knobs/src/base.js b/addons/knobs/src/base.js index b7dde4e83410..266d0be2ac18 100644 --- a/addons/knobs/src/base.js +++ b/addons/knobs/src/base.js @@ -48,9 +48,9 @@ export function object(name, value) { export function select(name, options, value) { return deprecate( - manager.knob(name, { type: 'select', options, value }), + manager.knob.bind(manager), 'in v4 keys/values of the options argument are reversed' - ); + )(name, { type: 'select', options, value }); } export function selectV2(name, options, value) { diff --git a/examples/official-storybook/stories/addon-knobs.stories.js b/examples/official-storybook/stories/addon-knobs.stories.js index 2a868d03eeca..57a30b360181 100644 --- a/examples/official-storybook/stories/addon-knobs.stories.js +++ b/examples/official-storybook/stories/addon-knobs.stories.js @@ -9,6 +9,7 @@ import { boolean, color, select, + selectV2, array, date, button, @@ -56,6 +57,12 @@ storiesOf('Addons|Knobs.withKnobs', module) cherry: 'Cherry', }; const fruit = select('Fruit', fruits, 'apple'); + const otherFruits = { + Lime: 'lime', + Coconut: 'coconut', + Tomato: 'tomato', + }; + const otherFruit = selectV2('Other Fruit', otherFruits, 'lime'); const dollars = number('Dollars', 12.5, { min: 0, max: 100, step: 0.01 }); const years = number('Years in NY', 9); @@ -71,7 +78,9 @@ storiesOf('Addons|Knobs.withKnobs', module) 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}.`; + const intro = `My name is ${name}, I'm ${age} years old, and my favorite fruit is ${fruit}.${ + otherFruit === 'None' ? '' : ` 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' }; @@ -113,6 +122,12 @@ storiesOf('Addons|Knobs.withKnobsOptions', module) cherry: 'Cherry', }; const fruit = select('Fruit', fruits, 'apple'); + const otherFruits = { + Lime: 'lime', + Coconut: 'coconut', + Tomato: 'tomato', + }; + const otherFruit = selectV2('Other Fruit', otherFruits, 'lime'); const dollars = number('Dollars', 12.5, { min: 0, max: 100, step: 0.01 }); const backgroundColor = color('background', '#ffff00'); @@ -127,7 +142,7 @@ storiesOf('Addons|Knobs.withKnobsOptions', module) 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}.`; + 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' }; From 1d1f0a7a504df763fd20d429d716a181b96be75c Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Tue, 30 Jan 2018 13:27:51 +1100 Subject: [PATCH 6/8] fix example --- examples/official-storybook/stories/addon-knobs.stories.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/official-storybook/stories/addon-knobs.stories.js b/examples/official-storybook/stories/addon-knobs.stories.js index 57a30b360181..2bc9119b6176 100644 --- a/examples/official-storybook/stories/addon-knobs.stories.js +++ b/examples/official-storybook/stories/addon-knobs.stories.js @@ -78,9 +78,7 @@ storiesOf('Addons|Knobs.withKnobs', module) 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}.${ - otherFruit === 'None' ? '' : ` 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}.`; const style = { backgroundColor, ...otherStyles }; const salutation = nice ? 'Nice to meet you!' : 'Leave me alone!'; const dateOptions = { year: 'numeric', month: 'long', day: 'numeric' }; From 1fa81fb9c7e011d864129a7e1274ca9642858694 Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Tue, 30 Jan 2018 16:03:01 +1100 Subject: [PATCH 7/8] update snapshot with text from selectV2 example --- .../stories/__snapshots__/addon-knobs.stories.storyshot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/official-storybook/stories/__snapshots__/addon-knobs.stories.storyshot b/examples/official-storybook/stories/__snapshots__/addon-knobs.stories.storyshot index 0bf3a0717c79..87bac29a3ec8 100644 --- a/examples/official-storybook/stories/__snapshots__/addon-knobs.stories.storyshot +++ b/examples/official-storybook/stories/__snapshots__/addon-knobs.stories.storyshot @@ -16,7 +16,7 @@ exports[`Storyshots Addons|Knobs.withKnobs tweaks static values 1`] = ` style="background-color:#ffff00;border:3px solid #ff00ff;padding:10px" >

- My name is Storyteller, I'm 70 years old, and my favorite fruit is apple. + My name is Storyteller, I'm 70 years old, and my favorite fruit is apple. I also enjoy lime.

My birthday is: January 20, 2017 @@ -70,7 +70,7 @@ exports[`Storyshots Addons|Knobs.withKnobsOptions tweaks static values with debo If you are encountering performance issues with state updating too often, use withKnobsOptions to debounce changes.

- My name is Storyteller, I'm 70 years old, and my favorite fruit is apple. + My name is Storyteller, I'm 70 years old, and my favorite fruit is apple. I also enjoy lime.

My birthday is: January 20, 2017 From 0a1140fd7db9353eb5ab0d0568616b5e04995989 Mon Sep 17 00:00:00 2001 From: Simon Knox Date: Thu, 1 Feb 2018 09:53:03 +1100 Subject: [PATCH 8/8] deprecate properly --- addons/knobs/src/base.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/addons/knobs/src/base.js b/addons/knobs/src/base.js index 266d0be2ac18..8d3cbc66a4c9 100644 --- a/addons/knobs/src/base.js +++ b/addons/knobs/src/base.js @@ -46,12 +46,10 @@ export function object(name, value) { return manager.knob(name, { type: 'object', value }); } -export function select(name, options, value) { - return deprecate( - manager.knob.bind(manager), - 'in v4 keys/values of the options argument are reversed' - )(name, { type: 'select', options, value }); -} +export const select = deprecate( + (name, options, value) => manager.knob(name, { type: 'select', options, value }), + 'in v4 keys/values of the options argument are reversed' +); export function selectV2(name, options, value) { return manager.knob(name, { type: 'select', selectV2: true, options, value });