From 478980f40941881dd1adeba78112317b05651eaa Mon Sep 17 00:00:00 2001 From: Ilza Medeiros Date: Mon, 6 Nov 2023 09:26:13 -0300 Subject: [PATCH] fix(@clayui/treeview) - Fix ClayTreeView broken when using filtered items --- .../src/tree-view/useMultipleSelection.tsx | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/clay-core/src/tree-view/useMultipleSelection.tsx b/packages/clay-core/src/tree-view/useMultipleSelection.tsx index 75b2942792..f81ba3436b 100644 --- a/packages/clay-core/src/tree-view/useMultipleSelection.tsx +++ b/packages/clay-core/src/tree-view/useMultipleSelection.tsx @@ -4,7 +4,7 @@ */ import {useControlledState} from '@clayui/shared'; -import {Key, useCallback, useMemo, useRef} from 'react'; +import {Key, useCallback, useEffect, useMemo, useRef} from 'react'; import {getKey} from '../collection'; import {ITreeProps, createImmutableTree} from './useTree'; @@ -139,6 +139,10 @@ export function useMultipleSelection>( key ) as LayoutInfo; + if (!keyMap) { + return false; + } + const children = [...keyMap.children]; const unselected = children.some( @@ -165,6 +169,43 @@ export function useMultipleSelection>( } }, [selectedKeys]); + /** + * This `useEffect` makes `useMemo` been called every time the items change and + * this can cause some performance issues. We cannot change the `useMemo` because + * it's needed in other treeview cases. This needs improvements in the future. + */ + + useEffect(() => { + if (props.selectionMode === 'multiple-recursive' && !isUncontrolled) { + const newSelectedKeys = new Set(selectedKeys); + + props.layoutKeys.current.forEach((keyMap, key) => { + if (!keyMap) { + return false; + } + + const children = [...keyMap.children]; + + if (!children.length) { + return; + } + + if (children.every((key) => selectedKeys.has(key))) { + newSelectedKeys.add(key); + indeterminateKeys.current.delete(key); + } else if (children.some((key) => selectedKeys.has(key))) { + newSelectedKeys.delete(key); + indeterminateKeys.current.add(key); + } else { + newSelectedKeys.delete(key); + indeterminateKeys.current.delete(key); + } + }); + + setSelectionKeys(newSelectedKeys); + } + }, [props.items]); + const toggleParentSelection = useCallback( ( hasIndeterminate: boolean,