
Masonry Grid
Bento & Grids
Search by name, tag, category or type
Source and install need .
pnpm dlx shadcn@latest add @assembli/filterable-gridA directory grid for templates, integrations or work: filter pills with live counts, a search box that "/" jumps to, and a sort menu. Cards slide into place as the results change, and an empty state offers a way back. Generic over any item type with render and accessor props.
Other props pass through to the root element.
items*
T[]
getKey*
(item: T) => string
getCategory*
(item: T) => string | string[]
The filter value each item belongs to. Items can belong to several.
getSearchText
(item: T) => string
Text the search box matches against. Leave it out to hide the search box.
renderItem*
(item: T) => React.ReactNode
filters*
GridFilter[]
Filter tabs, in order. An "All" tab is added in front. Counts are worked out for you.
allLabel
string
Default "All"
sorts
GridSort<T>[]
defaultFilter
string
Default ALL
onFilterChange
(value: string) => void
noun
{ one: string; other: string }
Default { one: "result", other: "results" }
The noun for the result count: { one: "template", other: "templates" }.
minItemWidth
string
Default "16rem"
Cards never get narrower than this, as a CSS length.
searchPlaceholder
string
Default "Search"
| Prop | Type | Default | Description |
|---|---|---|---|
| items* | T[] | – | |
| getKey* | (item: T) => string | – | |
| getCategory* | (item: T) => string | string[] | – | The filter value each item belongs to. Items can belong to several. |
| getSearchText | (item: T) => string | – | Text the search box matches against. Leave it out to hide the search box. |
| renderItem* | (item: T) => React.ReactNode | – | |
| filters* | GridFilter[] | – | Filter tabs, in order. An "All" tab is added in front. Counts are worked out for you. |
| allLabel | string | "All" | |
| sorts | GridSort<T>[] | – | |
| defaultFilter | string | ALL | |
| onFilterChange | (value: string) => void | – | |
| noun | { one: string; other: string } | { one: "result", other: "results" } | The noun for the result count: { one: "template", other: "templates" }. |
| minItemWidth | string | "16rem" | Cards never get narrower than this, as a CSS length. |
| searchPlaceholder | string | "Search" |