Skip to content

Commit

Permalink
Add web-platform specific Picker events using HOF
Browse files Browse the repository at this point in the history
  • Loading branch information
redstar504 committed Mar 10, 2023
1 parent e00e207 commit 6e3b8fc
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 26 deletions.
60 changes: 34 additions & 26 deletions src/components/Picker.js → src/components/Picker/Picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import React, {PureComponent} from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import RNPickerSelect from 'react-native-picker-select';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import FormHelpMessage from './FormHelpMessage';
import Text from './Text';
import styles from '../styles/styles';
import themeColors from '../styles/themes/default';
import {ScrollContext} from './ScrollViewWithContext';
import Icon from '../Icon';
import * as Expensicons from '../Icon/Expensicons';
import FormHelpMessage from '../FormHelpMessage';
import Text from '../Text';
import styles from '../../styles/styles';
import themeColors from '../../styles/themes/default';
import {ScrollContext} from '../ScrollViewWithContext';

const propTypes = {
/** Picker label */
Expand Down Expand Up @@ -75,6 +75,9 @@ const propTypes = {
current: PropTypes.element,
}),
]),

/** Additional events passed to the core Picker for specific platforms such as web */
additionalPickerEvents: PropTypes.func,
};

const defaultProps = {
Expand All @@ -97,6 +100,7 @@ const defaultProps = {
),
onBlur: () => {},
innerRef: () => {},
additionalPickerEvents: () => {},
};

class Picker extends PureComponent {
Expand Down Expand Up @@ -151,6 +155,18 @@ class Picker extends PureComponent {
this.props.onInputChange(this.props.items[0].value, 0);
}

setIsOpen() {
this.setState({
isOpen: true,
});
}

setIsClosed() {
this.setState({
isOpen: false,
});
}

render() {
const hasError = !_.isEmpty(this.props.errorText);

Expand Down Expand Up @@ -184,30 +200,22 @@ class Picker extends PureComponent {
Icon={() => this.props.icon(this.props.size)}
disabled={this.props.isDisabled}
fixAndroidTouchableBug
onOpen={() => this.setState({isOpen: true})}
onClose={() => this.setState({isOpen: false})}
onOpen={() => this.setIsOpen()}
onClose={() => this.setIsClosed()}
textInputProps={{allowFontScaling: false}}
pickerProps={{
onFocus: () => this.setState({isOpen: true}),
onFocus: () => this.setIsOpen(),
onBlur: () => {
this.setState({isOpen: false});
this.setIsClosed();
this.props.onBlur();
},

// The following 2 handlers are specific to web (onChange overrides onValueChange on web)
// They are used to make the picker indicator behave the same way as it does on native
onMouseDown: () => {
this.setState({isOpen: true});
},
onChange: (e) => {
if (e.target.selectedIndex === undefined) {
return;
}
const index = e.target.selectedIndex;
const value = e.target.options[index].value;
this.onInputChange(value, index);
this.setState({isOpen: false});
},
...this.props.additionalPickerEvents(
() => this.setIsOpen(),
(value, index) => {
this.onInputChange(value, index);
this.setIsClosed();
},
),
}}
ref={(el) => {
if (!_.isFunction(this.props.innerRef)) {
Expand Down
21 changes: 21 additions & 0 deletions src/components/Picker/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, {forwardRef} from 'react';
import BasePicker from './Picker';

const additionalPickerEvents = (onMouseDown, onChange) => ({
onMouseDown,
onChange: (e) => {
if (e.target.selectedIndex === undefined) {
return;
}
const index = e.target.selectedIndex;
const value = e.target.options[index].value;
onChange(value, index);
},
});

const Picker = forwardRef((props, ref) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<BasePicker {...props} additionalPickerEvents={additionalPickerEvents} innerRef={ref} />
));

export default Picker;
9 changes: 9 additions & 0 deletions src/components/Picker/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React, {forwardRef} from 'react';
import BasePicker from './Picker';

const Picker = forwardRef((props, ref) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<BasePicker {...props} innerRef={ref} />
));

export default Picker;

0 comments on commit 6e3b8fc

Please sign in to comment.