diff --git a/docs/storybook/1-components/CheckBox/CheckBoxScreen.js b/docs/storybook/1-components/CheckBox/CheckBoxScreen.js new file mode 100644 index 00000000..b1fe55ce --- /dev/null +++ b/docs/storybook/1-components/CheckBox/CheckBoxScreen.js @@ -0,0 +1,93 @@ +/* eslint-disable react/jsx-sort-props */ + +/** + * @flow + */ + +import CustomSize from './examples/CustomSize'; +import PropColor from './examples/PropColor'; +import PropDisabled from './examples/PropDisabled'; +import PropOnValueChange from './examples/PropOnValueChange'; +import PropValue from './examples/PropValue'; +import React from 'react'; +import UIExplorer, { + AppText, + Code, + Description, + DocItem, + Section, + storiesOf +} from '../../ui-explorer'; + +const CheckBoxScreen = () => ( + + + + This is a controlled component that requires an onValueChange callback that + updates the value prop in order for the component to reflect user actions. If the{' '} + value prop is not updated, the component will continue to render the supplied{' '} + value prop instead of the expected result of any user actions. + + + +
+ + + + }} + label="web" + name="color" + typeInfo="?color" + /> + + + }} + name="disabled" + typeInfo="?boolean = false" + /> + + + + + }} + name="onValueChange" + typeInfo="?function" + /> + + + }} + name="value" + typeInfo="?boolean = false" + /> +
+ +
+ ', + render: () => + }} + name="Custom size" + /> +
+
+); + +storiesOf('Components', module).add('CheckBox', CheckBoxScreen); diff --git a/docs/storybook/1-components/CheckBox/examples/CustomSize.js b/docs/storybook/1-components/CheckBox/examples/CustomSize.js new file mode 100644 index 00000000..8c0807ad --- /dev/null +++ b/docs/storybook/1-components/CheckBox/examples/CustomSize.js @@ -0,0 +1,20 @@ +/** + * @flow + */ + +import React from 'react'; +import styles from './styles'; +import { CheckBox, View } from 'react-native'; + +const CustomSizeExample = () => ( + + + + + + + + +); + +export default CustomSizeExample; diff --git a/docs/storybook/1-components/CheckBox/examples/PropColor.js b/docs/storybook/1-components/CheckBox/examples/PropColor.js new file mode 100644 index 00000000..aaf530a9 --- /dev/null +++ b/docs/storybook/1-components/CheckBox/examples/PropColor.js @@ -0,0 +1,20 @@ +/** + * @flow + */ + +import React from 'react'; +import styles from './styles'; +import { CheckBox, View } from 'react-native'; + +const CheckBoxColorExample = () => ( + + + + + + + + +); + +export default CheckBoxColorExample; diff --git a/docs/storybook/1-components/CheckBox/examples/PropDisabled.js b/docs/storybook/1-components/CheckBox/examples/PropDisabled.js new file mode 100755 index 00000000..86aa0a77 --- /dev/null +++ b/docs/storybook/1-components/CheckBox/examples/PropDisabled.js @@ -0,0 +1,20 @@ +/** + * @flow + */ + +import React from 'react'; +import styles from './styles'; +import { CheckBox, View } from 'react-native'; + +const CheckBoxDisabledExample = () => ( + + + + + + + + +); + +export default CheckBoxDisabledExample; diff --git a/docs/storybook/1-components/CheckBox/examples/PropOnValueChange.js b/docs/storybook/1-components/CheckBox/examples/PropOnValueChange.js new file mode 100755 index 00000000..aeb10620 --- /dev/null +++ b/docs/storybook/1-components/CheckBox/examples/PropOnValueChange.js @@ -0,0 +1,59 @@ +/** + * @flow + */ + +import styles from './styles'; +import React, { PureComponent } from 'react'; +import { CheckBox, Text, View } from 'react-native'; + +class CheckBoxOnValueChangeExample extends PureComponent { + state = { + eventSwitchIsOn: false, + eventSwitchRegressionIsOn: true + }; + + render() { + const { eventSwitchIsOn, eventSwitchRegressionIsOn } = this.state; + + return ( + + + + + {eventSwitchIsOn ? 'On' : 'Off'} + + + + + {eventSwitchRegressionIsOn ? 'On' : 'Off'} + + + ); + } + + _handleEventSwitch = value => { + this.setState({ eventSwitchIsOn: value }); + }; + + _handleEventSwitchRegression = value => { + this.setState({ eventSwitchRegressionIsOn: value }); + }; +} + +export default CheckBoxOnValueChangeExample; diff --git a/docs/storybook/1-components/CheckBox/examples/PropValue.js b/docs/storybook/1-components/CheckBox/examples/PropValue.js new file mode 100755 index 00000000..7f368f1c --- /dev/null +++ b/docs/storybook/1-components/CheckBox/examples/PropValue.js @@ -0,0 +1,20 @@ +/** + * @flow + */ + +import React from 'react'; +import styles from './styles'; +import { CheckBox, View } from 'react-native'; + +const CheckBoxValueExample = () => ( + + + + + + + + +); + +export default CheckBoxValueExample; diff --git a/docs/storybook/1-components/CheckBox/examples/styles.js b/docs/storybook/1-components/CheckBox/examples/styles.js new file mode 100755 index 00000000..e0a2f08f --- /dev/null +++ b/docs/storybook/1-components/CheckBox/examples/styles.js @@ -0,0 +1,23 @@ +/** + * @flow + */ + +import { StyleSheet } from 'react-native'; + +const styles = StyleSheet.create({ + row: { + flexDirection: 'row', + flexWrap: 'wrap' + }, + marginRight: { + marginRight: 10 + }, + marginBottom: { + marginBottom: 10 + }, + alignCenter: { + alignItems: 'center' + } +}); + +export default styles; diff --git a/docs/storybook/1-components/CheckBox/helpers.js b/docs/storybook/1-components/CheckBox/helpers.js new file mode 100644 index 00000000..7b87cf0e --- /dev/null +++ b/docs/storybook/1-components/CheckBox/helpers.js @@ -0,0 +1,36 @@ +/** + * @flow + */ + +import React from 'react'; +import { StyleSheet, View } from 'react-native'; + +const DividerHorizontal = () => ; +const DividerVertical = () => ; + +export const styles = StyleSheet.create({ + horizontalDivider: { + width: '0.6rem' + }, + verticalDivider: { + height: '1.3125rem' + }, + row: { + flexDirection: 'row', + flexWrap: 'wrap' + }, + marginRight: { + marginRight: 10 + }, + marginBottom: { + marginBottom: 10 + }, + marginVertical: { + marginVertical: 5 + }, + alignCenter: { + alignItems: 'center' + } +}); + +export { DividerHorizontal, DividerVertical }; diff --git a/src/apis/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap b/src/apis/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap index f4b61597..b8d66b98 100644 --- a/src/apis/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap +++ b/src/apis/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap @@ -39,6 +39,9 @@ exports[`apis/AppRegistry/renderApplication getApplication 3`] = ` .rn-backgroundColor-wib322{background-color:transparent} .rn-backgroundColor-8ndhhv{background-color:rgba(33,150,243,1)} .rn-backgroundColor-15al3ab{background-color:rgba(223,223,223,1)} +.rn-backgroundColor-44z8sh{background-color:rgba(255,255,255,1)} +.rn-backgroundColor-5itogg{background-color:rgba(0,150,136,1)} +.rn-backgroundColor-1v82r4u{background-color:rgba(170,184,194,1)} .rn-backgroundColor-1hj8efq{background-color:rgba(213,213,213,1)} .rn-backgroundColor-1bgzomc{background-color:rgba(189,189,189,1)} .rn-color-homxoj{color:inherit} @@ -56,9 +59,13 @@ exports[`apis/AppRegistry/renderApplication getApplication 3`] = ` .rn-borderBottomStyle-rull8r{border-bottom-style:solid} .rn-borderLeftStyle-mm0ijv{border-left-style:solid} .rn-borderTopWidth-13yce4e{border-top-width:0px} +.rn-borderTopWidth-1jxfwug{border-top-width:2px} .rn-borderRightWidth-fnigne{border-right-width:0px} +.rn-borderRightWidth-18p6if4{border-right-width:2px} .rn-borderBottomWidth-ndvcnb{border-bottom-width:0px} +.rn-borderBottomWidth-wgabs5{border-bottom-width:2px} .rn-borderLeftWidth-gxnn5r{border-left-width:0px} +.rn-borderLeftWidth-dwliz8{border-left-width:2px} .rn-boxSizing-deolkf{box-sizing:border-box} .rn-display-6koalj{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex} .rn-display-xoduu5{display:-webkit-inline-box;display:-moz-inline-box;display:-ms-inline-flexbox;display:-webkit-inline-flex;display:inline-flex} @@ -98,6 +105,7 @@ exports[`apis/AppRegistry/renderApplication getApplication 3`] = ` .rn-height-1pi2tsx{height:100%} .rn-height-z80fyv{height:20px} .rn-height-1r8g8re{height:36px} +.rn-height-10ptun7{height:16px} .rn-height-4v7adb{height:5px} .rn-height-1dernwh{height:70%} .rn-opacity-1272l3b{opacity:0} @@ -105,6 +113,7 @@ exports[`apis/AppRegistry/renderApplication getApplication 3`] = ` .rn-width-13qz1uu{width:100%} .rn-width-19wmn03{width:20px} .rn-width-1acpoxo{width:36px} +.rn-width-1janqcz{width:16px} .rn-touchAction-19z077z{-ms-touch-action:none;touch-action:none} .rn-touchAction-1gvxusu{-ms-touch-action:manipulate;touch-action:manipulate} .rn-WebkitOverflowScrolling-150rngu{-webkit-overflow-scrolling:touch} @@ -152,11 +161,28 @@ exports[`apis/AppRegistry/renderApplication getApplication 3`] = ` .rn-borderBottomLeftRadius-pm2fo{border-bottom-left-radius:0px} .rn-fontWeight-majxgm{font-weight:500} .rn-textTransform-tsynxw{text-transform:uppercase} +.rn-borderTopColor-j4x2lb{border-top-color:rgba(101,119,134,1)} +.rn-borderTopColor-gj2eto{border-top-color:rgba(0,150,136,1)} +.rn-borderTopColor-1j7vz2b{border-top-color:rgba(204,214,221,1)} +.rn-borderTopColor-2dclza{border-top-color:rgba(170,184,194,1)} +.rn-borderTopColor-kqr9px{border-top-color:black} +.rn-borderRightColor-12i18q1{border-right-color:rgba(101,119,134,1)} +.rn-borderRightColor-31ud7z{border-right-color:rgba(0,150,136,1)} +.rn-borderRightColor-10fg1ub{border-right-color:rgba(204,214,221,1)} +.rn-borderRightColor-8jf312{border-right-color:rgba(170,184,194,1)} +.rn-borderRightColor-q0dj5p{border-right-color:black} +.rn-borderBottomColor-mg3rfb{border-bottom-color:rgba(101,119,134,1)} +.rn-borderBottomColor-1bgnb8i{border-bottom-color:rgba(0,150,136,1)} +.rn-borderBottomColor-zxuuv6{border-bottom-color:rgba(204,214,221,1)} +.rn-borderBottomColor-1yeakrt{border-bottom-color:rgba(170,184,194,1)} +.rn-borderBottomColor-1ah7hsa{border-bottom-color:black} +.rn-borderLeftColor-vnhemr{border-left-color:rgba(101,119,134,1)} +.rn-borderLeftColor-tbzcuz{border-left-color:rgba(0,150,136,1)} +.rn-borderLeftColor-1p34dw6{border-left-color:rgba(204,214,221,1)} +.rn-borderLeftColor-bluj2i{border-left-color:rgba(170,184,194,1)} +.rn-borderLeftColor-137uh4u{border-left-color:black} +.rn-backgroundImage-rs94m5{background-image:url(\\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K\\")} .rn-alignSelf-k200y{-ms-flex-item-align:start;-webkit-align-self:flex-start;align-self:flex-start} .rn-boxShadow-1ewcgjf{box-shadow:0px 1px 3px rgba(0,0,0,0.5)} -.rn-borderTopColor-kqr9px{border-top-color:black} -.rn-borderRightColor-q0dj5p{border-right-color:black} -.rn-borderBottomColor-1ah7hsa{border-bottom-color:black} -.rn-borderLeftColor-137uh4u{border-left-color:black} .rn-resize-1dz5y72{resize:none}" `; diff --git a/src/apis/StyleSheet/__tests__/__snapshots__/index-test.js.snap b/src/apis/StyleSheet/__tests__/__snapshots__/index-test.js.snap index 6faaa0f7..acc3f418 100644 --- a/src/apis/StyleSheet/__tests__/__snapshots__/index-test.js.snap +++ b/src/apis/StyleSheet/__tests__/__snapshots__/index-test.js.snap @@ -34,6 +34,9 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit .rn-backgroundColor-wib322{background-color:transparent} .rn-backgroundColor-8ndhhv{background-color:rgba(33,150,243,1)} .rn-backgroundColor-15al3ab{background-color:rgba(223,223,223,1)} +.rn-backgroundColor-44z8sh{background-color:rgba(255,255,255,1)} +.rn-backgroundColor-5itogg{background-color:rgba(0,150,136,1)} +.rn-backgroundColor-1v82r4u{background-color:rgba(170,184,194,1)} .rn-backgroundColor-1hj8efq{background-color:rgba(213,213,213,1)} .rn-backgroundColor-1bgzomc{background-color:rgba(189,189,189,1)} .rn-color-homxoj{color:inherit} @@ -51,9 +54,13 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit .rn-borderBottomStyle-rull8r{border-bottom-style:solid} .rn-borderLeftStyle-mm0ijv{border-left-style:solid} .rn-borderTopWidth-13yce4e{border-top-width:0px} +.rn-borderTopWidth-1jxfwug{border-top-width:2px} .rn-borderRightWidth-fnigne{border-right-width:0px} +.rn-borderRightWidth-18p6if4{border-right-width:2px} .rn-borderBottomWidth-ndvcnb{border-bottom-width:0px} +.rn-borderBottomWidth-wgabs5{border-bottom-width:2px} .rn-borderLeftWidth-gxnn5r{border-left-width:0px} +.rn-borderLeftWidth-dwliz8{border-left-width:2px} .rn-boxSizing-deolkf{box-sizing:border-box} .rn-display-6koalj{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex} .rn-display-xoduu5{display:-webkit-inline-box;display:-moz-inline-box;display:-ms-inline-flexbox;display:-webkit-inline-flex;display:inline-flex} @@ -93,6 +100,7 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit .rn-height-1pi2tsx{height:100%} .rn-height-z80fyv{height:20px} .rn-height-1r8g8re{height:36px} +.rn-height-10ptun7{height:16px} .rn-height-4v7adb{height:5px} .rn-height-1dernwh{height:70%} .rn-opacity-1272l3b{opacity:0} @@ -100,6 +108,7 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit .rn-width-13qz1uu{width:100%} .rn-width-19wmn03{width:20px} .rn-width-1acpoxo{width:36px} +.rn-width-1janqcz{width:16px} .rn-touchAction-19z077z{-ms-touch-action:none;touch-action:none} .rn-touchAction-1gvxusu{-ms-touch-action:manipulate;touch-action:manipulate} .rn-WebkitOverflowScrolling-150rngu{-webkit-overflow-scrolling:touch} @@ -147,12 +156,29 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit .rn-borderBottomLeftRadius-pm2fo{border-bottom-left-radius:0px} .rn-fontWeight-majxgm{font-weight:500} .rn-textTransform-tsynxw{text-transform:uppercase} +.rn-borderTopColor-j4x2lb{border-top-color:rgba(101,119,134,1)} +.rn-borderTopColor-gj2eto{border-top-color:rgba(0,150,136,1)} +.rn-borderTopColor-1j7vz2b{border-top-color:rgba(204,214,221,1)} +.rn-borderTopColor-2dclza{border-top-color:rgba(170,184,194,1)} +.rn-borderTopColor-kqr9px{border-top-color:black} +.rn-borderRightColor-12i18q1{border-right-color:rgba(101,119,134,1)} +.rn-borderRightColor-31ud7z{border-right-color:rgba(0,150,136,1)} +.rn-borderRightColor-10fg1ub{border-right-color:rgba(204,214,221,1)} +.rn-borderRightColor-8jf312{border-right-color:rgba(170,184,194,1)} +.rn-borderRightColor-q0dj5p{border-right-color:black} +.rn-borderBottomColor-mg3rfb{border-bottom-color:rgba(101,119,134,1)} +.rn-borderBottomColor-1bgnb8i{border-bottom-color:rgba(0,150,136,1)} +.rn-borderBottomColor-zxuuv6{border-bottom-color:rgba(204,214,221,1)} +.rn-borderBottomColor-1yeakrt{border-bottom-color:rgba(170,184,194,1)} +.rn-borderBottomColor-1ah7hsa{border-bottom-color:black} +.rn-borderLeftColor-vnhemr{border-left-color:rgba(101,119,134,1)} +.rn-borderLeftColor-tbzcuz{border-left-color:rgba(0,150,136,1)} +.rn-borderLeftColor-1p34dw6{border-left-color:rgba(204,214,221,1)} +.rn-borderLeftColor-bluj2i{border-left-color:rgba(170,184,194,1)} +.rn-borderLeftColor-137uh4u{border-left-color:black} +.rn-backgroundImage-rs94m5{background-image:url(\\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K\\")} .rn-alignSelf-k200y{-ms-flex-item-align:start;-webkit-align-self:flex-start;align-self:flex-start} .rn-boxShadow-1ewcgjf{box-shadow:0px 1px 3px rgba(0,0,0,0.5)} -.rn-borderTopColor-kqr9px{border-top-color:black} -.rn-borderRightColor-q0dj5p{border-right-color:black} -.rn-borderBottomColor-1ah7hsa{border-bottom-color:black} -.rn-borderLeftColor-137uh4u{border-left-color:black} .rn-resize-1dz5y72{resize:none}", }, ] diff --git a/src/components/CheckBox/__tests__/index-test.js b/src/components/CheckBox/__tests__/index-test.js new file mode 100644 index 00000000..7f443762 --- /dev/null +++ b/src/components/CheckBox/__tests__/index-test.js @@ -0,0 +1,60 @@ +/* eslint-env jest */ + +import CheckBox from '../'; +import React from 'react'; +import { shallow } from 'enzyme'; + +const checkboxSelector = 'input[type="checkbox"]'; + +describe('CheckBox', () => { + describe('disabled', () => { + test('when "false" a default checkbox is rendered', () => { + const component = shallow(); + expect(component.find(checkboxSelector).prop('disabled')).toBe(false); + }); + + test('when "true" a disabled checkbox is rendered', () => { + const component = shallow(); + expect(component.find(checkboxSelector).prop('disabled')).toBe(true); + }); + }); + + describe('onChange', () => { + test('is called with the event object', () => { + const onChange = jest.fn(); + const component = shallow(); + component.find('input').simulate('change', { nativeEvent: { target: { checked: true } } }); + expect(onChange).toHaveBeenCalledWith({ + nativeEvent: { target: { checked: true }, value: true } + }); + }); + }); + + describe('onValueChange', () => { + test('when value is "false" it receives "true"', () => { + const onValueChange = jest.fn(); + const component = shallow(); + component.find('input').simulate('change', { nativeEvent: { target: { checked: true } } }); + expect(onValueChange).toHaveBeenCalledWith(true); + }); + + test('when value is "true" it receives "false"', () => { + const onValueChange = jest.fn(); + const component = shallow(); + component.find('input').simulate('change', { nativeEvent: { target: { checked: false } } }); + expect(onValueChange).toHaveBeenCalledWith(false); + }); + }); + + describe('value', () => { + test('when "false" an unchecked checkbox is rendered', () => { + const component = shallow(); + expect(component.find(checkboxSelector).prop('checked')).toBe(false); + }); + + test('when "true" a checked checkbox is rendered', () => { + const component = shallow(); + expect(component.find(checkboxSelector).prop('checked')).toBe(true); + }); + }); +}); diff --git a/src/components/CheckBox/index.js b/src/components/CheckBox/index.js new file mode 100644 index 00000000..81aed826 --- /dev/null +++ b/src/components/CheckBox/index.js @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2017-present, Nicolas Gallagher. + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + * + * @providesModule CheckBox + * @flow + */ + +import applyNativeMethods from '../../modules/applyNativeMethods'; +import ColorPropType from '../../propTypes/ColorPropType'; +import createElement from '../../modules/createElement'; +import StyleSheet from '../../apis/StyleSheet'; +import UIManager from '../../apis/UIManager'; +import View from '../View'; +import ViewPropTypes, { type ViewProps } from '../View/ViewPropTypes'; +import React, { Component } from 'react'; +import { bool, func } from 'prop-types'; + +type Props = ViewProps & { + color?: ColorPropType, + disabled?: boolean, + onChange?: Function, + onValueChange?: Function, + value?: boolean +}; + +class CheckBox extends Component { + _checkboxElement: HTMLInputElement; + + static displayName = 'CheckBox'; + + static propTypes = { + ...ViewPropTypes, + color: ColorPropType, + disabled: bool, + onChange: func, + onValueChange: func, + value: bool + }; + + static defaultProps = { + disabled: false, + value: false + }; + + blur() { + UIManager.blur(this._checkboxElement); + } + + focus() { + UIManager.focus(this._checkboxElement); + } + + render() { + const { + color, + disabled, + /* eslint-disable */ + onChange, + onValueChange, + /* eslint-enable */ + style, + value, + ...other + } = this.props; + + const fakeControl = ( + + ); + + const nativeControl = createElement('input', { + checked: value, + disabled: disabled, + onChange: this._handleChange, + ref: this._setCheckboxRef, + style: [styles.nativeControl, styles.cursorInherit], + type: 'checkbox' + }); + + return ( + + {fakeControl} + {nativeControl} + + ); + } + + _handleChange = (event: Object) => { + const { onChange, onValueChange } = this.props; + const value = event.nativeEvent.target.checked; + event.nativeEvent.value = value; + onChange && onChange(event); + onValueChange && onValueChange(value); + }; + + _setCheckboxRef = element => { + this._checkboxElement = element; + }; +} + +const styles = StyleSheet.create({ + root: { + cursor: 'pointer', + height: 16, + userSelect: 'none', + width: 16 + }, + cursorDefault: { + cursor: 'default' + }, + cursorInherit: { + cursor: 'inherit' + }, + fakeControl: { + alignItems: 'center', + backgroundColor: '#fff', + borderColor: '#657786', + borderRadius: 2, + borderStyle: 'solid', + borderWidth: 2, + height: '100%', + justifyContent: 'center', + width: '100%' + }, + fakeControlChecked: { + backgroundColor: '#009688', + backgroundImage: + 'url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")', + backgroundRepeat: 'no-repeat', + borderColor: '#009688' + }, + fakeControlDisabled: { + borderColor: '#CCD6DD' + }, + fakeControlCheckedAndDisabled: { + backgroundColor: '#AAB8C2', + borderColor: '#AAB8C2' + }, + nativeControl: { + ...StyleSheet.absoluteFillObject, + height: '100%', + margin: 0, + opacity: 0, + padding: 0, + width: '100%' + } +}); + +export default applyNativeMethods(CheckBox); diff --git a/src/components/Switch/index.js b/src/components/Switch/index.js index 999138c6..5f304b55 100644 --- a/src/components/Switch/index.js +++ b/src/components/Switch/index.js @@ -1,4 +1,10 @@ /** + * Copyright (c) 2016-present, Nicolas Gallagher. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + * * @providesModule Switch * @flow */ diff --git a/src/module.js b/src/module.js index 5b927a66..f0ac07fa 100644 --- a/src/module.js +++ b/src/module.js @@ -30,6 +30,7 @@ import Vibration from './apis/Vibration'; import ActivityIndicator from './components/ActivityIndicator'; import ART from './components/ART'; import Button from './components/Button'; +import CheckBox from './components/CheckBox'; import FlatList from './components/FlatList'; import Image from './components/Image'; import ImageBackground from './components/Image/ImageBackground'; @@ -95,6 +96,7 @@ export { ActivityIndicator, ART, Button, + CheckBox, FlatList, Image, ImageBackground, @@ -163,6 +165,7 @@ const ReactNative = { ActivityIndicator, ART, Button, + CheckBox, FlatList, Image, ImageBackground,