{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "filter-table",
  "type": "registry:component",
  "title": "Filter table",
  "description": "Status chips that reorganize live data.",
  "categories": [
    "ai-interface"
  ],
  "registryDependencies": [
    "https://irisui.dev/r/foundation.json"
  ],
  "files": [
    {
      "path": "src/registry/components/filter-table/filter-table.tsx",
      "content": "\"use client\";\n\nimport { useState } from \"react\";\n\n/* ─────────────────────────────────────────────────────────\n * FILTER TABLE\n * Status chips directly filter the task table.\n * ───────────────────────────────────────────────────────── */\n\ntype Status = \"todo\" | \"progress\" | \"done\";\n\nexport type TableRow = { task: string; date: string; status: Status; owner: string };\n\nexport type FilterTableLabels = {\n  columns: { task: string; date: string; status: string; owner: string };\n};\n\nconst FILTERS: { key: \"all\" | Status; label: string; dot?: string; count: number }[] = [\n  { key: \"all\", label: \"All\", count: 5 },\n  { key: \"todo\", label: \"To do\", dot: \"#f09a2f\", count: 2 },\n  { key: \"progress\", label: \"In progress\", dot: \"#16a6c7\", count: 2 },\n  { key: \"done\", label: \"Completed\", dot: \"#25a878\", count: 1 },\n];\n\nconst ROWS: TableRow[] = [\n  { task: \"Write the first spec\", date: \"18 Sep\", status: \"todo\", owner: \"Katerina Vlachou\" },\n  { task: \"Add login\", date: \"22 Sep\", status: \"progress\", owner: \"Katerina Vlachou\" },\n  { task: \"Connect an agent\", date: \"24 Sep\", status: \"todo\", owner: \"Stelios Antoniou\" },\n  { task: \"Move pricing page to EUR\", date: \"29 Sep\", status: \"progress\", owner: \"Nefeli Kontou\" },\n  { task: \"Ship the changelog\", date: \"22 Sep\", status: \"done\", owner: \"Tomasz Wrona\" },\n];\n\nconst LABELS: FilterTableLabels = {\n  columns: { task: \"Task name\", date: \"Date\", status: \"Status\", owner: \"Owner\" },\n};\n\n/* Each pill tints one base hue (--tag-base) against the surface: soft pastel with a matching border in light, a\n * richer fill with brighter text in dark. */\nconst PILL_TINT =\n  \"border-[color-mix(in_srgb,var(--tag-base)_34%,var(--surface))] bg-[color-mix(in_srgb,var(--tag-base)_20%,var(--surface))] text-[color-mix(in_srgb,var(--tag-base)_92%,var(--ink))] dark:bg-[color-mix(in_srgb,var(--tag-base)_34%,var(--surface))] dark:text-[color-mix(in_srgb,var(--tag-base)_86%,white)]\";\n\nconst PILLS: Record<Status, { label: string; cls: string }> = {\n  todo: { label: \"To do\", cls: \"[--tag-base:oklch(0.757_0.153_66.401)]\" },\n  progress: { label: \"In progress\", cls: \"[--tag-base:oklch(0.671_0.118_219.351)]\" },\n  done: { label: \"Completed\", cls: \"[--tag-base:oklch(0.652_0.131_162.865)]\" },\n};\n\nexport default function FilterTable({\n  rows = ROWS,\n  labels = LABELS,\n}: {\n  rows?: TableRow[];\n  labels?: FilterTableLabels;\n  variant?: string;\n} = {}) {\n  const [filter, setFilter] = useState<\"all\" | Status>(\"all\");\n\n  return (\n    <div className=\"w-full max-w-105\">\n      {/* filter chips */}\n      <div className=\"-mx-1 mb-1 flex items-center gap-1 overflow-x-auto px-1 py-1\" style={{ scrollbarWidth: \"none\" }}>\n        {FILTERS.map((f) => {\n          const active = filter === f.key;\n          return (\n            <button\n              key={f.key}\n              type=\"button\"\n              aria-pressed={active}\n              onClick={() => setFilter(f.key)}\n              className={`flex h-6.5 shrink-0 items-center gap-1.5 rounded-button px-2.5 text-[12px]\n                font-medium transition-[background-color,box-shadow,color] duration-200\n                ${active ? \"bg-surface text-ink shadow-btn\" : \"text-ink-2 hover:bg-hover\"}`}\n            >\n              {f.dot && <span className=\"size-1.5 rounded-full\" style={{ background: f.dot }} />}\n              {f.label}\n              <span\n                className={`rounded-[4px] px-1 text-[10.5px] tabular-nums\n                  ${active ? \"bg-field text-ink-2\" : \"text-ink-3\"}`}\n              >\n                {f.count}\n              </span>\n            </button>\n          );\n        })}\n      </div>\n\n      {/* table */}\n      <section\n        aria-label=\"Scrollable task table\"\n        className=\"overflow-x-auto rounded-card bg-surface shadow-card\"\n        // oxlint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- the table scrolls sideways; a focusable region lets keyboard users scroll it\n        tabIndex={0}\n        style={{ scrollbarWidth: \"none\" }}\n      >\n        <div className=\"min-w-[420px]\">\n          <div className=\"grid grid-cols-[minmax(0,1.3fr)_minmax(0,0.6fr)_minmax(0,0.95fr)_minmax(0,0.9fr)] border-b border-[var(--grid-line)] text-[12.5px] font-medium text-ink-2\">\n            <span className=\"border-r border-[var(--grid-line)] px-3 py-2\">{labels.columns.task}</span>\n            <span className=\"border-r border-[var(--grid-line)] px-3 py-2\">{labels.columns.date}</span>\n            <span className=\"border-r border-[var(--grid-line)] px-3 py-2\">{labels.columns.status}</span>\n            <span className=\"px-3 py-2\">{labels.columns.owner}</span>\n          </div>\n          {rows.map((row) => {\n            const shown = filter === \"all\" || row.status === filter;\n            const pill = PILLS[row.status];\n            return (\n              <div\n                key={row.task}\n                className=\"grid transition-[grid-template-rows,opacity] duration-300\"\n                style={{\n                  gridTemplateRows: shown ? \"1fr\" : \"0fr\",\n                  opacity: shown ? 1 : 0,\n                  transitionTimingFunction: \"cubic-bezier(0.23, 1, 0.32, 1)\",\n                }}\n              >\n                <div className=\"overflow-hidden\">\n                  <div\n                    className=\"grid grid-cols-[minmax(0,1.3fr)_minmax(0,0.6fr)_minmax(0,0.95fr)_minmax(0,0.9fr)] border-b\n                      border-[var(--grid-line)] text-[13px] transition-colors duration-100 hover:bg-hover\"\n                  >\n                    <span className=\"flex min-w-0 items-center border-r border-[var(--grid-line)] px-3 py-2\">\n                      <span className=\"truncate font-medium text-ink\">{row.task}</span>\n                    </span>\n                    <span className=\"flex items-center whitespace-nowrap border-r border-[var(--grid-line)] px-3 py-2 text-ink-2 tabular-nums\">\n                      {row.date}\n                    </span>\n                    <span className=\"flex items-center border-r border-[var(--grid-line)] px-3 py-2\">\n                      <span\n                        className={`inline-flex h-[23px] shrink-0 items-center whitespace-nowrap rounded-[8px] border px-[7px]\n                          text-[13px] font-medium ${PILL_TINT} ${pill.cls}`}\n                      >\n                        {pill.label}\n                      </span>\n                    </span>\n                    <span className=\"flex min-w-0 items-center px-3 py-2 text-ink-2\">\n                      <span className=\"truncate\">{row.owner}</span>\n                    </span>\n                  </div>\n                </div>\n              </div>\n            );\n          })}\n        </div>\n      </section>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/iris/filter-table/filter-table.tsx"
    }
  ],
  "docs": "Docs and live preview: https://irisui.dev/components/filter-table",
  "meta": {
    "kind": "component",
    "group": "AI interface",
    "export": "FilterTable",
    "docs": "https://irisui.dev/components/filter-table"
  }
}
