Skip to content

Commit

Permalink
Merge pull request #41968 from bernhardoj/fix/41570-cant-navigate-to-…
Browse files Browse the repository at this point in the history
…disabled-checkbox-item-using-arrow-keyboard

Fix can't navigate with arrow key to admin in group members page
  • Loading branch information
puneetlath authored May 27, 2024
2 parents 7abb749 + acc4b28 commit b565af1
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,18 @@ function BaseSelectionList<TItem extends ListItem>(
const incrementPage = () => setCurrentPage((prev) => prev + 1);

/**
* Iterates through the sections and items inside each section, and builds 3 arrays along the way:
* Iterates through the sections and items inside each section, and builds 4 arrays along the way:
* - `allOptions`: Contains all the items in the list, flattened, regardless of section
* - `disabledOptionsIndexes`: Contains the indexes of all the disabled items in the list, to be used by the ArrowKeyFocusManager
* - `disabledOptionsIndexes`: Contains the indexes of all the unselectable and disabled items in the list
* - `disabledArrowKeyOptionsIndexes`: Contains the indexes of item that is not navigatable by the arrow key. The list is separated from disabledOptionsIndexes because unselectable item is still navigatable by the arrow key.
* - `itemLayouts`: Contains the layout information for each item, header and footer in the list,
* so we can calculate the position of any given item when scrolling programmatically
*/
const flattenedSections = useMemo<FlattenedSectionsReturn<TItem>>(() => {
const allOptions: TItem[] = [];

const disabledOptionsIndexes: number[] = [];
const disabledArrowKeyOptionsIndexes: number[] = [];
let disabledIndex = 0;

let offset = 0;
Expand All @@ -134,9 +136,13 @@ function BaseSelectionList<TItem extends ListItem>(
});

// If disabled, add to the disabled indexes array
const isItemDisabled = !!section.isDisabled || (item.isDisabled && !item.isSelected);
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if (!!section.isDisabled || (item.isDisabled && !item.isSelected) || item.isDisabledCheckbox) {
if (isItemDisabled || item.isDisabledCheckbox) {
disabledOptionsIndexes.push(disabledIndex);
if (isItemDisabled) {
disabledArrowKeyOptionsIndexes.push(disabledIndex);
}
}
disabledIndex += 1;

Expand Down Expand Up @@ -169,6 +175,7 @@ function BaseSelectionList<TItem extends ListItem>(
allOptions,
selectedOptions,
disabledOptionsIndexes,
disabledArrowKeyOptionsIndexes,
itemLayouts,
allSelected: selectedOptions.length > 0 && selectedOptions.length === allOptions.length - disabledOptionsIndexes.length,
};
Expand Down Expand Up @@ -230,21 +237,21 @@ function BaseSelectionList<TItem extends ListItem>(
[flattenedSections.allOptions],
);

const [disabledIndexes, setDisabledIndexes] = useState(flattenedSections.disabledOptionsIndexes);
const [disabledArrowKeyIndexes, setDisabledArrowKeyIndexes] = useState(flattenedSections.disabledArrowKeyOptionsIndexes);
useEffect(() => {
if (arraysEqual(disabledIndexes, flattenedSections.disabledOptionsIndexes)) {
if (arraysEqual(disabledArrowKeyIndexes, flattenedSections.disabledArrowKeyOptionsIndexes)) {
return;
}

setDisabledIndexes(flattenedSections.disabledOptionsIndexes);
setDisabledArrowKeyIndexes(flattenedSections.disabledArrowKeyOptionsIndexes);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [flattenedSections.disabledOptionsIndexes]);
}, [flattenedSections.disabledArrowKeyOptionsIndexes]);

// 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,
disabledIndexes: disabledArrowKeyIndexes,
isActive: true,
onFocusedIndexChange: (index: number) => {
scrollToIndex(index, true);
Expand Down
1 change: 1 addition & 0 deletions src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ type FlattenedSectionsReturn<TItem extends ListItem> = {
allOptions: TItem[];
selectedOptions: TItem[];
disabledOptionsIndexes: number[];
disabledArrowKeyOptionsIndexes: number[];
itemLayouts: ItemLayout[];
allSelected: boolean;
};
Expand Down

0 comments on commit b565af1

Please sign in to comment.