{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "table-status",
  "title": "Status table",
  "description": "Styled table: the Status set. 5 decorative table variations (BadgeTable, DotTable, ToneTable, ProgressTable, IconTable) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/table-status.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport { AlertTriangle, CheckCircle2, Clock, Info, XCircle } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Status table family: 5 tables with status cells. The status text maps to a\n   semantic tone (info/success/warning/danger) and the cell carries data-tone: a\n   badge, a dot, a full tone background, a progress bar and an icon. Color comes ONLY\n   from semantic tokens - the tone tokens (-foreground/-soft/-soft-foreground) and\n   alpha color-mix. Deterministic, renders with no props too. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\ntype Column = { key: string; label: React.ReactNode }\ntype Row = Record<string, React.ReactNode>\n\ntype TableProps = {\n  className?: string\n  size?: StyledSize\n  columns?: Column[]\n  rows?: Row[]\n}\n\ntype Tone = \"neutral\" | \"info\" | \"success\" | \"warning\" | \"danger\"\n\n/* A sensible default data set so it renders without props. */\nconst defaultColumns: Column[] = [\n  { key: \"name\", label: \"Name\" },\n  { key: \"role\", label: \"Role\" },\n  { key: \"status\", label: \"Status\" },\n]\n\nconst defaultRows: Row[] = [\n  { name: \"Ada Lovelace\", role: \"Engineer\", status: \"Active\" },\n  { name: \"Alan Turing\", role: \"Researcher\", status: \"Pending\" },\n  { name: \"Grace Hopper\", role: \"Architect\", status: \"Failed\" },\n  { name: \"Katherine Johnson\", role: \"Analyst\", status: \"Queued\" },\n]\n\n/* An extra column plus deterministic percentages for the progress variant. */\nconst progressColumns: Column[] = [\n  { key: \"name\", label: \"Name\" },\n  { key: \"status\", label: \"Status\" },\n  { key: \"progress\", label: \"Progress\" },\n]\n\nconst progressRows: Row[] = [\n  { name: \"Ada Lovelace\", status: \"Active\", progress: \"92\" },\n  { name: \"Alan Turing\", status: \"Pending\", progress: \"58\" },\n  { name: \"Grace Hopper\", status: \"Failed\", progress: \"24\" },\n  { name: \"Katherine Johnson\", status: \"Queued\", progress: \"71\" },\n]\n\n/* Hucre yogunlugu: padding + metin olcegi. */\nconst cell: Record<StyledSize, string> = {\n  sm: \"px-2.5 py-1.5 text-xs\",\n  md: \"px-3 py-2 text-sm\",\n  lg: \"px-4 py-2.5 text-sm\",\n  xl: \"px-5 py-3 text-base\",\n}\n\nconst headCell: Record<StyledSize, string> = {\n  sm: \"px-2.5 py-1.5 text-xs\",\n  md: \"px-3 py-2 text-xs\",\n  lg: \"px-4 py-2.5 text-sm\",\n  xl: \"px-5 py-3 text-sm\",\n}\n\nconst tableBase = \"w-full border-collapse text-left align-middle text-foreground\"\nconst headBase = \"font-medium text-muted-foreground\"\n\nfunction resolve(columns: Column[] | undefined, rows: Row[] | undefined, fbCols: Column[], fbRows: Row[]) {\n  return {\n    cols: columns && columns.length > 0 ? columns : fbCols,\n    data: rows && rows.length > 0 ? rows : fbRows,\n  }\n}\n\n/* Durum metnini semantik tona esler (deterministik, buyuk/kucuk harf duyarsiz). */\nconst toneByStatus: Record<string, Tone> = {\n  active: \"success\",\n  done: \"success\",\n  complete: \"success\",\n  pending: \"warning\",\n  away: \"warning\",\n  failed: \"danger\",\n  error: \"danger\",\n  blocked: \"danger\",\n  queued: \"info\",\n  running: \"info\",\n}\n\nfunction toText(value: React.ReactNode): string {\n  if (typeof value === \"string\") return value\n  if (typeof value === \"number\") return String(value)\n  return \"\"\n}\n\nfunction toneOf(value: React.ReactNode): Tone {\n  return toneByStatus[toText(value).trim().toLowerCase()] ?? \"neutral\"\n}\n\n/* Yumusak ton yuzeyleri (rozet / zemin). */\nconst softTone: Record<Tone, string> = {\n  neutral: \"bg-muted text-muted-foreground border-border\",\n  info: \"bg-info-soft text-info-soft-foreground border-info/40\",\n  success: \"bg-success-soft text-success-soft-foreground border-success/40\",\n  warning: \"bg-warning-soft text-warning-soft-foreground border-warning/40\",\n  danger: \"bg-danger-soft text-danger-soft-foreground border-danger/40\",\n}\n\n/* Dolu ton yuzeyleri. */\nconst solidTone: Record<Tone, string> = {\n  neutral: \"bg-muted text-muted-foreground\",\n  info: \"bg-info text-info-foreground\",\n  success: \"bg-success text-success-foreground\",\n  warning: \"bg-warning text-warning-foreground\",\n  danger: \"bg-danger text-danger-foreground\",\n}\n\n/* Nokta / cubuk dolgusu. */\nconst dotTone: Record<Tone, string> = {\n  neutral: \"bg-muted-foreground\",\n  info: \"bg-info\",\n  success: \"bg-success\",\n  warning: \"bg-warning\",\n  danger: \"bg-danger\",\n}\n\n/* Metin tonu. */\nconst textTone: Record<Tone, string> = {\n  neutral: \"text-muted-foreground\",\n  info: \"text-info\",\n  success: \"text-success\",\n  warning: \"text-warning\",\n  danger: \"text-danger\",\n}\n\nconst iconTone: Record<Tone, React.ReactNode> = {\n  neutral: <Info />,\n  info: <Clock />,\n  success: <CheckCircle2 />,\n  warning: <AlertTriangle />,\n  danger: <XCircle />,\n}\n\nconst iconBox =\n  \"inline-flex items-center gap-1.5 [&_svg]:size-4 [&_svg]:shrink-0 [&>svg]:shrink-0 [&_i]:text-base [&_i]:leading-none [&>i]:shrink-0\"\n\n/* Badge: durum, ton renkli yumusak bir rozet olarak okunur. */\nexport function BadgeTable({ className, size = \"md\", columns, rows }: TableProps) {\n  const { cols, data } = resolve(columns, rows, defaultColumns, defaultRows)\n  return (\n    <div\n      data-slot=\"styled-table\"\n      className={cn(\"w-full overflow-x-auto rounded-lg border border-border\", className)}\n    >\n      <table className={tableBase}>\n        <thead>\n          <tr className=\"border-b border-border bg-muted\">\n            {cols.map((col) => (\n              <th key={col.key} scope=\"col\" className={cn(headBase, headCell[size])}>\n                {col.label}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>\n          {data.map((row, i) => {\n            const tone = toneOf(row.status)\n            return (\n              <tr key={i} className=\"border-b border-border/60 last:border-b-0\">\n                {cols.map((col) =>\n                  col.key === \"status\" ? (\n                    <td key={col.key} data-tone={tone} className={cell[size]}>\n                      <span\n                        className={cn(\n                          \"inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium\",\n                          softTone[tone]\n                        )}\n                      >\n                        {row[col.key]}\n                      </span>\n                    </td>\n                  ) : (\n                    <td key={col.key} className={cell[size]}>\n                      {row[col.key]}\n                    </td>\n                  )\n                )}\n              </tr>\n            )\n          })}\n        </tbody>\n      </table>\n    </div>\n  )\n}\n\n/* Dot: the status is shown with a small tone dot + plain text. */\nexport function DotTable({ className, size = \"md\", columns, rows }: TableProps) {\n  const { cols, data } = resolve(columns, rows, defaultColumns, defaultRows)\n  return (\n    <div\n      data-slot=\"styled-table\"\n      className={cn(\"w-full overflow-x-auto rounded-lg border border-border\", className)}\n    >\n      <table className={tableBase}>\n        <thead>\n          <tr className=\"border-b border-border\">\n            {cols.map((col) => (\n              <th key={col.key} scope=\"col\" className={cn(headBase, headCell[size])}>\n                {col.label}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>\n          {data.map((row, i) => {\n            const tone = toneOf(row.status)\n            return (\n              <tr key={i} className=\"border-b border-border/60 last:border-b-0\">\n                {cols.map((col) =>\n                  col.key === \"status\" ? (\n                    <td key={col.key} data-tone={tone} className={cell[size]}>\n                      <span className=\"inline-flex items-center gap-2\">\n                        <span\n                          aria-hidden=\"true\"\n                          className={cn(\"size-2 shrink-0 rounded-full\", dotTone[tone])}\n                        />\n                        {row[col.key]}\n                      </span>\n                    </td>\n                  ) : (\n                    <td key={col.key} className={cell[size]}>\n                      {row[col.key]}\n                    </td>\n                  )\n                )}\n              </tr>\n            )\n          })}\n        </tbody>\n      </table>\n    </div>\n  )\n}\n\n/* Tone: the whole row is painted with the soft tone of the state, and the state cell takes the solid tone. */\nexport function ToneTable({ className, size = \"md\", columns, rows }: TableProps) {\n  const { cols, data } = resolve(columns, rows, defaultColumns, defaultRows)\n  return (\n    <div\n      data-slot=\"styled-table\"\n      className={cn(\"w-full overflow-x-auto rounded-lg border border-border\", className)}\n    >\n      <table className={tableBase}>\n        <thead>\n          <tr className=\"border-b border-border bg-muted\">\n            {cols.map((col) => (\n              <th key={col.key} scope=\"col\" className={cn(headBase, headCell[size])}>\n                {col.label}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>\n          {data.map((row, i) => {\n            const tone = toneOf(row.status)\n            return (\n              <tr\n                key={i}\n                data-tone={tone}\n                className={cn(\"border-b border-border/60 last:border-b-0\", softTone[tone])}\n              >\n                {cols.map((col) =>\n                  col.key === \"status\" ? (\n                    <td key={col.key} data-tone={tone} className={cell[size]}>\n                      <span\n                        className={cn(\n                          \"inline-flex items-center rounded-md px-2 py-0.5 text-xs font-semibold\",\n                          solidTone[tone]\n                        )}\n                      >\n                        {row[col.key]}\n                      </span>\n                    </td>\n                  ) : (\n                    <td key={col.key} className={cell[size]}>\n                      {row[col.key]}\n                    </td>\n                  )\n                )}\n              </tr>\n            )\n          })}\n        </tbody>\n      </table>\n    </div>\n  )\n}\n\n/* Progress: durum tonuyla dolan bir ilerleme cubugu kolonu. */\nexport function ProgressTable({ className, size = \"md\", columns, rows }: TableProps) {\n  const { cols, data } = resolve(columns, rows, progressColumns, progressRows)\n  return (\n    <div\n      data-slot=\"styled-table\"\n      className={cn(\"w-full overflow-x-auto rounded-lg border border-border\", className)}\n    >\n      <table className={tableBase}>\n        <thead>\n          <tr className=\"border-b border-border bg-muted\">\n            {cols.map((col) => (\n              <th key={col.key} scope=\"col\" className={cn(headBase, headCell[size])}>\n                {col.label}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>\n          {data.map((row, i) => {\n            const tone = toneOf(row.status)\n            const raw = Number(toText(row.progress))\n            const pct = Number.isNaN(raw) ? 0 : Math.min(100, Math.max(0, raw))\n            return (\n              <tr key={i} className=\"border-b border-border/60 last:border-b-0\">\n                {cols.map((col) => {\n                  if (col.key === \"progress\") {\n                    return (\n                      <td key={col.key} data-tone={tone} className={cn(cell[size], \"min-w-40\")}>\n                        <span className=\"flex items-center gap-2\">\n                          <span\n                            role=\"progressbar\"\n                            aria-valuenow={pct}\n                            aria-valuemin={0}\n                            aria-valuemax={100}\n                            aria-label={`Progress ${pct} percent`}\n                            className=\"h-1.5 w-full overflow-hidden rounded-full bg-[color-mix(in_oklab,var(--color-foreground)_10%,transparent)]\"\n                          >\n                            <span\n                              className={cn(\"block h-full rounded-full\", dotTone[tone])}\n                              style={{ width: `${pct}%` }}\n                            />\n                          </span>\n                          <span className=\"w-9 shrink-0 text-right text-xs tabular-nums text-muted-foreground\">\n                            {`${pct}%`}\n                          </span>\n                        </span>\n                      </td>\n                    )\n                  }\n                  if (col.key === \"status\") {\n                    return (\n                      <td key={col.key} data-tone={tone} className={cn(cell[size], textTone[tone])}>\n                        {row[col.key]}\n                      </td>\n                    )\n                  }\n                  return (\n                    <td key={col.key} className={cell[size]}>\n                      {row[col.key]}\n                    </td>\n                  )\n                })}\n              </tr>\n            )\n          })}\n        </tbody>\n      </table>\n    </div>\n  )\n}\n\n/* Icon: the status is marked with a lucide icon matching the tone + colored text. */\nexport function IconTable({ className, size = \"md\", columns, rows }: TableProps) {\n  const { cols, data } = resolve(columns, rows, defaultColumns, defaultRows)\n  return (\n    <div\n      data-slot=\"styled-table\"\n      className={cn(\"w-full overflow-x-auto rounded-lg border border-border\", className)}\n    >\n      <table className={tableBase}>\n        <thead>\n          <tr className=\"border-b border-border bg-muted\">\n            {cols.map((col) => (\n              <th key={col.key} scope=\"col\" className={cn(headBase, headCell[size])}>\n                {col.label}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>\n          {data.map((row, i) => {\n            const tone = toneOf(row.status)\n            return (\n              <tr key={i} className=\"border-b border-border/60 last:border-b-0\">\n                {cols.map((col) =>\n                  col.key === \"status\" ? (\n                    <td key={col.key} data-tone={tone} className={cell[size]}>\n                      <span className={cn(iconBox, textTone[tone], \"font-medium\")}>\n                        {iconTone[tone]}\n                        {row[col.key]}\n                      </span>\n                    </td>\n                  ) : (\n                    <td key={col.key} className={cell[size]}>\n                      {row[col.key]}\n                    </td>\n                  )\n                )}\n              </tr>\n            )\n          })}\n        </tbody>\n      </table>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/table-status.tsx"
    }
  ],
  "categories": [
    "styled",
    "table"
  ],
  "type": "registry:component"
}