Floating label form
Centred waitlist form with a two-column field grid.
Usage
import { WaitlistForm } from '@/components/blocks/waitlist-02'
<WaitlistForm />
// Send the values to your own endpoint
<WaitlistForm
onSubmit={async (values) => {
const response = await fetch('/api/waitlist', {
method: 'POST',
body: JSON.stringify(values),
})
if (!response.ok) throw new Error('We couldn’t save your spot. Try again.')
}}
/>
// Your own fields and question
<WaitlistForm
title="Get early access"
fields={[
{ type: 'text', name: 'name', label: 'Full name', autoComplete: 'name' },
{ type: 'email', name: 'email', label: 'Work email', autoComplete: 'email' },
{
type: 'select',
name: 'teamSize',
label: 'How big is your team?',
options: [
{ value: '1-10', label: '1–10' },
{ value: '11-50', label: '11–50' },
{ value: '51+', label: '51+' },
],
},
{ type: 'url', name: 'website', label: 'Website URL', required: false },
]}
/>
Install
pnpm dlx shadcn@latest add @pastaui-pro/waitlist-02npx shadcn@latest add @pastaui-pro/waitlist-02yarn dlx shadcn@latest add @pastaui-pro/waitlist-02bunx --bun shadcn@latest add @pastaui-pro/waitlist-02Source
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | = 'Join the waitlist' | Main heading. |
| description | ReactNode | = Short invite line | Subtitle under the heading. |
| fields | WaitlistField[] | = Name, email, phone, website and a yes/no question | Fields to render, in order. Each has type ('text' | 'email' | 'url' | 'tel' | 'select'), name, label, and optional placeholder, autoComplete and required (true by default). Select fields take options: { value, label }[]; tel fields take countries and defaultCountry. |
| submitLabel | string | = 'Join now' | Button text. |
| legal | ReactNode | = Email updates note | Small note under the button. Pass null to hide it. |
| successTitle / successDescription | string / ReactNode | = 'You’re on the list' / thank-you line | Copy for the panel shown after a successful submit. |
| onSubmit | (values: Record<string, string>) => void | Promise<void> | = — | Called with trimmed values keyed by field name once every field is valid. Phone values include the dial code, with the ISO code under `${name}Country`, and URLs get https:// added. Throw to show the error message. Without it, the form simulates success. |
| className | string | = — | Additional classes for the section. |
| style | CSSProperties | = — | Inline styles, handy for overriding the --pp-* theme variables. |