react-native-picker-select
Advanced tools
Comparing version 3.0.0 to 3.0.1
102
package.json
{ | ||
"name": "react-native-picker-select", | ||
"version": "3.0.0", | ||
"description": "A Picker component for React Native which emulates the native <select> interfaces for each platform", | ||
"license": "MIT", | ||
"author": "Michael Lefkowitz <lefkowitz.michael@gmail.com>", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/lawnstarter/react-native-picker-select.git" | ||
}, | ||
"main": "src/index.js", | ||
"keywords": [ | ||
"dropdown", | ||
"picker", | ||
"select", | ||
"react", | ||
"react-native" | ||
], | ||
"dependencies": { | ||
"lodash.isequal": "^4.5.0" | ||
}, | ||
"devDependencies": { | ||
"babel-jest": "^22.4.3", | ||
"babel-preset-react-native": "^4.0.0", | ||
"enzyme": "^3.3.0", | ||
"enzyme-adapter-react-16": "^1.1.1", | ||
"enzyme-to-json": "^3.3.3", | ||
"eslint": "^4.19.1", | ||
"eslint-config-airbnb": "^16.1.0", | ||
"eslint-plugin-import": "^2.11.0", | ||
"eslint-plugin-jsx-a11y": "^6.0.3", | ||
"eslint-plugin-react": "^7.7.0", | ||
"jest": "^22.4.3", | ||
"prop-types": "^15.6.1", | ||
"react": "16.3.2", | ||
"react-dom": "^16.3.2", | ||
"react-native": "0.55.3", | ||
"react-test-renderer": "^16.3.2" | ||
}, | ||
"scripts": { | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"test:coverage": "jest --coverage", | ||
"open:coverage": "open ./coverage/lcov-report/index.html" | ||
}, | ||
"jest": { | ||
"preset": "react-native", | ||
"setupFiles": [ | ||
"./test/setup.js" | ||
], | ||
"snapshotSerializers": [ | ||
"enzyme-to-json/serializer" | ||
] | ||
} | ||
"name": "react-native-picker-select", | ||
"version": "3.0.1", | ||
"description": | ||
"A Picker component for React Native which emulates the native <select> interfaces for each platform", | ||
"license": "MIT", | ||
"author": "Michael Lefkowitz <lefkowitz.michael@gmail.com>", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/lawnstarter/react-native-picker-select.git" | ||
}, | ||
"main": "src/index.js", | ||
"keywords": ["dropdown", "picker", "select", "react", "react-native"], | ||
"files": ["LICENSE", "README.md", "src/index.js"], | ||
"dependencies": { | ||
"lodash.isequal": "^4.5.0" | ||
}, | ||
"devDependencies": { | ||
"babel-jest": "^22.4.3", | ||
"babel-preset-react-native": "^4.0.0", | ||
"enzyme": "^3.3.0", | ||
"enzyme-adapter-react-16": "^1.1.1", | ||
"enzyme-to-json": "^3.3.3", | ||
"eslint-config-ls-react": "https://github.com/lawnstarter/eslint-config-ls-react#2.0.1", | ||
"husky": "^0.14.3", | ||
"jest": "^22.4.3", | ||
"prettier": "^1.12.1", | ||
"pretty-quick": "^1.4.1", | ||
"prop-types": "^15.6.1", | ||
"react": "16.3.2", | ||
"react-dom": "^16.3.2", | ||
"react-native": "0.55.3", | ||
"react-test-renderer": "^16.3.2" | ||
}, | ||
"scripts": { | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"test:coverage": "jest --coverage", | ||
"open:coverage": "open ./coverage/lcov-report/index.html", | ||
"precommit": "pretty-quick --staged", | ||
"prettier:debug-check": | ||
"prettier --config ./.prettierrc.js --debug-check \"{src,test}/**/*.js\"", | ||
"preprettier:all": "yarn run prettier:debug-check", | ||
"prettier:all": "prettier --config ./.prettierrc.js --write \"{src,test}/**/*.js\"" | ||
}, | ||
"jest": { | ||
"preset": "react-native", | ||
"setupFiles": ["./test/setup.js"], | ||
"snapshotSerializers": ["enzyme-to-json/serializer"] | ||
} | ||
} |
@@ -0,3 +1,5 @@ | ||
# react-native-picker-select | ||
# React Native Picker Select | ||
[![npm version](https://badge.fury.io/js/react-native-picker-select.svg)](https://badge.fury.io/js/react-native-picker-select) | ||
[![CircleCI](https://circleci.com/gh/lawnstarter/react-native-picker-select.svg?style=svg)](https://circleci.com/gh/lawnstarter/react-native-picker-select) | ||
@@ -14,3 +16,2 @@ A Picker component for React Native which emulates the native `<select>` interfaces for iOS and Android | ||
## Getting Started | ||
@@ -24,55 +25,33 @@ | ||
| Component | RN | | ||
| --------- |------------| | ||
| >= 3.0.0 | >= 0.55.3 | | ||
| < 3.0.0 | < 0.55.3 | | ||
| Component | RN | | ||
| --------- | --------- | | ||
| >= 3.0.0 | >= 0.55.3 | | ||
| < 3.0.0 | < 0.55.3 | | ||
### Usage | ||
### Props | ||
**Required Props** | ||
* `onValueChange` - function | ||
* Callback which returns `value, index` | ||
* `items` - array | ||
* The items for the component to render. Each item should be in the following format: | ||
```js | ||
{ | ||
label: 'Orange', | ||
value: 'orange', | ||
key: 'orange', | ||
} | ||
``` | ||
* The label and the value are required, but the key will be based upon the label if it isn't included | ||
* The value can be any data type | ||
| Name | Type | Description | Required? | iOS / Android | | ||
| ----------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------------- | | ||
| onValueChange | function | Callback which returns `value, index` | Y | Both | | ||
| items | array | _ The items for the component to render. Each item should be in the following format:<br>`{label: 'Orange',value: 'orange',key: 'orange'}`<br>_ The label and the value are required, but the key will be based upon the label if it isn't included<br>\* The value can be any data type | Y | Both | | ||
| placeholder | object | _ An override for the default placeholder object with a label of `Select an item...` and a value of `null`<br>_ An empty object can be used if you'd like to disable the placeholder entirely | N | Both | | ||
| disabled | boolean | Disables interaction with the component | N | Both | | ||
| value | any | Will attempt to locate a matching value from the `items` array by checking each item's `value` property. If found, it will update the component to show that item as selected. If the value is not found, it will default to the first item. | N | Both | | ||
| style | object | Style overrides for most parts of the component. More details below. | N | Both | | ||
| hideDoneBar | boolean | Hides the bar with tabbing arrows and Done link to exit the modal. While this is typical on `select` elements on the web, the [interface guidelines](https://developer.apple.com/ios/human-interface-guidelines/controls/pickers/) does not include it. | N | iOS | | ||
| hideIcon | boolean | Hides the floating downward arrow on the right side of the input box | N | iOS | | ||
| onUpArrow / onDownArrow | function | _ Presence enables the corresponding arrow<br>_ Closes the picker<br>\* Calls the callback provided | N | iOS | | ||
**Optional Props** | ||
* `placeholder` - object | ||
* An override for the default placeholder object with a label of `Select an item...` and a value of `null` | ||
* An empty object can be used if you'd like to disable the placeholder entirely | ||
* `disabled` - boolean | ||
* Disables interaction with the component | ||
* `value` - any | ||
* Will attempt to locate a matching value from the `items` array by checking each item's `value` property. If found, it will update the component to show that item as selected. If the value is not found, it will default to the first item. | ||
* `style` - object | ||
* Style overrides for most parts of the component. More details below. | ||
* `hideDoneBar` - boolean - *iOS ONLY* | ||
* For the iOS component, hides the bar with tabbing arrows and Done link to exit the modal. While this is typical on `<select>` elements on the web, the [interface guidelines](https://developer.apple.com/ios/human-interface-guidelines/controls/pickers/) does not include it. | ||
* `hideIcon` - boolean - *iOS ONLY* | ||
* For the iOS component, hides the floating downward arrow on the right side of the input box | ||
* `onUpArrow` and/or `onDownArrow` - function - *iOS ONLY* | ||
* Presence enables the corresponding arrow for iOS | ||
* Closes the picker | ||
* Calls the callback provided | ||
### Styling | ||
* iOS | ||
* The component wraps a TextInput without styling. In the style prop, pass a style object named `inputIOS` to style the input | ||
* Alternatively, you can pass children (such as a custom button or input) for the component to wrap | ||
* Other styles that can be modified for iOS are named `viewContainer`, `icon`, `done`, `modalViewTop`, `modalViewMiddle`, `modalViewBottom`, and `placeholderColor` | ||
* Android | ||
* The default Picker component acts similiarly to a TextInput until it is tapped, although it does not include an underline | ||
* We emulate a typical underline, which can be modified with a style object named `underline` | ||
* The main input can be modified with the style object named `inputAndroid` | ||
* Alternatively, you can pass children (such as a custom button or input) for the component to wrap | ||
* Other styles that can be modified for Android are named `viewContainer` and `placeholderColor` | ||
* iOS | ||
* The component wraps a TextInput without styling. In the style prop, pass a style object named `inputIOS` to style the input | ||
* Alternatively, you can pass children (such as a custom button or input) for the component to wrap | ||
* Other styles that can be modified for iOS are named `viewContainer`, `icon`, `done`, `modalViewTop`, `modalViewMiddle`, `modalViewBottom`, and `placeholderColor` | ||
* Android | ||
* The default Picker component acts similiarly to a TextInput until it is tapped, although it does not include an underline | ||
* We emulate a typical underline, which can be modified with a style object named `underline` | ||
* The main input can be modified with the style object named `inputAndroid` | ||
* Alternatively, you can pass children (such as a custom button or input) for the component to wrap | ||
* Other styles that can be modified for Android are named `viewContainer` and `placeholderColor` | ||
@@ -87,6 +66,6 @@ [See Examples](https://github.com/lawnstarter/react-native-picker-select/tree/master/example) | ||
- [ ] Update Android picker to look closer to platform's `<select>` | ||
* [ ] Update Android picker to look closer to platform's `<select>` | ||
## License | ||
react-native-picker-select is [MIT licensed](https://github.com/lawnstarter/react-native-picker-select/tree/master/LICENSE). | ||
react-native-picker-select is [MIT licensed](https://github.com/lawnstarter/react-native-picker-select/tree/master/LICENSE) |
673
src/index.js
import React, { PureComponent } from 'react'; | ||
import { | ||
Modal, | ||
Picker, | ||
Platform, | ||
StyleSheet, | ||
Text, | ||
TextInput, | ||
TouchableOpacity, | ||
TouchableWithoutFeedback, | ||
View, | ||
Modal, | ||
Picker, | ||
Platform, | ||
StyleSheet, | ||
Text, | ||
TextInput, | ||
TouchableOpacity, | ||
TouchableWithoutFeedback, | ||
View, | ||
} from 'react-native'; | ||
@@ -17,361 +17,382 @@ import PropTypes from 'prop-types'; | ||
function handlePlaceholder({ placeholder }) { | ||
if (isEqual(placeholder, {})) { | ||
return []; | ||
} | ||
return [placeholder]; | ||
if (isEqual(placeholder, {})) { | ||
return []; | ||
} | ||
return [placeholder]; | ||
} | ||
function getSelectedItem({ items, value }) { | ||
return items.find(item => isEqual(item.value, value)) || items[0]; | ||
return ( | ||
items.find((item) => { | ||
return isEqual(item.value, value); | ||
}) || items[0] | ||
); | ||
} | ||
export default class RNPickerSelect extends PureComponent { | ||
static getDerivedStateFromProps(nextProps, prevState) { | ||
// update items if items prop changes | ||
const itemsChanged = !isEqual(prevState.items, nextProps.items); | ||
// update selectedItem if value prop is defined and differs from currently selected item | ||
const newSelectedItem = getSelectedItem({ items: prevState.items, value: nextProps.value }); | ||
const selectedItemChanged = !isEqual(nextProps.value, undefined) && !isEqual(prevState.selectedItem, newSelectedItem); | ||
static getDerivedStateFromProps(nextProps, prevState) { | ||
// update items if items prop changes | ||
const itemsChanged = !isEqual(prevState.items, nextProps.items); | ||
// update selectedItem if value prop is defined and differs from currently selected item | ||
const newSelectedItem = getSelectedItem({ items: prevState.items, value: nextProps.value }); | ||
const selectedItemChanged = | ||
!isEqual(nextProps.value, undefined) && | ||
!isEqual(prevState.selectedItem, newSelectedItem); | ||
if (itemsChanged || selectedItemChanged) { | ||
return { | ||
items: itemsChanged ? handlePlaceholder({ placeholder: nextProps.placeholder }).concat(nextProps.items) : prevState.items, | ||
selectedItem: selectedItemChanged ? newSelectedItem : prevState.selectedItem, | ||
}; | ||
if (itemsChanged || selectedItemChanged) { | ||
return { | ||
items: itemsChanged | ||
? handlePlaceholder({ placeholder: nextProps.placeholder }).concat( | ||
nextProps.items | ||
) | ||
: prevState.items, | ||
selectedItem: selectedItemChanged ? newSelectedItem : prevState.selectedItem, | ||
}; | ||
} | ||
return null; | ||
} | ||
return null; | ||
} | ||
constructor(props) { | ||
super(props); | ||
constructor(props) { | ||
super(props); | ||
const items = handlePlaceholder({ placeholder: props.placeholder }).concat(props.items); | ||
this.state = { | ||
items, | ||
selectedItem: getSelectedItem({ items, value: props.value }), | ||
showPicker: false, | ||
animationType: undefined, | ||
}; | ||
const items = handlePlaceholder({ placeholder: props.placeholder }).concat(props.items); | ||
this.state = { | ||
items, | ||
selectedItem: getSelectedItem({ items, value: props.value }), | ||
showPicker: false, | ||
animationType: undefined, | ||
}; | ||
this.onUpArrow = this.onUpArrow.bind(this); | ||
this.onDownArrow = this.onDownArrow.bind(this); | ||
this.onValueChange = this.onValueChange.bind(this); | ||
this.togglePicker = this.togglePicker.bind(this); | ||
} | ||
this.onUpArrow = this.onUpArrow.bind(this); | ||
this.onDownArrow = this.onDownArrow.bind(this); | ||
this.onValueChange = this.onValueChange.bind(this); | ||
this.togglePicker = this.togglePicker.bind(this); | ||
} | ||
onUpArrow() { | ||
this.togglePicker(); | ||
setTimeout(() => { | ||
this.props.onUpArrow(); | ||
}); | ||
} | ||
onUpArrow() { | ||
this.togglePicker(); | ||
setTimeout(() => { | ||
this.props.onUpArrow(); | ||
}); | ||
} | ||
onDownArrow() { | ||
this.togglePicker(); | ||
setTimeout(() => { | ||
this.props.onDownArrow(); | ||
}); | ||
} | ||
onDownArrow() { | ||
this.togglePicker(); | ||
setTimeout(() => { | ||
this.props.onDownArrow(); | ||
}); | ||
} | ||
onValueChange(value, index) { | ||
this.props.onValueChange(value, index); | ||
onValueChange(value, index) { | ||
this.props.onValueChange(value, index); | ||
this.setState({ | ||
selectedItem: this.state.items[index], | ||
}); | ||
} | ||
this.setState({ | ||
selectedItem: this.state.items[index], | ||
}); | ||
} | ||
togglePicker(animate = false) { | ||
if (this.props.disabled) { | ||
return; | ||
} | ||
this.setState({ | ||
animationType: animate ? this.props.animationType : undefined, | ||
showPicker: !this.state.showPicker, | ||
}); | ||
if (!this.state.showPicker && this.inputRef) { | ||
this.inputRef.focus(); | ||
this.inputRef.blur(); | ||
} | ||
} | ||
togglePicker(animate = false) { | ||
if (this.props.disabled) { | ||
return; | ||
renderPickerItems() { | ||
return this.state.items.map((item) => { | ||
return ( | ||
<Picker.Item label={item.label} value={item.value} key={item.key || item.label} /> | ||
); | ||
}); | ||
} | ||
this.setState({ | ||
animationType: animate ? 'slide' : undefined, | ||
showPicker: !this.state.showPicker, | ||
}); | ||
if (!this.state.showPicker && this.inputRef) { | ||
this.inputRef.focus(); | ||
this.inputRef.blur(); | ||
renderPlaceholderStyle() { | ||
const styleModifiers = {}; | ||
if ( | ||
!isEqual(this.props.placeholder, {}) && | ||
this.state.selectedItem.label === this.props.placeholder.label | ||
) { | ||
styleModifiers.color = this.props.style.placeholderColor || '#C7C7CD'; | ||
} | ||
return styleModifiers; | ||
} | ||
} | ||
renderPickerItems() { | ||
return this.state.items.map(item => ( | ||
<Picker.Item | ||
label={item.label} | ||
value={item.value} | ||
key={item.key || item.label} | ||
/> | ||
)); | ||
} | ||
renderDoneBar() { | ||
if (this.props.hideDoneBar) { | ||
return null; | ||
} | ||
renderPlaceholderStyle() { | ||
const styleModifiers = {}; | ||
if (!this.noPlaceholder && this.state.selectedItem.label === this.props.placeholder.label) { | ||
styleModifiers.color = this.props.style.placeholderColor || '#C7C7CD'; | ||
return ( | ||
<View style={[styles.modalViewMiddle, this.props.style.modalViewMiddle]}> | ||
<View style={{ flex: 1, flexDirection: 'row', marginLeft: 15 }}> | ||
<TouchableOpacity | ||
activeOpacity={this.props.onUpArrow ? 0.5 : 1} | ||
onPress={this.props.onUpArrow ? this.onUpArrow : null} | ||
> | ||
<View | ||
style={[ | ||
styles.chevron, | ||
this.props.style.chevron, | ||
styles.chevronUp, | ||
this.props.style.chevronUp, | ||
this.props.onUpArrow | ||
? [styles.chevronActive, this.props.style.chevronActive] | ||
: {}, | ||
]} | ||
/> | ||
</TouchableOpacity> | ||
<View style={{ marginHorizontal: 10 }} /> | ||
<TouchableOpacity | ||
activeOpacity={this.props.onDownArrow ? 0.5 : 1} | ||
onPress={this.props.onDownArrow ? this.onDownArrow : null} | ||
> | ||
<View | ||
style={[ | ||
styles.chevron, | ||
this.props.style.chevron, | ||
styles.chevronDown, | ||
this.props.style.chevronDown, | ||
this.props.onDownArrow | ||
? [styles.chevronActive, this.props.style.chevronActive] | ||
: {}, | ||
]} | ||
/> | ||
</TouchableOpacity> | ||
</View> | ||
<TouchableWithoutFeedback | ||
onPress={() => { | ||
this.togglePicker(true); | ||
}} | ||
hitSlop={{ top: 2, right: 2, bottom: 2, left: 2 }} | ||
> | ||
<View> | ||
<Text style={[styles.done, this.props.style.done]}>Done</Text> | ||
</View> | ||
</TouchableWithoutFeedback> | ||
</View> | ||
); | ||
} | ||
return styleModifiers; | ||
} | ||
renderDoneBar() { | ||
if (this.props.hideDoneBar) { | ||
return null; | ||
renderIcon() { | ||
if (this.props.hideIcon) { | ||
return null; | ||
} | ||
return <View style={[styles.icon, this.props.style.icon]} />; | ||
} | ||
return ( | ||
<View style={[styles.modalViewMiddle, this.props.style.modalViewMiddle]}> | ||
<View style={{ flex: 1, flexDirection: 'row', marginLeft: 15 }}> | ||
<TouchableOpacity | ||
activeOpacity={this.props.onUpArrow ? 0.5 : 1} | ||
onPress={this.props.onUpArrow ? this.onUpArrow : null} | ||
> | ||
<View | ||
style={[ | ||
styles.chevron, | ||
styles.chevronUp, | ||
this.props.onUpArrow ? styles.chevronActive : {}, | ||
]} | ||
/> | ||
</TouchableOpacity> | ||
<View style={{ marginHorizontal: 10 }} /> | ||
<TouchableOpacity | ||
activeOpacity={this.props.onDownArrow ? 0.5 : 1} | ||
onPress={this.props.onDownArrow ? this.onDownArrow : null} | ||
> | ||
<View | ||
style={[ | ||
styles.chevron, | ||
styles.chevronDown, | ||
this.props.onDownArrow ? styles.chevronActive : {}, | ||
]} | ||
/> | ||
</TouchableOpacity> | ||
</View> | ||
<TouchableWithoutFeedback | ||
onPress={() => { | ||
this.togglePicker(true); | ||
}} | ||
hitSlop={{ top: 2, right: 2, bottom: 2, left: 2 }} | ||
> | ||
<View> | ||
<Text style={[styles.done, this.props.style.done]}>Done</Text> | ||
</View> | ||
</TouchableWithoutFeedback> | ||
</View> | ||
); | ||
} | ||
renderTextInputOrChildren() { | ||
if (this.props.children) { | ||
return <View pointerEvents="box-only">{this.props.children}</View>; | ||
} | ||
return ( | ||
<View pointerEvents="box-only"> | ||
<TextInput | ||
style={[this.props.style.inputIOS, this.renderPlaceholderStyle()]} | ||
value={this.state.selectedItem.label} | ||
ref={(ref) => { | ||
this.inputRef = ref; | ||
}} | ||
/> | ||
{this.renderIcon()} | ||
</View> | ||
); | ||
} | ||
renderIcon() { | ||
if (this.props.hideIcon) { | ||
return null; | ||
renderIOS() { | ||
return ( | ||
<View style={[styles.viewContainer, this.props.style.viewContainer]}> | ||
<TouchableWithoutFeedback | ||
onPress={() => { | ||
this.togglePicker(true); | ||
}} | ||
> | ||
{this.renderTextInputOrChildren()} | ||
</TouchableWithoutFeedback> | ||
<Modal | ||
visible={this.state.showPicker} | ||
transparent | ||
animationType={this.state.animationType} | ||
> | ||
<TouchableOpacity | ||
style={[styles.modalViewTop, this.props.style.modalViewTop]} | ||
onPress={() => { | ||
this.togglePicker(true); | ||
}} | ||
/> | ||
{this.renderDoneBar()} | ||
<View style={[styles.modalViewBottom, this.props.style.modalViewBottom]}> | ||
<Picker | ||
onValueChange={this.onValueChange} | ||
selectedValue={this.state.selectedItem.value} | ||
testId="RNPickerSelectIOS" | ||
> | ||
{this.renderPickerItems()} | ||
</Picker> | ||
</View> | ||
</Modal> | ||
</View> | ||
); | ||
} | ||
return <View style={[styles.icon, this.props.style.icon]} />; | ||
} | ||
renderTextInputOrChildren() { | ||
if (this.props.children) { | ||
return <View pointerEvents="box-only">{this.props.children}</View>; | ||
renderAndroidHeadless() { | ||
return ( | ||
<View style={{ borderWidth: 0 }}> | ||
{this.props.children} | ||
<Picker | ||
style={{ position: 'absolute', top: 0, width: 1000, height: 1000 }} | ||
onValueChange={this.onValueChange} | ||
selectedValue={this.state.selectedItem.value} | ||
testId="RNPickerSelectAndroid" | ||
mode={this.props.mode} | ||
enabled={!this.props.disabled} | ||
> | ||
{this.renderPickerItems()} | ||
</Picker> | ||
</View> | ||
); | ||
} | ||
return ( | ||
<View pointerEvents="box-only"> | ||
<TextInput | ||
style={[this.props.style.inputIOS, this.renderPlaceholderStyle()]} | ||
value={this.state.selectedItem.label} | ||
ref={(ref) => { | ||
this.inputRef = ref; | ||
}} | ||
/> | ||
{ this.renderIcon() } | ||
</View> | ||
); | ||
} | ||
renderIOS() { | ||
return ( | ||
<View style={[styles.viewContainer, this.props.style.viewContainer]}> | ||
<TouchableWithoutFeedback | ||
onPress={() => { | ||
this.togglePicker(true); | ||
}} | ||
> | ||
{ this.renderTextInputOrChildren() } | ||
</TouchableWithoutFeedback> | ||
<Modal | ||
visible={this.state.showPicker} | ||
transparent | ||
animationType={this.state.animationType} | ||
> | ||
<TouchableOpacity | ||
style={[styles.modalViewTop, this.props.style.modalViewTop]} | ||
onPress={() => { | ||
this.togglePicker(true); | ||
}} | ||
/> | ||
{ this.renderDoneBar() } | ||
<View | ||
style={[styles.modalViewBottom, this.props.style.modalViewBottom]} | ||
> | ||
<Picker | ||
onValueChange={this.onValueChange} | ||
selectedValue={this.state.selectedItem.value} | ||
testId="RNPickerSelectIOS" | ||
> | ||
{ this.renderPickerItems() } | ||
</Picker> | ||
</View> | ||
</Modal> | ||
</View> | ||
); | ||
} | ||
renderAndroid() { | ||
if (this.props.children) { | ||
return this.renderAndroidHeadless(); | ||
} | ||
renderAndroidHeadless() { | ||
return ( | ||
<View style={{ borderWidth: 0 }}> | ||
{ this.props.children } | ||
<Picker | ||
style={{ position: 'absolute', top: 0, width: 1000, height: 1000 }} | ||
onValueChange={this.onValueChange} | ||
selectedValue={this.state.selectedItem.value} | ||
testId="RNPickerSelectAndroid" | ||
mode={this.props.mode} | ||
enabled={!this.props.disabled} | ||
> | ||
{ this.renderPickerItems() } | ||
</Picker> | ||
</View> | ||
); | ||
} | ||
return ( | ||
<View style={[styles.viewContainer, this.props.style.viewContainer]}> | ||
<Picker | ||
style={[this.props.style.inputAndroid, this.renderPlaceholderStyle()]} | ||
onValueChange={this.onValueChange} | ||
selectedValue={this.state.selectedItem.value} | ||
testId="RNPickerSelectAndroid" | ||
mode={this.props.mode} | ||
enabled={!this.props.disabled} | ||
> | ||
{this.renderPickerItems()} | ||
</Picker> | ||
<View style={[styles.underline, this.props.style.underline]} /> | ||
</View> | ||
); | ||
} | ||
renderAndroid() { | ||
if (this.props.children) { | ||
return this.renderAndroidHeadless(); | ||
render() { | ||
return Platform.OS === 'ios' ? this.renderIOS() : this.renderAndroid(); | ||
} | ||
return ( | ||
<View style={[styles.viewContainer, this.props.style.viewContainer]}> | ||
<Picker | ||
style={[this.props.style.inputAndroid, this.renderPlaceholderStyle()]} | ||
onValueChange={this.onValueChange} | ||
selectedValue={this.state.selectedItem.value} | ||
testId="RNPickerSelectAndroid" | ||
mode={this.props.mode} | ||
enabled={!this.props.disabled} | ||
> | ||
{ this.renderPickerItems() } | ||
</Picker> | ||
<View style={[styles.underline, this.props.style.underline]} /> | ||
</View> | ||
); | ||
} | ||
render() { | ||
return Platform.OS === 'ios' ? this.renderIOS() : this.renderAndroid(); | ||
} | ||
} | ||
RNPickerSelect.propTypes = { | ||
onValueChange: PropTypes.func.isRequired, | ||
items: PropTypes.arrayOf(PropTypes.shape({ | ||
label: PropTypes.string.isRequired, | ||
value: PropTypes.any.isRequired, | ||
key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | ||
})).isRequired, | ||
placeholder: PropTypes.shape({ | ||
label: PropTypes.string, | ||
value: PropTypes.any, | ||
}), | ||
hideDoneBar: PropTypes.bool, | ||
hideIcon: PropTypes.bool, | ||
disabled: PropTypes.bool, | ||
value: PropTypes.any, // eslint-disable-line react/forbid-prop-types | ||
style: PropTypes.object, // eslint-disable-line react/forbid-prop-types | ||
children: PropTypes.any, // eslint-disable-line react/forbid-prop-types | ||
mode: PropTypes.string, | ||
onUpArrow: PropTypes.func, | ||
onDownArrow: PropTypes.func, | ||
onValueChange: PropTypes.func.isRequired, | ||
items: PropTypes.arrayOf( | ||
PropTypes.shape({ | ||
label: PropTypes.string.isRequired, | ||
value: PropTypes.any.isRequired, | ||
key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), | ||
}) | ||
).isRequired, | ||
placeholder: PropTypes.shape({ | ||
label: PropTypes.string, | ||
value: PropTypes.any, | ||
}), | ||
hideDoneBar: PropTypes.bool, | ||
hideIcon: PropTypes.bool, | ||
disabled: PropTypes.bool, | ||
value: PropTypes.any, // eslint-disable-line react/forbid-prop-types | ||
style: PropTypes.object, // eslint-disable-line react/forbid-prop-types | ||
children: PropTypes.any, // eslint-disable-line react/forbid-prop-types | ||
mode: PropTypes.string, | ||
animationType: PropTypes.string, | ||
onUpArrow: PropTypes.func, | ||
onDownArrow: PropTypes.func, | ||
}; | ||
RNPickerSelect.defaultProps = { | ||
placeholder: { | ||
label: 'Select an item...', | ||
value: null, | ||
}, | ||
hideDoneBar: false, | ||
hideIcon: false, | ||
disabled: false, | ||
value: undefined, | ||
style: {}, | ||
children: null, | ||
mode: 'dialog', | ||
onUpArrow: null, | ||
onDownArrow: null, | ||
placeholder: { | ||
label: 'Select an item...', | ||
value: null, | ||
}, | ||
hideDoneBar: false, | ||
hideIcon: false, | ||
disabled: false, | ||
value: undefined, | ||
style: {}, | ||
children: null, | ||
mode: 'dialog', | ||
animationType: 'slide', | ||
onUpArrow: null, | ||
onDownArrow: null, | ||
}; | ||
const styles = StyleSheet.create({ | ||
viewContainer: { | ||
alignSelf: 'stretch', | ||
}, | ||
chevron: { | ||
width: 15, | ||
height: 15, | ||
backgroundColor: 'transparent', | ||
borderTopWidth: 1.5, | ||
borderTopColor: '#D0D4DB', | ||
borderRightWidth: 1.5, | ||
borderRightColor: '#D0D4DB', | ||
}, | ||
chevronUp: { | ||
transform: [{ translateY: 17 }, { rotate: '-45deg' }], | ||
}, | ||
chevronDown: { | ||
transform: [{ translateY: 8 }, { rotate: '135deg' }], | ||
}, | ||
chevronActive: { | ||
borderTopColor: '#007AFE', | ||
borderRightColor: '#007AFE', | ||
}, | ||
icon: { | ||
position: 'absolute', | ||
backgroundColor: 'transparent', | ||
borderTopWidth: 10, | ||
borderTopColor: 'gray', | ||
borderRightWidth: 10, | ||
borderRightColor: 'transparent', | ||
borderLeftWidth: 10, | ||
borderLeftColor: 'transparent', | ||
width: 0, | ||
height: 0, | ||
top: 20, | ||
right: 10, | ||
}, | ||
modalViewTop: { | ||
flex: 1, | ||
}, | ||
modalViewMiddle: { | ||
height: 44, | ||
zIndex: 2, | ||
flexDirection: 'row', | ||
justifyContent: 'space-between', | ||
backgroundColor: '#EFF1F2', | ||
borderTopWidth: 0.5, | ||
borderTopColor: '#919498', | ||
}, | ||
modalViewBottom: { | ||
height: 215, | ||
justifyContent: 'center', | ||
backgroundColor: '#D0D4DB', | ||
}, | ||
done: { | ||
color: '#007AFE', | ||
fontWeight: 'bold', | ||
padding: 10, | ||
fontSize: 18, | ||
}, | ||
underline: { | ||
borderTopWidth: 1, | ||
borderTopColor: '#888988', | ||
marginHorizontal: 4, | ||
}, | ||
viewContainer: { | ||
alignSelf: 'stretch', | ||
}, | ||
chevron: { | ||
width: 15, | ||
height: 15, | ||
backgroundColor: 'transparent', | ||
borderTopWidth: 1.5, | ||
borderTopColor: '#D0D4DB', | ||
borderRightWidth: 1.5, | ||
borderRightColor: '#D0D4DB', | ||
}, | ||
chevronUp: { | ||
transform: [{ translateY: 17 }, { rotate: '-45deg' }], | ||
}, | ||
chevronDown: { | ||
transform: [{ translateY: 8 }, { rotate: '135deg' }], | ||
}, | ||
chevronActive: { | ||
borderTopColor: '#007AFE', | ||
borderRightColor: '#007AFE', | ||
}, | ||
icon: { | ||
position: 'absolute', | ||
backgroundColor: 'transparent', | ||
borderTopWidth: 10, | ||
borderTopColor: 'gray', | ||
borderRightWidth: 10, | ||
borderRightColor: 'transparent', | ||
borderLeftWidth: 10, | ||
borderLeftColor: 'transparent', | ||
width: 0, | ||
height: 0, | ||
top: 20, | ||
right: 10, | ||
}, | ||
modalViewTop: { | ||
flex: 1, | ||
}, | ||
modalViewMiddle: { | ||
height: 44, | ||
zIndex: 2, | ||
flexDirection: 'row', | ||
justifyContent: 'space-between', | ||
backgroundColor: '#EFF1F2', | ||
borderTopWidth: 0.5, | ||
borderTopColor: '#919498', | ||
}, | ||
modalViewBottom: { | ||
height: 215, | ||
justifyContent: 'center', | ||
backgroundColor: '#D0D4DB', | ||
}, | ||
done: { | ||
color: '#007AFE', | ||
fontWeight: 'bold', | ||
padding: 10, | ||
fontSize: 18, | ||
}, | ||
underline: { | ||
borderTopWidth: 1, | ||
borderTopColor: '#888988', | ||
marginHorizontal: 4, | ||
}, | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15
21920
4
369
69