Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Table With Pagination Skeleton Block for React

A paged audit log that loads in place: pressing a page number, Previous or Next shows the bars again and then that page's eight entries, with the pager real from the first paint.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show a paged table while each page loads, with this table skeleton with pagination for React with Base UI. A hairline frame with a plus mark on each corner holds a native table of eight audit entries from Alidade, an audit log for admin consoles, over a pager band. The four column heads and the Pagination (Previous, the numbered pages and Next) are real from the first paint; each cell is a Skeleton bar that becomes the time, the actor, the action or the target, and "Showing 1-8 of 24" is a bar too. Pressing a page goes back to the bars and then shows that page's eight typed entries, and Reload fetches the current page again. The panel is the same height on every page. On a phone the actor and the target fold under the action and the pager keeps Previous, Next and "Page 1 of 3". It's built from Skeleton, Pagination, Button and Guides, with a CSS entrance only. For logs, order histories and any table that pages.

FAQ

What stays local, and how do I wire it to a real query?

Nothing is fetched. The 24 entries, three pages of eight, are typed in ENTRIES, Load starts a 700 millisecond timer, and when it ends the phase becomes ready and the data swaps in; Reload goes back to the bars and in again. To wire it for real, delete the timer, the Load button and the polite line, and set data-state (loading or ready) and aria-busy on the region from your query's pending state, or use the bars as a Suspense fallback and render the real rows when they arrive. The bars are derived from the same array as the data, so keep one row component for both. Key your query on the page number and set the pager's links to your own URLs.

Is the pager real while loading?

Yes. It is chrome: its buttons exist before the data does, and pressing one starts a load of that page. A press while a page is already loading is ignored, so the requests can't pile up. The ends are marked disabled and leave the tab order on the first and last page.

Does the table keep its height between pages?

Each bar and its data sit in one grid cell, so the larger of the two sets the cell's box and the swap changes nothing around it. The table is fixed-layout with set column widths and fixed row heights, the heads and the frame are real in both phases, and the polite line reserves two lines, so the panel is exactly as tall before, during and after loading at every width. Every page has the same number of rows, so a short last page needs placeholder rows in your own data.

Is it accessible?

The region is marked busy while it loads and carries a screen-reader-only "Loading the audit log…", and the polite line announces what loaded once. The bars are hidden from assistive technology and the layer that isn't showing is invisible, so it is neither read nor focusable. The pulse stops when the data is in, and under reduced motion there is no pulse, no spinner and no stagger: the swap is instant. The pager is a labelled navigation landmark and the current page is marked.

How does it look on a phone?

The table drops to two columns, the time and the action, with the actor and the target on a second line under the action. The numbered pages are replaced by a "Page 1 of 3" label between Previous and Next, which keeps the pager on one line at 320 pixels.