2015-03-10 19:11:28 -07:00
|
|
|
/**
|
2015-03-23 15:07:33 -07:00
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
*
|
2018-02-16 18:24:55 -08:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2015-03-10 19:11:28 -07:00
|
|
|
*
|
|
|
|
* @providesModule PickerIOS
|
|
|
|
*
|
2015-03-17 13:42:44 -07:00
|
|
|
* This is a controlled component version of RCTPickerIOS
|
2015-03-10 19:11:28 -07:00
|
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
|
2018-03-03 15:04:46 -08:00
|
|
|
const NativeMethodsMixin = require('NativeMethodsMixin');
|
|
|
|
const React = require('React');
|
2017-04-12 16:09:48 -07:00
|
|
|
const PropTypes = require('prop-types');
|
2018-03-03 15:04:46 -08:00
|
|
|
const StyleSheet = require('StyleSheet');
|
|
|
|
const StyleSheetPropType = require('StyleSheetPropType');
|
|
|
|
const TextStylePropTypes = require('TextStylePropTypes');
|
|
|
|
const View = require('View');
|
2017-03-24 00:22:57 -07:00
|
|
|
const ViewPropTypes = require('ViewPropTypes');
|
2018-03-03 15:04:46 -08:00
|
|
|
const processColor = require('processColor');
|
2015-03-10 19:11:28 -07:00
|
|
|
|
2018-03-03 15:04:46 -08:00
|
|
|
const createReactClass = require('create-react-class');
|
|
|
|
const itemStylePropType = StyleSheetPropType(TextStylePropTypes);
|
|
|
|
const requireNativeComponent = require('requireNativeComponent');
|
2015-03-10 19:11:28 -07:00
|
|
|
|
2018-03-03 15:04:46 -08:00
|
|
|
const PickerIOS = createReactClass({
|
2017-07-07 14:24:25 -07:00
|
|
|
displayName: 'PickerIOS',
|
2015-03-10 19:11:28 -07:00
|
|
|
mixins: [NativeMethodsMixin],
|
|
|
|
|
|
|
|
propTypes: {
|
2017-03-24 00:22:57 -07:00
|
|
|
...ViewPropTypes,
|
2015-12-08 07:44:56 -08:00
|
|
|
itemStyle: itemStylePropType,
|
2017-04-12 16:09:48 -07:00
|
|
|
onValueChange: PropTypes.func,
|
|
|
|
selectedValue: PropTypes.any, // string or integer basically
|
2015-03-10 19:11:28 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
getInitialState: function() {
|
|
|
|
return this._stateFromProps(this.props);
|
|
|
|
},
|
|
|
|
|
2018-02-08 10:26:45 -08:00
|
|
|
UNSAFE_componentWillReceiveProps: function(nextProps) {
|
2015-03-10 19:11:28 -07:00
|
|
|
this.setState(this._stateFromProps(nextProps));
|
|
|
|
},
|
|
|
|
|
2015-03-17 13:42:44 -07:00
|
|
|
// Translate PickerIOS prop and children into stuff that RCTPickerIOS understands.
|
2015-03-10 19:11:28 -07:00
|
|
|
_stateFromProps: function(props) {
|
2018-03-03 15:04:46 -08:00
|
|
|
let selectedIndex = 0;
|
|
|
|
const items = [];
|
2016-10-14 18:50:19 -07:00
|
|
|
React.Children.toArray(props.children).forEach(function (child, index) {
|
2015-03-10 19:11:28 -07:00
|
|
|
if (child.props.value === props.selectedValue) {
|
|
|
|
selectedIndex = index;
|
|
|
|
}
|
2016-12-03 18:46:20 -08:00
|
|
|
items.push({
|
|
|
|
value: child.props.value,
|
|
|
|
label: child.props.label,
|
|
|
|
textColor: processColor(child.props.color),
|
|
|
|
});
|
2015-03-10 19:11:28 -07:00
|
|
|
});
|
|
|
|
return {selectedIndex, items};
|
|
|
|
},
|
2016-02-19 06:49:41 -08:00
|
|
|
|
2015-03-10 19:11:28 -07:00
|
|
|
render: function() {
|
|
|
|
return (
|
|
|
|
<View style={this.props.style}>
|
2015-03-17 13:42:44 -07:00
|
|
|
<RCTPickerIOS
|
2015-12-08 07:44:56 -08:00
|
|
|
ref={picker => this._picker = picker}
|
|
|
|
style={[styles.pickerIOS, this.props.itemStyle]}
|
2015-03-10 19:11:28 -07:00
|
|
|
items={this.state.items}
|
|
|
|
selectedIndex={this.state.selectedIndex}
|
|
|
|
onChange={this._onChange}
|
2016-11-07 18:01:09 -08:00
|
|
|
onStartShouldSetResponder={() => true}
|
|
|
|
onResponderTerminationRequest={() => false}
|
2015-03-10 19:11:28 -07:00
|
|
|
/>
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
_onChange: function(event) {
|
|
|
|
if (this.props.onChange) {
|
|
|
|
this.props.onChange(event);
|
|
|
|
}
|
|
|
|
if (this.props.onValueChange) {
|
2016-02-19 06:49:41 -08:00
|
|
|
this.props.onValueChange(event.nativeEvent.newValue, event.nativeEvent.newIndex);
|
2015-03-10 19:11:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
2015-12-04 06:56:41 -08:00
|
|
|
if (this._picker && this.state.selectedIndex !== event.nativeEvent.newIndex) {
|
|
|
|
this._picker.setNativeProps({
|
2015-03-10 19:11:28 -07:00
|
|
|
selectedIndex: this.state.selectedIndex
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2016-07-26 01:00:02 -07:00
|
|
|
PickerIOS.Item = class extends React.Component {
|
|
|
|
static propTypes = {
|
2017-04-12 16:09:48 -07:00
|
|
|
value: PropTypes.any, // string or integer basically
|
|
|
|
label: PropTypes.string,
|
|
|
|
color: PropTypes.string,
|
2016-07-26 01:00:02 -07:00
|
|
|
};
|
2015-03-10 19:11:28 -07:00
|
|
|
|
2016-07-26 01:00:02 -07:00
|
|
|
render() {
|
2015-03-10 19:11:28 -07:00
|
|
|
// These items don't get rendered directly.
|
|
|
|
return null;
|
2016-07-26 01:00:02 -07:00
|
|
|
}
|
|
|
|
};
|
2015-03-10 19:11:28 -07:00
|
|
|
|
2018-03-03 15:04:46 -08:00
|
|
|
const styles = StyleSheet.create({
|
2015-06-05 08:46:17 -07:00
|
|
|
pickerIOS: {
|
2015-03-10 19:11:28 -07:00
|
|
|
// 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.
|
2016-04-26 04:20:56 -07:00
|
|
|
height: 216,
|
2015-03-10 19:11:28 -07:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2018-03-03 15:04:46 -08:00
|
|
|
const RCTPickerIOS = requireNativeComponent('RCTPicker', {
|
2015-12-08 07:44:56 -08:00
|
|
|
propTypes: {
|
|
|
|
style: itemStylePropType,
|
|
|
|
},
|
|
|
|
}, {
|
2015-09-08 03:27:44 -07:00
|
|
|
nativeOnly: {
|
|
|
|
items: true,
|
|
|
|
onChange: true,
|
|
|
|
selectedIndex: true,
|
|
|
|
},
|
|
|
|
});
|
2015-03-10 19:11:28 -07:00
|
|
|
|
|
|
|
module.exports = PickerIOS;
|