@uniformdev/search 0.0.4 → 0.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/dist/react.d.mts +112 -3
- package/dist/react.d.ts +112 -3
- package/dist/react.js +354 -23
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +355 -18
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -104,22 +104,26 @@ var SearchProvider = ({
|
|
|
104
104
|
}, {}),
|
|
105
105
|
[filterBy, urlParams]
|
|
106
106
|
);
|
|
107
|
+
const buildFilters = useCallback(
|
|
108
|
+
(excludeField) => Object.entries(selectedFilters).reduce((acc, [fieldKey, values]) => {
|
|
109
|
+
var _a2;
|
|
110
|
+
if (excludeField && fieldKey === excludeField) return acc;
|
|
111
|
+
if (!values || values.length === 0) return acc;
|
|
112
|
+
const filterType = (_a2 = filterBy.find((f) => f.fieldKey === fieldKey)) == null ? void 0 : _a2.type;
|
|
113
|
+
if (filterType === "range") {
|
|
114
|
+
const [min, max] = values;
|
|
115
|
+
return { ...acc, [`${fieldKey}[gte]`]: min, [`${fieldKey}[lte]`]: max };
|
|
116
|
+
}
|
|
117
|
+
return { ...acc, [`${fieldKey}[in]`]: values };
|
|
118
|
+
}, {}),
|
|
119
|
+
[selectedFilters, filterBy]
|
|
120
|
+
);
|
|
121
|
+
const currentFilters = useMemo(() => buildFilters(), [buildFilters]);
|
|
107
122
|
useEffect(() => {
|
|
108
123
|
const requestId = ++searchRequestIdRef.current;
|
|
109
124
|
const doFetch = async () => {
|
|
110
125
|
var _a2, _b2;
|
|
111
126
|
const currentOrderByQuery = (urlParams == null ? void 0 : urlParams[UNIFORM_SEARCH_ORDER_BY_KEY]) || defaultOrderByQuery;
|
|
112
|
-
const buildFilters = (excludeField) => Object.entries(selectedFilters).reduce((acc, [fieldKey, values]) => {
|
|
113
|
-
var _a3;
|
|
114
|
-
if (excludeField && fieldKey === excludeField) return acc;
|
|
115
|
-
if (!values || values.length === 0) return acc;
|
|
116
|
-
const filterType = (_a3 = filterBy.find((f) => f.fieldKey === fieldKey)) == null ? void 0 : _a3.type;
|
|
117
|
-
if (filterType === "range") {
|
|
118
|
-
const [min, max] = values;
|
|
119
|
-
return { ...acc, [`${fieldKey}[gte]`]: min, [`${fieldKey}[lte]`]: max };
|
|
120
|
-
}
|
|
121
|
-
return { ...acc, [`${fieldKey}[in]`]: values };
|
|
122
|
-
}, {});
|
|
123
127
|
const selectedFacetFields = Object.keys(selectedFilters).filter((k) => {
|
|
124
128
|
var _a3;
|
|
125
129
|
return ((_a3 = selectedFilters[k]) == null ? void 0 : _a3.length) > 0;
|
|
@@ -167,6 +171,7 @@ var SearchProvider = ({
|
|
|
167
171
|
doFetch().catch((error) => console.error("Search fetch error:", error)).finally(() => setIsLoading(false));
|
|
168
172
|
}, [
|
|
169
173
|
baseFilterString,
|
|
174
|
+
buildFilters,
|
|
170
175
|
defaultOrderByQuery,
|
|
171
176
|
facetBy,
|
|
172
177
|
filterBy,
|
|
@@ -307,6 +312,11 @@ var SearchProvider = ({
|
|
|
307
312
|
setOrderBy,
|
|
308
313
|
registerOrderBy,
|
|
309
314
|
unregisterOrderBy,
|
|
315
|
+
performSearch,
|
|
316
|
+
queryBy,
|
|
317
|
+
locale,
|
|
318
|
+
baseFilterString,
|
|
319
|
+
currentFilters,
|
|
310
320
|
filterOptions: filterBy,
|
|
311
321
|
setFilterOptions,
|
|
312
322
|
registerFilterOption,
|
|
@@ -317,11 +327,16 @@ var SearchProvider = ({
|
|
|
317
327
|
formatResultsSummary
|
|
318
328
|
}),
|
|
319
329
|
[
|
|
330
|
+
baseFilterString,
|
|
320
331
|
clearFilters,
|
|
332
|
+
currentFilters,
|
|
321
333
|
defaultOrderByQuery,
|
|
322
334
|
entries,
|
|
323
335
|
facets,
|
|
324
336
|
filterBy,
|
|
337
|
+
locale,
|
|
338
|
+
performSearch,
|
|
339
|
+
queryBy,
|
|
325
340
|
setFilterOptions,
|
|
326
341
|
registerFilterOption,
|
|
327
342
|
unregisterFilterOption,
|
|
@@ -358,14 +373,335 @@ function useSearch() {
|
|
|
358
373
|
return context;
|
|
359
374
|
}
|
|
360
375
|
|
|
376
|
+
// src/react/useAutocomplete.ts
|
|
377
|
+
import {
|
|
378
|
+
useCallback as useCallback2,
|
|
379
|
+
useEffect as useEffect2,
|
|
380
|
+
useId,
|
|
381
|
+
useMemo as useMemo2,
|
|
382
|
+
useRef as useRef2,
|
|
383
|
+
useState as useState2
|
|
384
|
+
} from "react";
|
|
385
|
+
var NO_ACTIVE_INDEX = -1;
|
|
386
|
+
var DEFAULT_PER_PAGE = 6;
|
|
387
|
+
var DEFAULT_MIN_QUERY_LENGTH = 1;
|
|
388
|
+
var DEFAULT_DEBOUNCE_MS = 150;
|
|
389
|
+
function useAutocomplete(options) {
|
|
390
|
+
var _a;
|
|
391
|
+
const {
|
|
392
|
+
performSearch,
|
|
393
|
+
queryBy,
|
|
394
|
+
baseFilterBy,
|
|
395
|
+
filters,
|
|
396
|
+
locale,
|
|
397
|
+
perPage = DEFAULT_PER_PAGE,
|
|
398
|
+
minQueryLength = DEFAULT_MIN_QUERY_LENGTH,
|
|
399
|
+
debounceMs = DEFAULT_DEBOUNCE_MS,
|
|
400
|
+
openOnFocus = false,
|
|
401
|
+
onSelect,
|
|
402
|
+
onSubmit,
|
|
403
|
+
maxTypos,
|
|
404
|
+
minLengthFor1Typo,
|
|
405
|
+
minLengthFor2Typos,
|
|
406
|
+
typoFallbackThreshold,
|
|
407
|
+
prioritizeExactMatch
|
|
408
|
+
} = options;
|
|
409
|
+
const baseId = useId();
|
|
410
|
+
const listboxId = `${baseId}-listbox`;
|
|
411
|
+
const labelId = `${baseId}-label`;
|
|
412
|
+
const inputId = `${baseId}-input`;
|
|
413
|
+
const optionId = useCallback2((index) => `${baseId}-option-${index}`, [baseId]);
|
|
414
|
+
const [query, setQueryState] = useState2("");
|
|
415
|
+
const [suggestions, setSuggestions] = useState2([]);
|
|
416
|
+
const [isLoading, setIsLoading] = useState2(false);
|
|
417
|
+
const [isOpen, setIsOpen] = useState2(false);
|
|
418
|
+
const [activeIndex, setActiveIndex] = useState2(NO_ACTIVE_INDEX);
|
|
419
|
+
const debounceRef = useRef2(null);
|
|
420
|
+
const requestIdRef = useRef2(0);
|
|
421
|
+
const queryByString = useMemo2(() => (queryBy == null ? void 0 : queryBy.length) ? queryBy.join(",") : void 0, [queryBy]);
|
|
422
|
+
const fetchConfigRef = useRef2({
|
|
423
|
+
performSearch,
|
|
424
|
+
queryByString,
|
|
425
|
+
baseFilterBy,
|
|
426
|
+
filters,
|
|
427
|
+
locale,
|
|
428
|
+
perPage,
|
|
429
|
+
maxTypos,
|
|
430
|
+
minLengthFor1Typo,
|
|
431
|
+
minLengthFor2Typos,
|
|
432
|
+
typoFallbackThreshold,
|
|
433
|
+
prioritizeExactMatch
|
|
434
|
+
});
|
|
435
|
+
fetchConfigRef.current = {
|
|
436
|
+
performSearch,
|
|
437
|
+
queryByString,
|
|
438
|
+
baseFilterBy,
|
|
439
|
+
filters,
|
|
440
|
+
locale,
|
|
441
|
+
perPage,
|
|
442
|
+
maxTypos,
|
|
443
|
+
minLengthFor1Typo,
|
|
444
|
+
minLengthFor2Typos,
|
|
445
|
+
typoFallbackThreshold,
|
|
446
|
+
prioritizeExactMatch
|
|
447
|
+
};
|
|
448
|
+
const runSearch = useCallback2((value) => {
|
|
449
|
+
const requestId = ++requestIdRef.current;
|
|
450
|
+
const cfg = fetchConfigRef.current;
|
|
451
|
+
setIsLoading(true);
|
|
452
|
+
cfg.performSearch({
|
|
453
|
+
page: 0,
|
|
454
|
+
perPage: cfg.perPage,
|
|
455
|
+
queryBy: cfg.queryByString,
|
|
456
|
+
baseFilterBy: cfg.baseFilterBy,
|
|
457
|
+
filters: cfg.filters,
|
|
458
|
+
search: value,
|
|
459
|
+
locale: cfg.locale,
|
|
460
|
+
maxTypos: cfg.maxTypos,
|
|
461
|
+
minLengthFor1Typo: cfg.minLengthFor1Typo,
|
|
462
|
+
minLengthFor2Typos: cfg.minLengthFor2Typos,
|
|
463
|
+
typoFallbackThreshold: cfg.typoFallbackThreshold,
|
|
464
|
+
prioritizeExactMatch: cfg.prioritizeExactMatch
|
|
465
|
+
}).then((result) => {
|
|
466
|
+
var _a2, _b;
|
|
467
|
+
if (requestId !== requestIdRef.current) return;
|
|
468
|
+
const items = (_b = (_a2 = result == null ? void 0 : result.data) == null ? void 0 : _a2.items) != null ? _b : [];
|
|
469
|
+
setSuggestions(items);
|
|
470
|
+
setActiveIndex(NO_ACTIVE_INDEX);
|
|
471
|
+
setIsOpen(items.length > 0);
|
|
472
|
+
}).catch((error) => {
|
|
473
|
+
if (requestId !== requestIdRef.current) return;
|
|
474
|
+
console.error("Autocomplete fetch error:", error);
|
|
475
|
+
setSuggestions([]);
|
|
476
|
+
}).finally(() => {
|
|
477
|
+
if (requestId !== requestIdRef.current) return;
|
|
478
|
+
setIsLoading(false);
|
|
479
|
+
});
|
|
480
|
+
}, []);
|
|
481
|
+
const setQuery = useCallback2(
|
|
482
|
+
(value) => {
|
|
483
|
+
setQueryState(value);
|
|
484
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
485
|
+
if (value.trim().length < minQueryLength) {
|
|
486
|
+
requestIdRef.current++;
|
|
487
|
+
setSuggestions([]);
|
|
488
|
+
setActiveIndex(NO_ACTIVE_INDEX);
|
|
489
|
+
setIsOpen(false);
|
|
490
|
+
setIsLoading(false);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
debounceRef.current = setTimeout(() => runSearch(value), debounceMs);
|
|
494
|
+
},
|
|
495
|
+
[debounceMs, minQueryLength, runSearch]
|
|
496
|
+
);
|
|
497
|
+
useEffect2(() => {
|
|
498
|
+
return () => {
|
|
499
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
500
|
+
};
|
|
501
|
+
}, []);
|
|
502
|
+
const open = useCallback2(() => {
|
|
503
|
+
if (suggestions.length > 0) setIsOpen(true);
|
|
504
|
+
}, [suggestions.length]);
|
|
505
|
+
const close = useCallback2(() => {
|
|
506
|
+
setIsOpen(false);
|
|
507
|
+
setActiveIndex(NO_ACTIVE_INDEX);
|
|
508
|
+
}, []);
|
|
509
|
+
const clear = useCallback2(() => {
|
|
510
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
511
|
+
requestIdRef.current++;
|
|
512
|
+
setQueryState("");
|
|
513
|
+
setSuggestions([]);
|
|
514
|
+
setActiveIndex(NO_ACTIVE_INDEX);
|
|
515
|
+
setIsOpen(false);
|
|
516
|
+
setIsLoading(false);
|
|
517
|
+
}, []);
|
|
518
|
+
const selectItem = useCallback2(
|
|
519
|
+
(item) => {
|
|
520
|
+
close();
|
|
521
|
+
onSelect == null ? void 0 : onSelect(item);
|
|
522
|
+
},
|
|
523
|
+
[close, onSelect]
|
|
524
|
+
);
|
|
525
|
+
const activeItem = activeIndex >= 0 ? (_a = suggestions[activeIndex]) != null ? _a : null : null;
|
|
526
|
+
const handleKeyDown = useCallback2(
|
|
527
|
+
(event) => {
|
|
528
|
+
const count = suggestions.length;
|
|
529
|
+
switch (event.key) {
|
|
530
|
+
case "ArrowDown": {
|
|
531
|
+
event.preventDefault();
|
|
532
|
+
if (!isOpen) {
|
|
533
|
+
open();
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (count === 0) return;
|
|
537
|
+
setActiveIndex((prev) => prev + 1 > count - 1 ? NO_ACTIVE_INDEX : prev + 1);
|
|
538
|
+
break;
|
|
539
|
+
}
|
|
540
|
+
case "ArrowUp": {
|
|
541
|
+
event.preventDefault();
|
|
542
|
+
if (!isOpen) {
|
|
543
|
+
open();
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (count === 0) return;
|
|
547
|
+
setActiveIndex((prev) => prev <= NO_ACTIVE_INDEX ? count - 1 : prev - 1);
|
|
548
|
+
break;
|
|
549
|
+
}
|
|
550
|
+
case "Home": {
|
|
551
|
+
if (!isOpen || count === 0) return;
|
|
552
|
+
event.preventDefault();
|
|
553
|
+
setActiveIndex(0);
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
case "End": {
|
|
557
|
+
if (!isOpen || count === 0) return;
|
|
558
|
+
event.preventDefault();
|
|
559
|
+
setActiveIndex(count - 1);
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
case "Enter": {
|
|
563
|
+
if (isOpen && activeIndex >= 0 && suggestions[activeIndex]) {
|
|
564
|
+
event.preventDefault();
|
|
565
|
+
selectItem(suggestions[activeIndex]);
|
|
566
|
+
} else {
|
|
567
|
+
close();
|
|
568
|
+
onSubmit == null ? void 0 : onSubmit(query);
|
|
569
|
+
}
|
|
570
|
+
break;
|
|
571
|
+
}
|
|
572
|
+
case "Escape": {
|
|
573
|
+
if (isOpen) {
|
|
574
|
+
event.preventDefault();
|
|
575
|
+
close();
|
|
576
|
+
}
|
|
577
|
+
break;
|
|
578
|
+
}
|
|
579
|
+
default:
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
},
|
|
583
|
+
[activeIndex, close, isOpen, onSubmit, open, query, selectItem, suggestions]
|
|
584
|
+
);
|
|
585
|
+
const getLabelProps = useCallback2(() => ({ id: labelId, htmlFor: inputId }), [labelId, inputId]);
|
|
586
|
+
const getInputProps = useCallback2(
|
|
587
|
+
(userProps = {}) => {
|
|
588
|
+
var _a2, _b;
|
|
589
|
+
return {
|
|
590
|
+
...userProps,
|
|
591
|
+
id: (_a2 = userProps.id) != null ? _a2 : inputId,
|
|
592
|
+
role: "combobox",
|
|
593
|
+
"aria-autocomplete": "list",
|
|
594
|
+
"aria-expanded": isOpen,
|
|
595
|
+
"aria-controls": listboxId,
|
|
596
|
+
"aria-activedescendant": activeIndex >= 0 ? optionId(activeIndex) : void 0,
|
|
597
|
+
"aria-labelledby": (_b = userProps["aria-labelledby"]) != null ? _b : labelId,
|
|
598
|
+
autoComplete: "off",
|
|
599
|
+
value: query,
|
|
600
|
+
onChange: (event) => {
|
|
601
|
+
var _a3;
|
|
602
|
+
setQuery(event.target.value);
|
|
603
|
+
(_a3 = userProps.onChange) == null ? void 0 : _a3.call(userProps, event);
|
|
604
|
+
},
|
|
605
|
+
onKeyDown: (event) => {
|
|
606
|
+
var _a3;
|
|
607
|
+
handleKeyDown(event);
|
|
608
|
+
(_a3 = userProps.onKeyDown) == null ? void 0 : _a3.call(userProps, event);
|
|
609
|
+
},
|
|
610
|
+
onFocus: (event) => {
|
|
611
|
+
var _a3;
|
|
612
|
+
if (openOnFocus) open();
|
|
613
|
+
(_a3 = userProps.onFocus) == null ? void 0 : _a3.call(userProps, event);
|
|
614
|
+
},
|
|
615
|
+
onBlur: (event) => {
|
|
616
|
+
var _a3;
|
|
617
|
+
close();
|
|
618
|
+
(_a3 = userProps.onBlur) == null ? void 0 : _a3.call(userProps, event);
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
},
|
|
622
|
+
[
|
|
623
|
+
activeIndex,
|
|
624
|
+
close,
|
|
625
|
+
handleKeyDown,
|
|
626
|
+
inputId,
|
|
627
|
+
isOpen,
|
|
628
|
+
labelId,
|
|
629
|
+
listboxId,
|
|
630
|
+
open,
|
|
631
|
+
openOnFocus,
|
|
632
|
+
optionId,
|
|
633
|
+
query,
|
|
634
|
+
setQuery
|
|
635
|
+
]
|
|
636
|
+
);
|
|
637
|
+
const getListboxProps = useCallback2(
|
|
638
|
+
(userProps = {}) => {
|
|
639
|
+
var _a2;
|
|
640
|
+
return {
|
|
641
|
+
...userProps,
|
|
642
|
+
id: listboxId,
|
|
643
|
+
role: "listbox",
|
|
644
|
+
"aria-labelledby": (_a2 = userProps["aria-labelledby"]) != null ? _a2 : labelId
|
|
645
|
+
};
|
|
646
|
+
},
|
|
647
|
+
[labelId, listboxId]
|
|
648
|
+
);
|
|
649
|
+
const getItemProps = useCallback2(
|
|
650
|
+
({
|
|
651
|
+
item,
|
|
652
|
+
index,
|
|
653
|
+
userProps = {}
|
|
654
|
+
}) => ({
|
|
655
|
+
...userProps,
|
|
656
|
+
id: optionId(index),
|
|
657
|
+
role: "option",
|
|
658
|
+
"aria-selected": index === activeIndex,
|
|
659
|
+
onMouseMove: (event) => {
|
|
660
|
+
var _a2;
|
|
661
|
+
if (index !== activeIndex) setActiveIndex(index);
|
|
662
|
+
(_a2 = userProps.onMouseMove) == null ? void 0 : _a2.call(userProps, event);
|
|
663
|
+
},
|
|
664
|
+
// Prevent the input from blurring (which would close the panel) before the click lands.
|
|
665
|
+
onMouseDown: (event) => {
|
|
666
|
+
var _a2;
|
|
667
|
+
event.preventDefault();
|
|
668
|
+
(_a2 = userProps.onMouseDown) == null ? void 0 : _a2.call(userProps, event);
|
|
669
|
+
},
|
|
670
|
+
onClick: (event) => {
|
|
671
|
+
var _a2;
|
|
672
|
+
selectItem(item);
|
|
673
|
+
(_a2 = userProps.onClick) == null ? void 0 : _a2.call(userProps, event);
|
|
674
|
+
}
|
|
675
|
+
}),
|
|
676
|
+
[activeIndex, optionId, selectItem]
|
|
677
|
+
);
|
|
678
|
+
return {
|
|
679
|
+
query,
|
|
680
|
+
setQuery,
|
|
681
|
+
suggestions,
|
|
682
|
+
isLoading,
|
|
683
|
+
isOpen,
|
|
684
|
+
activeIndex,
|
|
685
|
+
activeItem,
|
|
686
|
+
open,
|
|
687
|
+
close,
|
|
688
|
+
clear,
|
|
689
|
+
selectItem,
|
|
690
|
+
getLabelProps,
|
|
691
|
+
getInputProps,
|
|
692
|
+
getListboxProps,
|
|
693
|
+
getItemProps
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
|
|
361
697
|
// src/react/usePagination.ts
|
|
362
|
-
import { useMemo as
|
|
698
|
+
import { useMemo as useMemo3 } from "react";
|
|
363
699
|
var DOTS = "...";
|
|
364
700
|
var range = (start, end) => {
|
|
365
701
|
const length = end - start + 1;
|
|
366
702
|
return Array.from({ length }, (_, idx) => idx + start);
|
|
367
703
|
};
|
|
368
|
-
var usePagination = ({ totalCount, perPage, siblingCount = 1, currentPage }) =>
|
|
704
|
+
var usePagination = ({ totalCount, perPage, siblingCount = 1, currentPage }) => useMemo3(() => {
|
|
369
705
|
const totalPageCount = Math.ceil(totalCount / perPage);
|
|
370
706
|
const totalPageNumbers = siblingCount + 5;
|
|
371
707
|
if (totalPageNumbers >= totalPageCount) {
|
|
@@ -394,7 +730,7 @@ var usePagination = ({ totalCount, perPage, siblingCount = 1, currentPage }) =>
|
|
|
394
730
|
}, [totalCount, perPage, siblingCount, currentPage]);
|
|
395
731
|
|
|
396
732
|
// src/react/useSearchPagination.ts
|
|
397
|
-
import { useMemo as
|
|
733
|
+
import { useMemo as useMemo4, useCallback as useCallback3 } from "react";
|
|
398
734
|
function useSearchPagination(siblingCount) {
|
|
399
735
|
const { page, pageSize, results, setPage, isLoading } = useSearch();
|
|
400
736
|
const pages = usePagination({
|
|
@@ -403,23 +739,23 @@ function useSearchPagination(siblingCount) {
|
|
|
403
739
|
perPage: pageSize,
|
|
404
740
|
siblingCount
|
|
405
741
|
}) || [];
|
|
406
|
-
const lastPage =
|
|
742
|
+
const lastPage = useMemo4(
|
|
407
743
|
() => Number(pages[pages.length - 1]) || 0,
|
|
408
744
|
[pages]
|
|
409
745
|
);
|
|
410
|
-
const goToPage =
|
|
746
|
+
const goToPage = useCallback3(
|
|
411
747
|
(p) => {
|
|
412
748
|
if (!isLoading) setPage(p);
|
|
413
749
|
},
|
|
414
750
|
[isLoading, setPage]
|
|
415
751
|
);
|
|
416
|
-
const goToPrev =
|
|
752
|
+
const goToPrev = useCallback3(
|
|
417
753
|
() => {
|
|
418
754
|
if (page > 0 && !isLoading) setPage(page - 1);
|
|
419
755
|
},
|
|
420
756
|
[page, isLoading, setPage]
|
|
421
757
|
);
|
|
422
|
-
const goToNext =
|
|
758
|
+
const goToNext = useCallback3(
|
|
423
759
|
() => {
|
|
424
760
|
if (page < lastPage && !isLoading) setPage(page + 1);
|
|
425
761
|
},
|
|
@@ -500,6 +836,7 @@ export {
|
|
|
500
836
|
SearchItemUrlResolverProvider,
|
|
501
837
|
SearchProvider,
|
|
502
838
|
createDefaultUrlResolver,
|
|
839
|
+
useAutocomplete,
|
|
503
840
|
usePagination,
|
|
504
841
|
useSearch,
|
|
505
842
|
useSearchPagination,
|