shadcn.io is not affiliated with official shadcn/ui
Permission Matrix Table Block for Svelte
A roles-by-permissions table with a checkbox per cell, inherited cells ticked and locked with a lock and the role they come from, a tri-state checkbox per group and role, and a head that counts what each role has.
Installation
Overview
Show what each role can do, and why, with this permission matrix for Svelte with Ark UI. A compact header names the table and holds a Reset button. Inside a hairline frame with a plus mark on each corner, a native table lists fourteen Keyledger permissions in three groups (Documents, Billing, Members) against three roles: Viewer, Editor and Admin. Every cell is a Checkbox. The roles inherit, so Editor has everything Viewer has and Admin everything Editor has: an inherited cell is ticked and locked, with a lock and the words "Inherited from Viewer" naming where it comes from. Each group has a row of its own whose checkbox per role is ticked, empty or a dash, and ticks or clears the cells of the group that are not locked. Each head counts what the role has ("Admin: 14 of 14"), and a polite line says what each change did. On a phone the table scrolls sideways under a sticky first column. It is built from Checkbox, Button and Guides. For admin consoles, role editors and any place a permission has an owner.
FAQ
How do I use my own roles and permissions?
Edit ROLES (each names the role it inherits from, or none), GROUPS, PERMISSIONS and START, the list of grants each role is given on its own. Inheritance is worked out from that list: a cell is locked when any role below it has the permission itself. Add a fourth role by giving it a parent and it takes the same rules.
Why can't I untick an inherited cell?
Because the permission isn't set on that role: it comes from a lower one. The cell is ticked, shows a lock and says where it comes from, and a press explains it in the status line instead of doing nothing. Clear it on the role it comes from and every role above follows.
What does a group checkbox do?
It sets every cell of that group that isn't locked, for one role. It is ticked when the role has all of the group, empty when it has none and a dash when it has some. If every cell in the group is inherited it has nothing to change and says so.
How is it read by a screen reader?
Every box is named by its role and permission ("Editor: Edit documents"), a locked one adds "inherited from Viewer", and a group box is named "Documents for Editor". The table has a caption, the first column is a row header and the heads count in words ("6 of 14"). One polite line reports each change. A locked box stays focusable so its reason can be read.
What stays local, and how do I wire real permissions?
The grants are one useState list and Reset restores the typed START. To use real roles, load the grants from your API, send a change from setPermission and setGroup and apply the result when it answers. Keep the inheritance rule on the server too, so a client can't grant what a lower role doesn't have.