Skip to content

Commit f403595

Browse files
darrenengphwebi
authored andcommitted
feat: support form switch
- make Input api similar to CustomInput (e.g. allow writing <Input type="switch" /> - make FormGroup api for switch similar to api for checkbox (e.g. allow writing <FormGroup switch />) https://getbootstrap.com/docs/5.0/forms/checks-radios/#switches
1 parent 06868e2 commit f403595

5 files changed

Lines changed: 62 additions & 8 deletions

File tree

docs/lib/examples/InputType.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ const Example = (props) => {
140140
<Input id="InputType-checkbox" type="checkbox" />
141141
<Label for="InputType-checkbox" check>Check me out</Label>
142142
</FormGroup>
143+
<FormGroup switch>
144+
<Input id="InputType-switch" type="switch" />
145+
<Label for="InputType-switch" check>Check me out</Label>
146+
</FormGroup>
143147
</Form>
144148
);
145149
}

src/FormGroup.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const propTypes = {
77
children: PropTypes.node,
88
row: PropTypes.bool,
99
check: PropTypes.bool,
10+
switch: PropTypes.bool,
1011
inline: PropTypes.bool,
1112
disabled: PropTypes.bool,
1213
tag: tagPropType,
@@ -30,14 +31,17 @@ const FormGroup = (props) => {
3031
...attributes
3132
} = props;
3233

34+
const formCheck = check || props.switch;
35+
3336
const classes = mapToCssModules(classNames(
3437
className,
3538
row ? 'row' : false,
36-
check ? 'form-check' : 'mb-3',
37-
check && inline ? 'form-check-inline' : false,
38-
check && disabled ? 'disabled' : false
39+
formCheck ? 'form-check' : 'mb-3',
40+
props.switch ? 'form-switch' : false,
41+
formCheck && inline ? 'form-check-inline' : false,
42+
formCheck && disabled ? 'disabled' : false
3943
), cssModule);
40-
44+
4145
if (Tag === 'fieldset') {
4246
attributes.disabled = disabled;
4347
}

src/Input.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class Input extends React.Component {
6363
...attributes
6464
} = this.props;
6565

66-
const checkInput = ['radio', 'checkbox'].indexOf(type) > -1;
66+
const checkInput = ['switch', 'radio', 'checkbox'].indexOf(type) > -1;
6767
const isNotaNumber = new RegExp('\\D', 'g');
6868

6969
const textareaInput = type === 'textarea';
@@ -112,7 +112,7 @@ class Input extends React.Component {
112112
);
113113

114114
if (Tag === 'input' || (tag && typeof tag === 'function')) {
115-
attributes.type = type;
115+
attributes.type = type === 'switch' ? 'checkbox' : type;
116116
}
117117

118118
if (

src/__tests__/FormGroup.spec.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,41 @@ describe('FormGroup', () => {
3434
expect(wrapper.hasClass('form-check')).toBe(true);
3535
});
3636

37+
it('should render with "form-check" and "form-switch" class when switch prop is truthy', () => {
38+
const wrapper = shallow(<FormGroup switch>Yo!</FormGroup>);
39+
40+
expect(wrapper.hasClass('form-check')).toBe(true);
41+
expect(wrapper.hasClass('form-switch')).toBe(true);
42+
});
43+
3744
it('should not render with "form-check-inline" class when check prop is truthy and inline prop is falsy', () => {
3845
const wrapper = shallow(<FormGroup check>Yo!</FormGroup>);
3946

4047
expect(wrapper.hasClass('form-check-inline')).toBe(false);
4148
});
4249

50+
it('should not render with "form-check-inline" class when switch prop is truthy and inline prop is falsy', () => {
51+
const wrapper = shallow(<FormGroup switch>Yo!</FormGroup>);
52+
53+
expect(wrapper.hasClass('form-check-inline')).toBe(false);
54+
});
55+
4356
it('should render with "form-check" and "form-check-inline" classes when check prop and inline prop are both truthy', () => {
4457
const wrapper = shallow(<FormGroup check inline>Yo!</FormGroup>);
4558

4659
expect(wrapper.hasClass('form-check')).toBe(true);
4760
expect(wrapper.hasClass('form-check-inline')).toBe(true);
4861
});
4962

50-
it('should not render with "form-check-inline" class when check prop is falsy and inline prop is truthy', () => {
63+
it('should render with "form-check" and "form-switch" and "form-check-inline" classes when check prop and inline prop are both truthy', () => {
64+
const wrapper = shallow(<FormGroup switch inline>Yo!</FormGroup>);
65+
66+
expect(wrapper.hasClass('form-check')).toBe(true);
67+
expect(wrapper.hasClass('form-switch')).toBe(true);
68+
expect(wrapper.hasClass('form-check-inline')).toBe(true);
69+
});
70+
71+
it('should not render with "form-check-inline" class when check and switch prop are falsy and inline prop is truthy', () => {
5172
const wrapper = shallow(<FormGroup inline>Yo!</FormGroup>);
5273

5374
expect(wrapper.hasClass('form-check-inline')).toBe(false);
@@ -59,7 +80,13 @@ describe('FormGroup', () => {
5980
expect(wrapper.hasClass('mb-3')).toBe(false);
6081
});
6182

62-
it('should not render with "disabled" class when disabled prop is truthy but check is not', () => {
83+
it('should not render with "mb-3" class when switch prop is truthy', () => {
84+
const wrapper = shallow(<FormGroup switch>Yo!</FormGroup>);
85+
86+
expect(wrapper.hasClass('mb-3')).toBe(false);
87+
});
88+
89+
it('should not render with "disabled" class when disabled prop is truthy but check and switch are not', () => {
6390
const wrapper = shallow(<FormGroup disabled>Yo!</FormGroup>);
6491

6592
expect(wrapper.hasClass('disabled')).toBe(false);
@@ -72,6 +99,13 @@ describe('FormGroup', () => {
7299
expect(wrapper.hasClass('form-check')).toBe(true);
73100
});
74101

102+
it('should render with "disabled" class when both switch and disabled props are truthy', () => {
103+
const wrapper = shallow(<FormGroup switch disabled>Yo!</FormGroup>);
104+
105+
expect(wrapper.hasClass('disabled')).toBe(true);
106+
expect(wrapper.hasClass('form-check')).toBe(true);
107+
});
108+
75109
it('should render with "row" class when row prop is truthy', () => {
76110
const wrapper = shallow(<FormGroup row>Yo!</FormGroup>);
77111

src/__tests__/Input.spec.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,12 @@ describe('Input', () => {
211211
expect(wrapper.hasClass('form-check-input')).toBe(true);
212212
});
213213

214+
it('should render with "form-check-input" class when type is switch', () => {
215+
const wrapper = shallow(<Input type="switch" />);
216+
217+
expect(wrapper.hasClass('form-check-input')).toBe(true);
218+
});
219+
214220
it('should not render with "form-check-input" nor "form-control" class when type is checkbox and addon is truthy', () => {
215221
const wrapper = shallow(<Input addon type="checkbox" />);
216222

@@ -243,6 +249,12 @@ describe('Input', () => {
243249
expect(wrapper.hasClass('other')).toBe(true);
244250
});
245251

252+
it('should render checkbox type when type is switch', () => {
253+
const input = shallow(<Input type="switch" />);
254+
255+
expect(input.find('[type="checkbox"]').exists()).toBe(true);
256+
});
257+
246258
it('should render "select" and "textarea" without type property', () => {
247259
const input = shallow(<Input type="select">Yo!</Input>);
248260
const textarea = shallow(<Input type="textarea" />);

0 commit comments

Comments
 (0)