Eval table
Evaluation runs side by side: scores per run, the diff against the baseline, failing rows first, and the full output one keypress away.
Part of Pro, $99 once. What you get
npx shadcn@latest add @pixilui-pro/eval-tablepnpm dlx shadcn@latest add @pixilui-pro/eval-tableyarn dlx shadcn@latest add @pixilui-pro/eval-tablebunx --bun shadcn@latest add @pixilui-pro/eval-tablenpx pixilui@latest add eval-tablepnpm dlx pixilui@latest add eval-tableyarn dlx pixilui@latest add eval-tablebunx --bun pixilui@latest add eval-tablePress a header and the rows travel to their new order on a spring, regressions first, so you can follow one case as it moves.
Eval table is part of PixilUI Pro
- Every Pro item, 2 today and each one added later
- Installs with shadcn,
npx pixiluior MCP - The source, Copy prompt and agent notes on every page
$99once
100 founder spots at $99 when Pro opens
- Access as soon as you pay
- Updates for life
- A full refund within 14 days if you have not installed or copied any Pro source. After that, a refund only when an item is broken and we cannot fix it within 14 days of your report.
Already have Pro? Log in
Install#
Eval table is part of PixilUI Pro
- Every Pro item, 2 today and each one added later
- Installs with shadcn,
npx pixiluior MCP - The source, Copy prompt and agent notes on every page
$99once
100 founder spots at $99 when Pro opens
- Access as soon as you pay
- Updates for life
- A full refund within 14 days if you have not installed or copied any Pro source. After that, a refund only when an item is broken and we cannot fix it within 14 days of your report.
Already have Pro? Log in
npx shadcn@latest add @pixilui-pro/eval-tablepnpm dlx shadcn@latest add @pixilui-pro/eval-tableyarn dlx shadcn@latest add @pixilui-pro/eval-tablebunx --bun shadcn@latest add @pixilui-pro/eval-tableThe @pixilui-pro registry and your token are set up from your account.
Adds components/pixilui/eval-table.tsx. Needs motion, clsx, tailwind-merge.
Usage#
Use it when
- Comparing a candidate prompt, model or agent version against a baseline on the same eval set.
- A release review where the question is which cases got worse, and why.
- Pasting a run comparison into a pull request or a doc with Copy as markdown.
Use something else when
- A single run's score over time: use a chart.
- Thousands of cases at once: page or virtualise them first; the table renders every row.
- A general data grid with editing: this table only reads.
API#
| Prop | Type | Default | Description |
|---|---|---|---|
runsrequired | EvalTableRun[] | The runs to compare, left to right. Two is the usual case; more columns scroll sideways. | |
casesrequired | EvalTableCase[] | The eval cases, one row each. | |
baseline | string | Run the diff and status compare against. Defaults to the first run. | |
candidate | string | Run being judged. Defaults to the last run. | |
sort | EvalTableSort | Controlled sort. | |
defaultSort | EvalTableSort | { key: "status", direction: "asc" } | Starting sort when uncontrolled: failing rows first. |
onSortChange | (sort: EvalTableSort) => void | Runs when a header is pressed. | |
defaultExpanded | string[] | [] | Rows open at first render, by case id. |
onCopy | (markdown: string) => void | Promise<void> | Receives the table as markdown, in the current order. Leave it out and the clipboard gets it. Return a promise to show pending. | |
formatScore | (score: number) => string | defaultFormat | Formats scores and diffs. Defaults to two decimals. |
loading | boolean | false | Shows placeholder rows and sets aria-busy while results load. |
labels | Partial<EvalTableLabels> | Copy overrides, for translation and house terms. |
Also takes every native <div> attribute except onCopy, and a ref to it.
Keyboard#
- Tab
- Moves through Copy as markdown, the sortable headers, then into the rows (one row is in the tab order).
- Enter
- On a header, sorts by it; pressing again flips the direction. On a row, opens or closes its full output.
- ArrowDownArrowUp
- Moves between rows.
- HomeEnd
- Jumps to the first or last row.
- ArrowRightArrowLeft
- Opens or closes the focused row.
Accessibility#
- A real table with an accessible name; headers are column headers with aria-sort on the sorted one.
- Each row's case is a button with aria-expanded that controls its detail row.
- Pass and fail are written out for screen readers beside each score; colour is never the only signal.
- Rows use a roving tab index, so the table is one Tab stop however long it is.
- Copy results are announced in a polite live region; loading sets aria-busy on the table.
Motion#
- Sorting moves rows to their new places on the smooth spring, so you can follow a case as it travels.
- Opening a row grows its detail on the morph spring; closing shrinks it on the smooth spring, never overshooting.
- The row chevron and the sort arrow turn on the snappy spring.
- Copy as markdown morphs to Copied and back with the button's label swap.
- Reduced motion: rows jump to their places, and the detail fades in without growing.
Responsive#
- Fills its container. Columns keep their natural width; narrower than the table, it scrolls sideways inside its own frame.
- Give the root a height (or max height) and the header stays put while the rows scroll under it.
- The detail shows outputs side by side from 640px, stacked below.
Performance#
- Sorting is memoised on cases and sort; only open rows render their outputs.
Notes for AI#
Also in the markdown page and llms.txt
- Pass runs in display order and cases with results keyed by run id; the first run is the baseline and the last the candidate unless you say otherwise.
- Status compares candidate with baseline: regressed (passed before, fails now), failing, fixed, passing. The default sort puts regressions first, biggest drop first.
- Set a height on the root (h-96, max-h-[70vh]) for the sticky header to matter.
- Use onCopy to send the markdown somewhere other than the clipboard, such as a pull request comment.
- evalTableMarkdown, evalTableStatus and evalTableDiff are exported for use outside the table.