-
Notifications
You must be signed in to change notification settings - Fork 37
/
index.ts
42 lines (36 loc) · 1.24 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { useState, useEffect, useCallback, useMemo } from '@wordpress/element';
import uFuzzy from '@leeoniya/ufuzzy';
// eslint-disable-next-line new-cap
const fuzzy = new uFuzzy();
/**
* useFilteredList
*
* @param {Array} list list of items to filter
* @param {string} searchTerm search term string
* @param {string?} property name of the prop
* @returns {Array} filtered list
*/
export function useFilteredList<TListItem extends { [key: string]: string }>(
list: TListItem[] = [],
searchTerm = '',
property: keyof TListItem = 'name',
) {
const [filteredList, setFilteredList] = useState(list);
const propertyList = useMemo(() => list.map((item) => item[property]), [list, property]);
const filterList = useCallback(
(searchTerm: string) => {
const matchedNames = fuzzy.filter(propertyList, searchTerm);
const results = matchedNames?.map((index) => list[index]) || [];
return results;
},
[propertyList, list],
);
useEffect(() => {
const hasListItems = !!list?.length;
const hasSearchTerm = searchTerm !== '';
const canFilter = hasSearchTerm && hasListItems;
const newFilteredList = canFilter ? filterList(searchTerm) : list;
setFilteredList(newFilteredList);
}, [searchTerm, filterList, list]);
return [filteredList];
}