# Team and roles

An owner invites people to a workspace, sets what each one can open with a role and sees who has not accepted, in a table with a search, filters, a roles legend and a bulk bar.

Block · With a Pass · https://tactileui.dev/blocks/team-and-roles

> The code and styling for this block come with the Pass. Sign in if you have one. Sign in: https://tactileui.dev/auth/sign-in The price: https://tactileui.dev/pricing

## Use it

With a Pass, install it with npx shadcn add @tactile/team-and-roles (https://tactileui.dev/docs/registry-and-mcp). It lands in tactile/team-and-roles/.

Load the stylesheet as well as the module, or it renders unstyled: tactile/team-and-roles/team-and-roles.css. In a bundler such as Vite, import each CSS file next to the module import; in plain HTML, link it.

Then mount(element, options) from tactile/team-and-roles/team-and-roles.mjs. Every option has a default; tactile/team-and-roles-example.html shows it running. The sample copy (headings, labels, figures) is placeholder: replace it with the page's own.

## Anatomy

Role select per row, Two step state, Pending invite resend, Search and filter toolbar, Bulk bar, Row menu, Invite dialog validation, Role capabilities checklist, Phone cards, Keyboard range selection, Finish following, Quiet volume

## Usage notes

The team screen of an app people share: an owner asks someone in, chooses a role, and watches the invite until it is accepted. The head says how many seats are used and carries the one contrast key. The table is the record: an avatar, a name, an email, a role select in every row, the state, the two-step state and a row menu. A toolbar searches by name or email and filters for pending invites and two-step off; checking rows lifts a bulk bar with Change role, Resend invite and Remove. The side column explains the four roles and says how many people have two-step sign-in on. The invite dialog is a field, a role, one line and a read-only checklist of what that role can do.

## Options

| Option | Type | Description |
| - | - | - |
| title | text | Page title |
| lead | text | Lead |
| state | enum | Normal, the skeleton while the roles arrive, or the first-person empty screen. |
| finish | enum | Auto takes the page’s own finish tokens if it has them, then its data-finish, then the visitor’s system. |

## Methods

- people
- update
- destroy

## States

1. **At rest**: The page head with the title, the seats used, the lead and the Invite key; the People panel with its toolbar, five rows, pagination and the roles legend beside it. Nothing runs.
2. **Invite dialog**: The Invite key opens a native dialog: Email (placeholder name@studio.com), Role at Member, the line that explains the role, and the read-only checklist that follows the role. Cancel is flat; Send invite is the contrast key. Focus starts in the Email field.
3. **Already on the team**: An active member’s address, for example priya@halden.studio, puts That email is already on the team. in the field’s hint, marks the field in error and leaves the focus in the field. The dialog stays open.
4. **Invite sent**: Sending to nia@halden.studio closes the dialog, shows the toast Invite sent to nia@halden.studio., and puts her row at Invited just now. A new address is added as a row in the same state.
5. **Selected rows**: Space checks a row, Shift+Space extends the range from the last row checked, and the header key selects every row in view. The bulk bar slides up from the foot of the panel with 2 people selected and the keys Change role, Resend invite, Remove and Clear. Escape or Clear releases the rows.
6. **Loading**: The avatar and name print; the role, state, two-step and action cells are skeleton bars. The toolbar is inert. Nothing else runs.
7. **Empty**: No one else yet, the sentence Invite the first person, and the roles legend shows under it., and one contrast key, Invite someone. The roles legend moves under the empty state.
8. **Phone**: The page head keeps the title and an icon Invite key; the bulk bar pins above the home indicator.
9. **Keyboard**: Space checks a row, Shift+Space extends the range, the header key selects all. The role select opens with Alt+Down (the platform’s own select). Escape closes the invite dialog and returns the focus to the Invite key; Escape in the bulk bar releases the rows and returns the focus to the table.
10. **Reduced motion**: The bulk bar appears in place; the dialog changes at once; nothing else moves.
11. **Finishes and volume**: Every surface and lamp reads the kit’s tokens, so all twelve finishes follow. The screen is set in the Quiet volume; its parts keep their sizes and draw hairlines and a whisper of depth.

## How it works

Original composition. Ledgerly, its workspace, the five people and their addresses are sample copy for an invented invoicing app, and the preview says so. The screen is made only of the Tactile UI Kit's parts, with the kit's tokens for every surface and lamp; the block writes no colour and restyles no part. It needs the kit's kit.css and kit.mjs beside it.
