Skip to content

Commit dabfcd5

Browse files
authored
Merge pull request #10 from OlimpiaZurek/add_keyboardDidHide_listener
Implement keyboardDidHide listener and open modal if the Keyboard appears
2 parents c92aab1 + 82ec9e4 commit dabfcd5

File tree

2 files changed

+47
-17
lines changed

2 files changed

+47
-17
lines changed

src/index.js

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import { Dimensions } from 'react-native';
1010
// This height was tested thoroughly on several iPhone Models (from iPhone 8 to 14 Pro)
1111
const IOS_MODAL_HEIGHT = 262;
1212

13-
const preserveSpaces = (label) => {
13+
const preserveSpaces = (label) => {
1414
return label.replace(/ /g, '\u00a0');
15-
}
15+
};
1616

1717
export default class RNPickerSelect extends PureComponent {
1818
static propTypes = {
@@ -151,6 +151,7 @@ export default class RNPickerSelect extends PureComponent {
151151
this.scrollToInput = this.scrollToInput.bind(this);
152152
this.togglePicker = this.togglePicker.bind(this);
153153
this.renderInputAccessoryView = this.renderInputAccessoryView.bind(this);
154+
this.updatePickerState = this.updatePickerState.bind(this);
154155
}
155156

156157
componentDidUpdate = (prevProps, prevState) => {
@@ -264,23 +265,10 @@ export default class RNPickerSelect extends PureComponent {
264265
}
265266
}
266267

267-
togglePicker(animate = false, postToggleCallback) {
268-
const { modalProps, disabled } = this.props;
269-
const { showPicker } = this.state;
270-
271-
if (disabled) {
272-
return;
273-
}
274-
275-
if (!showPicker) {
276-
Keyboard.dismiss();
277-
}
278-
268+
updatePickerState = (animate = false, postToggleCallback) => {
269+
const { modalProps } = this.props;
279270
const animationType =
280271
modalProps && modalProps.animationType ? modalProps.animationType : 'slide';
281-
282-
this.triggerOpenCloseCallbacks();
283-
284272
this.setState(
285273
(prevState) => {
286274
return {
@@ -294,6 +282,26 @@ export default class RNPickerSelect extends PureComponent {
294282
}
295283
}
296284
);
285+
};
286+
287+
togglePicker(animate = false, postToggleCallback) {
288+
const { disabled } = this.props;
289+
290+
if (disabled) {
291+
return;
292+
}
293+
294+
this.triggerOpenCloseCallbacks();
295+
296+
if (Keyboard.isVisible()) {
297+
const keyboardListener = Keyboard.addListener('keyboardDidHide', () => {
298+
this.updatePickerState(animate, postToggleCallback);
299+
keyboardListener.remove();
300+
});
301+
Keyboard.dismiss();
302+
} else {
303+
this.updatePickerState(animate, postToggleCallback);
304+
}
297305
}
298306

299307
renderPickerItems() {

test/test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ describe('RNPickerSelect', () => {
4242
beforeEach(() => {
4343
jest.resetAllMocks();
4444
jest.spyOn(Keyboard, 'dismiss');
45+
jest.spyOn(Keyboard, 'addListener');
46+
Keyboard.isVisible = jest.fn().mockReturnValue(false);
4547
});
4648

4749
describe('when provided an itemKey prop', () => {
@@ -144,6 +146,25 @@ describe('RNPickerSelect', () => {
144146
expect(wrapper.state().showPicker).toEqual(true);
145147
});
146148

149+
it('should call Keyboard.addListener when keyboard is visible', () => {
150+
Keyboard.isVisible.mockReturnValue(true);
151+
const wrapper = shallow(<RNPickerSelect items={selectItems} onValueChange={noop} />);
152+
153+
const touchable = wrapper.find('TouchableOpacity').at(1);
154+
touchable.simulate('press');
155+
expect(Keyboard.addListener).toHaveBeenCalledTimes(1);
156+
expect(Keyboard.addListener).toHaveBeenCalledWith('keyboardDidHide', expect.any(Function));
157+
});
158+
159+
it('should not call Keyboard.addListener when keyboard is not visible', () => {
160+
Keyboard.isVisible.mockReturnValue(false);
161+
const wrapper = shallow(<RNPickerSelect items={selectItems} onValueChange={noop} />);
162+
163+
const touchable = wrapper.find('TouchableOpacity').at(1);
164+
touchable.simulate('press');
165+
expect(Keyboard.addListener).not.toHaveBeenCalled();
166+
});
167+
147168
it('should not show the picker when pressed if disabled', () => {
148169
const wrapper = shallow(
149170
<RNPickerSelect
@@ -245,6 +266,7 @@ describe('RNPickerSelect', () => {
245266
});
246267

247268
it('should call Keyboard.dismiss when opened', () => {
269+
Keyboard.isVisible.mockReturnValue(true);
248270
const wrapper = shallow(<RNPickerSelect items={selectItems} onValueChange={noop} />);
249271

250272
const touchable = wrapper.find('[testID="ios_touchable_wrapper"]');

0 commit comments

Comments
 (0)