Bolt prompt to build a data table with sorting
A sortable table sounds trivial until nulls, accents, and unstable comparators show up in real data. This prompt has Bolt build the component along with a 200-row demo page seeded with exactly those cases, so the preview doubles as a test bed and the tri-state sort has to survive it before you ship.
Last updated
Build a reusable data table in this Bolt project: src/components/DataTable.tsx plus a useSort.ts hook, TypeScript, Tailwind, no table library.
API: the component takes rows and a columns array, each column being { key, header, sortable, type, align, render }. Everything else stays internal.
Sorting behavior:
- Clicking a sortable header cycles ascending, descending, then unsorted, and the third click restores the original row order exactly.
- The active header shows a direction arrow and sets aria-sort on the th so screen readers announce it.
- String columns compare with localeCompare, numeric columns numerically, date columns by timestamp, chosen by the column's type field, never by sniffing cell values.
- Null and undefined cells sink to the bottom in both directions.
- Sorting is stable, so equal values keep their relative order.
Mechanics: a sticky header row inside a scrollable container with a fixed max height, zebra striping, hover highlight, and the container owning overflow-x so wide tables scroll inside themselves instead of stretching the page in Bolt's preview.
States: a loading prop renders skeleton rows matching column widths, an empty prop shows a message centered across all columns, and a cell whose render function throws shows an error glyph instead of unmounting the table.
Demo: wire it to a demo page with 200 generated rows including accented names, negative numbers, mixed-case strings, and some null dates, because those inputs expose most comparator bugs.
Acceptance: in the preview, sort each column both directions, confirm accented names order sensibly, nulls stay last either way, and the third click returns the seed order untouched.Same task in other tools
Questions about this prompt
Why does the third click return to unsorted?
Data often arrives in a meaningful order: priority from the server, manual ranking, insertion time. Two-state sorting destroys that order permanently, while tri-state restores it. Supporting it forces the component to sort a copy and keep the original array untouched, which is also what makes the stable-sort requirement checkable.
Can this handle server-side sorting for big datasets?
The component sorts in memory, which is fine into the thousands of rows. Past that, ask Bolt to add an onSortChange callback exposing column and direction, skip internal sorting whenever it is provided, and pass those params to your backend. The header UI and aria-sort behavior stay identical either way.
Dates sort wrong even though the column is typed as date. Why?
The cells probably hold pre-formatted strings, so the comparator silently falls back to string ordering. A date-typed column requires the row value to be a Date or a timestamp, with formatting applied only inside the render function. Keep the display value and the sort value separate and the ordering fixes itself.