KQ-1715 · INVITE/ACCEPT
Invite Accept
An invitation landing whose invite is a card: the workspace, who asked, a personal line, the role with what it can do, and when it lapses. Accept turns the card over on snap — its scale dipping with the angle by exactly what perspective adds, so it never grows past its box — while the role chip lifts off on flick, travels flat to its slot on the back on glide and lands on snap, carrying the role to a sign-up form with the name and email already filled. The form is real (labels, autocomplete, Enter submits, errors under their fields, a rejected join kept on the form), focus moves to the first empty field after the turn, Escape turns back, and an expired invite offers to ask again.
invite open · editor · Basinworks
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/invite-accept
Props
- invite
- { inviter, workspace, role, roleSummary?, email, name?, note?, sentAt, expiresAt }
- default defaultInvite
- The invitation: who sent it, the workspace, the role (and what it can do), the invitee and when it lapses.
- now
- number
- default defaultInviteNow
- The moment expiry counts from, ms since the epoch; the clock is never read during render.
- side / defaultSide
- "front" | "back"
- default — / "front"
- Which face of the card is up, controlled or initial.
- onSideChange
- (side: "front" | "back") => void
- default —
- Fires from the Accept, Back or Escape that turned the card.
- onAccept
- (details: { name, email, password, role }) => void | Promise<void>
- default —
- The form was sent. A promise holds it pending; a rejection keeps the form with its message, or puts it under the field its `field` names.
- onDecline
- (invite) => void
- default —
- Decline was pressed.
- onSignIn
- (email: string) => void
- default —
- Sign in was chosen instead, with the invite's address.
- onRequestNew
- (invite) => void
- default —
- A new invite was asked for, after expiry or a decline.
- status
- "ready" | "loading" | "error"
- default "ready"
- Whether the invite has loaded: a skeleton while loading, a broken-link card on error.
- passwordMinLength
- number
- default 10
- The shortest password the form accepts; the hint ticks when it is met.
- cardStyle
- "plain" | "ticket" | "pass"
- default "plain"
- The card's make: a plain card, a ticket with notches and a perforated stub, or a pass with a coloured band.
- flipAxis
- "y" | "x"
- default "y"
- The axis the card turns about: sideways or top over bottom.
- accent
- string
- default "var(--accent-bright)"
- Any CSS colour for the workspace mark, primary buttons, pass band, role chip and checks.
- disabled
- boolean
- default false
- Every action is unavailable.
- className
- string
- default —
- Classes for the outer section.
| Prop | Type | Default | Description |
|---|---|---|---|
| invite | { inviter, workspace, role, roleSummary?, email, name?, note?, sentAt, expiresAt } | defaultInvite | The invitation: who sent it, the workspace, the role (and what it can do), the invitee and when it lapses. |
| now | number | defaultInviteNow | The moment expiry counts from, ms since the epoch; the clock is never read during render. |
| side / defaultSide | "front" | "back" | — / "front" | Which face of the card is up, controlled or initial. |
| onSideChange | (side: "front" | "back") => void | — | Fires from the Accept, Back or Escape that turned the card. |
| onAccept | (details: { name, email, password, role }) => void | Promise<void> | — | The form was sent. A promise holds it pending; a rejection keeps the form with its message, or puts it under the field its `field` names. |
| onDecline | (invite) => void | — | Decline was pressed. |
| onSignIn | (email: string) => void | — | Sign in was chosen instead, with the invite's address. |
| onRequestNew | (invite) => void | — | A new invite was asked for, after expiry or a decline. |
| status | "ready" | "loading" | "error" | "ready" | Whether the invite has loaded: a skeleton while loading, a broken-link card on error. |
| passwordMinLength | number | 10 | The shortest password the form accepts; the hint ticks when it is met. |
| cardStyle | "plain" | "ticket" | "pass" | "plain" | The card's make: a plain card, a ticket with notches and a perforated stub, or a pass with a coloured band. |
| flipAxis | "y" | "x" | "y" | The axis the card turns about: sideways or top over bottom. |
| accent | string | "var(--accent-bright)" | Any CSS colour for the workspace mark, primary buttons, pass band, role chip and checks. |
| disabled | boolean | false | Every action is unavailable. |
| className | string | — | Classes for the outer section. |