Repository: vazco/uniforms
Pull request #348 (2017-09-26 21:34:28)

added checkbox option for BoolField for antd
PR adds ability to create an antd `Checkbox` with uniforms `BoolField` instead of just the antd `Switch`.

### Usage
```javascript
<BoolField
    checkbox
    name="myCheckbox"
    label="Check here if you agree"
/>
```

![](https://user-images.githubusercontent.com/136654/30885234-6e2f3b38-a2e0-11e7-8f43-23eabf3a1017.png)
![](https://user-images.githubusercontent.com/136654/30885252-79da9ce8-a2e0-11e7-9ed4-aff90912b321.png)


codecov[bot]: # [Codecov](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=h1) Report
> Merging [#348](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=desc) into [master](https://codecov.io/gh/vazco/uniforms/commit/313344b8ba7aa3331e6073b050978a9f10a91a62?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/vazco/uniforms/pull/348/graphs/tree.svg?token=PEY7QrNpKu&width=650&height=150&src=pr)](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=tree)

```diff
@@          Coverage Diff          @@
##           master   #348   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files         156    156           
  Lines        1305   1306    +1     
=====================================
+ Hits         1305   1306    +1
```


| [Impacted Files](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/uniforms/src/filterDOMProps.js](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=tree#diff-cGFja2FnZXMvdW5pZm9ybXMvc3JjL2ZpbHRlckRPTVByb3BzLmpz) | `100% <ø> (ø)` | :arrow_up: |
| [packages/uniforms-antd/src/BoolField.js](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=tree#diff-cGFja2FnZXMvdW5pZm9ybXMtYW50ZC9zcmMvQm9vbEZpZWxkLmpz) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=footer). Last update [313344b...5641a4c](https://codecov.io/gh/vazco/uniforms/pull/348?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

purplecones: Thanks for feedback, learning something new every day.

Patch:
diff --git a/packages/uniforms-antd/src/BoolField.js b/packages/uniforms-antd/src/BoolField.js
index baa66768..f53a5925 100644
--- a/packages/uniforms-antd/src/BoolField.js
+++ b/packages/uniforms-antd/src/BoolField.js
@@ -1,26 +1,28 @@
 import Icon           from 'antd/lib/icon';
 import React          from 'react';
+import Checkbox       from 'antd/lib/checkbox';
 import Switch         from 'antd/lib/switch';
 import connectField   from 'uniforms/connectField';
 import filterDOMProps from 'uniforms/filterDOMProps';
 
 import wrapField from './wrapField';
 
-const Bool = props =>
+const Bool = ({checkbox, ...props}) =>
     wrapField(props, (
-        <Switch
-            checked={props.value}
-            disabled={props.disabled}
-            id={props.id}
-            name={props.name}
-            onChange={() => props.onChange(!props.value)}
-            ref={props.inputRef}
-            {...filterDOMProps(props)}
-        />
+        React.createElement(checkbox ? Checkbox : Switch, {
+            checked: props.value,
+            disabled: props.disabled,
+            id: props.id,
+            name: props.name,
+            onChange: () => props.onChange(!props.value),
+            ref: props.inputRef,
+            ...filterDOMProps(props)
+        })
     ))
 ;
 
 Bool.defaultProps = {
+    checkbox: false,
     checkedChildren:   <Icon type="check" />,
     unCheckedChildren: <Icon type="cross" />
 };


Test patch:
diff --git a/packages/uniforms-antd/__tests__/BoolField.js b/packages/uniforms-antd/__tests__/BoolField.js
index 817467c5..0358d262 100644
--- a/packages/uniforms-antd/__tests__/BoolField.js
+++ b/packages/uniforms-antd/__tests__/BoolField.js
@@ -1,19 +1,27 @@
-import React   from 'react';
-import Switch  from 'antd/lib/switch';
-import {mount} from 'enzyme';
+import React    from 'react';
+import Switch   from 'antd/lib/switch';
+import Checkbox from 'antd/lib/checkbox';
+import {mount}  from 'enzyme';
 
 import BoolField from 'uniforms-antd/BoolField';
 
 import createContext from './_createContext';
 
-test('<BoolField> - renders an input', () => {
+test('<BoolField> - renders a switch input', () => {
     const element = <BoolField name="x" />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
     expect(wrapper.find(Switch)).toHaveLength(1);
 });
 
-test('<BoolField> - renders a input with correct id (inherited)', () => {
+test('<BoolField> - renders a checkbox input', () => {
+    const element = <BoolField checkbox name="x" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+});
+
+test('<BoolField> - renders a switch input with correct id (inherited)', () => {
     const element = <BoolField name="x" />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
@@ -21,7 +29,15 @@ test('<BoolField> - renders a input with correct id (inherited)', () => {
     expect(wrapper.find(Switch).prop('id')).toBeTruthy();
 });
 
-test('<BoolField> - renders a input with correct id (specified)', () => {
+test('<BoolField> - renders a checkbox input with correct id (inherited)', () => {
+    const element = <BoolField checkbox name="x" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+    expect(wrapper.find(Checkbox).prop('id')).toBeTruthy();
+});
+
+test('<BoolField> - renders a switch input with correct id (specified)', () => {
     const element = <BoolField name="x" id="y" />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
@@ -29,7 +45,15 @@ test('<BoolField> - renders a input with correct id (specified)', () => {
     expect(wrapper.find(Switch).prop('id')).toBe('y');
 });
 
-test('<BoolField> - renders a input with correct name', () => {
+test('<BoolField> - renders a checkbox input with correct id (specified)', () => {
+    const element = <BoolField checkbox name="x" id="y" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+    expect(wrapper.find(Checkbox).prop('id')).toBe('y');
+});
+
+test('<BoolField> - renders a switch input with correct name', () => {
     const element = <BoolField name="x" />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
@@ -37,7 +61,15 @@ test('<BoolField> - renders a input with correct name', () => {
     expect(wrapper.find(Switch).prop('name')).toBe('x');
 });
 
-test('<BoolField> - renders an input with correct disabled state', () => {
+test('<BoolField> - renders a checkbox input with correct name', () => {
+    const element = <BoolField checkbox name="x" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+    expect(wrapper.find(Checkbox).prop('name')).toBe('x');
+});
+
+test('<BoolField> - renders a switch input with correct disabled state', () => {
     const element = <BoolField name="x" disabled />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
@@ -45,7 +77,15 @@ test('<BoolField> - renders an input with correct disabled state', () => {
     expect(wrapper.find(Switch).prop('disabled')).toBe(true);
 });
 
-test('<BoolField> - renders a input with correct label (specified)', () => {
+test('<BoolField> - renders a checkbox input with correct disabled state', () => {
+    const element = <BoolField checkbox name="x" disabled />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+    expect(wrapper.find(Checkbox).prop('disabled')).toBe(true);
+});
+
+test('<BoolField> - renders a switch input with correct label (specified)', () => {
     const element = <BoolField name="x" label="BoolFieldLabel" />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
@@ -53,7 +93,15 @@ test('<BoolField> - renders a input with correct label (specified)', () => {
     expect(wrapper.find('label').text()).toBe('BoolFieldLabel'); // Label is prefixed with a &nbsp;.
 });
 
-test('<BoolField> - renders a input with correct value (default)', () => {
+test('<BoolField> - renders a checkbox input with correct label (specified)', () => {
+    const element = <BoolField checkbox name="x" label="BoolFieldLabel" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find('label')).toHaveLength(2);
+    expect(wrapper.find('label').first().text()).toBe('BoolFieldLabel'); // Label is prefixed with a &nbsp;.
+});
+
+test('<BoolField> - renders a switch input with correct value (default)', () => {
     const element = <BoolField name="x" />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
@@ -61,7 +109,15 @@ test('<BoolField> - renders a input with correct value (default)', () => {
     expect(wrapper.find(Switch).prop('checked')).toBe(undefined);
 });
 
-test('<BoolField> - renders a input with correct value (model)', () => {
+test('<BoolField> - renders a checkbox input with correct value (default)', () => {
+    const element = <BoolField checkbox name="x" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+    expect(wrapper.find(Checkbox).prop('checked')).toBe(undefined);
+});
+
+test('<BoolField> - renders a switch input with correct value (model)', () => {
     const element = <BoolField name="x" />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}, {model: {x: true}}));
 
@@ -69,7 +125,15 @@ test('<BoolField> - renders a input with correct value (model)', () => {
     expect(wrapper.find(Switch).prop('checked')).toBe(true);
 });
 
-test('<BoolField> - renders a input with correct value (specified)', () => {
+test('<BoolField> - renders a checkbox input with correct value (model)', () => {
+    const element = <BoolField checkbox name="x" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}, {model: {x: true}}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+    expect(wrapper.find(Checkbox).prop('checked')).toBe(true);
+});
+
+test('<BoolField> - renders a switch input with correct value (specified)', () => {
     const element = <BoolField name="x" value />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
@@ -77,7 +141,15 @@ test('<BoolField> - renders a input with correct value (specified)', () => {
     expect(wrapper.find(Switch).prop('checked')).toBe(true);
 });
 
-test('<BoolField> - renders a input which correctly reacts on change', () => {
+test('<BoolField> - renders a checkbox input with correct value (specified)', () => {
+    const element = <BoolField checkbox name="x" value />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+    expect(wrapper.find(Checkbox).prop('checked')).toBe(true);
+});
+
+test('<BoolField> - renders a switch input which correctly reacts on change', () => {
     const onChange = jest.fn();
 
     const element = <BoolField name="x" />;
@@ -88,7 +160,18 @@ test('<BoolField> - renders a input which correctly reacts on change', () => {
     expect(onChange).toHaveBeenLastCalledWith('x', true);
 });
 
-test('<BoolField> - renders a wrapper with unknown props', () => {
+test('<BoolField> - renders a checkbox input which correctly reacts on change', () => {
+    const onChange = jest.fn();
+
+    const element = <BoolField checkbox name="x" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}, {onChange}));
+
+    expect(wrapper.find(Checkbox)).toHaveLength(1);
+    expect(wrapper.find(Checkbox).prop('onChange')()).toBeFalsy();
+    expect(onChange).toHaveBeenLastCalledWith('x', true);
+});
+
+test('<BoolField> - renders a switch wrapper with unknown props', () => {
     const element = <BoolField name="x" data-x="x" data-y="y" data-z="z" />;
     const wrapper = mount(element, createContext({x: {type: Boolean}}));
 
@@ -96,3 +179,12 @@ test('<BoolField> - renders a wrapper with unknown props', () => {
     expect(wrapper.find(Switch).prop('data-y')).toBe('y');
     expect(wrapper.find(Switch).prop('data-z')).toBe('z');
 });
+
+test('<BoolField> - renders a checkbox wrapper with unknown props', () => {
+    const element = <BoolField checkbox name="x" data-x="x" data-y="y" data-z="z" />;
+    const wrapper = mount(element, createContext({x: {type: Boolean}}));
+
+    expect(wrapper.find(Checkbox).prop('data-x')).toBe('x');
+    expect(wrapper.find(Checkbox).prop('data-y')).toBe('y');
+    expect(wrapper.find(Checkbox).prop('data-z')).toBe('z');
+});