Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Role Assignment Command Menu Block for Svelte

A team admin's command menu hung under a member's role chip: pick a member in step one, a role with its permission count in step two, and the chip on the members list changes behind the menu.

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

Change someone's role in two steps with this role command menu for Svelte with Ark UI. It opens from a members list in Hatband, a team admin, whose header holds an outline field with its ⌘ K cap, and the list is drawn under a soft scrim inside a hairline frame with a plus mark on each corner, the menu hung under a member's role chip. The menu is the catalog Command: step one lists six members with an initials avatar, their email and their current role, and step two lists five roles with how many of the twelve permissions each grants and a Current mark. A band above the field names the step and holds a Back button, and Backspace in an empty field goes back too. Choosing a role changes the chip on that member's row, which turns foreground, and closes the menu. 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 members, step and query. For member lists, invitations and any change that needs a who and then a what.

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 members list, 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 step or a change 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.

How do the two steps work?

The block keeps the chosen member in state: empty means step one, a member's id means step two. Choosing a member clears the search, changes the field's placeholder to "Pick a role for Priya…", starts a new list and says "Choose a role for Priya Nair" on the status line. The Back button, or Backspace in an empty field, returns to the members. The band above the field has the same height in both steps because the Back button is only hidden in step one, not removed.

Can the last Owner be demoted?

No. Choosing another role for the only Owner does nothing but say that Hatband needs at least one Owner and that someone else must become Owner first. Choosing a role a member already has says so too, without a change. Every refusal and every success is on the status line, and inside the dialog on its own live region.

How does the chip change behind the menu?

The members list is a drawing of the block's members state, so setting a role updates the member there and the chip takes the foreground colour to show which row changed. The drawing is hidden from assistive technology; the status line states "Tomas Berg is now Admin. Nothing is saved." for everyone.

What stays local, and how do I wire it?

All of it. The six members and the five roles are typed constants, and a change only edits the state. In your app load START from your directory, send the change to your API in pick and apply it only when the call succeeds, and keep the last-Owner rule on the server as well as in the menu.

Is it accessible from the keyboard?

Yes. Type to search, the arrow keys move through the rows, Enter picks the member and then the role, and Backspace in an empty field goes back. 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.