Skip to content

Commit 1973cbc

Browse files
feat: add skip blur option (#1704)
* feat: add skip blur option * fix: skipBlur option disables both endEditing and blur * docs: add skipBlur option to doc * test: add unit testing for skipBlur * docs: tweak * docs: tweaks * chore: fix lint --------- Co-authored-by: Maciej Jastrzebski <[email protected]>
1 parent 2c52201 commit 1973cbc

File tree

5 files changed

+72
-7
lines changed

5 files changed

+72
-7
lines changed

src/user-event/type/__tests__/type-managed.test.tsx

+27
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,31 @@ describe('type() for managed TextInput', () => {
110110

111111
expect(events).toMatchSnapshot('input: "ABC", value: "XXX"');
112112
});
113+
114+
it('skips blur and endEditing events when `skipBlur: true` in managed TextInput', async () => {
115+
const { events, logEvent } = createEventLogger();
116+
render(<ManagedTextInput logEvent={logEvent} />);
117+
118+
const user = userEvent.setup();
119+
await user.type(screen.getByTestId('input'), 'a', {
120+
skipBlur: true,
121+
});
122+
123+
const eventNames = getEventsNames(events);
124+
125+
// Ensure 'endEditing' and 'blur' are not present
126+
expect(eventNames).not.toContain('endEditing');
127+
expect(eventNames).not.toContain('blur');
128+
129+
// Verify the exact events that should be present
130+
expect(eventNames).toEqual([
131+
'pressIn',
132+
'focus',
133+
'pressOut',
134+
'keyPress',
135+
'change',
136+
'changeText',
137+
'selectionChange',
138+
]);
139+
});
113140
});

src/user-event/type/__tests__/type.test.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -386,4 +386,34 @@ describe('type()', () => {
386386
await user.type(input, ' World');
387387
expect(input).toHaveDisplayValue('Hello World');
388388
});
389+
390+
it('skips blur and endEditing events when `skipBlur: true`', async () => {
391+
const { events } = renderTextInputWithToolkit();
392+
393+
const user = userEvent.setup();
394+
await user.type(screen.getByTestId('input'), 'a', {
395+
skipBlur: true,
396+
});
397+
398+
const eventNames = getEventsNames(events);
399+
400+
// Ensure 'endEditing' and 'blur' are not present
401+
expect(eventNames).not.toContain('endEditing');
402+
expect(eventNames).not.toContain('blur');
403+
404+
// Verify the exact events that should be present
405+
expect(eventNames).toEqual([
406+
'pressIn',
407+
'focus',
408+
'pressOut',
409+
'keyPress',
410+
'change',
411+
'changeText',
412+
'selectionChange',
413+
]);
414+
415+
expect(lastEventPayload(events, 'selectionChange')).toMatchObject({
416+
nativeEvent: { selection: { start: 1, end: 1 } },
417+
});
418+
});
389419
});

src/user-event/type/type.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { parseKeys } from './parse-keys';
1212
export interface TypeOptions {
1313
skipPress?: boolean;
1414
submitEditing?: boolean;
15+
skipBlur?: boolean;
1516
}
1617

1718
export async function type(
@@ -67,9 +68,10 @@ export async function type(
6768
dispatchEvent(element, 'submitEditing', EventBuilder.TextInput.submitEditing(finalText));
6869
}
6970

70-
dispatchEvent(element, 'endEditing', EventBuilder.TextInput.endEditing(finalText));
71-
72-
dispatchEvent(element, 'blur', EventBuilder.Common.blur());
71+
if (!options?.skipBlur) {
72+
dispatchEvent(element, 'endEditing', EventBuilder.TextInput.endEditing(finalText));
73+
dispatchEvent(element, 'blur', EventBuilder.Common.blur());
74+
}
7375
}
7476

7577
type EmitTypingEventsContext = {

website/docs/12.x/docs/api/events/user-event.mdx

+5-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@ type(
8686
element: ReactTestInstance,
8787
text: string,
8888
options?: {
89-
skipPress?: boolean
90-
submitEditing?: boolean
89+
skipPress?: boolean;
90+
skipBlur?: boolean;
91+
submitEditing?: boolean;
9192
}
9293
```
9394
@@ -109,6 +110,7 @@ This function will add text to the text already present in the text input (as sp
109110
### Options {#type-options}
110111
111112
- `skipPress` - if true, `pressIn` and `pressOut` events will not be triggered.
113+
- `skipBlur` - if true, `endEditing` and `blur` events will not be triggered when typing is complete.
112114
- `submitEditing` - if true, `submitEditing` event will be triggered after typing the text.
113115
114116
### Sequence of events {#type-sequence}
@@ -140,6 +142,7 @@ The `pressIn` and `pressOut` events are sent by default but can be skipped by pa
140142
- `blur`
141143
142144
The `submitEditing` event is skipped by default. It can sent by setting the `submitEditing: true` option.
145+
The `endEditing` and `blur` events can be skipped by passing the `skipBlur: true` option.
143146
144147
## `clear()`
145148

website/docs/13.x-next/docs/api/events/user-event.mdx

+5-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ type(
8080
element: ReactTestInstance,
8181
text: string,
8282
options?: {
83-
skipPress?: boolean
84-
submitEditing?: boolean
83+
skipPress?: boolean;
84+
skipBlur?: boolean;
85+
submitEditing?: boolean;
8586
}
8687
```
8788
@@ -103,6 +104,7 @@ This function will add text to the text already present in the text input (as sp
103104
### Options {#type-options}
104105
105106
- `skipPress` - if true, `pressIn` and `pressOut` events will not be triggered.
107+
- `skipBlur` - if true, `endEditing` and `blur` events will not be triggered when typing is complete.
106108
- `submitEditing` - if true, `submitEditing` event will be triggered after typing the text.
107109
108110
### Sequence of events {#type-sequence}
@@ -134,6 +136,7 @@ The `pressIn` and `pressOut` events are sent by default but can be skipped by pa
134136
- `blur`
135137
136138
The `submitEditing` event is skipped by default. It can sent by setting the `submitEditing: true` option.
139+
The `endEditing` and `blur` events can be skipped by passing the `skipBlur: true` option.
137140
138141
## `clear()`
139142

0 commit comments

Comments
 (0)