Identity-gate sheet: connect wallet → pick a handle (live avatar) → join. Built on Sheet.
Anatomy
┌ Sheet · "Join the tide" ───────────┐ │ ✓ wallet connected 7xKt…9fQ2 │ ← collapses once connected │ ◐40 [ @handle ✓ available ]│ ← live avatar + availability │ ┌────────────────────────────────┐ │ │ │ Join the tide │ │ ← full-width brand CTA │ └────────────────────────────────┘ │ └──────────────────────────────────────┘
Props
| Prop | Type | Default | Notes | |||
|---|---|---|---|---|---|---|
open / onOpenChange | boolean / (b) => void | — | Controlled, forwarded to Sheet. | |||
walletAddress | string | null` | — | Truthy → step 1 collapses to a checked row (shortened addr). | ||
onConnectWallet | () => void | — | Shown when not connected. | |||
handle | string | — | Controlled; sanitized to [a-z0-9_]. | |||
onHandleChange | (v: string) => void | — | Availability check is the caller's job. | |||
availability | "idle" | "checking" \ | "available" \ | "taken"` | "idle" | Inline indicator + gates the CTA. |
onJoin | () => void | — | Fires only when connected + available. |
Motion
Sheet slide + drag-dismiss; buttons press-scale 0.98. Avatar updates instantly as the handle changes (no transition — identity is calm).
A11y
- · Handle input is
@-prefixed with a real<input>; sanitized on change. - · CTA
disabledcommunicates gating; availability is text + color, not color alone. - · Wallet address shortened for display; full value stays in caller state.