Permission Matrix
Roles across, permissions down, with inheritance, locked roles and one tab stop.
- Data
- 2 files
- No extra npm packages
- Accessibility notes
Loading the example…
pnpm dlx @dowel-ui/cli add permission-matrixNo npm packages are needed beyond what Dowel already requires.
import { PermissionMatrix } from "@/components/ui/permission-matrix";Default
Editing
As Record
Flat
<PermissionMatrix>
| Prop | Type | Default |
|---|---|---|
grants (required) | Grants | — |
label (required)Names the matrix: "Permissions for Acme". | string | — |
permissions (required) | Permission[] | — |
roles (required) | Role[] | — |
onChangeA change to make. Several ids arrive together when a group toggle was used. Omit to render the matrix as a record. | (roleId: string, permissionIds: string[], granted: boolean) => void | — |
Plus every attribute of <table> except onChange.
A grid in the WAI-ARIA sense: role="grid" with one tab stop, arrow keys between cells, Home and End along a row and Ctrl with them across the whole matrix — the right call for a matrix that is operated, where it was the wrong one for a diff that is read. Every checkbox is named by both coordinates, "Delete projects for Editor", so a reader arriving by arrow key knows where they are without re-reading the headers. An inherited grant is a checked box that cannot be changed here, marked aria-disabled rather than disabled so it stays in the keyboard path, with the role it came from as its description. A locked role says in each cell's description that nothing can be changed. Group toggles are tri-state, and the column header counts each role's grants in text.
8/8
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — passes
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — does not apply
- className merged — passes
- Visible focus — does not apply
- No fixed widths — passes