diff --git a/src/index.js b/src/index.js
index b7ce7b12..04bae2ac 100644
--- a/src/index.js
+++ b/src/index.js
@@ -10,9 +10,9 @@ import { Dimensions } from 'react-native';
// This height was tested thoroughly on several iPhone Models (from iPhone 8 to 14 Pro)
const IOS_MODAL_HEIGHT = 262;
-const preserveSpaces = (label) => {
+const preserveSpaces = (label) => {
return label.replace(/ /g, '\u00a0');
- }
+};
export default class RNPickerSelect extends PureComponent {
static propTypes = {
@@ -151,6 +151,7 @@ export default class RNPickerSelect extends PureComponent {
this.scrollToInput = this.scrollToInput.bind(this);
this.togglePicker = this.togglePicker.bind(this);
this.renderInputAccessoryView = this.renderInputAccessoryView.bind(this);
+ this.updatePickerState = this.updatePickerState.bind(this);
}
componentDidUpdate = (prevProps, prevState) => {
@@ -264,23 +265,10 @@ export default class RNPickerSelect extends PureComponent {
}
}
- togglePicker(animate = false, postToggleCallback) {
- const { modalProps, disabled } = this.props;
- const { showPicker } = this.state;
-
- if (disabled) {
- return;
- }
-
- if (!showPicker) {
- Keyboard.dismiss();
- }
-
+ updatePickerState = (animate = false, postToggleCallback) => {
+ const { modalProps } = this.props;
const animationType =
modalProps && modalProps.animationType ? modalProps.animationType : 'slide';
-
- this.triggerOpenCloseCallbacks();
-
this.setState(
(prevState) => {
return {
@@ -294,6 +282,26 @@ export default class RNPickerSelect extends PureComponent {
}
}
);
+ };
+
+ togglePicker(animate = false, postToggleCallback) {
+ const { disabled } = this.props;
+
+ if (disabled) {
+ return;
+ }
+
+ this.triggerOpenCloseCallbacks();
+
+ if (Keyboard.isVisible()) {
+ const keyboardListener = Keyboard.addListener('keyboardDidHide', () => {
+ this.updatePickerState(animate, postToggleCallback);
+ keyboardListener.remove();
+ });
+ Keyboard.dismiss();
+ } else {
+ this.updatePickerState(animate, postToggleCallback);
+ }
}
renderPickerItems() {
diff --git a/test/test.js b/test/test.js
index b5e6a6c9..804388c6 100644
--- a/test/test.js
+++ b/test/test.js
@@ -42,6 +42,8 @@ describe('RNPickerSelect', () => {
beforeEach(() => {
jest.resetAllMocks();
jest.spyOn(Keyboard, 'dismiss');
+ jest.spyOn(Keyboard, 'addListener');
+ Keyboard.isVisible = jest.fn().mockReturnValue(false);
});
describe('when provided an itemKey prop', () => {
@@ -144,6 +146,25 @@ describe('RNPickerSelect', () => {
expect(wrapper.state().showPicker).toEqual(true);
});
+ it('should call Keyboard.addListener when keyboard is visible', () => {
+ Keyboard.isVisible.mockReturnValue(true);
+ const wrapper = shallow();
+
+ const touchable = wrapper.find('TouchableOpacity').at(1);
+ touchable.simulate('press');
+ expect(Keyboard.addListener).toHaveBeenCalledTimes(1);
+ expect(Keyboard.addListener).toHaveBeenCalledWith('keyboardDidHide', expect.any(Function));
+ });
+
+ it('should not call Keyboard.addListener when keyboard is not visible', () => {
+ Keyboard.isVisible.mockReturnValue(false);
+ const wrapper = shallow();
+
+ const touchable = wrapper.find('TouchableOpacity').at(1);
+ touchable.simulate('press');
+ expect(Keyboard.addListener).not.toHaveBeenCalled();
+ });
+
it('should not show the picker when pressed if disabled', () => {
const wrapper = shallow(
{
});
it('should call Keyboard.dismiss when opened', () => {
+ Keyboard.isVisible.mockReturnValue(true);
const wrapper = shallow();
const touchable = wrapper.find('[testID="ios_touchable_wrapper"]');