diff --git a/docs/lib/examples/InputType.js b/docs/lib/examples/InputType.js index 1b9b286b7..fcb46ac1c 100644 --- a/docs/lib/examples/InputType.js +++ b/docs/lib/examples/InputType.js @@ -140,6 +140,10 @@ const Example = (props) => { + + + + ); } diff --git a/src/FormGroup.js b/src/FormGroup.js index 25f7eeb9f..b4b56fd0f 100644 --- a/src/FormGroup.js +++ b/src/FormGroup.js @@ -7,6 +7,7 @@ const propTypes = { children: PropTypes.node, row: PropTypes.bool, check: PropTypes.bool, + switch: PropTypes.bool, inline: PropTypes.bool, disabled: PropTypes.bool, tag: tagPropType, @@ -30,14 +31,17 @@ const FormGroup = (props) => { ...attributes } = props; + const formCheck = check || props.switch; + const classes = mapToCssModules(classNames( className, row ? 'row' : false, - check ? 'form-check' : 'mb-3', - check && inline ? 'form-check-inline' : false, - check && disabled ? 'disabled' : false + formCheck ? 'form-check' : 'mb-3', + props.switch ? 'form-switch' : false, + formCheck && inline ? 'form-check-inline' : false, + formCheck && disabled ? 'disabled' : false ), cssModule); - + if (Tag === 'fieldset') { attributes.disabled = disabled; } diff --git a/src/Input.js b/src/Input.js index 6c18f5b89..a0bb9e435 100644 --- a/src/Input.js +++ b/src/Input.js @@ -63,7 +63,7 @@ class Input extends React.Component { ...attributes } = this.props; - const checkInput = ['radio', 'checkbox'].indexOf(type) > -1; + const checkInput = ['switch', 'radio', 'checkbox'].indexOf(type) > -1; const isNotaNumber = new RegExp('\\D', 'g'); const textareaInput = type === 'textarea'; @@ -112,7 +112,7 @@ class Input extends React.Component { ); if (Tag === 'input' || (tag && typeof tag === 'function')) { - attributes.type = type; + attributes.type = type === 'switch' ? 'checkbox' : type; } if ( diff --git a/src/__tests__/FormGroup.spec.js b/src/__tests__/FormGroup.spec.js index 5750afa82..64e247205 100644 --- a/src/__tests__/FormGroup.spec.js +++ b/src/__tests__/FormGroup.spec.js @@ -34,12 +34,25 @@ describe('FormGroup', () => { expect(wrapper.hasClass('form-check')).toBe(true); }); + it('should render with "form-check" and "form-switch" class when switch prop is truthy', () => { + const wrapper = shallow(Yo!); + + expect(wrapper.hasClass('form-check')).toBe(true); + expect(wrapper.hasClass('form-switch')).toBe(true); + }); + it('should not render with "form-check-inline" class when check prop is truthy and inline prop is falsy', () => { const wrapper = shallow(Yo!); expect(wrapper.hasClass('form-check-inline')).toBe(false); }); + it('should not render with "form-check-inline" class when switch prop is truthy and inline prop is falsy', () => { + const wrapper = shallow(Yo!); + + expect(wrapper.hasClass('form-check-inline')).toBe(false); + }); + it('should render with "form-check" and "form-check-inline" classes when check prop and inline prop are both truthy', () => { const wrapper = shallow(Yo!); @@ -47,7 +60,15 @@ describe('FormGroup', () => { expect(wrapper.hasClass('form-check-inline')).toBe(true); }); - it('should not render with "form-check-inline" class when check prop is falsy and inline prop is truthy', () => { + it('should render with "form-check" and "form-switch" and "form-check-inline" classes when check prop and inline prop are both truthy', () => { + const wrapper = shallow(Yo!); + + expect(wrapper.hasClass('form-check')).toBe(true); + expect(wrapper.hasClass('form-switch')).toBe(true); + expect(wrapper.hasClass('form-check-inline')).toBe(true); + }); + + it('should not render with "form-check-inline" class when check and switch prop are falsy and inline prop is truthy', () => { const wrapper = shallow(Yo!); expect(wrapper.hasClass('form-check-inline')).toBe(false); @@ -59,7 +80,13 @@ describe('FormGroup', () => { expect(wrapper.hasClass('mb-3')).toBe(false); }); - it('should not render with "disabled" class when disabled prop is truthy but check is not', () => { + it('should not render with "mb-3" class when switch prop is truthy', () => { + const wrapper = shallow(Yo!); + + expect(wrapper.hasClass('mb-3')).toBe(false); + }); + + it('should not render with "disabled" class when disabled prop is truthy but check and switch are not', () => { const wrapper = shallow(Yo!); expect(wrapper.hasClass('disabled')).toBe(false); @@ -72,6 +99,13 @@ describe('FormGroup', () => { expect(wrapper.hasClass('form-check')).toBe(true); }); + it('should render with "disabled" class when both switch and disabled props are truthy', () => { + const wrapper = shallow(Yo!); + + expect(wrapper.hasClass('disabled')).toBe(true); + expect(wrapper.hasClass('form-check')).toBe(true); + }); + it('should render with "row" class when row prop is truthy', () => { const wrapper = shallow(Yo!); diff --git a/src/__tests__/Input.spec.js b/src/__tests__/Input.spec.js index 78eb25d45..6cc6354de 100644 --- a/src/__tests__/Input.spec.js +++ b/src/__tests__/Input.spec.js @@ -211,6 +211,12 @@ describe('Input', () => { expect(wrapper.hasClass('form-check-input')).toBe(true); }); + it('should render with "form-check-input" class when type is switch', () => { + const wrapper = shallow(); + + expect(wrapper.hasClass('form-check-input')).toBe(true); + }); + it('should not render with "form-check-input" nor "form-control" class when type is checkbox and addon is truthy', () => { const wrapper = shallow(); @@ -243,6 +249,12 @@ describe('Input', () => { expect(wrapper.hasClass('other')).toBe(true); }); + it('should render checkbox type when type is switch', () => { + const input = shallow(); + + expect(input.find('[type="checkbox"]').exists()).toBe(true); + }); + it('should render "select" and "textarea" without type property', () => { const input = shallow(Yo!); const textarea = shallow();