FoodEase
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.json

Installs 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

FieldTypeDescription
itemsT[]The full list to filter
optionsMatchSorterOptions<T>match-sorter options. keys specifies which fields to search

Returns

FieldTypeDescription
filteredItemsT[]Filtered (and ranked) list. Returns all items when query is empty
setQuery(query: string) => voidSet the current search string
querystringCurrent raw query string
deferredQuerystringDeferred query used for filtering (slightly behind query on slow renders)

How It Works

  • When query is empty or whitespace, all items are returned unchanged
  • Otherwise matchSorter(items, query, options) is called — it ranks results by match quality (exact > prefix > contains)
  • useDeferredValue defers the filter computation so the input stays responsive even with large lists

On this page