Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Audit Trail Table Block for Radix UI

An audit trail table with a strip of 14 day buttons, each a bar sized by its event count, that filters the events to one day, plus an actor menu, a sortable Time head and masked IP addresses.

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

See when things happened before you read what, with this audit trail table for React with Radix UI. A compact header names the trail. Inside a hairline frame with a plus mark on each corner, the first band is a strip of the last 14 days: each day is a button that holds a bar sized by its number of events and the count in text, and a day with nothing in it is a hollow sliver with a zero. Pressing a day limits the table to it, pressing it again or "All 14 days" clears it, and a Select narrows it to one actor. The table lists time, actor, action, resource and an address masked to its first three groups, in a fixed-height region with a sticky head; the Time head sorts newest or oldest first. A day or an actor with nothing in it shows an empty state with a button that shows all 14 days. Dates are typed values in UTC. On a phone the strip scrolls sideways and the action moves under the actor. It's built from Select, Button, Empty and Guides. For security logs, compliance exports and admin consoles.

FAQ

How is the day strip built, and is it a chart?

It's a fieldset of 14 real buttons, not a chart. Each holds the count as text, a bar whose height is its share of the busiest day and the date, and says whether it is chosen with aria-pressed. Each button is named in full ("Oct 14, 5 events"), so a screen reader never needs the bars. A day with no events keeps a hollow bar of a few pixels so it can still be pressed and still says zero.

How do the day, the actor and the sort combine?

The day and the actor both narrow the list, so choosing Oct 12 and Calista Merriweather shows only her events on that day, and the status line says so ("2 of 41 events: Oct 12, Calista Merriweather"). The Time head only changes the order, newest first at the start. Each new filter returns the region to its top.

Why are the IP addresses masked, and can I show them in full?

Audit pages are read by many people, so the demo shows only the first three groups and never holds the last one in its data. If your viewers are allowed to see the whole address, store it in the event and show it in the IP cell; if only some are, render the cell from a permission rather than hiding the column with CSS. The addresses here are from documentation ranges.

What stays local, and how do I wire a real log?

The 41 events are typed in EVENTS and the filtering is in the page. For a real log, send the chosen day and actor to your API, return the events and their per-day counts, and keep the strip and the table as they are. Dates are ISO strings in UTC formatted with a fixed time zone, so server and browser agree.

Is it keyboard and screen reader friendly?

Yes. Tab reaches the day buttons (arrow keys are not needed, each is its own stop), the actor menu and the Time head, which is a real button inside a th with aria-sort. The table has a caption and row headers, the status line is a polite live region present from the start, and the scrolling region is focusable.

How does it look on a phone?

The strip scrolls sideways with each day snapping into place, the weekday names drop out and the date numbers stay. The Action and IP columns go; the action moves under the actor's name, and the Resource column keeps its place. Nothing else scrolls sideways.