-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
7535 refactor picker compatible form #7807
Changes from 26 commits
4ef2b51
def46e5
01fa795
a5db0db
68d619f
d940295
c243e76
857ca43
5353111
dc3ba4c
37451fa
82c9cd2
addc22a
0724ae4
094efba
170fc70
ff316d8
7fb4b0f
58d70b5
cf69266
73ef24c
e9a33e2
b8158b9
2da10cf
a893f1a
57ab9f7
bc1310d
f12725a
189ca7c
4287a7a
5dcec43
eb0013d
3f0f3da
7da320a
5060819
bcc4c66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,49 @@ | ||
import React from 'react'; | ||
import RNPickerSelect from 'react-native-picker-select'; | ||
import _ from 'underscore'; | ||
|
||
import styles from '../../../styles/styles'; | ||
import * as basePickerPropTypes from './basePickerPropTypes'; | ||
import basePickerStyles from './basePickerStyles'; | ||
|
||
const BasePicker = props => ( | ||
<RNPickerSelect | ||
onValueChange={props.onChange} | ||
items={props.items} | ||
style={props.size === 'normal' ? basePickerStyles(props.disabled, props.hasError, props.focused) : styles.pickerSmall} | ||
useNativeAndroidPickerStyle={false} | ||
placeholder={props.placeholder} | ||
value={props.value} | ||
Icon={() => props.icon(props.size)} | ||
disabled={props.disabled} | ||
fixAndroidTouchableBug | ||
onOpen={props.onOpen} | ||
onClose={props.onClose} | ||
pickerProps={{ | ||
onFocus: props.onOpen, | ||
onBlur: props.onClose, | ||
}} | ||
/> | ||
); | ||
class BasePicker extends React.Component { | ||
luacmartins marked this conversation as resolved.
Show resolved
Hide resolved
|
||
constructor(props) { | ||
super(props); | ||
|
||
this.state = { | ||
selectedValue: this.props.value || this.props.defaultValue, | ||
}; | ||
} | ||
|
||
handleChange = (value) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Reference: https://github.com/Expensify/App/blob/main/STYLE.md#functions-1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice catch! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also I found I can not use |
||
this.props.onChange(value); | ||
this.setState({selectedValue: value}); | ||
} | ||
|
||
render() { | ||
const hasError = !_.isEmpty(this.props.errorText); | ||
return ( | ||
<RNPickerSelect | ||
onValueChange={this.handleChange} | ||
items={this.props.items} | ||
style={this.props.size === 'normal' ? basePickerStyles(this.props.disabled, hasError, this.props.focused) : styles.pickerSmall} | ||
useNativeAndroidPickerStyle={false} | ||
placeholder={this.props.placeholder} | ||
value={this.state.selectedValue} | ||
Icon={() => this.props.icon(this.props.size)} | ||
disabled={this.props.disabled} | ||
fixAndroidTouchableBug | ||
onOpen={this.props.onOpen} | ||
onClose={this.props.onClose} | ||
pickerProps={{ | ||
onFocus: this.props.onOpen, | ||
onBlur: this.props.onBlur, | ||
ref: this.props.innerRef, | ||
}} | ||
/> | ||
); | ||
} | ||
} | ||
|
||
BasePicker.propTypes = basePickerPropTypes.propTypes; | ||
BasePicker.defaultProps = basePickerPropTypes.defaultProps; | ||
luacmartins marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -6,6 +6,7 @@ import BasePicker from './BasePicker'; | |||||
import Text from '../Text'; | ||||||
import styles from '../../styles/styles'; | ||||||
import InlineErrorText from '../InlineErrorText'; | ||||||
import * as FormUtils from '../../libs/FormUtils'; | ||||||
|
||||||
const propTypes = { | ||||||
/** Picker label */ | ||||||
|
@@ -14,22 +15,39 @@ const propTypes = { | |||||
/** Should the picker appear disabled? */ | ||||||
isDisabled: PropTypes.bool, | ||||||
|
||||||
/** Should the input be styled for errors */ | ||||||
hasError: PropTypes.bool, | ||||||
/** Input value */ | ||||||
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), | ||||||
luacmartins marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
/** Error text to display */ | ||||||
errorText: PropTypes.string, | ||||||
|
||||||
/** Customize the Picker container */ | ||||||
containerStyles: PropTypes.arrayOf(PropTypes.object), | ||||||
|
||||||
/** Indicates that the input is being used with the Form component */ | ||||||
isFormInput: PropTypes.bool, | ||||||
|
||||||
/** | ||||||
* The ID used to uniquely identify the input | ||||||
* | ||||||
* @param {Object} props - props passed to the input | ||||||
* @returns {Object} - returns an Error object if isFormInput is supplied but inputID is falsey or not a string | ||||||
*/ | ||||||
inputID: props => FormUtils.validateInputIDProps(props), | ||||||
|
||||||
/** Saves a draft of the input value when used in a form */ | ||||||
shouldSaveDraft: PropTypes.bool, | ||||||
}; | ||||||
|
||||||
const defaultProps = { | ||||||
label: '', | ||||||
isDisabled: false, | ||||||
hasError: false, | ||||||
errorText: '', | ||||||
containerStyles: [], | ||||||
isFormInput: false, | ||||||
inputID: undefined, | ||||||
shouldSaveDraft: false, | ||||||
value: undefined, | ||||||
}; | ||||||
|
||||||
class Picker extends PureComponent { | ||||||
|
@@ -48,6 +66,7 @@ class Picker extends PureComponent { | |||||
style={[ | ||||||
styles.pickerContainer, | ||||||
this.props.isDisabled && styles.inputDisabled, | ||||||
...this.props.containerStyles, | ||||||
]} | ||||||
> | ||||||
{this.props.label && ( | ||||||
|
@@ -58,13 +77,14 @@ class Picker extends PureComponent { | |||||
onClose={() => this.setState({isOpen: false})} | ||||||
disabled={this.props.isDisabled} | ||||||
focused={this.state.isOpen} | ||||||
hasError={this.props.hasError} | ||||||
errorText={this.props.errorText} | ||||||
value={this.props.value} | ||||||
luacmartins marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading | ||||||
{...pickerProps} | ||||||
/> | ||||||
</View> | ||||||
{!_.isEmpty(this.props.errorText) && ( | ||||||
<InlineErrorText> | ||||||
<InlineErrorText style={[styles.ml3]}> | ||||||
luacmartins marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should also be applied from right edge as well.
Suggested change
|
||||||
{this.props.errorText} | ||||||
</InlineErrorText> | ||||||
)} | ||||||
|
@@ -76,4 +96,5 @@ class Picker extends PureComponent { | |||||
Picker.propTypes = propTypes; | ||||||
Picker.defaultProps = defaultProps; | ||||||
|
||||||
export default Picker; | ||||||
// eslint-disable-next-line react/jsx-props-no-spreading | ||||||
luacmartins marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
export default React.forwardRef((props, ref) => <Picker {...props} innerRef={ref} key={props.inputID} />); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add comment