Contact section

A validated contact form that morphs into a confirmation, support channels, and office cards with local times.

Preview
Contact section preview

Talk to our team

Questions about licensing, a bug you can't pin down, or a component you wish existed. A person reads every message.

  • Replies within one business day
  • hello@example.com
Topic
500 characters left

We reply within one business day.

When to use

  • Contact pages and sections on marketing sites.
  • Sales or support pages that list several channels with response times.
  • Companies with offices in several time zones.

When not to use

  • Use support-widget for an in-app help launcher.
  • Use signup-form or login blocks for account flows.

shadcn CLI

Also installs (7)

  • manicat-foundation
  • avatar
  • button
  • copy-button
  • input
  • segmented-control
  • textarea
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "contact-section",
  "type": "registry:block",
  "title": "Contact section",
  "description": "A validated contact form that morphs into a confirmation, support channels, and office cards with local times.",
  "categories": [
    "blocks"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json",
    "https://manicat.viraza.net/r/avatar.json",
    "https://manicat.viraza.net/r/button.json",
    "https://manicat.viraza.net/r/copy-button.json",
    "https://manicat.viraza.net/r/input.json",
    "https://manicat.viraza.net/r/segmented-control.json",
    "https://manicat.viraza.net/r/textarea.json"
  ],
  "files": [
    {
      "path": "registry/blocks/contact-section/contact-section.tsx",
      "type": "registry:component",
      "target": "@components/manicat/blocks/contact-section/contact-section.tsx"
    },
    {
      "path": "registry/blocks/contact-section/contact-section.module.css",
      "type": "registry:component",
      "target": "@components/manicat/blocks/contact-section/contact-section.module.css"
    },
    {
      "path": "lib/media.ts",
      "type": "registry:lib",
      "target": "@components/manicat/lib/media.ts"
    },
    {
      "path": "registry/components/textarea/textarea.tsx",
      "type": "registry:component",
      "target": "@components/manicat/textarea/textarea.tsx"
    },
    {
      "path": "registry/components/textarea/textarea.module.css",
      "type": "registry:component",
      "target": "@components/manicat/textarea/textarea.module.css"
    },
    {
      "path": "registry/components/segmented-control/segmented-control.tsx",
      "type": "registry:component",
      "target": "@components/manicat/segmented-control/segmented-control.tsx"
    },
    {
      "path": "registry/components/segmented-control/segmented-control.module.css",
      "type": "registry:component",
      "target": "@components/manicat/segmented-control/segmented-control.module.css"
    },
    {
      "path": "registry/components/input/input.tsx",
      "type": "registry:component",
      "target": "@components/manicat/input/input.tsx"
    },
    {
      "path": "registry/components/input/input.module.css",
      "type": "registry:component",
      "target": "@components/manicat/input/input.module.css"
    },
    {
      "path": "registry/components/copy-button/copy-button.tsx",
      "type": "registry:component",
      "target": "@components/manicat/copy-button/copy-button.tsx"
    },
    {
      "path": "registry/components/copy-button/copy-button.module.css",
      "type": "registry:component",
      "target": "@components/manicat/copy-button/copy-button.module.css"
    },
    {
      "path": "lib/use-copy-feedback.ts",
      "type": "registry:lib",
      "target": "@components/manicat/lib/use-copy-feedback.ts"
    },
    {
      "path": "registry/components/button/button.tsx",
      "type": "registry:component",
      "target": "@components/manicat/button/button.tsx"
    },
    {
      "path": "registry/components/button/button.module.css",
      "type": "registry:component",
      "target": "@components/manicat/button/button.module.css"
    },
    {
      "path": "registry/components/avatar/avatar.tsx",
      "type": "registry:component",
      "target": "@components/manicat/avatar/avatar.tsx"
    },
    {
      "path": "registry/components/avatar/avatar.module.css",
      "type": "registry:component",
      "target": "@components/manicat/avatar/avatar.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/blocks/contact-section",
  "meta": {
    "tier": "free",
    "kind": "block",
    "docs": "https://manicat.viraza.net/components/blocks/contact-section",
    "markdown": "https://uiarc.dev/components/blocks/contact-section/markdown"
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { ContactSection } from "manicat/registry/blocks/contact-section/contact-section";

export function ContactSectionExample() {
  // Size containers have no width of their own: give the demo the whole row.
  return <div className="w-full"><ContactSection /></div>;
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

Contact form A form with topics; onSubmit receives the message.

Contact form A form with topics; onSubmit receives the message. preview

Talk to us

We usually answer within one business day.

  • Replies within one business day
  • hello@example.com
Topic
500 characters left

We reply within one business day.

Keyboard interactions

KeysAction
Arrow keysMove between topic chips, which form a radio group.

Accessibility

  • Fields use labelled Arc Input and Textarea; errors appear after the first submit and update as you type.
  • A failed send shows a role="alert" message and keeps the form.
  • Office open status is written out, not shown by color alone.

Motion

  • The form card springs into the confirmation; faces slide along one axis in the direction of travel out of a soft blur.
  • The topic highlight glides between chips.
  • Reduced motion swaps faces without travel.

Responsive behavior

  • Container queries: below 820px the form layout stacks and the channel list becomes a horizontal scrolling row; below 520px field rows stack and the submit button fills the width.

Performance

  • The offices variant re-renders every 15 seconds to keep local times live; other variants have no timers.

Notes for AI

  • Without onSubmit the form only simulates sending; always wire it in production.
  • Offices compute local time and open status with Intl.DateTimeFormat in each timeZone.
  • Composes Arc Input, Textarea, Button, CopyButton, SegmentedControl, and Avatar.