shadcn.io is not affiliated with official shadcn/ui
Sticky Header Table Block for React
A sixty-row cash ledger in a fixed-height region where the column heads and the day row stay at the top while you scroll, with a Jump to menu of weeks that scrolls the region and a band that names the day at the top.
Installation
Overview
Keep a long table's heading and its day in view, with this sticky header table for React with Base UI. A compact header names the ledger, and inside a hairline frame with a plus mark on each corner a band holds a "Jump to" Native Select of four weeks and says which day is at the top as you scroll ("At the top: Mon 7 Sept"). Under it a native table of sixty entries from a small shop's cash book scrolls inside a fixed-height region. Each day is a group that opens with a row naming the day and its net, and each entry shows its time, a description with its category under it, the amount and the running balance. The column heads stick at the top and the day row sticks directly under them, on solid backgrounds, so neither scrolls away; choosing a week from the menu scrolls the region itself, never the page. The region's height never changes. It's built from Native Select and Guides, with a CSS entrance only. For ledgers, logs, statements and any long list with groups.
FAQ
How do I use my own entries?
The ledger is built at the top of the file: WEEKDAYS lists what happens on each trading day (a time, a description, a category and an amount in cents), SCALES makes each week trade a little differently, and OPENING is the starting balance. LEDGER adds the running balance to each entry and DAYS groups them. Replace those with your own rows, in cents and in date order, keep the balance derived rather than typed, and the groups, nets, menu and band all follow from them.
How do the head and the day stay put?
The table uses separate borders (border-separate border-spacing-0) so cells can keep their own rules while they stick. The head cells are sticky top-0 with a solid background and a higher stacking level; each day's row is sticky top-10 (just under the 40 pixel head) on a slightly darker solid. Every day is its own table group, but a sticky cell is held by the whole table, so the day at the top stays and the next one slides over it, which is why the backgrounds are opaque.
How does Jump to work?
The menu lists the first day of each week. Choosing one sets the region's scrollTop to that day's row less the head, the way a script would, and never uses scrollIntoView, so the page doesn't move. The menu follows the scroll too: as you scroll, the day at the top is read from the groups' positions and the menu shows its week. A polite line, present from the start, says where you jumped ("Jumped to the week of 21 Sept.").
How does it look on a phone?
All four columns stay. The description is cut with an ellipsis, with its full text as a title, and the category under it, the amount and the balance keep their figures in full, so nothing scrolls sideways. The region keeps its height and is focusable, so it can be scrolled with the arrow keys.
Is a table with group rows accessible?
Yes. It's a native table with a caption, th scope="col" heads, a row header for each entry (its description) and, for each day, a header cell that spans the table with scope="rowgroup", so a screen reader announces the day for the entries under it. The amount's sign is in the text ("+€214.50", "-€186.40"), not a colour.
What stays local?
Everything is typed data, and the menu's value, the day at the top and the polite line are the only state; nothing is fetched. For a real ledger, load a window of entries around the day being read and keep the head, the group rows and the region as they are; the polite line and the "At the top" label are fed from the same day.
Related
- Pro
Pinned Columns Table
Columns and pagingA vehicle log of ten columns whose first and last stay pinned while the rest scroll under them, with a shadow that appears only when there is something to scroll under and a switch that turns the pins off.
- Pro
Density Table
Columns and pagingA page list with a three-way density toggle (Compact, Comfortable, Spacious) that sets row height and text size together, in a fixed-height region so the block never changes height, with a line that says what the mode does.
- 1234Pro
Paginated Orders Table
Columns and pagingAn orders table of 24 rows that pages: a rows-per-page menu, the numbered pagination, a polite line saying which orders are on screen, and every page drawn once more unseen so the pager never moves.
- Pro
Searchable Catalogue Table
Sort and searchA library catalogue table with a search field and an availability menu: typing keeps the titles whose name or author holds the words and marks them, the foot says how many match, and an empty state under the head clears the search.
- Pro
Resizable Columns Table
Columns and pagingA translation workbench table whose column dividers are focusable separators: drag them or use the arrow keys (Shift for bigger steps, Home to reset), with minimum and maximum widths, truncated cells and a Reset widths button.
- Pro
Baseline Comparison Table
Totals and comparisonFive camera bodies compared against one you pick: every figure shows its own value and, under it, a signed difference or Same or Different against the baseline, with sticky spec names and grouped rows.