shadcn.io is not affiliated with official shadcn/ui
Task List Skeleton Block for React
Today's tasks that load in place: a real heading and Add task button over six rows whose checkboxes, titles, tags, initials and times arrive, then tick off with a live count.
Installation
Overview
Show a to-do list while it loads, then let people tick it off, with this task list skeleton for React with Base UI. A hairline frame with a plus mark on each corner holds a band with the heading "Today", a count and a ghost Add task button, over six task rows from Cringle, a to-do app for small crews. The heading and the button are real from the first paint; the count and each row's checkbox (a square bar until the row arrives), title, tag, assignee initials and due time are Skeleton bars that become the data in the same cell, row by row, when you press Load. Once loaded the boxes are real Checkbox controls: ticking a task strikes its title and updates "3 of 6 done" and the polite line. On a phone the due time folds under the title. It's built from Skeleton, Checkbox, Badge, Button and Guides, with a CSS entrance only. For to-do lists, checklists and any list of rows that waits for a query.
FAQ
What stays local, and how do I wire it to a real query?
Nothing is fetched. The six tasks are typed in TASKS, 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 tasks when they arrive. The bars are derived from the same array as the data, so keep one component for both. The ticks live in the component's state; send each change to your own API in tick, and keep the typed ones in TICKED_AT_START only for the demo.
What do the checkboxes do?
They tick the task locally: the title is struck through and muted, the count in the band follows ("4 of 6 done"), and the polite line says it too. A struck title is also muted and the box is solid, so the state is never a color alone. Reload puts the ticks back to the typed ones.
Does the list keep its height while it loads?
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. Every row has a fixed height, and the checkbox, title, tag, initials and time each share a cell with their bar, so a tick changes no box. The heads, labels and frame are real in both phases, and the polite line reserves two lines, so the block is exactly as tall before, during and after loading at every width.
What does Add task do?
Nothing, and it says so: "Add task isn't wired in this demo." Wire it to your own create flow and prepend the new task to your data.
Is it accessible?
The region is marked busy while it loads and carries a screen-reader-only "Loading tasks…", 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. Each checkbox is named "Done:" and the task's title, the keyboard ticks it with Space, and the initials are hidden from assistive technology in favor of "Assigned to" and the name.