Hooks
useVisibleItems
Hook that filters a list with match-sorter and deferred query updates for smooth search-as-you-type
Overview
useVisibleItems takes an array of items and match-sorter options, exposes a setQuery function, and returns filteredItems. The query is wrapped in useDeferredValue so filtering doesn't block the UI on large lists.
Used internally by SearchableContainer. Use it directly when you need search filtering without the full container.
Installation
npx shadcn@latest add https://foodease-dev-registry.cap.reachcinema.io/r/v1/use-visible-items.jsonInstalls match-sorter as an npm dependency.
Usage
Basic
import useVisibleItems from "@/hooks/useVisibleItems"
const { filteredItems, setQuery } = useVisibleItems({
items: products,
options: { keys: ["name"] },
})With a Custom Search Input
import useVisibleItems from "@/hooks/useVisibleItems"
export default function FilterableList({ items }) {
const { filteredItems, setQuery } = useVisibleItems({
items,
options: { keys: ["name", "description"] },
})
return (
<div>
<input
type="search"
placeholder="Search..."
onChange={(e) => setQuery(e.target.value)}
/>
<ul>
{filteredItems.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
)
}Multiple Search Keys
const { filteredItems, setQuery } = useVisibleItems({
items: staff,
options: { keys: ["firstName", "lastName", "roleName"] },
})Nested Key Paths
const { filteredItems, setQuery } = useVisibleItems({
items: orders,
options: { keys: ["customer.name", "reference"] },
})API Reference
Parameters
| Field | Type | Description |
|---|---|---|
items | T[] | The full list to filter |
options | MatchSorterOptions<T> | match-sorter options. keys specifies which fields to search |
Returns
| Field | Type | Description |
|---|---|---|
filteredItems | T[] | Filtered (and ranked) list. Returns all items when query is empty |
setQuery | (query: string) => void | Set the current search string |
query | string | Current raw query string |
deferredQuery | string | Deferred query used for filtering (slightly behind query on slow renders) |
How It Works
- When
queryis empty or whitespace, all items are returned unchanged - Otherwise
matchSorter(items, query, options)is called — it ranks results by match quality (exact > prefix > contains) useDeferredValuedefers the filter computation so the input stays responsive even with large lists