mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 17:45:59 +00:00
b454d31ab8
Summary:According to the [docs](http://facebook.github.io/react-native/releases/0.20/docs/picker.html#onvaluechange), `Picker`'s `onValueChange` should be called with `itemValue` and `itemPosition` but currently only `itemValue` is passed. This PR fixes that. The position is passed as the 2nd parameter to not introduce any breaking change, and also to respect the current documentation. The documentation doesn't need to be changed as it will be correct with this PR, but maybe it needs to be updated until this is merged? Closes https://github.com/facebook/react-native/pull/5874 Differential Revision: D2953936 Pulled By: nicklockwood fb-gh-sync-id: b8c1283013d4c7ed315066d8750f601f76f6bbb2 shipit-source-id: b8c1283013d4c7ed315066d8750f601f76f6bbb2
128 lines
3.7 KiB
JavaScript
128 lines
3.7 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-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 PickerIOS
|
|
*
|
|
* This is a controlled component version of RCTPickerIOS
|
|
*/
|
|
'use strict';
|
|
|
|
var NativeMethodsMixin = require('NativeMethodsMixin');
|
|
var React = require('React');
|
|
var ReactChildren = require('ReactChildren');
|
|
var RCTPickerIOSConsts = require('NativeModules').UIManager.RCTPicker.Constants;
|
|
var StyleSheet = require('StyleSheet');
|
|
var StyleSheetPropType = require('StyleSheetPropType');
|
|
var TextStylePropTypes = require('TextStylePropTypes');
|
|
var View = require('View');
|
|
|
|
var itemStylePropType = StyleSheetPropType(TextStylePropTypes);
|
|
var requireNativeComponent = require('requireNativeComponent');
|
|
|
|
var PickerIOS = React.createClass({
|
|
mixins: [NativeMethodsMixin],
|
|
|
|
propTypes: {
|
|
...View.propTypes,
|
|
itemStyle: itemStylePropType,
|
|
onValueChange: React.PropTypes.func,
|
|
selectedValue: React.PropTypes.any, // string or integer basically
|
|
},
|
|
|
|
getInitialState: function() {
|
|
return this._stateFromProps(this.props);
|
|
},
|
|
|
|
componentWillReceiveProps: function(nextProps) {
|
|
this.setState(this._stateFromProps(nextProps));
|
|
},
|
|
|
|
// Translate PickerIOS prop and children into stuff that RCTPickerIOS understands.
|
|
_stateFromProps: function(props) {
|
|
var selectedIndex = 0;
|
|
var items = [];
|
|
ReactChildren.forEach(props.children, function (child, index) {
|
|
if (child.props.value === props.selectedValue) {
|
|
selectedIndex = index;
|
|
}
|
|
items.push({value: child.props.value, label: child.props.label});
|
|
});
|
|
return {selectedIndex, items};
|
|
},
|
|
|
|
render: function() {
|
|
return (
|
|
<View style={this.props.style}>
|
|
<RCTPickerIOS
|
|
ref={picker => this._picker = picker}
|
|
style={[styles.pickerIOS, this.props.itemStyle]}
|
|
items={this.state.items}
|
|
selectedIndex={this.state.selectedIndex}
|
|
onChange={this._onChange}
|
|
/>
|
|
</View>
|
|
);
|
|
},
|
|
|
|
_onChange: function(event) {
|
|
if (this.props.onChange) {
|
|
this.props.onChange(event);
|
|
}
|
|
if (this.props.onValueChange) {
|
|
this.props.onValueChange(event.nativeEvent.newValue, event.nativeEvent.newIndex);
|
|
}
|
|
|
|
// The picker is a controlled component. This means we expect the
|
|
// on*Change handlers to be in charge of updating our
|
|
// `selectedValue` prop. That way they can also
|
|
// disallow/undo/mutate the selection of certain values. In other
|
|
// words, the embedder of this component should be the source of
|
|
// truth, not the native component.
|
|
if (this._picker && this.state.selectedIndex !== event.nativeEvent.newIndex) {
|
|
this._picker.setNativeProps({
|
|
selectedIndex: this.state.selectedIndex
|
|
});
|
|
}
|
|
},
|
|
});
|
|
|
|
PickerIOS.Item = React.createClass({
|
|
propTypes: {
|
|
value: React.PropTypes.any, // string or integer basically
|
|
label: React.PropTypes.string,
|
|
},
|
|
|
|
render: function() {
|
|
// These items don't get rendered directly.
|
|
return null;
|
|
},
|
|
});
|
|
|
|
var styles = StyleSheet.create({
|
|
pickerIOS: {
|
|
// The picker will conform to whatever width is given, but we do
|
|
// have to set the component's height explicitly on the
|
|
// surrounding view to ensure it gets rendered.
|
|
height: RCTPickerIOSConsts.ComponentHeight,
|
|
},
|
|
});
|
|
|
|
var RCTPickerIOS = requireNativeComponent('RCTPicker', {
|
|
propTypes: {
|
|
style: itemStylePropType,
|
|
},
|
|
}, {
|
|
nativeOnly: {
|
|
items: true,
|
|
onChange: true,
|
|
selectedIndex: true,
|
|
},
|
|
});
|
|
|
|
module.exports = PickerIOS;
|