Filter Table
Data & TablesStatus chips that reorganize live data.
Interactive Live Preview
components/ui/filter-table.tsxTypeScript · React 19
1"use client";23import { useState } from "react";45/* ─────────────────────────────────────────────────────────6 * FILTER TABLE7 * Status chips directly filter the task table.8 * ───────────────────────────────────────────────────────── */910type Status = "todo" | "progress" | "done";1112const FILTERS: { key: "all" | Status; label: string; dot?: string; count: number }[] = [13 { key: "all", label: "All", count: 5 },14 { key: "todo", label: "To do", dot: "#f09a2f", count: 2 },15 { key: "progress", label: "In Progress", dot: "#16a6c7", count: 2 },16 { key: "done", label: "Completed", dot: "#25a878", count: 1 },17];1819const ROWS: { task: string; date: string; status: Status; owner: string }[] = [20 { task: "Restock mango sorbet", date: "Dec 03", status: "todo", owner: "Mango Moon Gelato" },21 { task: "Churn black sesame", date: "Sep 22", status: "progress", owner: "Kumo Creamery" },22 { task: "Print summer menu", date: "Jan 02", status: "todo", owner: "Coral Coast Sorbet" },23 { task: "Taste-test batch 42", date: "Nov 08", status: "progress", owner: "Maple Orbit" },24 { task: "Order waffle cones", date: "Apr 14", status: "done", owner: "Aurora Scoops" },25];2627const PILLS: Record<Status, { label: string; cls: string }> = {28 todo: { label: "To do", cls: "filter-status-todo" },29 progress: { label: "In Progress", cls: "filter-status-progress" },30 done: { label: "Completed", cls: "filter-status-done" },31};3233export default function FilterTable() {34 const [filter, setFilter] = useState<"all" | Status>("all");3536 return (37 <div className="w-full max-w-105">38 {/* filter chips */}39 <div40 className="-mx-1 mb-1 flex items-center gap-1 overflow-x-auto px-1 py-1"41 style={{ scrollbarWidth: "none" }}42 >43 {FILTERS.map((f) => {44 const active = filter === f.key;45 return (46 <button47 key={f.key}48 type="button"49 aria-pressed={active}50 onClick={() => setFilter(f.key)}51 className={`flex h-6.5 shrink-0 items-center gap-1.5 rounded-full px-2.5 text-[12px]52 font-medium transition-[background-color,box-shadow,color] duration-20053 ${active ? "bg-surface text-ink shadow-btn" : "text-ink-2 hover:bg-hover"}`}54 >55 {f.dot && <span className="size-1.5 rounded-full" style={{ background: f.dot }} />}56 {f.label}57 <span58 className={`rounded-[4px] px-1 text-[10.5px] tabular-nums59 ${active ? "bg-field text-ink-2" : "text-ink-3"}`}60 >61 {f.count}62 </span>63 </button>64 );65 })}66 </div>6768 {/* table */}69 <div70 aria-label="Scrollable task table"71 className="overflow-x-auto rounded-card bg-surface shadow-card"72 role="region"73 tabIndex={0}74 style={{ scrollbarWidth: "none" }}75 >76 <div className="min-w-[420px]">77 <div className="grid grid-cols-[1.3fr_0.6fr_0.95fr_0.9fr] gap-x-2 border-b border-line px-3 py-2 text-[12.5px] font-medium text-ink-3">78 <span>Task name</span>79 <span>Date</span>80 <span>Status</span>81 <span>Advisor</span>82 </div>83 {ROWS.map((row) => {84 const shown = filter === "all" || row.status === filter;85 const pill = PILLS[row.status];86 return (87 <div88 key={row.task}89 className="grid transition-[grid-template-rows,opacity] duration-300"90 style={{91 gridTemplateRows: shown ? "1fr" : "0fr",92 opacity: shown ? 1 : 0,93 transitionTimingFunction: "cubic-bezier(0.23, 1, 0.32, 1)",94 }}95 >96 <div className="overflow-hidden">97 <div98 className="grid grid-cols-[1.3fr_0.6fr_0.95fr_0.9fr] gap-x-2 items-center border-b99 border-line px-3 py-2 text-[13px] transition-colors duration-100100 last:border-0 hover:bg-hover"101 >102 <span className="truncate font-medium text-ink">{row.task}</span>103 <span className="text-ink-2 tabular-nums">{row.date}</span>104 <span>105 <span106 className={`inline-flex h-[23px] items-center rounded-[8px] border px-[7px]107 text-[13px] font-medium ${pill.cls}`}108 >109 {pill.label}110 </span>111 </span>112 <span className="truncate text-ink-2">{row.owner}</span>113 </div>114 </div>115 </div>116 );117 })}118 </div>119 </div>120 </div>121 );122}123
Props & Specification
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | string | "default" | Visual state and layout presentation mode. |
| className | string | "" | Optional Tailwind CSS wrapper class overrides. |
Related Components in Data & Tables
Audit Activity Stream↗
Real-time enterprise agent activity audit trail with JSON payload diff inspector.
Episodic Vector Memory↗
Vector semantic memory recall grid showing episodic memories and decay score.
Benchmark Evaluation Matrix↗
Multi-test LLM evals table testing accuracy, latency, and hallucination rate.