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.

KQ-1715 · INVITE/ACCEPT
Basinworks12 members

Mara Lindqvist invited you to join Basinworks.

We're moving the river survey here; your transect notes would help.
EditorExpires in 6 days
  • Edit surveys, maps and field notes
  • Invite teammates as viewers
  • No access to billing or payouts

Already have an account?

Editor

Create your account

One more step and you're in Basinworks.

From Mara's invite
At least 10 characters

Have an account?

Editor

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.