diff --git a/components/lib/tree/Tree.js b/components/lib/tree/Tree.js index 085cd7e8a9..6be2bacd48 100644 --- a/components/lib/tree/Tree.js +++ b/components/lib/tree/Tree.js @@ -1,8 +1,7 @@ import * as React from 'react'; import { localeOption, PrimeReactContext } from '../api/Api'; import { useHandleStyle } from '../componentbase/ComponentBase'; -import { useMergeProps } from '../hooks/Hooks'; -import { useUpdateEffect } from '../hooks/useUpdateEffect'; +import { useDebounce, useMergeProps, useUpdateEffect } from '../hooks/Hooks'; import { SearchIcon } from '../icons/search'; import { SpinnerIcon } from '../icons/spinner'; import { classNames, DomHandler, IconUtils, ObjectUtils } from '../utils/Utils'; @@ -15,7 +14,7 @@ export const Tree = React.memo( const context = React.useContext(PrimeReactContext); const props = TreeBase.getProps(inProps, context); - const [filterValueState, setFilterValueState] = React.useState(''); + const [filterValue, filterValueState, setFilterValueState] = useDebounce('', props.filterDelay || 0); const [expandedKeysState, setExpandedKeysState] = React.useState(props.expandedKeys); const elementRef = React.useRef(null); const filteredNodes = React.useRef([]); @@ -523,7 +522,9 @@ export const Tree = React.memo( const createFilter = () => { if (props.filter) { - const value = ObjectUtils.isNotEmpty(filteredValue) ? filteredValue : ''; + let value = props.onFilterValueChange ? props.filterValue : filterValue; + + value = ObjectUtils.isNotEmpty(value) ? value : ''; const searchIconProps = mergeProps( { className: cx('searchIcon') diff --git a/components/lib/tree/TreeBase.js b/components/lib/tree/TreeBase.js index 48b9f37ea9..a717c64656 100644 --- a/components/lib/tree/TreeBase.js +++ b/components/lib/tree/TreeBase.js @@ -129,6 +129,7 @@ export const TreeBase = ComponentBase.extend({ expandedKeys: null, filter: false, filterBy: 'label', + filterDelay: 300, filterIcon: null, filterLocale: undefined, filterMode: 'lenient', diff --git a/components/lib/tree/tree.d.ts b/components/lib/tree/tree.d.ts index 328eab06b0..32eebe5625 100644 --- a/components/lib/tree/tree.d.ts +++ b/components/lib/tree/tree.d.ts @@ -542,6 +542,11 @@ export interface TreeProps { * @defaultValue false */ filter?: boolean | undefined; + /** + * Delay in milliseconds before filtering the data. + * @defaultValue 300 + */ + filterDelay?: number | undefined; /** * Icon of the filter. */ diff --git a/components/lib/treeselect/TreeSelect.js b/components/lib/treeselect/TreeSelect.js index 8f04fe831d..a5b135b9ba 100644 --- a/components/lib/treeselect/TreeSelect.js +++ b/components/lib/treeselect/TreeSelect.js @@ -1,7 +1,7 @@ import * as React from 'react'; -import PrimeReact, { PrimeReactContext, localeOption, ariaLabel } from '../api/Api'; +import PrimeReact, { PrimeReactContext, ariaLabel, localeOption } from '../api/Api'; import { useHandleStyle } from '../componentbase/ComponentBase'; -import { useMergeProps, useMountEffect, useOverlayListener, useUnmountEffect, useUpdateEffect } from '../hooks/Hooks'; +import { useDebounce, useMergeProps, useMountEffect, useOverlayListener, useUnmountEffect, useUpdateEffect } from '../hooks/Hooks'; import { ChevronDownIcon } from '../icons/chevrondown'; import { SearchIcon } from '../icons/search'; import { TimesIcon } from '../icons/times'; @@ -22,7 +22,7 @@ export const TreeSelect = React.memo( const [focusedState, setFocusedState] = React.useState(false); const [overlayVisibleState, setOverlayVisibleState] = React.useState(false); const [expandedKeysState, setExpandedKeysState] = React.useState(props.expandedKeys); - const [filterValueState, setFilterValueState] = React.useState(''); + const [filterValue, filterValueState, setFilterValueState] = useDebounce('', props.filterDelay || 0); const elementRef = React.useRef(null); const overlayRef = React.useRef(null); const filterInputRef = React.useRef(null); @@ -667,6 +667,7 @@ export const TreeSelect = React.memo( expandedKeys={expandedKeys} filter={props.filter} filterBy={props.filterBy} + filterDelay={props.filterDelay} filterLocale={props.filterLocale} filterMode={props.filterMode} filterPlaceholder={props.filterPlaceholder} @@ -696,7 +697,9 @@ export const TreeSelect = React.memo( const createFilterElement = () => { if (props.filter) { - const filterValue = ObjectUtils.isNotEmpty(filteredValue) ? filteredValue : ''; + let filterValue = props.onFilterValueChange ? props.filterValue : filterValue; + + filterValue = ObjectUtils.isNotEmpty(filterValue) ? filterValue : ''; const filterContainerProps = mergeProps( { className: cx('filterContainer') diff --git a/components/lib/treeselect/TreeSelectBase.js b/components/lib/treeselect/TreeSelectBase.js index 28f0a38290..07c360f9c6 100644 --- a/components/lib/treeselect/TreeSelectBase.js +++ b/components/lib/treeselect/TreeSelectBase.js @@ -150,6 +150,7 @@ export const TreeSelectBase = ComponentBase.extend({ expandedKeys: null, filter: false, filterBy: 'label', + filterDelay: 300, filterIcon: null, filterInputAutoFocus: true, filterLocale: undefined, diff --git a/components/lib/treeselect/treeselect.d.ts b/components/lib/treeselect/treeselect.d.ts index b3fb79afbe..c8641271f5 100644 --- a/components/lib/treeselect/treeselect.d.ts +++ b/components/lib/treeselect/treeselect.d.ts @@ -428,6 +428,11 @@ export interface TreeSelectProps extends Omit