Command Palette

Search for a command to run...

Pokedex

Controllable primitives to build Pokédex UIs: search, domain filters, incremental pagination, and renderItem-based collections.

5 / 10
bulbasaur

Bulbasaur (Japanese: フシギダネ Fushigidane) is a dual-type Grass/Poison Pokémon introduced in Generation I.

grasspoison
charmander

Charmander (Japanese: ヒトカゲ Hitokage) is a Fire-type Pokémon introduced in Generation I.

fire
squirtle

Squirtle (Japanese: カメール Kamēru) is a Water-type Pokémon introduced in Generation I.

water
pikachu

Pikachu (Japanese: ピカチュウ Pikachū) is an Electric-type Pokémon introduced in Generation I.

electric
jigglypuff

Jigglypuff (Japanese: ポッポ Poppo) is a Normal/Fairy-type Pokémon introduced in Generation I.

normalfairy

Installation

Usage

The root filters items by comparing the normalized query against item.name, PokedexItems renders a responsive grid, and PokedexLoadMore manages its own labels. The component composes Radix UI primitives and shadcn/ui components (button, empty, input-group) under the hood. Data fetching is always the consumer's responsibility — you supply the items array; this component handles state and rendering.

Tip

Building a full Pokédex? Follow the step-by-step guide at Build a Pokédex.

Examples

Grid

PokedexItems renders a responsive grid by default; pageSize + PokedexLoadMore add incremental pagination.

BUbulbasaur
CHcharmander
SQsquirtle
PIpikachu
JIjigglypuff
GEgengar

Empty state

PokedexEmpty appears only when there are no matches; PokedexClear resets the search and disables itself automatically.

Sin resultados
Ningún Pokémon coincide con la búsqueda.

Count

PokedexCount accepts a render prop with visible, matched, and total for formatting the count display.

Mostrando 4 de 9 coincidencias (9 en total)
bulbasaur
ivysaur
venusaur
charmander

Controlled state

Each piece of state follows the value / defaultValue / onChange pattern, so you can sync search with the URL, a form, or external state.

Server-side filtering

If your items already arrive filtered (server-side search, external index), disable internal filtering with shouldFilter.

Data-aware filters

The filter shape (PokedexFilterState) covers generations, primary/secondary type, legendaries, and mythicals. Only your app knows which generation each Pokémon belongs to, so inject your own filterFn — or pre-filter and use shouldFilter={false}.

Infinite scroll

usePokedex() exposes the full context state. Wire loadMore to an IntersectionObserver instead of a button.

Accessibility

PokedexSearch is a standard text <input> — add your own aria-label or associate it with a <label>. The built-in clear button and PokedexClear expose accessible labels and disable themselves when there is nothing to clear.

Keyboard interactions

KeyDescription
EscapeClears the search if there is text. When the query is already empty, the event continues to propagate (e.g., to close a containing dialog).

API Reference

Pokedex

Root of the component set. Owns the search, filter, and pagination state, and exposes it through context to all subcomponents. query and filters follow the controlled/uncontrolled pattern. Also accepts all native <div> props.

PropTypeDefault
itemsT[][]
getItemKeyitem.name ?? index
getItemNameitem.name
querystring
defaultQuerystring""
onQueryChange
filtersPokedexFilterState
defaultFiltersPokedexFilterStateEMPTY_POKEDEX_FILTERS
onFiltersChange
shouldFilterbooleantrue
filterFnmatcher por query
pageSizenumber
loadingbooleanfalse
asChildbooleanfalse

PokedexSearch

Search input bound to the context query, with a search icon and a built-in clear button (visible only when there is text). className is applied to the wrapper; all other props go to the <input>. Also accepts all native <input> props.

PropTypeDefault
placeholderstring"Buscar Pokémon…"
onChange

PokedexClear

Button that resets the search, the filters, or both. Disables itself automatically when there is nothing to clear. Also accepts all native <button> props.

PropTypeDefault
clears"all"
variant"outline"
size"sm"

PokedexItems

Renders the visible items (including the pagination window) with a key resolved by getItemKey. Responsive grid by default; override className for any other layout (list, table, masonry). Also accepts all native <div> props.

PropTypeDefault
renderItem
classNamestringgrid responsive 1→5 col
asChildbooleanfalse

PokedexEmpty

Empty state. Only renders when there are no matches and loading is false. Compose its content with EmptyHeader, EmptyTitle, EmptyDescription, and EmptyContent. Exposes data-reason="no-match" when there is an active query or filters, and data-reason="no-items" when no items arrived at all. Also accepts all native <div> props.

PokedexLoadMore

Pagination button. Returns null when pageSize is unset or there are no matches; disables itself and exposes data-state="exhausted" when all results are shown. Also accepts all native <button> props.

PropTypeDefault
childrenReactNode"Load more" / "No more"
variant"default"
size"default"

PokedexCount

Result count display. Also accepts all native <span> props.

PropTypeDefault
childrenvisible / matched
asChildbooleanfalse

usePokedex

Context access hook — must be used inside <Pokedex>. Generic: usePokedex<MyType>().

PropertyTypeDescription
itemsT[]All items as supplied.
matchedItemsT[]Items after filterFn (or items when shouldFilter is false).
visibleItemsT[]Matches trimmed to the current pagination window.
query / queryNormalizedstringRaw query and normalized form (trimmed + lowercased).
setQuery(query: string) => voidUpdates the query.
filtersPokedexFilterStateCurrent filter state.
setFilters(filters | updater) => voidReplaces or updates filters.
toggleGeneration / togglePrimaryType / toggleSecondaryType(name: string) => voidToggles a value in the corresponding list.
setGenerations(names: string[]) => voidReplaces the generation selection (e.g., radio behavior).
setLegendaryOnly / setMythicalOnly(value: boolean) => voidEnables or disables the flag.
clearFilters() => voidResets to EMPTY_POKEDEX_FILTERS.
hasActiveFiltersbooleantrue when any filter is active.
pageSizenumber | nullnull when pagination is disabled.
visibleCountnumberCurrent window size.
hasMorebooleanWhether more items remain to be shown.
loadMore() => voidExpands the window by pageSize.
loadingbooleanThe loading prop from the root.

PokedexFilterState

EMPTY_POKEDEX_FILTERS is exported as the initial/reset value.