Waitlist Input
NewInstallation
npx shadcn@latest add https://uibrik.com/r/waitlist-input.jsonInstall the packages
npm install motionAdd the cn helper
Imports
cnfrom@/lib/utils, whichshadcn initcreates. Add it by hand without shadcn.Copy the source into your project
components/uibrik/waitlist-input/waitlist-input.tsx"use client"; // An email field with its button inside. Submitting shrinks the button to a // spinner, then the whole field settles into a confirmation in the same // footprint, so the page around it never moves. A thrown error shows under // the field (out of flow, for the same reason) and the email stays put for // another try. import { AnimatePresence, motion, useReducedMotion } from "motion/react"; import { useId, useRef, useState, type FormEvent } from "react"; import { cn } from "@/lib/utils"; const EASE_OUT: [number, number, number, number] = [0.23, 1, 0.32, 1]; const SPRING = { type: "spring", duration: 0.4, bounce: 0 } as const; const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; type Status = "idle" | "loading" | "done"; export type WaitlistInputProps = { placeholder?: string; buttonLabel?: string; /** Shown once joined. `{email}` is replaced with the address. */ successMessage?: string; /**
Adds the files to
components/uibrik/waitlist-input and installs motion. With the @uibrik namespace set up: npx shadcn@latest add @uibrik/waitlist-input.Props
WaitlistInput- placeholder
- Type string
- "you@company.com"
- Placeholder in the field.
- buttonLabel
- Type string
- "Join waitlist"
- Text on the button.
- successMessage
- Type string
- "You're on the list. We'll write to {email}."
- Shown once joined. {email} becomes the address.
- radius
- Type number
- 14
- Corner radius of the field. The button follows it.
- onSubmit
- Type (email: string) => void | Promise<void>
- –
- Called with the email. Return a promise for the loading state; throw with a message to show it.
- className
- Type string
- –
- Classes for the form.