-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reviewed By: achen1 Differential Revision: D5281736 fbshipit-source-id: 9a3c93eeace2d80be4ddbd4ffc3258c1d3637480
- Loading branch information
1 parent
dacb1fb
commit 84b11dd
Showing
11 changed files
with
437 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/** | ||
* 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. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @providesModule CheckBox | ||
* @flow | ||
* @format | ||
*/ | ||
'use strict'; | ||
|
||
const NativeMethodsMixin = require('NativeMethodsMixin'); | ||
const PropTypes = require('prop-types'); | ||
const React = require('React'); | ||
const StyleSheet = require('StyleSheet'); | ||
const ViewPropTypes = require('ViewPropTypes'); | ||
|
||
const createReactClass = require('create-react-class'); | ||
const requireNativeComponent = require('requireNativeComponent'); | ||
|
||
type DefaultProps = { | ||
value: boolean, | ||
disabled: boolean, | ||
}; | ||
|
||
/** | ||
* Renders a boolean input. | ||
* | ||
* 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. | ||
* | ||
* @keyword checkbox | ||
* @keyword toggle | ||
*/ | ||
// $FlowFixMe(>=0.41.0) | ||
let CheckBox = createReactClass({ | ||
displayName: 'CheckBox', | ||
propTypes: { | ||
...ViewPropTypes, | ||
/** | ||
* The value of the checkbox. If true the checkbox will be turned on. | ||
* Default value is false. | ||
*/ | ||
value: PropTypes.bool, | ||
/** | ||
* If true the user won't be able to toggle the checkbox. | ||
* Default value is false. | ||
*/ | ||
disabled: PropTypes.bool, | ||
/** | ||
* Used in case the props change removes the component. | ||
*/ | ||
onChange: PropTypes.func, | ||
/** | ||
* Invoked with the new value when the value changes. | ||
*/ | ||
onValueChange: PropTypes.func, | ||
/** | ||
* Used to locate this view in end-to-end tests. | ||
*/ | ||
testID: PropTypes.string, | ||
}, | ||
|
||
getDefaultProps: function(): DefaultProps { | ||
return { | ||
value: false, | ||
disabled: false, | ||
}; | ||
}, | ||
|
||
mixins: [NativeMethodsMixin], | ||
|
||
_rctCheckBox: {}, | ||
_onChange: function(event: Object) { | ||
this._rctCheckBox.setNativeProps({value: this.props.value}); | ||
// Change the props after the native props are set in case the props | ||
// change removes the component | ||
this.props.onChange && this.props.onChange(event); | ||
this.props.onValueChange && | ||
this.props.onValueChange(event.nativeEvent.value); | ||
}, | ||
|
||
render: function() { | ||
let props = {...this.props}; | ||
props.onStartShouldSetResponder = () => true; | ||
props.onResponderTerminationRequest = () => false; | ||
props.enabled = !this.props.disabled; | ||
props.on = this.props.value; | ||
props.style = [styles.rctCheckBox, this.props.style]; | ||
|
||
return ( | ||
<RCTCheckBox | ||
{...props} | ||
ref={ref => { | ||
/* $FlowFixMe(>=0.53.0 site=react_native_fb) This comment suppresses an | ||
* error when upgrading Flow's support for React. Common errors found | ||
* when upgrading Flow's React support are documented at | ||
* https://fburl.com/eq7bs81w */ | ||
this._rctCheckBox = ref; | ||
}} | ||
onChange={this._onChange} | ||
/> | ||
); | ||
}, | ||
}); | ||
|
||
let styles = StyleSheet.create({ | ||
rctCheckBox: { | ||
height: 32, | ||
width: 32, | ||
}, | ||
}); | ||
|
||
let RCTCheckBox = requireNativeComponent('AndroidCheckBox', CheckBox, { | ||
nativeOnly: { | ||
onChange: true, | ||
on: true, | ||
enabled: true, | ||
}, | ||
}); | ||
|
||
module.exports = CheckBox; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/** | ||
* 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. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @flow | ||
* @providesModule CheckBoxExample | ||
* @format | ||
*/ | ||
'use strict'; | ||
|
||
const React = require('react'); | ||
const ReactNative = require('react-native'); | ||
const {CheckBox, Text, View} = ReactNative; | ||
|
||
class BasicCheckBoxExample extends React.Component<{}, $FlowFixMeState> { | ||
state = { | ||
trueCheckBoxIsOn: true, | ||
falseCheckBoxIsOn: false, | ||
}; | ||
|
||
render() { | ||
return ( | ||
<View> | ||
<CheckBox | ||
onValueChange={value => this.setState({falseCheckBoxIsOn: value})} | ||
style={{marginBottom: 10}} | ||
value={this.state.falseCheckBoxIsOn} | ||
/> | ||
<CheckBox | ||
onValueChange={value => this.setState({trueCheckBoxIsOn: value})} | ||
value={this.state.trueCheckBoxIsOn} | ||
/> | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
class DisabledCheckBoxExample extends React.Component<{}, $FlowFixMeState> { | ||
render() { | ||
return ( | ||
<View> | ||
<CheckBox disabled={true} style={{marginBottom: 10}} value={true} /> | ||
<CheckBox disabled={true} value={false} /> | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
class EventCheckBoxExample extends React.Component<{}, $FlowFixMeState> { | ||
state = { | ||
eventCheckBoxIsOn: false, | ||
eventCheckBoxRegressionIsOn: true, | ||
}; | ||
|
||
render() { | ||
return ( | ||
<View style={{flexDirection: 'row', justifyContent: 'space-around'}}> | ||
<View> | ||
<CheckBox | ||
onValueChange={value => this.setState({eventCheckBoxIsOn: value})} | ||
style={{marginBottom: 10}} | ||
value={this.state.eventCheckBoxIsOn} | ||
/> | ||
<CheckBox | ||
onValueChange={value => this.setState({eventCheckBoxIsOn: value})} | ||
style={{marginBottom: 10}} | ||
value={this.state.eventCheckBoxIsOn} | ||
/> | ||
<Text> | ||
{this.state.eventCheckBoxIsOn ? 'On' : 'Off'} | ||
</Text> | ||
</View> | ||
<View> | ||
<CheckBox | ||
onValueChange={value => | ||
this.setState({eventCheckBoxRegressionIsOn: value})} | ||
style={{marginBottom: 10}} | ||
value={this.state.eventCheckBoxRegressionIsOn} | ||
/> | ||
<CheckBox | ||
onValueChange={value => | ||
this.setState({eventCheckBoxRegressionIsOn: value})} | ||
style={{marginBottom: 10}} | ||
value={this.state.eventCheckBoxRegressionIsOn} | ||
/> | ||
<Text> | ||
{this.state.eventCheckBoxRegressionIsOn ? 'On' : 'Off'} | ||
</Text> | ||
</View> | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
let examples = [ | ||
{ | ||
title: 'CheckBoxes can be set to true or false', | ||
render(): React.Element<any> { | ||
return <BasicCheckBoxExample />; | ||
}, | ||
}, | ||
{ | ||
title: 'CheckBoxes can be disabled', | ||
render(): React.Element<any> { | ||
return <DisabledCheckBoxExample />; | ||
}, | ||
}, | ||
{ | ||
title: 'Change events can be detected', | ||
render(): React.Element<any> { | ||
return <EventCheckBoxExample />; | ||
}, | ||
}, | ||
{ | ||
title: 'CheckBoxes are controlled components', | ||
render(): React.Element<any> { | ||
return <CheckBox />; | ||
}, | ||
}, | ||
]; | ||
|
||
exports.title = '<CheckBox>'; | ||
exports.displayName = 'CheckBoxExample'; | ||
exports.description = 'Native boolean input'; | ||
exports.examples = examples; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
ReactAndroid/src/main/java/com/facebook/react/views/checkbox/BUCK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
include_defs("//ReactAndroid/DEFS") | ||
|
||
android_library( | ||
name = "checkbox", | ||
srcs = glob(["*.java"]), | ||
visibility = [ | ||
"PUBLIC", | ||
], | ||
deps = [ | ||
react_native_dep("third-party/android/support/v4:lib-support-v4"), | ||
react_native_dep("third-party/java/jsr-305:jsr-305"), | ||
react_native_target("java/com/facebook/react/bridge:bridge"), | ||
react_native_target("java/com/facebook/react/common:common"), | ||
react_native_target("java/com/facebook/react/uimanager:uimanager"), | ||
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"), | ||
], | ||
) |
38 changes: 38 additions & 0 deletions
38
ReactAndroid/src/main/java/com/facebook/react/views/checkbox/ReactCheckBox.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/** | ||
* Copyright (c) 2017-present, Facebook, Inc. All rights reserved. | ||
* | ||
* <p>This source code is licensed under the BSD-style license found in the LICENSE file in the root | ||
* directory of this source tree. An additional grant of patent rights can be found in the PATENTS | ||
* file in the same directory. | ||
*/ | ||
package com.facebook.react.views.checkbox; | ||
|
||
import android.content.Context; | ||
import android.widget.CheckBox; | ||
|
||
/** CheckBox that has its value controlled by JS. */ | ||
/*package*/ class ReactCheckBox extends CheckBox { | ||
|
||
private boolean mAllowChange; | ||
|
||
public ReactCheckBox(Context context) { | ||
super(context); | ||
mAllowChange = true; | ||
} | ||
|
||
@Override | ||
public void setChecked(boolean checked) { | ||
if (mAllowChange) { | ||
mAllowChange = false; | ||
super.setChecked(checked); | ||
} | ||
} | ||
|
||
/*package*/ void setOn(boolean on) { | ||
// If the checkbox has a different value than the value sent by JS, we must change it. | ||
if (isChecked() != on) { | ||
super.setChecked(on); | ||
} | ||
mAllowChange = true; | ||
} | ||
} |
Oops, something went wrong.