# Team invites

> Invite-by-email, share dialog and pending invites — address chips with validation and seat projection, link access that explains itself and revoke with a timed undo.

- Collection: Examples
- Tier: pro
- Docs: https://geturui.com/docs/team-invites
- Install: `npx shadcn@latest add @geturui-pro/team-invites`
- Dependencies: motion, lucide-react

## Variants

### Invite by email

Typed or pasted addresses become chips, invalid ones are flagged, a seat bar projects usage and sending clears the chips with a stagger.

Install: `npx shadcn@latest add @geturui-pro/team-invites-email-invite`

```tsx
import { InviteByEmail } from "@/components/examples/team-invites/email-invite";

export function InviteTeam() {
  return <InviteByEmail defaultEmails={[]} defaultRole="member" onInvite={(emails, role) => api.invite(emails, role)} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| team | `string` | — | Workspace name in the title. |
| defaultEmails | `string[]` | — | Prefilled chips. |
| defaultRole | `"admin" | "member" | "viewer"` | "member" | Initial role. |
| seatsUsed / seatsTotal | `number` | 6 / 10 | Seat bar and limit. |
| onInvite | `(emails, role) => void` | — | Valid addresses only. |

### Share dialog

Share panel with an invite field, per-person access, general link access with an explainer that crossfades and a copy-link confirmation.

Install: `npx shadcn@latest add @geturui-pro/team-invites-share-dialog`

```tsx
import { ShareDialog } from "@/components/examples/team-invites/share-dialog";

export function ShareDoc() {
  return <ShareDialog item="Q4 roadmap" org="Northwind" link={url} onChange={(s) => api.updateSharing(s)} onClose={close} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| item / org / link | `string` | — | What is shared, the organisation and the URL copied. |
| people | `{ id; name; email; access }[]` | — | "owner" | "edit" | "comment" | "view". |
| defaultGeneral | `"restricted" | "org" | "link"` | "org" | General access. |
| onChange | `({ people, general }) => void` | — | Fires on every access change. |
| onClose | `() => void` | — | Close and Done handler. |

### Pending invites

Pending list with expired flags, resend that spins then confirms, and revoke that collapses the row and offers a timed undo.

Install: `npx shadcn@latest add @geturui-pro/team-invites-pending-invites`

```tsx
import { PendingInvites } from "@/components/examples/team-invites/pending-invites";

export function Pending() {
  return <PendingInvites invites={invites} onResend={(id) => api.resend(id)} onRevoke={api.revoke} onUndo={api.restore} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| invites | `{ id; email; role; sent; expired? }[]` | — | Pending invites. |
| onResend | `(id) => Promise<void> | void` | — | Awaited; defaults to a short delay. |
| onRevoke / onUndo | `(id) => void` | — | Revoke and restore handlers. |

## Accessibility

- Invalid addresses are marked with an icon and aria-label, and the hint below the field is announced politely.
- Access pickers are native selects with labels, so they work with every keyboard and screen reader.
- Revoked rows announce an undo bar via role=status; it stays for five seconds.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
