Skip to content

Commit c4bfd4b

Browse files
committed
fix(UI): Add short delay before auto focus on email first
Because: * Users are sometimes seeing what seems to be an orphaned dropdown email list This commit: * Adds a very short settimeout on autofocus of that input, to prevent the dropdown being orphaned if the input unmounts mid-render closes FXA-14009
1 parent d71dc16 commit c4bfd4b

2 files changed

Lines changed: 39 additions & 2 deletions

File tree

packages/fxa-settings/src/pages/Index/index.test.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import { screen, waitFor } from '@testing-library/react';
5+
import { act, screen, waitFor } from '@testing-library/react';
66
import { userEvent } from '@testing-library/user-event';
77
import { createMockIndexOAuthNativeIntegration, Subject } from './mocks';
88
import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localizationProvider';
@@ -252,4 +252,30 @@ describe('Index page', () => {
252252
).toHaveAttribute('data-glean-id', 'email_first_submit');
253253
});
254254
});
255+
256+
describe('email input auto-focus', () => {
257+
beforeEach(() => {
258+
jest.useFakeTimers();
259+
});
260+
261+
afterEach(() => {
262+
jest.useRealTimers();
263+
});
264+
265+
it('does not focus the email input until the defer timeout elapses', () => {
266+
renderWithLocalizationProvider(<Subject />);
267+
268+
expect(screen.getByLabelText('Enter your email')).not.toHaveFocus();
269+
});
270+
271+
it('focuses the email input after the defer timeout elapses', () => {
272+
renderWithLocalizationProvider(<Subject />);
273+
274+
act(() => {
275+
jest.advanceTimersByTime(10);
276+
});
277+
278+
expect(screen.getByLabelText('Enter your email')).toHaveFocus();
279+
});
280+
});
255281
});

packages/fxa-settings/src/pages/Index/index.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,22 @@ export const Index = ({
7979
const legalTerms = integration.getLegalTerms();
8080

8181
const emailEngageEventEmitted = useRef(false);
82+
const emailInputRef = useRef<HTMLInputElement>(null);
8283

8384
useEffect(() => {
8485
GleanMetrics.emailFirst.view();
8586
}, []);
8687

88+
// Defer auto-focus once. If the container redirects an already-signed-in user
89+
// away, intermittently the browser's email autocomplete dropdown can be shown on
90+
// the next page, presumably from a redirect mid-render. See FXA-14009
91+
useEffect(() => {
92+
const timer = setTimeout(() => {
93+
emailInputRef.current?.focus();
94+
}, 10);
95+
return () => clearTimeout(timer);
96+
}, []);
97+
8798
const onSubmit = async ({ email }: IndexFormData) => {
8899
setIsSubmitting(true);
89100
try {
@@ -198,7 +209,7 @@ export const Index = ({
198209
inputMode="email"
199210
label="Enter your email"
200211
inputRef={register()}
201-
autoFocus
212+
inputRefDOM={emailInputRef}
202213
errorText={tooltipErrorMessage}
203214
onChange={handleInputChange}
204215
autoCapitalize="off"

0 commit comments

Comments
 (0)