react-virtual-renderer 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -122
- package/dist/components/VirtualGrid.d.ts +2 -6
- package/dist/components/VirtualGrid.d.ts.map +1 -1
- package/dist/components/VirtualGrid.js +112 -147
- package/dist/components/VirtualGrid.js.map +1 -1
- package/dist/components/VirtualList.d.ts.map +1 -1
- package/dist/components/VirtualList.js +51 -29
- package/dist/components/VirtualList.js.map +1 -1
- package/dist/core/MeasurementSystem.d.ts +18 -24
- package/dist/core/MeasurementSystem.d.ts.map +1 -1
- package/dist/core/MeasurementSystem.js +100 -71
- package/dist/core/MeasurementSystem.js.map +1 -1
- package/dist/core/VirtualizationEngine.d.ts +9 -54
- package/dist/core/VirtualizationEngine.d.ts.map +1 -1
- package/dist/core/VirtualizationEngine.js +70 -153
- package/dist/core/VirtualizationEngine.js.map +1 -1
- package/dist/hooks/useInfiniteScroll.d.ts +28 -10
- package/dist/hooks/useInfiniteScroll.d.ts.map +1 -1
- package/dist/hooks/useInfiniteScroll.js +31 -14
- package/dist/hooks/useInfiniteScroll.js.map +1 -1
- package/dist/hooks/useLazyLoad.d.ts +32 -11
- package/dist/hooks/useLazyLoad.d.ts.map +1 -1
- package/dist/hooks/useLazyLoad.js +44 -21
- package/dist/hooks/useLazyLoad.js.map +1 -1
- package/dist/hooks/useScrollRestoration.d.ts +46 -5
- package/dist/hooks/useScrollRestoration.d.ts.map +1 -1
- package/dist/hooks/useScrollRestoration.js +138 -41
- package/dist/hooks/useScrollRestoration.js.map +1 -1
- package/dist/hooks/useVirtualList.js +1 -1
- package/dist/hooks/useVirtualList.js.map +1 -1
- package/dist/hooks/useVirtualizedSearch.d.ts +29 -29
- package/dist/hooks/useVirtualizedSearch.d.ts.map +1 -1
- package/dist/hooks/useVirtualizedSearch.js +63 -149
- package/dist/hooks/useVirtualizedSearch.js.map +1 -1
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.js +1 -10
- package/dist/index.esm.js.map +1 -1
- package/dist/types.d.ts +28 -11
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -2
|
@@ -1,60 +1,157 @@
|
|
|
1
|
-
import { useEffect, useRef,
|
|
2
|
-
const
|
|
1
|
+
import { useCallback, useEffect, useRef, } from 'react';
|
|
2
|
+
const DEFAULT_STORAGE_KEY = 'virtualize-scroll-positions';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* Useful when navigating away and coming back to a list
|
|
4
|
+
* Shared cache across all hook instances.
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const positionCache = new Map();
|
|
7
|
+
function isBrowser() {
|
|
8
|
+
return (typeof window !== 'undefined' &&
|
|
9
|
+
typeof document !== 'undefined');
|
|
10
|
+
}
|
|
11
|
+
export function useScrollRestoration(key, containerRef, { persist = true, storageKey = DEFAULT_STORAGE_KEY, storage, autoSave = false, maxEntries = 100, useRAF = true, enabled = true, onError, } = {}) {
|
|
12
|
+
const storageRef = useRef(storage ??
|
|
13
|
+
(isBrowser()
|
|
14
|
+
? window.localStorage
|
|
15
|
+
: null));
|
|
16
|
+
/**
|
|
17
|
+
* Load cache once
|
|
18
|
+
*/
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!enabled ||
|
|
21
|
+
!persist ||
|
|
22
|
+
!storageRef.current) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (positionCache.size > 0)
|
|
26
|
+
return;
|
|
27
|
+
try {
|
|
28
|
+
const raw = storageRef.current.getItem(storageKey);
|
|
29
|
+
if (!raw)
|
|
30
|
+
return;
|
|
31
|
+
const positions = JSON.parse(raw);
|
|
32
|
+
positions.forEach((position) => {
|
|
33
|
+
positionCache.set(position.key, position);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
onError?.(error);
|
|
38
|
+
}
|
|
39
|
+
}, [
|
|
40
|
+
enabled,
|
|
41
|
+
persist,
|
|
42
|
+
storageKey,
|
|
43
|
+
onError,
|
|
44
|
+
]);
|
|
45
|
+
const persistCache = useCallback(() => {
|
|
46
|
+
if (!persist ||
|
|
47
|
+
!storageRef.current) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const positions = Array.from(positionCache.values())
|
|
52
|
+
.sort((a, b) => b.timestamp - a.timestamp)
|
|
53
|
+
.slice(0, maxEntries);
|
|
54
|
+
storageRef.current.setItem(storageKey, JSON.stringify(positions));
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
onError?.(error);
|
|
58
|
+
}
|
|
59
|
+
}, [
|
|
60
|
+
persist,
|
|
61
|
+
storageKey,
|
|
62
|
+
maxEntries,
|
|
63
|
+
onError,
|
|
64
|
+
]);
|
|
10
65
|
const savePosition = useCallback(() => {
|
|
11
|
-
if (!
|
|
66
|
+
if (!enabled)
|
|
67
|
+
return;
|
|
68
|
+
const element = containerRef.current;
|
|
69
|
+
if (!element)
|
|
12
70
|
return;
|
|
13
71
|
const position = {
|
|
14
72
|
key,
|
|
15
|
-
|
|
73
|
+
top: element.scrollTop,
|
|
74
|
+
left: element.scrollLeft,
|
|
16
75
|
timestamp: Date.now(),
|
|
17
76
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
}, [key, containerRef]);
|
|
28
|
-
// Restore scroll position from localStorage
|
|
77
|
+
positionCache.set(key, position);
|
|
78
|
+
persistCache();
|
|
79
|
+
}, [
|
|
80
|
+
key,
|
|
81
|
+
containerRef,
|
|
82
|
+
enabled,
|
|
83
|
+
persistCache,
|
|
84
|
+
]);
|
|
29
85
|
const restorePosition = useCallback(() => {
|
|
30
|
-
if (!
|
|
86
|
+
if (!enabled)
|
|
31
87
|
return;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
88
|
+
const element = containerRef.current;
|
|
89
|
+
if (!element)
|
|
90
|
+
return;
|
|
91
|
+
const position = positionCache.get(key);
|
|
92
|
+
if (!position)
|
|
93
|
+
return;
|
|
94
|
+
const restore = () => {
|
|
95
|
+
if (!containerRef.current)
|
|
35
96
|
return;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
97
|
+
containerRef.current.scrollTop =
|
|
98
|
+
position.top;
|
|
99
|
+
containerRef.current.scrollLeft =
|
|
100
|
+
position.left;
|
|
101
|
+
};
|
|
102
|
+
if (useRAF) {
|
|
103
|
+
requestAnimationFrame(restore);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
restore();
|
|
107
|
+
}
|
|
108
|
+
}, [
|
|
109
|
+
key,
|
|
110
|
+
containerRef,
|
|
111
|
+
enabled,
|
|
112
|
+
useRAF,
|
|
113
|
+
]);
|
|
114
|
+
/**
|
|
115
|
+
* Restore on mount.
|
|
116
|
+
*/
|
|
52
117
|
useEffect(() => {
|
|
118
|
+
if (!enabled)
|
|
119
|
+
return;
|
|
53
120
|
restorePosition();
|
|
121
|
+
}, [enabled, restorePosition]);
|
|
122
|
+
/**
|
|
123
|
+
* Save on unmount.
|
|
124
|
+
*/
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (!enabled)
|
|
127
|
+
return;
|
|
54
128
|
return () => {
|
|
55
129
|
savePosition();
|
|
56
130
|
};
|
|
57
|
-
}, [
|
|
131
|
+
}, [enabled, savePosition]);
|
|
132
|
+
/**
|
|
133
|
+
* Optional auto-save mode.
|
|
134
|
+
*/
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (!enabled ||
|
|
137
|
+
!autoSave ||
|
|
138
|
+
!containerRef.current) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const element = containerRef.current;
|
|
142
|
+
const handleScroll = () => {
|
|
143
|
+
savePosition();
|
|
144
|
+
};
|
|
145
|
+
element.addEventListener('scroll', handleScroll, { passive: true });
|
|
146
|
+
return () => {
|
|
147
|
+
element.removeEventListener('scroll', handleScroll);
|
|
148
|
+
};
|
|
149
|
+
}, [
|
|
150
|
+
enabled,
|
|
151
|
+
autoSave,
|
|
152
|
+
savePosition,
|
|
153
|
+
containerRef,
|
|
154
|
+
]);
|
|
58
155
|
return {
|
|
59
156
|
savePosition,
|
|
60
157
|
restorePosition,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScrollRestoration.js","sourceRoot":"","sources":["../../src/hooks/useScrollRestoration.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"useScrollRestoration.js","sourceRoot":"","sources":["../../src/hooks/useScrollRestoration.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,7 +33,7 @@ export function useVirtualList(params) {
|
|
|
33
33
|
*/
|
|
34
34
|
useEffect(() => {
|
|
35
35
|
const engine = engineRef.current;
|
|
36
|
-
const visibleItems = engine.getVisibleItems(scrollOffset, containerHeight, items.length, overscan
|
|
36
|
+
const visibleItems = engine.getVisibleItems(scrollOffset, containerHeight, items.length, overscan);
|
|
37
37
|
const nextVirtualItems = visibleItems.map((item) => ({
|
|
38
38
|
index: item.index,
|
|
39
39
|
offset: item.offset,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVirtualList.js","sourceRoot":"","sources":["../../src/hooks/useVirtualList.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,QAAQ,EACR,WAAW,EACX,MAAM,EACN,SAAS,GAGZ,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AA0E9D;;GAEG;AACH,MAAM,UAAU,cAAc,CAC1B,MAA+B;IAE/B,MAAM,EACF,KAAK,EACL,eAAe,EACf,QAAQ,GAAG,CAAC,EACZ,eAAe,GAAG,SAAS,EAC3B,iBAAiB,GAAG,EAAE,EACtB,QAAQ,EACR,WAAW,EACX,aAAa,GAAG,EAAE,GACrB,GAAG,MAAM,CAAC;IAEX;;OAEG;IACH,MAAM,SAAS,GAAG,MAAM,CACpB,IAAI,oBAAoB,CACpB,iBAAiB,CACpB,CACJ,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,CACzB,IAAI,iBAAiB,EAAE,CAC1B,CAAC;IAEF;;OAEG;IACH,MAAM,YAAY,GACd,MAAM,CAAiB,IAAI,CAAC,CAAC;IAEjC,MAAM,QAAQ,GACV,MAAM,CAAiB,IAAI,CAAC,CAAC;IAEjC;;OAEG;IACH,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GACjC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEhB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAC/B,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpB,MAAM,gBAAgB,GAAG,MAAM,CAE7B,IAAI,CAAC,CAAC;IAER,MAAM,mBAAmB,GACrB,MAAM,CAAC,CAAC,CAAC,CAAC;IAEd,MAAM,kBAAkB,GACpB,MAAM,CACF,eAAe,CAClB,CAAC;IAEN;;OAEG;IACH,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GACjC,QAAQ,CAAgB,EAAE,CAAC,CAAC;IAEhC;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE;QACX,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;QAEjC,MAAM,YAAY,GACd,MAAM,CAAC,eAAe,CAClB,YAAY,EACZ,eAAe,EACf,KAAK,CAAC,MAAM,EACZ,QAAQ,
|
|
1
|
+
{"version":3,"file":"useVirtualList.js","sourceRoot":"","sources":["../../src/hooks/useVirtualList.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface UseVirtualizedSearchParams<T> {
|
|
3
|
-
|
|
2
|
+
export interface UseVirtualizedSearchParams<T> {
|
|
3
|
+
/**
|
|
4
|
+
* Source items.
|
|
5
|
+
*/
|
|
6
|
+
items: readonly T[];
|
|
7
|
+
/**
|
|
8
|
+
* Search value.
|
|
9
|
+
*/
|
|
4
10
|
searchValue: string;
|
|
5
|
-
|
|
6
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Fields to search.
|
|
13
|
+
*/
|
|
14
|
+
searchFields: readonly (keyof T)[];
|
|
15
|
+
/**
|
|
16
|
+
* Case-sensitive search.
|
|
17
|
+
* Default: false
|
|
18
|
+
*/
|
|
7
19
|
caseSensitive?: boolean;
|
|
8
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Enable deferred searching.
|
|
22
|
+
* Default: true
|
|
23
|
+
*/
|
|
24
|
+
deferSearch?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Optional custom matcher.
|
|
27
|
+
*/
|
|
28
|
+
matcher?: (item: T, query: string) => boolean;
|
|
9
29
|
}
|
|
10
|
-
interface UseVirtualizedSearchReturn<T> {
|
|
30
|
+
export interface UseVirtualizedSearchReturn<T> {
|
|
11
31
|
filteredItems: T[];
|
|
12
|
-
highlightMatch: (text: string) => React.ReactNode;
|
|
13
32
|
resultCount: number;
|
|
33
|
+
query: string;
|
|
14
34
|
hasMatch: (item: T) => boolean;
|
|
15
35
|
isSearching: boolean;
|
|
36
|
+
highlightMatch: (text: string) => React.ReactNode;
|
|
16
37
|
}
|
|
17
|
-
|
|
18
|
-
* Hook for efficient searching within virtualized lists
|
|
19
|
-
* Filters items without re-measuring
|
|
20
|
-
*/
|
|
21
|
-
export declare function useVirtualizedSearch<T>({ items, searchValue, searchFields, caseSensitive, highlightColor, }: UseVirtualizedSearchParams<T>): UseVirtualizedSearchReturn<T>;
|
|
38
|
+
export declare function useVirtualizedSearch<T>({ items, searchValue, searchFields, caseSensitive, deferSearch, matcher, }: UseVirtualizedSearchParams<T>): UseVirtualizedSearchReturn<T>;
|
|
22
39
|
export default useVirtualizedSearch;
|
|
23
|
-
interface UseVirtualizedSearchParams<T> {
|
|
24
|
-
items: T[];
|
|
25
|
-
searchValue: string;
|
|
26
|
-
searchFields: (keyof T)[];
|
|
27
|
-
caseSensitive?: boolean;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Hook for efficient searching within virtualized lists
|
|
31
|
-
* Returns filtered items and match detection
|
|
32
|
-
* JSX rendering is handled in useVirtualizedSearch.tsx
|
|
33
|
-
*/
|
|
34
|
-
export declare function virtualizedSearch<T>({ items, searchValue, searchFields, caseSensitive, }: UseVirtualizedSearchParams<T>): {
|
|
35
|
-
filteredItems: T[];
|
|
36
|
-
hasMatch: (item: T) => boolean;
|
|
37
|
-
resultCount: number;
|
|
38
|
-
query: string;
|
|
39
|
-
};
|
|
40
40
|
//# sourceMappingURL=useVirtualizedSearch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVirtualizedSearch.d.ts","sourceRoot":"","sources":["../../src/hooks/useVirtualizedSearch.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"useVirtualizedSearch.d.ts","sourceRoot":"","sources":["../../src/hooks/useVirtualizedSearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAIN,MAAM,OAAO,CAAC;AAEf,MAAM,WAAW,0BAA0B,CAAC,CAAC;IACzC;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAEpB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IAEnC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,OAAO,CAAC,EAAE,CACN,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,MAAM,KACZ,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B,CAAC,CAAC;IACzC,aAAa,EAAE,CAAC,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,CACZ,IAAI,EAAE,MAAM,KACX,KAAK,CAAC,SAAS,CAAC;CACxB;AAoCD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,EACpC,KAAK,EACL,WAAW,EACX,YAAY,EACZ,aAAqB,EACrB,WAAkB,EAClB,OAAO,GACV,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,0BAA0B,CAAC,CAAC,CAAC,CA+H/D;AAED,eAAe,oBAAoB,CAAC"}
|
|
@@ -1,168 +1,82 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import React, { useMemo, useCallback, useDeferredValue } from 'react';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import React, { useMemo, useCallback, useDeferredValue, } from 'react';
|
|
3
|
+
function normalize(value, caseSensitive) {
|
|
4
|
+
return caseSensitive
|
|
5
|
+
? value
|
|
6
|
+
: value.toLowerCase();
|
|
7
|
+
}
|
|
8
|
+
function defaultMatcher(item, query, searchFields, caseSensitive) {
|
|
9
|
+
return searchFields.some((field) => {
|
|
10
|
+
const value = item[field];
|
|
11
|
+
if (value === null ||
|
|
12
|
+
value === undefined) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const normalizedValue = normalize(String(value).trim(), caseSensitive);
|
|
16
|
+
return normalizedValue.includes(query);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function useVirtualizedSearch({ items, searchValue, searchFields, caseSensitive = false, deferSearch = true, matcher, }) {
|
|
9
20
|
const normalizedQuery = useMemo(() => {
|
|
10
|
-
|
|
11
|
-
return caseSensitive ? trimmed : trimmed.toLowerCase();
|
|
21
|
+
return normalize(searchValue.trim(), caseSensitive);
|
|
12
22
|
}, [searchValue, caseSensitive]);
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
const deferredQuery = useDeferredValue(normalizedQuery);
|
|
24
|
+
const activeQuery = deferSearch
|
|
25
|
+
? deferredQuery
|
|
26
|
+
: normalizedQuery;
|
|
27
|
+
const isSearching = deferSearch &&
|
|
28
|
+
deferredQuery !== normalizedQuery;
|
|
29
|
+
const itemMatcher = useCallback((item) => {
|
|
30
|
+
if (!activeQuery) {
|
|
31
|
+
return true;
|
|
20
32
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return null;
|
|
33
|
+
if (matcher) {
|
|
34
|
+
return matcher(item, activeQuery);
|
|
24
35
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
return defaultMatcher(item, activeQuery, searchFields, caseSensitive);
|
|
37
|
+
}, [
|
|
38
|
+
activeQuery,
|
|
39
|
+
matcher,
|
|
40
|
+
searchFields,
|
|
41
|
+
caseSensitive,
|
|
42
|
+
]);
|
|
30
43
|
const filteredItems = useMemo(() => {
|
|
31
|
-
if (!
|
|
32
|
-
return items;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
const normalizedValue = caseSensitive
|
|
45
|
-
? stringValue
|
|
46
|
-
: stringValue.toLowerCase();
|
|
47
|
-
return normalizedValue.includes(deferredQuery);
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
console.warn(`Error accessing field ${String(field)}:`, error);
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
}, [items, deferredQuery, searchFields, caseSensitive]);
|
|
56
|
-
// Helper function to check if item matches
|
|
57
|
-
const hasMatch = useCallback((item) => {
|
|
58
|
-
if (!deferredQuery)
|
|
59
|
-
return true;
|
|
60
|
-
return searchFields.some((field) => {
|
|
61
|
-
try {
|
|
62
|
-
const value = item[field];
|
|
63
|
-
if (value === null || value === undefined)
|
|
64
|
-
return false;
|
|
65
|
-
const stringValue = String(value).trim();
|
|
66
|
-
const normalizedValue = caseSensitive
|
|
67
|
-
? stringValue
|
|
68
|
-
: stringValue.toLowerCase();
|
|
69
|
-
return normalizedValue.includes(deferredQuery);
|
|
70
|
-
}
|
|
71
|
-
catch {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}, [deferredQuery, searchFields, caseSensitive]);
|
|
76
|
-
// FIX #4 & #7: Improved highlighting with accessibility support
|
|
77
|
-
const highlightMatch = useCallback((text) => {
|
|
78
|
-
if (!normalizedQuery || !queryPattern)
|
|
79
|
-
return text;
|
|
80
|
-
if (!text)
|
|
44
|
+
if (!activeQuery) {
|
|
45
|
+
return [...items];
|
|
46
|
+
}
|
|
47
|
+
return items.filter(itemMatcher);
|
|
48
|
+
}, [
|
|
49
|
+
items,
|
|
50
|
+
activeQuery,
|
|
51
|
+
itemMatcher,
|
|
52
|
+
]);
|
|
53
|
+
const hasMatch = useCallback((item) => itemMatcher(item), [itemMatcher]);
|
|
54
|
+
const highlightRegex = useMemo(() => {
|
|
55
|
+
if (!normalizedQuery) {
|
|
81
56
|
return null;
|
|
82
|
-
try {
|
|
83
|
-
queryPattern.lastIndex = 0;
|
|
84
|
-
const parts = String(text).split(queryPattern);
|
|
85
|
-
return parts.map((part, index) => {
|
|
86
|
-
// Even indices are non-matching parts
|
|
87
|
-
if (index % 2 === 0) {
|
|
88
|
-
return part ? (_jsx(React.Fragment, { children: part }, index)) : null;
|
|
89
|
-
}
|
|
90
|
-
// Odd indices are matching parts
|
|
91
|
-
return (_jsx("mark", { style: {
|
|
92
|
-
backgroundColor: highlightColor,
|
|
93
|
-
padding: '0 2px',
|
|
94
|
-
borderRadius: '2px',
|
|
95
|
-
}, "aria-label": `Highlighted search result: ${part}`, children: part }, index));
|
|
96
|
-
});
|
|
97
57
|
}
|
|
98
|
-
|
|
99
|
-
|
|
58
|
+
const escaped = normalizedQuery.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
59
|
+
return new RegExp(`(${escaped})`, caseSensitive ? 'g' : 'gi');
|
|
60
|
+
}, [
|
|
61
|
+
normalizedQuery,
|
|
62
|
+
caseSensitive,
|
|
63
|
+
]);
|
|
64
|
+
const highlightMatch = useCallback((text) => {
|
|
65
|
+
if (!text ||
|
|
66
|
+
!highlightRegex) {
|
|
100
67
|
return text;
|
|
101
68
|
}
|
|
102
|
-
|
|
69
|
+
const parts = text.split(highlightRegex);
|
|
70
|
+
return parts.map((part, index) => index % 2 === 1 ? (_jsx("mark", { children: part }, index)) : (_jsx(React.Fragment, { children: part }, index)));
|
|
71
|
+
}, [highlightRegex]);
|
|
103
72
|
return {
|
|
104
73
|
filteredItems,
|
|
105
|
-
highlightMatch,
|
|
106
74
|
resultCount: filteredItems.length,
|
|
75
|
+
query: activeQuery,
|
|
107
76
|
hasMatch,
|
|
108
77
|
isSearching,
|
|
78
|
+
highlightMatch,
|
|
109
79
|
};
|
|
110
80
|
}
|
|
111
81
|
export default useVirtualizedSearch;
|
|
112
|
-
/**
|
|
113
|
-
* Hook for efficient searching within virtualized lists
|
|
114
|
-
* Returns filtered items and match detection
|
|
115
|
-
* JSX rendering is handled in useVirtualizedSearch.tsx
|
|
116
|
-
*/
|
|
117
|
-
export function virtualizedSearch({ items, searchValue, searchFields, caseSensitive = false, }) {
|
|
118
|
-
const normalizedQuery = searchValue.trim();
|
|
119
|
-
const query = caseSensitive ? normalizedQuery : normalizedQuery.toLowerCase();
|
|
120
|
-
const filteredItems = items.filter((item) => {
|
|
121
|
-
if (!query)
|
|
122
|
-
return true;
|
|
123
|
-
return searchFields.some((field) => {
|
|
124
|
-
try {
|
|
125
|
-
const value = item[field];
|
|
126
|
-
if (value === null || value === undefined)
|
|
127
|
-
return false;
|
|
128
|
-
const stringValue = String(value).trim();
|
|
129
|
-
if (!stringValue)
|
|
130
|
-
return false;
|
|
131
|
-
const normalizedValue = caseSensitive
|
|
132
|
-
? stringValue
|
|
133
|
-
: stringValue.toLowerCase();
|
|
134
|
-
return normalizedValue.includes(query);
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
console.warn(`Error accessing field ${String(field)}:`, error);
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
const hasMatch = (item) => {
|
|
143
|
-
if (!query)
|
|
144
|
-
return true;
|
|
145
|
-
return searchFields.some((field) => {
|
|
146
|
-
try {
|
|
147
|
-
const value = item[field];
|
|
148
|
-
if (value === null || value === undefined)
|
|
149
|
-
return false;
|
|
150
|
-
const stringValue = String(value).trim();
|
|
151
|
-
const normalizedValue = caseSensitive
|
|
152
|
-
? stringValue
|
|
153
|
-
: stringValue.toLowerCase();
|
|
154
|
-
return normalizedValue.includes(query);
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
return {
|
|
162
|
-
filteredItems,
|
|
163
|
-
hasMatch,
|
|
164
|
-
resultCount: filteredItems.length,
|
|
165
|
-
query,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
82
|
//# sourceMappingURL=useVirtualizedSearch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVirtualizedSearch.js","sourceRoot":"","sources":["../../src/hooks/useVirtualizedSearch.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"useVirtualizedSearch.js","sourceRoot":"","sources":["../../src/hooks/useVirtualizedSearch.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("react");class r{constructor(e=35){Object.defineProperty(this,"itemSizeMap",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"estimatedItemSize",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"itemCount",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"prefix",{enumerable:!0,configurable:!0,writable:!0,value:[0]}),Object.defineProperty(this,"dirty",{enumerable:!0,configurable:!0,writable:!0,value:!0}),this.estimatedItemSize=e}setItemCount(e){this.itemCount=e,this.dirty=!0}recordItemSize(e,t){this.itemSizeMap[e]!==t&&(this.itemSizeMap[e]=t,this.dirty=!0)}rebuildPrefix(){let e=0;this.prefix=[0];for(let t=0;t<this.itemCount;t++)e+=this.itemSizeMap[t]??this.estimatedItemSize,this.prefix[t+1]=e;this.dirty=!1}getItemSize(e){return this.itemSizeMap[e]??this.estimatedItemSize}getItemOffset(e){return this.dirty&&this.rebuildPrefix(),this.prefix[e]??0}getTotalSize(){return this.dirty&&this.rebuildPrefix(),this.prefix[this.itemCount]||0}binarySearch(e){this.dirty&&this.rebuildPrefix();let t=0,r=this.itemCount-1;for(;t<=r;){const n=t+r>>1,s=this.prefix[n];if(s===e)return n;s<e?t=n+1:r=n-1}return Math.max(0,t-1)}getVisibleRange(e,t,r,n=5){this.setItemCount(r);const s=this.binarySearch(e),i=this.binarySearch(e+t);return{startIndex:Math.max(0,s-n),endIndex:Math.min(r-1,i+n),overscanStartIndex:s,overscanEndIndex:i}}getVisibleItems(e,t,r,n){const s=this.getVisibleRange(e,t,r,n),i=[];for(let e=s.startIndex;e<=s.endIndex;e++)i.push({index:e,size:this.getItemSize(e),offset:this.getItemOffset(e)});return i}getScrollOffsetForIndex(e,t,r="start"){const n=this.getItemOffset(e),s=this.getItemSize(e);return"center"===r?Math.max(0,n-(t-s)/2):"end"===r?Math.max(0,n-t+s):Math.max(0,n)}}class n{constructor(){Object.defineProperty(this,"resizeObserver",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"measurements",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"observedElements",{enumerable:!0,configurable:!0,writable:!0,value:new WeakMap}),Object.defineProperty(this,"pendingUpdates",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"rafId",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"onMeasure",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"handleResize",{enumerable:!0,configurable:!0,writable:!0,value:e=>{for(const t of e){const e=t.target,r=this.observedElements.get(e);if(void 0===r)continue;const n=Math.round(t.contentRect.height);this.measurements.get(r)!==n&&(this.measurements.set(r,n),this.pendingUpdates.set(r,n))}this.flushPendingUpdates()}}),"undefined"!=typeof window&&"ResizeObserver"in window&&(this.resizeObserver=new ResizeObserver(this.handleResize))}startMeasuring(e,t){this.onMeasure=t;e.querySelectorAll("[data-virtualize-index]").forEach(e=>{const t=e.dataset.virtualizeIndex;if(void 0===t)return;const r=Number(t);this.observeItem(r,e)})}observeItem(e,t){t.dataset.virtualizeIndex=String(e),this.observedElements.set(t,e),this.resizeObserver?.observe(t),this.syncMeasure(e,t)}unobserveItem(e){this.resizeObserver?.unobserve(e),this.observedElements.delete(e)}flushPendingUpdates(){null===this.rafId&&(this.rafId=requestAnimationFrame(()=>{this.pendingUpdates.forEach((e,t)=>{this.onMeasure?.(t,e)}),this.pendingUpdates.clear(),this.rafId=null}))}syncMeasure(e,t){const r=t.getBoundingClientRect().height;if(r<=0)return;const n=Math.round(r);this.measurements.get(e)!==n&&(this.measurements.set(e,n),this.onMeasure?.(e,n))}stopMeasuring(){this.resizeObserver?.disconnect(),this.pendingUpdates.clear(),null!==this.rafId&&cancelAnimationFrame(this.rafId)}getMeasurement(e){return this.measurements.get(e)}getAllMeasurements(){return new Map(this.measurements)}clearPending(){this.pendingUpdates.clear()}clearMeasurements(){this.measurements.clear()}destroy(){this.stopMeasuring(),this.measurements.clear(),this.pendingUpdates.clear(),this.observedElements=new WeakMap,this.onMeasure=null}}function s(e){const{items:s,containerHeight:i,overscan:o=5,scrollDirection:l="forward",estimatedItemSize:u=35,onScroll:a,onScrollEnd:c,stickyIndices:f=[]}=e,d=t.useRef(new r(u)),h=t.useRef(new n),m=t.useRef(null),g=t.useRef(null),[p,b]=t.useState(0),[v,y]=t.useState(!1),x=t.useRef(null),S=t.useRef(0),I=t.useRef(l),[w,M]=t.useState([]);t.useEffect(()=>{const e=d.current.getVisibleItems(p,i,s.length,o).map(e=>({index:e.index,offset:e.offset,size:e.size,isSticky:f.includes(e.index)}));M(t=>{if(t.length===e.length){let r=!1;for(let n=0;n<t.length;n++){const s=t[n],i=e[n];if(s.index!==i.index||s.offset!==i.offset||s.size!==i.size||s.isSticky!==i.isSticky){r=!0;break}}if(!r)return t}return e})},[p,i,s.length,o,f]);const z=t.useCallback(e=>{const t=e.currentTarget.scrollTop;if(t===S.current)return;const r=t>S.current?"forward":"reverse";I.current=r,S.current=t,b(t),y(!0),a&&a(t,r),x.current&&clearTimeout(x.current),x.current=setTimeout(()=>{y(!1),c&&c()},150)},[a,c]);t.useEffect(()=>{const e=m.current;if(!e)return;const t=e=>{z(e)};return e.addEventListener("scroll",t),()=>{e.removeEventListener("scroll",t)}},[z]);const R=t.useCallback((e,t)=>{d.current.recordItemSize(e,t)},[]);t.useEffect(()=>{const e=m.current;return e&&h.current.startMeasuring(e,R),()=>{h.current.stopMeasuring()}},[R]);const E=t.useCallback((e,t="start")=>{const r=d.current.getScrollOffsetForIndex(e,i,t);m.current&&(m.current.scrollTop=r)},[i]),O=t.useCallback(e=>{m.current&&(m.current.scrollTop=e)},[]),k=t.useCallback((e,t)=>{const r=d.current.getItemOffset(e),n=f.includes(e);return{position:n?"sticky":"absolute",top:n?0:r,left:0,width:"100%",height:t,zIndex:n?10:0}},[f]);t.useEffect(()=>()=>{x.current&&clearTimeout(x.current),h.current.destroy()},[]);const C=d.current.getTotalSize();return{virtualItems:w,isScrolling:v,scrollOffset:p,totalSize:C,scrollToItem:E,scrollToOffset:O,setScrollOffset:b,containerRef:m,innerRef:g,getItemStyle:k}}const i=t.forwardRef(({items:r,renderItem:n,itemWrapper:i,itemKey:o,height:l=400,width:u=500,itemSize:a,overscan:c=5,scrollDirection:f="forward",onScroll:d,className:h="",itemClassName:m="",style:g={},estimatedItemSize:p=35,getItemSize:b,stickyIndices:v=[],onScrollEnd:y,innerRef:x,scrollOffsetRef:S},I)=>{const{virtualItems:w,isScrolling:M,scrollOffset:z,totalSize:R,containerRef:E,innerRef:O,getItemStyle:k}=s({items:r,containerHeight:"number"==typeof l?l:400,overscan:c,scrollDirection:f,estimatedItemSize:p,onScroll:d,onScrollEnd:y,stickyIndices:v}),C=t.useRef(null),j=t.useRef(null);t.useImperativeHandle(I,()=>C.current),t.useImperativeHandle(x,()=>j.current),t.useEffect(()=>{S&&(S.current=z)},[z,S]);const P={height:l,width:u,overflow:"auto",position:"relative",...g},T={position:"relative",height:R,width:"100%"};return e.jsx("div",{ref:e=>{C.current=e,E.current=e},className:`virtualize-container ${h}`,style:P,onScroll:e=>{const t=e.target,r=n?.__scrollHandler;r&&r(e),d&&d(t.scrollTop,"auto")},children:e.jsx("div",{ref:e=>{j.current=e,O.current=e},style:T,className:"virtualize-inner",children:w.map(s=>{const l=r[s.index],u=o?o(s.index,l):s.index,a=k(s.index,s.size),c={item:l,index:s.index,style:a,isScrolling:M},f=n(c);return i?e.jsx(t.Fragment,{children:i({item:l,index:s.index,style:a,children:f})},u):e.jsx("div",{"data-virtualize-index":s.index,className:m,style:{...a,boxSizing:"border-box"},children:f},u)})})})});i.displayName="VirtualList";const o=t.forwardRef(({items:r,renderItem:n,itemKey:s,height:i=600,width:o=800,columnCount:l=3,rowHeight:u=200,columnWidth:a,layout:c="grid",overscan:f=5,gap:d=16,onScroll:h,innerClassName:m,innerStyle:g},p)=>{const b=t.useRef(null);t.useImperativeHandle(p,()=>b.current);const[v,y]=t.useState(0),[x,S]=t.useState(!1),I=t.useRef(null),w="number"==typeof o?o:Number(o),M="number"==typeof i?i:Number(i),z=t.useMemo(()=>"number"==typeof l?Math.max(1,l):3,[l]),R=t.useMemo(()=>"number"==typeof a?a:(w-d*(z-1))/z,[a,w,z,d]),E=t.useMemo(()=>{const e=[];if("masonry"===c){const t=Array(z).fill(0);for(let n=0;n<r.length;n++){const r=t.indexOf(Math.min(...t)),s="function"==typeof u?u(n):u;e.push({x:r*(R+d),y:t[r],width:R,height:s}),t[r]+=s+d}}else for(let t=0;t<r.length;t++){const r=Math.floor(t/z),n=t%z,s="function"==typeof u?u(t):u;e.push({x:n*(R+d),y:r*(s+d),width:R,height:s})}return e},[r,z,R,d,c,u]),O=t.useMemo(()=>{const e=E.findIndex(e=>e.y+e.height>=v),t=E.findIndex(e=>e.y>v+M);return{start:Math.max(0,e-f),end:-1===t?r.length-1:Math.min(r.length-1,t+f)}},[E,v,M,f,r.length]),k=t.useMemo(()=>{if("masonry"===c){return Math.max(...E.length?E.map(e=>e.y+e.height):[0])}return Math.ceil(r.length/z)*(("function"==typeof u?200:u)+d)},[r.length,z,d,c,u,E]);t.useEffect(()=>()=>{I.current&&clearTimeout(I.current)},[]);const C={height:i,width:o,overflowY:"auto",overflowX:"hidden",position:"relative",...g},j={position:"relative",height:k,width:z*R+d*(z-1)};return e.jsx("div",{ref:b,className:m,style:C,onScroll:e=>{const t=e.currentTarget.scrollTop;y(t),S(!0),h?.(t,e.currentTarget.scrollLeft),I.current&&clearTimeout(I.current),I.current=setTimeout(()=>{S(!1)},120)},children:e.jsx("div",{style:j,children:Array.from({length:O.end-O.start+1},(t,i)=>{const o=O.start+i,l=r[o],u=E[o];if(!l||!u)return null;const a={position:"absolute",top:u.y,left:u.x,width:u.width,height:u.height};return e.jsx("div",{style:a,children:n({item:l,index:o,isScrolling:x,style:a})},s?.(o,l)??o)})})})});function l(e,t){return t?e:e.toLowerCase()}o.displayName="VirtualGrid";const u=new Map;exports.MeasurementSystem=n,exports.VirtualGrid=o,exports.VirtualList=i,exports.VirtualizationEngine=r,exports.useInfiniteScroll=function({onLoadMore:e,threshold:r=500,isLoading:n=!1,enabled:s=!0}){const i=t.useRef(null),[o,l]=t.useState(!1),u=t.useRef(!1),a=t.useRef(e);t.useEffect(()=>{a.current=e},[e]);const c=t.useCallback(()=>{if(!s||n)return;const e=i.current;if(!e)return;const{scrollTop:t,scrollHeight:o,clientHeight:c}=e,f=o-t-c<=r;l(f),!f||u.current||n||(u.current=!0,Promise.resolve(a.current()).finally(()=>{u.current=!1}))},[r,n,s]);return t.useEffect(()=>{if(!s)return;const e=i.current;if(!e)return;const t=()=>{c()};return e.addEventListener("scroll",t,{passive:!0}),c(),()=>{e.removeEventListener("scroll",t)}},[c,s]),{containerRef:i,isAtBottom:o,isLoading:n,checkIfAtBottom:c}},exports.useLazyLoad=function({threshold:e=.1,onVisible:r,root:n=null,rootMargin:s="0px",enabled:i=!0,once:o=!0}={}){const[l,u]=t.useState(!1),[a,c]=t.useState(null),f=t.useRef(null),d=t.useRef(r);return t.useEffect(()=>{d.current=r},[r]),t.useEffect(()=>{if(!i)return;const t=f.current;if(!t)return;if("undefined"==typeof window||!("IntersectionObserver"in window))return u(!0),void d.current?.();const r=new IntersectionObserver(([e])=>{c(e),e.isIntersecting?(u(!0),d.current?.(),o&&r.unobserve(e.target)):o||u(!1)},{threshold:e,root:n,rootMargin:s});return r.observe(t),()=>{r.disconnect()}},[e,n,s,i,o]),{ref:f,isVisible:l,entry:a}},exports.useScrollRestoration=function(e,r,{persist:n=!0,storageKey:s="virtualize-scroll-positions",storage:i,autoSave:o=!1,maxEntries:l=100,useRAF:a=!0,enabled:c=!0,onError:f}={}){const d=t.useRef(i??("undefined"!=typeof window&&"undefined"!=typeof document?window.localStorage:null));t.useEffect(()=>{if(c&&n&&d.current&&!(u.size>0))try{const e=d.current.getItem(s);if(!e)return;JSON.parse(e).forEach(e=>{u.set(e.key,e)})}catch(e){f?.(e)}},[c,n,s,f]);const h=t.useCallback(()=>{if(n&&d.current)try{const e=Array.from(u.values()).sort((e,t)=>t.timestamp-e.timestamp).slice(0,l);d.current.setItem(s,JSON.stringify(e))}catch(e){f?.(e)}},[n,s,l,f]),m=t.useCallback(()=>{if(!c)return;const t=r.current;if(!t)return;const n={key:e,top:t.scrollTop,left:t.scrollLeft,timestamp:Date.now()};u.set(e,n),h()},[e,r,c,h]),g=t.useCallback(()=>{if(!c)return;if(!r.current)return;const t=u.get(e);if(!t)return;const n=()=>{r.current&&(r.current.scrollTop=t.top,r.current.scrollLeft=t.left)};a?requestAnimationFrame(n):n()},[e,r,c,a]);return t.useEffect(()=>{c&&g()},[c,g]),t.useEffect(()=>{if(c)return()=>{m()}},[c,m]),t.useEffect(()=>{if(!c||!o||!r.current)return;const e=r.current,t=()=>{m()};return e.addEventListener("scroll",t,{passive:!0}),()=>{e.removeEventListener("scroll",t)}},[c,o,m,r]),{savePosition:m,restorePosition:g}},exports.useVirtualList=s,exports.useVirtualizedSearch=function({items:r,searchValue:n,searchFields:s,caseSensitive:i=!1,deferSearch:o=!0,matcher:u}){const a=t.useMemo(()=>l(n.trim(),i),[n,i]),c=t.useDeferredValue(a),f=o?c:a,d=o&&c!==a,h=t.useCallback(e=>!f||(u?u(e,f):function(e,t,r,n){return r.some(r=>{const s=e[r];return null!=s&&l(String(s).trim(),n).includes(t)})}(e,f,s,i)),[f,u,s,i]),m=t.useMemo(()=>f?r.filter(h):[...r],[r,f,h]),g=t.useCallback(e=>h(e),[h]),p=t.useMemo(()=>{if(!a)return null;const e=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`(${e})`,i?"g":"gi")},[a,i]),b=t.useCallback(r=>{if(!r||!p)return r;return r.split(p).map((r,n)=>n%2==1?e.jsx("mark",{children:r},n):e.jsx(t.Fragment,{children:r},n))},[p]);return{filteredItems:m,resultCount:m.length,query:f,hasMatch:g,isSearching:d,highlightMatch:b}};
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|