Playful modal
Modal-style contact card with a giant heading.
Usage
import { ContactPlayful, ContactPlayfulModal } from '@/components/blocks/contact-03'
// A button that opens the form in a modal
<ContactPlayfulModal triggerLabel="Contact us" />
// Control it yourself
<ContactPlayfulModal open={open} onOpenChange={setOpen} />
// Or place the card inline and handle closing yourself
<ContactPlayful onClose={() => setOpen(false)} />
// Swap in your own studio, copy and fields
<ContactPlayful
title="Let’s talk"
description="Tell us about your project and we’ll get back to you within a day."
email="studio@pinwheel.example"
phone="+44 20 7946 0714"
fields={[
{ type: 'text', name: 'name', label: 'Your name', autoComplete: 'name' },
{ type: 'email', name: 'email', label: 'Email', autoComplete: 'email' },
{ type: 'tel', name: 'phone', label: 'Phone', autoComplete: 'tel', required: false },
{ type: 'textarea', name: 'message', label: 'Message', minLength: 10 },
]}
onSubmit={async (values) => {
await fetch('/api/contact', { method: 'POST', body: JSON.stringify(values) })
}}
onClose={() => setOpen(false)}
/>
Install
pnpm dlx shadcn@latest add @pastaui-pro/contact-03npx shadcn@latest add @pastaui-pro/contact-03yarn dlx shadcn@latest add @pastaui-pro/contact-03bunx --bun shadcn@latest add @pastaui-pro/contact-03Source
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | = 'Contact us' | The heading at the top left. |
| description | string | = Short reply-time note | Supporting text under the heading. Pass an empty string to hide it. |
| email / phone | string | = 'studio@pennycress.example' / '+1 (617) 555-0129' | Direct contact links beside the send button. Pass an empty string to hide either. |
| fields | Contact03Field[] | = Project chips, name, email, message | Each: type ('text' | 'email' | 'tel' | 'textarea' | 'choice'), name, label, and optional placeholder, required (default true) and autoComplete. Textareas take minLength and maxLength and sit in the right column beside the short fields; choice fields take options and render as a full-width chip radio group. |
| submitLabel | string | = 'Send it over' | Label of the big send button. |
| successTitle / successDescription | string | = 'Thanks, it landed' / reply note | Copy for the success panel. The default description repeats the email entered. |
| onSubmit | (values: Contact03Values) => void | Promise<void> | = Simulated success | Receives the trimmed values once every field is valid. Throw an Error to show its message in the error state. |
| onClose / closeLabel | () => void / string | = — / 'Close contact form' | Renders the top-right close button when onClose is passed. |
| className | string | = — | Extra classes for the section. |
| style | CSSProperties | = — | Inline styles, handy for overriding the --pp-* theme variables. |