From e7e73c8e1c5fea51fc7d5d626afe066b007325c1 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Wed, 22 May 2024 21:32:38 +0200 Subject: [PATCH] fix: keyboard shortcuts in selection lists --- .../SelectionList/BaseSelectionList.tsx | 13 +++++++++- src/utils/arraysEqual.ts | 25 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/utils/arraysEqual.ts diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index 77b296740f2c..3e0ca80b5e41 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -26,6 +26,7 @@ import Log from '@libs/Log'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import arraysEqual from '@src/utils/arraysEqual'; import type {BaseSelectionListProps, ButtonOrCheckBoxRoles, FlattenedSectionsReturn, ListItem, SectionListDataType, SectionWithIndexOffset, SelectionListHandle} from './types'; function BaseSelectionList( @@ -228,11 +229,21 @@ function BaseSelectionList( [flattenedSections.allOptions], ); + const [disabledIndexes, setDisabledIndexes] = useState(flattenedSections.disabledOptionsIndexes); + useEffect(() => { + if (arraysEqual(disabledIndexes, flattenedSections.disabledOptionsIndexes)) { + return; + } + + setDisabledIndexes(flattenedSections.disabledOptionsIndexes); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [flattenedSections.disabledOptionsIndexes]); + // If `initiallyFocusedOptionKey` is not passed, we fall back to `-1`, to avoid showing the highlight on the first member const [focusedIndex, setFocusedIndex] = useArrowKeyFocusManager({ initialFocusedIndex: flattenedSections.allOptions.findIndex((option) => option.keyForList === initiallyFocusedOptionKey), maxIndex: Math.min(flattenedSections.allOptions.length - 1, CONST.MAX_SELECTION_LIST_PAGE_LENGTH * currentPage - 1), - disabledIndexes: flattenedSections.disabledOptionsIndexes, + disabledIndexes, isActive: true, onFocusedIndexChange: (index: number) => { scrollToIndex(index, true); diff --git a/src/utils/arraysEqual.ts b/src/utils/arraysEqual.ts new file mode 100644 index 000000000000..3a8111cc7bb7 --- /dev/null +++ b/src/utils/arraysEqual.ts @@ -0,0 +1,25 @@ +function arraysEqual(a: T[], b: T[]): boolean { + if (a === b) { + return true; + } + if (a == null || b == null) { + return false; + } + if (a.length !== b.length) { + return false; + } + + // If you don't care about the order of the elements inside + // the array, you should sort both arrays here. + // Please note that calling sort on an array will modify that array. + // you might want to clone your array first. + + for (let i = 0; i < a.length; ++i) { + if (a[i] !== b[i]) { + return false; + } + } + return true; +} + +export default arraysEqual;