From 9daff8bd374e32a90914a5f8c533474be65d8bb2 Mon Sep 17 00:00:00 2001 From: delangle Date: Thu, 18 Apr 2024 11:33:23 +0200 Subject: [PATCH 1/2] [TreeView] Fix type-ahead --- .../useTreeViewKeyboardNavigation.ts | 65 ++++++------------- 1 file changed, 20 insertions(+), 45 deletions(-) diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts index bcf20f45487f..67c07505fc2e 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts @@ -18,15 +18,6 @@ function isPrintableCharacter(string: string) { return !!string && string.length === 1 && !!string.match(/\S/); } -function findNextFirstChar(firstChars: string[], startIndex: number, char: string) { - for (let i = startIndex; i < firstChars.length; i += 1) { - if (char === firstChars[i]) { - return i; - } - } - return -1; -} - export const useTreeViewKeyboardNavigation: TreeViewPlugin< UseTreeViewKeyboardNavigationSignature > = ({ instance, params, state }) => { @@ -55,47 +46,31 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< firstCharMap.current = newFirstCharMap; }, [state.items.itemMetaMap, params.getItemId, instance]); - const getFirstMatchingItem = (itemId: string, firstChar: string) => { - let start: number; - let index: number; - const lowercaseChar = firstChar.toLowerCase(); - - const firstCharIds: string[] = []; - const firstChars: string[] = []; - // This really only works since the ids are strings - Object.keys(firstCharMap.current).forEach((mapItemId) => { - const map = instance.getItemMeta(mapItemId); - const visible = map.parentId ? instance.isItemExpanded(map.parentId) : true; - const shouldBeSkipped = params.disabledItemsFocusable - ? false - : instance.isItemDisabled(mapItemId); - - if (visible && !shouldBeSkipped) { - firstCharIds.push(mapItemId); - firstChars.push(firstCharMap.current[mapItemId]); - } - }); - - // Get start index for search based on position of currentItem - start = firstCharIds.indexOf(itemId) + 1; - if (start >= firstCharIds.length) { - start = 0; - } + const getFirstMatchingItem = (itemId: string, query: string) => { + const cleanQuery = query.toLowerCase(); - // Check remaining slots in the menu - index = findNextFirstChar(firstChars, start, lowercaseChar); + const getNextItem = (itemIdToCheck: string) => { + const nextItemId = getNextNavigableItem(instance, itemIdToCheck); + // We reached the end of the tree, check from the beginning + if (nextItemId == null) { + return getFirstNavigableItem(instance); + } - // If not found in remaining slots, check from beginning - if (index === -1) { - index = findNextFirstChar(firstChars, 0, lowercaseChar); - } + return nextItemId; + }; - // If a match was found... - if (index > -1) { - return firstCharIds[index]; + let matchingItemId: string | null = null; + let currentItemId: string = getNextItem(itemId); + // The "currentItemId !== itemId" condition is to avoid an infinite loop when there is no matching item. + while (matchingItemId == null && currentItemId !== itemId) { + if (firstCharMap.current[currentItemId] === cleanQuery) { + matchingItemId = currentItemId; + } else { + currentItemId = getNextItem(currentItemId); + } } - return null; + return matchingItemId; }; const canToggleItemSelection = (itemId: string) => From f4261c391013c474fd9a693b8b7bcbc2a29060f3 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Thu, 18 Apr 2024 13:44:26 +0200 Subject: [PATCH 2/2] Update packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts Co-authored-by: Michel Engelen <32863416+michelengelen@users.noreply.github.com> Signed-off-by: Flavien DELANGLE --- .../useTreeViewKeyboardNavigation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts index 67c07505fc2e..643bf09b2a3b 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.ts @@ -52,7 +52,7 @@ export const useTreeViewKeyboardNavigation: TreeViewPlugin< const getNextItem = (itemIdToCheck: string) => { const nextItemId = getNextNavigableItem(instance, itemIdToCheck); // We reached the end of the tree, check from the beginning - if (nextItemId == null) { + if (nextItemId === null) { return getFirstNavigableItem(instance); }