Skip to content

Commit f68f312

Browse files
authored
feat: support 'editable' prop on TextInput (#517)
* test: Add tests for non-editable TextInput * feat: use editable prop to check for event handling
1 parent d55ea0b commit f68f312

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

src/__tests__/fireEvent.test.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,46 @@ test('should not fire on disabled Pressable', () => {
193193
expect(handlePress).not.toHaveBeenCalled();
194194
});
195195

196+
test('should not fire on non-editable TextInput', () => {
197+
const placeholder = 'Test placeholder';
198+
const onChangeTextMock = jest.fn();
199+
const NEW_TEXT = 'New text';
200+
201+
const { getByPlaceholderText } = render(
202+
<View>
203+
<TextInput
204+
editable={false}
205+
placeholder={placeholder}
206+
onChangeText={onChangeTextMock}
207+
/>
208+
</View>
209+
);
210+
211+
fireEvent.changeText(getByPlaceholderText(placeholder), NEW_TEXT);
212+
expect(onChangeTextMock).not.toHaveBeenCalled();
213+
});
214+
215+
test('should not fire on non-editable TextInput with nested Text', () => {
216+
const placeholder = 'Test placeholder';
217+
const onChangeTextMock = jest.fn();
218+
const NEW_TEXT = 'New text';
219+
220+
const { getByPlaceholderText } = render(
221+
<View>
222+
<TextInput
223+
editable={false}
224+
placeholder={placeholder}
225+
onChangeText={onChangeTextMock}
226+
>
227+
<Text>Test text</Text>
228+
</TextInput>
229+
</View>
230+
);
231+
232+
fireEvent.changeText(getByPlaceholderText(placeholder), NEW_TEXT);
233+
expect(onChangeTextMock).not.toHaveBeenCalled();
234+
});
235+
196236
test('should pass event up on disabled TouchableOpacity', () => {
197237
const handleInnerPress = jest.fn();
198238
const handleOuterPress = jest.fn();

src/fireEvent.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
import act from './act';
33
import { ErrorWithStack } from './helpers/errors';
44

5+
const isTextInputComponent = (element: ReactTestInstance) => {
6+
// eslint-disable-next-line import/no-extraneous-dependencies
7+
const { TextInput } = require('react-native');
8+
return element.type === TextInput;
9+
};
10+
511
const findEventHandler = (
612
element: ReactTestInstance,
713
eventName: string,
@@ -14,8 +20,11 @@ const findEventHandler = (
1420

1521
const isHostComponent = typeof element.type === 'string';
1622
const hostElement = isHostComponent ? element : nearestHostDescendent;
17-
const isEventEnabled =
18-
hostElement?.props.onStartShouldSetResponder?.() !== false;
23+
24+
const isEventEnabled = isTextInputComponent(element)
25+
? element.props.editable !== false
26+
: hostElement?.props.onStartShouldSetResponder?.() !== false;
27+
1928
if (handler && isEventEnabled) return handler;
2029

2130
// Do not bubble event to the root element

0 commit comments

Comments
 (0)