Skip to content
Merged
2 changes: 1 addition & 1 deletion src/components/SelectionList/BaseListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function BaseListItem<TItem extends ListItem>({
const pressableRef = useRef<View | HTMLDivElement>(null);

// Sync focus on an item
useSyncFocus(pressableRef, Boolean(isFocused && shouldSyncFocus));
useSyncFocus(pressableRef, Boolean(isFocused), shouldSyncFocus);

const rightHandSideComponentRender = () => {
if (canSelectMultiple || !rightHandSideComponent) {
Expand Down
10 changes: 7 additions & 3 deletions src/hooks/useSyncFocus/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import {useLayoutEffect} from 'react';
import type {RefObject} from 'react';
import type {View} from 'react-native';
import useScreenWrapperTranstionStatus from '@hooks/useScreenWrapperTransitionStatus';

/**
* Custom React hook created to handle sync of focus on an element when the user navigates through the app with keyboard.
* When the user navigates through the app using the arrows and then the tab button, the focus on the element and the native focus of the browser differs.
* To maintain consistency when an element is focused in the app, the focus() method is additionally called on the focused element to eliminate the difference between native browser focus and application focus.
*/
const useSyncFocus = (ref: RefObject<HTMLDivElement | View>, isFocused: boolean) => {
const useSyncFocus = (ref: RefObject<HTMLDivElement | View>, isFocused: boolean, shouldSyncFocus = true) => {
const {didScreenTransitionEnd} = useScreenWrapperTranstionStatus();

useLayoutEffect(() => {
if (!isFocused) {
if (!isFocused || !shouldSyncFocus || !didScreenTransitionEnd) {
return;
}

ref.current?.focus();
}, [isFocused, ref]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [didScreenTransitionEnd, isFocused, ref]);
};

export default useSyncFocus;
4 changes: 4 additions & 0 deletions tests/perf-test/SelectionList.perf-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ jest.mock('@components/withKeyboardState', () => <TProps extends KeyboardStateCo
return WrappedComponent;
});

jest.mock('@react-navigation/stack', () => ({
useCardAnimation: () => {},
}));

jest.mock('@react-navigation/native', () => ({
useFocusEffect: () => {},
useIsFocused: () => true,
Expand Down