diff --git a/addons/knobs/README.md b/addons/knobs/README.md index 78b5039f760b..c26cfde24b88 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 be 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() {