Contact FormNew

Black tiles, a reaching hand and a real form.

npx shadcn@latest add "https://www.pinui.xyz/r/blocx/contact-form.json"
Live preview

When to use

  • A portfolio or studio contact section with a strong editorial look
  • Short enquiries: an email, an optional number and a message

When not to use

  • Forms with many fields or file uploads — the tiles are sized for three
  • Pages that need the form below the fold; the block is drawn to fill one viewport

Installation

Add Contact Form with the shadcn CLI — it writes the files into components/blocx/ and installs what they import — or copy it in by hand.

Requires React 19 · Next.js (it loads its fonts with next/font) · motion.

pnpm dlx shadcn@latest add "https://www.pinui.xyz/r/blocx/contact-form.json"

Images don’t travel through the CLI: copy public/blocx/contact-form/ (1 file) into your own public/ folder.

Usage

import ContactForm from "@/components/blocx/ContactForm";

export default function Page() {
  return (
    <ContactForm
      onSubmit={async (values) => {
        await fetch("/api/contact", { method: "POST", body: JSON.stringify(values) });
      }}
    />
  );
}

page.tsx · 12 lines

API reference

ContactForm

PropTypeDefaultDescription
onSubmit(values) => Promise<void> | void—Called with { email, contact, message } once they validate; left out, the demo waits a moment and says thanks

Accessibility

  • Every field has a real label; errors are tied to their field with aria-describedby and aria-invalid
  • A failed submit moves focus to the first field that needs fixing
  • The sending and sent states are announced through a polite live region

Motion

  • The guides draw themselves across the page, the headline rises word by word, the photo reveals upward and the tiles follow
  • Wrong fields shake; the button fills white with its label rolling over, shows bouncing dots while sending and draws a check when done
  • Reduced motion keeps every state change and drops the movement

Responsive behavior

  • The frame is drawn in its own units and scaled to fit both the window's width and height, so it always sits in one viewport
  • Portrait tablets get a tighter frame; below 760px it stacks photo over form and scrolls

Blocx · 8 blocks · 4 sections · part of Pin UI