mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-05 16:11:33 +08:00
Add radio buttons knob type
This commit is contained in:
parent
6ca316800d
commit
28a14d322f
44
addons/knobs/src/components/__tests__/RadioButtons.js
Normal file
44
addons/knobs/src/components/__tests__/RadioButtons.js
Normal file
@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import RadioButtonType from '../types/RadioButtons';
|
||||
|
||||
describe('RadioButtons', () => {
|
||||
let knob;
|
||||
|
||||
beforeEach(() => {
|
||||
knob = {
|
||||
name: 'Colors',
|
||||
value: '#00ff00',
|
||||
options: {
|
||||
Green: '#00ff00',
|
||||
Red: '#ff0000',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe('displays value', () => {
|
||||
it('correctly renders labels', () => {
|
||||
const wrapper = shallow(<RadioButtonType knob={knob} />);
|
||||
|
||||
const greenLabel = wrapper.find('label').first();
|
||||
expect(greenLabel.text()).toEqual('Green');
|
||||
});
|
||||
|
||||
it('sets value on the radio buttons', () => {
|
||||
const wrapper = shallow(<RadioButtonType knob={knob} />);
|
||||
|
||||
const greenInput = wrapper.find('input').first();
|
||||
expect(greenInput.prop('value')).toEqual('#00ff00');
|
||||
});
|
||||
|
||||
it('marks the correct checkbox as checked', () => {
|
||||
const wrapper = shallow(<RadioButtonType knob={knob} />);
|
||||
|
||||
const greenInput = wrapper.find('input').first();
|
||||
const redInput = wrapper.find('input').last();
|
||||
|
||||
expect(greenInput.prop('checked')).toEqual(true);
|
||||
expect(redInput.prop('checked')).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
66
addons/knobs/src/components/types/RadioButtons.js
Normal file
66
addons/knobs/src/components/types/RadioButtons.js
Normal file
@ -0,0 +1,66 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const styles = {
|
||||
label: {
|
||||
fontSize: 11,
|
||||
padding: '5px',
|
||||
},
|
||||
};
|
||||
|
||||
class RadioButtonsType extends Component {
|
||||
renderRadioButtonList({ options }) {
|
||||
if (Array.isArray(options)) {
|
||||
return options.map(val => this.renderRadioButton(val, val));
|
||||
}
|
||||
return Object.keys(options).map(key => this.renderRadioButton(key, options[key]));
|
||||
}
|
||||
|
||||
renderRadioButton(label, value) {
|
||||
const opts = { label, value };
|
||||
const { onChange } = this.props;
|
||||
const { name } = this.props.knob;
|
||||
const id = `${name}-${opts.value}`;
|
||||
|
||||
return (
|
||||
<div key={id}>
|
||||
<input
|
||||
type="radio"
|
||||
id={id}
|
||||
name={name}
|
||||
value={opts.value}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
checked={value === this.props.knob.value}
|
||||
/>
|
||||
<label style={styles.label} htmlFor={id}>
|
||||
{label}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { knob, onChange } = this.props;
|
||||
|
||||
return <div>{this.renderRadioButtonList(knob, onChange)}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
RadioButtonsType.defaultProps = {
|
||||
knob: {},
|
||||
onChange: value => value,
|
||||
};
|
||||
|
||||
RadioButtonsType.propTypes = {
|
||||
knob: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
options: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
||||
}),
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
RadioButtonsType.serialize = value => value;
|
||||
RadioButtonsType.deserialize = value => value;
|
||||
|
||||
export default RadioButtonsType;
|
@ -4,6 +4,7 @@ import ColorType from './Color';
|
||||
import BooleanType from './Boolean';
|
||||
import ObjectType from './Object';
|
||||
import SelectType from './Select';
|
||||
import RadioButtonsType from './RadioButtons';
|
||||
import ArrayType from './Array';
|
||||
import DateType from './Date';
|
||||
import ButtonType from './Button';
|
||||
@ -16,6 +17,7 @@ export default {
|
||||
boolean: BooleanType,
|
||||
object: ObjectType,
|
||||
select: SelectType,
|
||||
radioButtons: RadioButtonsType,
|
||||
array: ArrayType,
|
||||
date: DateType,
|
||||
button: ButtonType,
|
||||
|
@ -10,13 +10,27 @@ import {
|
||||
array,
|
||||
date,
|
||||
select,
|
||||
radioButtons,
|
||||
files,
|
||||
button,
|
||||
withKnobs as commonWithKnobs,
|
||||
withKnobsOptions as commonWithKnobsOptions,
|
||||
} from '.';
|
||||
|
||||
export { knob, text, boolean, number, color, object, array, date, select, files, button };
|
||||
export {
|
||||
knob,
|
||||
text,
|
||||
boolean,
|
||||
number,
|
||||
color,
|
||||
object,
|
||||
array,
|
||||
date,
|
||||
select,
|
||||
radioButtons,
|
||||
files,
|
||||
button,
|
||||
};
|
||||
|
||||
export const selectV2 = deprecate(select, 'selectV2 has been renamed to select');
|
||||
|
||||
|
@ -52,6 +52,10 @@ export function select(name, options, value, groupId) {
|
||||
return manager.knob(name, { type: 'select', selectV2: true, options, value, groupId });
|
||||
}
|
||||
|
||||
export function radioButtons(name, options, value, groupId) {
|
||||
return manager.knob(name, { type: 'radioButtons', options, value, groupId });
|
||||
}
|
||||
|
||||
export function array(name, value, separator = ',', groupId) {
|
||||
return manager.knob(name, { type: 'array', value, separator, groupId });
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ exports[`Storyshots Addons|Knobs.withKnobs tweaks static values 1`] = `
|
||||
style="background-color:#dedede;border:2px dashed silver;border-radius:10px;padding:10px"
|
||||
>
|
||||
<p>
|
||||
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 watermelon.
|
||||
</p>
|
||||
<p>
|
||||
My birthday is: January 20, 2017
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
boolean,
|
||||
color,
|
||||
select,
|
||||
radioButtons,
|
||||
array,
|
||||
date,
|
||||
button,
|
||||
@ -44,6 +45,13 @@ storiesOf('Addons|Knobs.withKnobs', module)
|
||||
Cherry: 'cherry',
|
||||
};
|
||||
const fruit = select('Fruit', fruits, 'apple');
|
||||
const otherFruits = {
|
||||
Kiwi: 'kiwi',
|
||||
Guava: 'guava',
|
||||
Watermelon: 'watermelon',
|
||||
};
|
||||
|
||||
const otherFruit = radioButtons('Other Fruit', otherFruits, 'watermelon');
|
||||
const dollars = number('Dollars', 12.5, { min: 0, max: 100, step: 0.01 });
|
||||
const years = number('Years in NY', 9);
|
||||
|
||||
@ -63,7 +71,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}.`;
|
||||
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' };
|
||||
|
@ -114,7 +114,7 @@ exports[`Storyshots Knobs with knobs 1`] = `
|
||||
allowFontScaling={true}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
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 watermelon.
|
||||
</Text>
|
||||
<Text
|
||||
accessible={true}
|
||||
|
Loading…
x
Reference in New Issue
Block a user