caliper uidocs

Contact section

Block

A contact form beside the ways to reach a team.

Installs components/ui/contact-section.tsxDepends on @radix-ui/react-popover, @radix-ui/react-slot, lucide-reactMotion none in component source
pnpm dlx shadcn@latest add https://caliperui.site/r/contact-section.json

Contact us

Tell us what you are building and we will point you to the right place.

Response time
Within one business day
Studio
12 Wharf Road, Leeds

When to use #

Use it for

  • A landing page needs a way to ask a question.

Skip it when

  • You only need an email address; use the newsletter signup.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/contact-section.json

Adds its 10 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

This is the code behind the preview above.

example.tsx
import { ContactSection } from "@/components/ui/contact-section"

const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

export function ContactSectionDemo() {
  return (
    <ContactSection
              description="Tell us what you are building and we will point you to the right place."
              details={[
                { label: "Email", value: "hello@caliper.example", href: "mailto:hello@caliper.example" },
                { label: "Response time", value: "Within one business day" },
                { label: "Studio", value: "12 Wharf Road, Leeds" },
              ]}
              topics={["Sales", "Support", "Partnerships", "Something else"]}
              onSubmit={async ({ message }) => {
                await wait(1000);
                if (/fail/i.test(message)) throw new Error("We couldn't send that right now. Your message is still here, try again.");
              }}
            />
  );
}

API reference #

ContactSection

component
PropTypeDefault
titlestring"Contact us"
descriptionstring—
detailsreadonly ContactDetail[]—
topicsreadonly string[]—
onSubmit *(values: { name: string; email: string; topic: string; message: string; }) => ContactResult | Promise<ContactResult>—
successTitlestring"Message sent"
successTextstring"Thanks. We will reply within one business day."
classNamestring—

Accessibility #

It exposes status semantics, with aria-labelledby and aria-hidden kept in step with state. Changes that matter are announced through a live region.

Keyboard and focus handling comes from Radix popover: arrow keys move through items, Enter and Space select, and Escape closes and returns focus.

Motion #

It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.