From 1973cbcaf9155ad4f5efdfb9caae10d16db1485f Mon Sep 17 00:00:00 2001 From: "MD. MOHIBUR RAHMAN" <35300157+mrpmohiburrahman@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:47:29 +0600 Subject: [PATCH] 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 --- .../type/__tests__/type-managed.test.tsx | 27 +++++++++++++++++ src/user-event/type/__tests__/type.test.tsx | 30 +++++++++++++++++++ src/user-event/type/type.ts | 8 +++-- .../docs/12.x/docs/api/events/user-event.mdx | 7 +++-- .../13.x-next/docs/api/events/user-event.mdx | 7 +++-- 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/user-event/type/__tests__/type-managed.test.tsx b/src/user-event/type/__tests__/type-managed.test.tsx index 37e9f03c7..6b1f45c9f 100644 --- a/src/user-event/type/__tests__/type-managed.test.tsx +++ b/src/user-event/type/__tests__/type-managed.test.tsx @@ -110,4 +110,31 @@ describe('type() for managed TextInput', () => { expect(events).toMatchSnapshot('input: "ABC", value: "XXX"'); }); + + it('skips blur and endEditing events when `skipBlur: true` in managed TextInput', async () => { + const { events, logEvent } = createEventLogger(); + render(); + + const user = userEvent.setup(); + await user.type(screen.getByTestId('input'), 'a', { + skipBlur: true, + }); + + const eventNames = getEventsNames(events); + + // Ensure 'endEditing' and 'blur' are not present + expect(eventNames).not.toContain('endEditing'); + expect(eventNames).not.toContain('blur'); + + // Verify the exact events that should be present + expect(eventNames).toEqual([ + 'pressIn', + 'focus', + 'pressOut', + 'keyPress', + 'change', + 'changeText', + 'selectionChange', + ]); + }); }); diff --git a/src/user-event/type/__tests__/type.test.tsx b/src/user-event/type/__tests__/type.test.tsx index 5753f4168..474216f58 100644 --- a/src/user-event/type/__tests__/type.test.tsx +++ b/src/user-event/type/__tests__/type.test.tsx @@ -386,4 +386,34 @@ describe('type()', () => { await user.type(input, ' World'); expect(input).toHaveDisplayValue('Hello World'); }); + + it('skips blur and endEditing events when `skipBlur: true`', async () => { + const { events } = renderTextInputWithToolkit(); + + const user = userEvent.setup(); + await user.type(screen.getByTestId('input'), 'a', { + skipBlur: true, + }); + + const eventNames = getEventsNames(events); + + // Ensure 'endEditing' and 'blur' are not present + expect(eventNames).not.toContain('endEditing'); + expect(eventNames).not.toContain('blur'); + + // Verify the exact events that should be present + expect(eventNames).toEqual([ + 'pressIn', + 'focus', + 'pressOut', + 'keyPress', + 'change', + 'changeText', + 'selectionChange', + ]); + + expect(lastEventPayload(events, 'selectionChange')).toMatchObject({ + nativeEvent: { selection: { start: 1, end: 1 } }, + }); + }); }); diff --git a/src/user-event/type/type.ts b/src/user-event/type/type.ts index 19fa66cc2..e9fcdf134 100644 --- a/src/user-event/type/type.ts +++ b/src/user-event/type/type.ts @@ -12,6 +12,7 @@ import { parseKeys } from './parse-keys'; export interface TypeOptions { skipPress?: boolean; submitEditing?: boolean; + skipBlur?: boolean; } export async function type( @@ -67,9 +68,10 @@ export async function type( dispatchEvent(element, 'submitEditing', EventBuilder.TextInput.submitEditing(finalText)); } - dispatchEvent(element, 'endEditing', EventBuilder.TextInput.endEditing(finalText)); - - dispatchEvent(element, 'blur', EventBuilder.Common.blur()); + if (!options?.skipBlur) { + dispatchEvent(element, 'endEditing', EventBuilder.TextInput.endEditing(finalText)); + dispatchEvent(element, 'blur', EventBuilder.Common.blur()); + } } type EmitTypingEventsContext = { diff --git a/website/docs/12.x/docs/api/events/user-event.mdx b/website/docs/12.x/docs/api/events/user-event.mdx index 5a8379fe8..8bbc10907 100644 --- a/website/docs/12.x/docs/api/events/user-event.mdx +++ b/website/docs/12.x/docs/api/events/user-event.mdx @@ -86,8 +86,9 @@ type( element: ReactTestInstance, text: string, options?: { - skipPress?: boolean - submitEditing?: boolean + skipPress?: boolean; + skipBlur?: boolean; + submitEditing?: boolean; } ``` @@ -109,6 +110,7 @@ This function will add text to the text already present in the text input (as sp ### Options {#type-options} - `skipPress` - if true, `pressIn` and `pressOut` events will not be triggered. +- `skipBlur` - if true, `endEditing` and `blur` events will not be triggered when typing is complete. - `submitEditing` - if true, `submitEditing` event will be triggered after typing the text. ### Sequence of events {#type-sequence} @@ -140,6 +142,7 @@ The `pressIn` and `pressOut` events are sent by default but can be skipped by pa - `blur` The `submitEditing` event is skipped by default. It can sent by setting the `submitEditing: true` option. +The `endEditing` and `blur` events can be skipped by passing the `skipBlur: true` option. ## `clear()` diff --git a/website/docs/13.x-next/docs/api/events/user-event.mdx b/website/docs/13.x-next/docs/api/events/user-event.mdx index 02eb4821f..f554bc53e 100644 --- a/website/docs/13.x-next/docs/api/events/user-event.mdx +++ b/website/docs/13.x-next/docs/api/events/user-event.mdx @@ -80,8 +80,9 @@ type( element: ReactTestInstance, text: string, options?: { - skipPress?: boolean - submitEditing?: boolean + skipPress?: boolean; + skipBlur?: boolean; + submitEditing?: boolean; } ``` @@ -103,6 +104,7 @@ This function will add text to the text already present in the text input (as sp ### Options {#type-options} - `skipPress` - if true, `pressIn` and `pressOut` events will not be triggered. +- `skipBlur` - if true, `endEditing` and `blur` events will not be triggered when typing is complete. - `submitEditing` - if true, `submitEditing` event will be triggered after typing the text. ### Sequence of events {#type-sequence} @@ -134,6 +136,7 @@ The `pressIn` and `pressOut` events are sent by default but can be skipped by pa - `blur` The `submitEditing` event is skipped by default. It can sent by setting the `submitEditing: true` option. +The `endEditing` and `blur` events can be skipped by passing the `skipBlur: true` option. ## `clear()`