Team Members
Team management with email invites, seat limits, role changes, pending invites and safe removal.
Overview
The settings screen every B2B product needs, with the edge cases handled. Invites validate the email, reject duplicates and stop when the plan’s seats are full, with a seat meter in the header. Pending invites are labelled and can be resent or revoked.
Roles change inline. Removing someone asks for confirmation in place rather than in a modal, and the last owner can’t be removed, with a tooltip explaining why. Status messages confirm each action without interrupting.
Use it in workspace or organisation settings. Wire onInvite to your API. State is controlled, so the list only changes when you say so.
When to use
- A single interaction you want to feel finished, dropped into an existing screen.
When not to use
- A whole page layout: look at Sections or Templates.
Installation
pnpm dlx shadcn@latest add https://sundaeui.dev/r/team-members.jsonnpx shadcn@latest add https://sundaeui.dev/r/team-members.jsonyarn dlx shadcn@latest add https://sundaeui.dev/r/team-members.jsonbunx --bun shadcn@latest add https://sundaeui.dev/r/team-members.jsonWorks in any React project. Files are written to components/sundae/. Read the source in the stage’s Code view. Pro assets need a personal token. See authenticated installs.
- No dependencies beyond React 18 or later.
- Copy team-members.tsx into components/sundae/.
- Make sure Tailwind scans that folder (v4 detects it automatically; v3 needs it in `content`).
- Import the component and use it as shown below.
Usage
import { TeamMembers } from '@/components/sundae/team-members'
<TeamMembers members={members} onChange={setMembers} seats={plan.seats} onInvite={(email, role) => api.invite({ email, role })} />Props
| Prop | Type | Default |
|---|---|---|
members*{ id, name, email, role, pending? }. | Member[] | — |
onChange*Called after role changes, invites and removals. | (members) => void | — |
seatsSeat limit. Shows a meter and blocks invites when full. | number | — |
onInvitePersists an invite. Throw to show an error. | (email, role) => Promise<void> | — |
Accessibility
- Every control is labelled, including per-member role selects and remove buttons.
- Invite errors and confirmations are announced through a status region.
- Removal confirms in place, and focus stays in the row.
Customization
- Edit ROLES and DESCRIPTIONS to match your permission model.
FAQ
- Is Team Members free?
- Team Members is part of Sundae Pro. The live preview is open to everyone; the source installs with a Pro account.
- How do I install Team Members?
- Run npx shadcn@latest add https://sundaeui.dev/r/team-members.json. The files are written to components/sundae/. It has no dependencies beyond React 18 or later.
- Does Team Members support keyboard and screen readers?
- Every control is labelled, including per-member role selects and remove buttons. Invite errors and confirmations are announced through a status region.
- Does Team Members respect reduced motion?
- Yes. With prefers-reduced-motion set, decorative motion is removed and state changes are instant.
More like this
All components →- Pro
Notification Center
Components · Refined - Pro
AI Composer
Components · Understated Fold Accordion
Components · UnderstatedConfirm Dialog
Components · Understated- Pro
Seat Checkout
Checkout · Understated - Pro
Sheet Drawer
Components · Refined