shadcn.io is not affiliated with official shadcn/ui
Permission Matrix Dashboard Block for React
Five roles by six resources in one table where each cell cycles None, Read, Write and Admin as a word and a shape, with changed cells marked, a switch that shows the actions each level allows and a dialog that reviews the changes.
Installation
Overview
Decide what each role can touch, with this role-based access matrix for React with Base UI. A hairline frame with a plus mark on each corner holds a native table: Owner, Admin, Editor, Viewer and Billing across the top, each with how many people hold it, and Users, Billing, Projects, API keys, Audit log and Integrations down the side. Every cell is a button that cycles None, Read, Write and Admin, drawn as a word beside a shape (a dash, an eye, a pencil and a shield) and never a colour; a cell you changed gets a dark outline and a dot. A Switch in the header adds a row of read-only marks per action under each resource: Read can view, Write can also create and Admin can also delete. The action foot counts unsaved changes, and its Shine Button opens a Dialog that lists each one ("Editor on API keys: Read to None") before saving. It's built from Switch, Dialog, Button, Shine Button and Guides, with native table and button cells. For admin consoles and access settings.
FAQ
How do I load my roles?
Edit ROLES, RESOURCES and SAVED_LEVELS, a number from 0 to 3 for each role on each resource. ACTIONS lists the actions and the level each one needs. The marks under a resource are worked out from the level, so adding an action is one line.
How do I move around the grid with the keyboard?
The matrix is one tab stop. Tab into it, move with the arrow keys, Home and End, and press Enter or Space to cycle a cell. Each cell's name says the role, the resource, the current level and what the next press does.
How are changes tracked?
Every cell is compared with the saved level, so cycling a cell back to where it started removes its mark and drops the count. The status line says how many changes are unsaved, and a polite note says what a press just did. Reset puts every level back.
What stays local, and how do I wire it for real?
All of it: Save changes keeps the levels in this page and the dialog says nothing was changed for real. To make it real, send the list the dialog shows to your API, refuse the save if a role or resource has changed since you loaded it, and keep the cells that failed marked.