gridcn1.2.2

Filtering

Quick search, per-column filters, faceted isAnyOf and isNoneOf, the header filter, and isBetween ranges.

The toolbar's search and filter surface: quick-search with match navigation, per-column filter menus, and click-to-sort headers (asc → desc → clear. Shift-click appends a secondary sort). The operator set adapts to the cell type. That's where faceted and range filtering live.

Click a header to sort (click again to reverse, a third click clears it); shift-click another header to add it as a secondary sort. Use Filter in the toolbar for per-column filters.

Name
Email
Age
Role
Score
Silent Tiger
user0@example.com
63
Viewer
4
Quick Lion
user1@example.com
67
Viewer
89
Swift Wolf
user2@example.com
40
Manager
80
Eager Lion
user3@example.com
50
User
51
Eager Tiger
user4@example.com
45
Viewer
83
Silent Wolf
user5@example.com
24
User
15
Swift Lion
user6@example.com
34
Viewer
62
Eager Lion
user7@example.com
21
Manager
42
Eager Eagle
user8@example.com
25
Editor
35
Bold Tiger
user9@example.com
19
Editor
52
Bold Bear
user10@example.com
42
User
28
Swift Wolf
user11@example.com
47
Manager
9
Swift Bear
user12@example.com
41
Viewer
45
Eager Wolf
user13@example.com
35
Editor
44
Swift Eagle
user14@example.com
65
Viewer
51
Quick Lion
user15@example.com
22
Manager
28
Bold Wolf
user16@example.com
30
Editor
76
Swift Eagle
user17@example.com
19
Admin
26
Eager Eagle
user18@example.com
35
Manager
70
Eager Bear
user19@example.com
33
Editor
67
Silent Lion
user20@example.com
48
Manager
89
Silent Tiger
user21@example.com
62
Manager
40
Eager Tiger
user22@example.com
51
Manager
82
Silent Lion
user23@example.com
26
Admin
16
Bold Eagle
user24@example.com
26
Admin
38
Bold Lion
user25@example.com
49
Viewer
3
Quick Tiger
user26@example.com
26
Viewer
41
Bold Eagle
user27@example.com
50
Editor
10
Swift Tiger
user28@example.com
55
Editor
6
Silent Lion
user29@example.com
35
Viewer
42
pnpm dlx shadcn@latest add @gridcn/data-grid-sorting-filtering-demo

What's in the demo

  • DataGridSearch: quick-search. It highlights and navigates matches, and never narrows viewIndex
  • DataGridFilterMenu: one filter per filterable: true column, joined with AND/OR
  • headerClickBehavior="sort": click cycles asc → desc → clear

Faceted (multi-value) filters

On select columns the filter menu offers isAnyOf: pick any number of options.choices and a row matches if its value is in the list. That is the faceted-filter shape: one filter per column, multiple values each. isNoneOf is the opposite: a row matches if its value is not in the list. text, number, and date columns offer both operators too.

Header filter

New

The header filter puts a searchable list of the column's values in each column header. The user checks the values to keep, and the grid stores the shorter of the checked and unchecked lists as isAnyOf or isNoneOf. See the toolbar add-on.

Name
Role
Age
Score
Silent Tiger
Viewer
63
4
Quick Lion
Viewer
67
89
Swift Wolf
Manager
40
80
Eager Lion
User
50
51
Eager Tiger
Viewer
45
83
Silent Wolf
User
24
15
Swift Lion
Viewer
34
62
Eager Lion
Manager
21
42
Eager Eagle
Editor
25
35
Bold Tiger
Editor
19
52
Bold Bear
User
42
28
Swift Wolf
Manager
47
9
Swift Bear
Viewer
41
45
Eager Wolf
Editor
35
44
Swift Eagle
Viewer
65
51
Quick Lion
Manager
22
28
Bold Wolf
Editor
30
76
Swift Eagle
Admin
19
26
Eager Eagle
Manager
35
70
Eager Bear
Editor
33
67
Silent Lion
Manager
48
89
Silent Tiger
Manager
62
40
Eager Tiger
Manager
51
82
Silent Lion
Admin
26
16
Bold Eagle
Admin
26
38
Bold Lion
Viewer
49
3
Quick Tiger
Viewer
26
41
Bold Eagle
Editor
50
10
Swift Tiger
Editor
55
6
Silent Lion
Viewer
35
42

Range filters

number and date columns get isBetween: an inclusive [min, max] tuple where either bound can be empty for an open-ended range (["", "10"] = "≤ 10"). Dates work because the date type stores ISO strings, which compare lexicographically.

Per-option counts (DIY)

The filter menu does not render live counts per choice. If you want them, compute them app-side from your own data and render them next to your choice UI. The grid only owns the match logic:

// app-side facet counts for a select column
const counts = useMemo(() => {
  const map = new Map<string, number>();
  for (const row of data) {
    const value = row.role;
    map.set(value, (map.get(value) ?? 0) + 1);
  }
  return map;
}, [data]);

On this page