Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Permissions Matrix Command Menu Block for Vue

An access-control console's command menu shown open over a team page: four roles with member counts, an audit log of three changes, and a pane with the highlighted role's permissions as a real table of ticks and words.

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

Check what a role can do before you grant it with this permissions command menu for Vue with Ark UI. It opens from the team page in Doorwarden, an access-control console, whose header holds an outline field with its ⌘ K cap, and the page is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The menu is the catalog Command beside a pane: the list holds four roles with their member counts and an Audit log group of three recent permission changes, and the pane follows the highlighted row and is a real table of six resources against Read, Write and Manage, each cell a tick or a dash with the word Yes or No. On an audit entry the pane shows the role it changed with that cell marked, and on a phone the pane sits under the list. Enter opens the role on the drawn team page. For preview the menu is drawn open in place when the page loads; the field, or Ctrl or ⌘ K while focus is in the block, opens the real command dialog with the same roles and query. For role editors, access reviews and any menu where the answer is a grid.

FAQ

Why is the menu already open, and what do I keep?

So you can see it without a click. On load the menu is the Command drawn inline over a picture of a team settings page, in a plain shell that is not modal, so nothing is trapped, hidden or focused and the page around the preview keeps working. The header's field opens the real command dialog, modal, with its focus trap, Escape and focus return, and the inline copy stays closed until a reload. Both show the same Palette and share the block's state, so a search in the copy is in the dialog. In your app keep the dialog and drop the copy: the "in-place" state, the scrim with its shell and the Escape and blur effects.

Is the permissions pane a real table?

Yes. It is a native table with a caption, column headers for the three actions and a row header for each of the six resources, so a screen reader announces "Billing, Write, No". Each cell shows a tick or a dash and the word Yes or No, so colour is never the only cue. The pane has a fixed height, so moving through the list never moves the list.

What does the Audit log group do?

Its three entries are typed changes with who made them and when. Highlighting one shows the role it changed in the pane with the changed cell shaded, bold and marked "changed" for assistive technology, and Enter opens that role on the team page. The search reads the entry's text and its author as well as the roles.

How does the pane follow the highlight?

The block keeps the highlighted row's value in state, fed by each library's own highlight event, and paneFor turns the row into the role and the cell to mark; with nothing matching, the pane says there is no role to show.

What stays local, and how do I wire it?

All of it. The roles, the matrix (one string of Y and N per resource) and the log are typed constants, and opening a role changes only the drawn page. In your app build ROLES and CHANGES from your access-control service and keep the same row and pane shapes; the table needs nothing else.

Is it accessible from the keyboard?

Yes. Type to search, the arrow keys move through the rows and the pane follows, and Enter opens the role. Escape closes the menu with focus on the field, and Ctrl or ⌘ K opens the dialog while focus is inside the block, and only then. The rows are options of a combobox and the first is highlighted when it opens.