Skip to content

Commit

Permalink
Prevent flashing when moving focus between child elements
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronccasanova committed Mar 28, 2024
1 parent 44b42ec commit fcc4191
Showing 1 changed file with 23 additions and 4 deletions.
27 changes: 23 additions & 4 deletions polaris-react/src/utilities/use-focus.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {RefObject} from 'react';
import {useState, useCallback} from 'react';
import {useCallback, useEffect, useRef, useState} from 'react';

import {useEventListener} from './use-event-listener';

Expand Down Expand Up @@ -27,12 +27,31 @@ export function useFocusIn(
ref: RefObject<HTMLElement>,
): boolean {
const [isFocusedIn, setIsFocusedIn] = useState(false);

const handleFocusIn = useCallback(() => setIsFocusedIn(true), []);
const handleFocusOut = useCallback(() => setIsFocusedIn(false), []);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);

const handleFocusIn = useCallback(() => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
setIsFocusedIn(true);
}, []);

const handleFocusOut = useCallback(() => {
// Prevents flashing when moving focus between child elements
timeoutRef.current = setTimeout(() => {
setIsFocusedIn(false);
}, 0);
}, []);

useEventListener('focusin', handleFocusIn, ref);
useEventListener('focusout', handleFocusOut, ref);
useEffect(
() => () => {
if (timeoutRef.current) clearTimeout(timeoutRef.current);
},
[],
);

return isFocusedIn;
}

0 comments on commit fcc4191

Please sign in to comment.