Files
react-native/Libraries/Components/Picker/PickerIOS.ios.js
T
Andres Suarez e1cfeaddd4 Move non-license comments out of license header
Summary: Changelog: [General] [Fixed] - License header cleanup

Reviewed By: cpojer

Differential Revision: D17749100

fbshipit-source-id: edca9c73a065e9fc311109cd6efeb1f75451a55a
2019-10-15 20:12:12 -07:00

149 lines
3.9 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
// This is a controlled component version of RCTPickerIOS.
'use strict';
const RCTPickerNativeComponent = require('./RCTPickerNativeComponent');
const React = require('react');
const StyleSheet = require('../../StyleSheet/StyleSheet');
const View = require('../View/View');
const processColor = require('../../StyleSheet/processColor');
import type {TextStyleProp} from '../../StyleSheet/StyleSheet';
import type {ColorValue} from '../../StyleSheet/StyleSheetTypes';
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
import type {ViewProps} from '../View/ViewPropTypes';
type PickerIOSChangeEvent = SyntheticEvent<
$ReadOnly<{|
newValue: number | string,
newIndex: number,
|}>,
>;
type RCTPickerIOSItemType = $ReadOnly<{|
label: ?Label,
value: ?(number | string),
textColor: ?number,
|}>;
type Label = Stringish | number;
type Props = $ReadOnly<{|
...ViewProps,
children: React.ChildrenArray<React.Element<typeof PickerIOSItem>>,
itemStyle?: ?TextStyleProp,
onChange?: ?(event: PickerIOSChangeEvent) => mixed,
onValueChange?: ?(itemValue: string | number, itemIndex: number) => mixed,
selectedValue: ?(number | string),
|}>;
type State = {|
selectedIndex: number,
items: $ReadOnlyArray<RCTPickerIOSItemType>,
|};
type ItemProps = $ReadOnly<{|
label: ?Label,
value?: ?(number | string),
color?: ?ColorValue,
|}>;
const PickerIOSItem = (props: ItemProps): null => {
return null;
};
class PickerIOS extends React.Component<Props, State> {
_picker: ?React.ElementRef<typeof RCTPickerNativeComponent> = null;
state: State = {
selectedIndex: 0,
items: [],
};
static Item: (props: ItemProps) => null = PickerIOSItem;
static getDerivedStateFromProps(props: Props): State {
let selectedIndex = 0;
const items = [];
React.Children.toArray(props.children)
.filter(child => child !== null)
.forEach(function(child, index) {
if (child.props.value === props.selectedValue) {
selectedIndex = index;
}
items.push({
value: child.props.value,
label: child.props.label,
textColor: processColor(child.props.color),
});
});
return {selectedIndex, items};
}
render(): React.Node {
return (
<View style={this.props.style}>
<RCTPickerNativeComponent
ref={picker => {
this._picker = picker;
}}
testID={this.props.testID}
style={[styles.pickerIOS, this.props.itemStyle]}
items={this.state.items}
selectedIndex={this.state.selectedIndex}
onChange={this._onChange}
/>
</View>
);
}
_onChange = 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,
});
}
};
}
const 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: 216,
},
});
module.exports = PickerIOS;