Tables & Lists
v1.0.0Added in 1.0.0
Who can do what: roles as columns, permissions by module as rows, with dependencies, unsaved-change dots and a per-role list on phones.
Tick a cell to grant a permission to a role; the group row's box grants or clears the whole module and shows a dash while only some are on. Granting a permission that needs others (Issue invoices needs View invoices) ticks them too and the cells that changed on their own flash once; revoking a requirement clears what depends on it, and both are announced. Cells that differ from the saved state get a dot, a faint tint and a count in the toolbar. The Owner column is locked (hover, focus or long-press a cell for why), and a role name cut by a narrow column shows whole on hover or a long press. Type in the search field to keep only the matching rows, with the letters marked and the number of matches at the end of the field; a matching module name keeps the whole module. Click a module name (or press Enter or Space on it) to fold it, during a search too (the next query opens it again); Expand all / Collapse all does every module. The grid is one Tab stop: arrows move between cells, module rows and labels included, Home / End jump to the first / last role, Ctrl or Cmd + Home / End to the corners, PageUp / PageDown move eight rows, Space toggles the focused box or opens the level select. The head sticks while you scroll and the label column stays pinned while wide grids scroll sideways, each gaining a hairline shadow only while something slides under it. Below 768px the grid becomes one accordion card per role with a switch per permission and a switch per module (or role chips over one list with mobileLayout="role-picker"); level selects open as bottom sheets.
npx wingo-ui@latest add permissions-matrixPro item: the CLI needs a Pro account. See plans
Click a role name to edit it · enforceDependencies=true · stickyHeader=true