Contact Us
blockmarketingTwo-column contact section. Left: eyebrow, headline, lede, icon contact rows (email / phone / office) and a live Mapbox map pinned to your office (pass accessToken + location; falls back to a placeholder without a token). Right: a Card-wrapped form (name / email / company / subject Select / message Textarea) that swaps to a success state. Calls onsubmit with the payload.
Installation
$pnpm dlx shadcn-svelte@latest add https://uipkge.dev/r/svelte/contact-us.json$npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/contact-us.json$yarn dlx shadcn-svelte@latest add https://uipkge.dev/r/svelte/contact-us.json$bunx shadcn-svelte@latest add https://uipkge.dev/r/svelte/contact-us.jsonManifest:
https://uipkge.dev/r/svelte/contact-us.jsonInstalls to:src/lib/components/blocks/contact-us/Variants
Loading interactive previews…
Loading interactive previews…
Theming
CSS custom properties referenced in this item. Override any of them in your :root or per-element to retheme.
--backgroundFiles installed (1)
src/lib/components/blocks/contact-us/ContactUs.svelte6.8 kB
<script lang="ts"> /** * Contact section — two columns. Left: eyebrow, headline, lede, icon-prefixed * contact rows, and a live map pinned to your office (pass `accessToken` + * `location`; falls back to a styled placeholder without a token). Right: a * Card-wrapped form (name / email / company / subject / message) that swaps to * a success state after submit. Calls `onsubmit` with the payload. */ import { CircleCheckBig, Mail, MapPin, Phone, Send } from '@lucide/svelte' import { Button } from '$lib/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '$lib/components/ui/card' import { Input } from '$lib/components/ui/input' import { Label } from '$lib/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '$lib/components/ui/select' import { Textarea } from '$lib/components/ui/textarea' import { Map, MapMarker } from '$lib/components/ui/map' export interface ContactSubmitPayload { name: string email: string company: string subject: string message: string } interface ContactUsProps { /** Mapbox token. Without it the map area shows a styled placeholder. */ accessToken?: string /** Office [lng, lat]. */ location?: [number, number] locationLabel?: string onsubmit?: (payload: ContactSubmitPayload) => void } let { accessToken = '', location = [-122.4194, 37.7749], locationLabel = 'San Francisco, CA', onsubmit, }: ContactUsProps = $props() let name = $state('') let email = $state('') let company = $state('') let subject = $state('sales') let message = $state('') let sent = $state(false) const canSubmit = $derived(name !== '' && email !== '' && message !== '') function submit() { if (!canSubmit) return onsubmit?.({ name, email, company, subject, message }) sent = true } </script> <section data-slot="contact-us" class="bg-background"> <div class="mx-auto max-w-6xl px-6 py-20"> <div class="grid gap-10 lg:grid-cols-2 lg:items-start"> <!-- Left: copy + contact rows + map --> <div class="space-y-6"> <p class="text-primary text-sm font-medium tracking-widest uppercase">Contact</p> <h2 class="text-3xl font-semibold tracking-tight sm:text-4xl">Talk to our team</h2> <p class="text-muted-foreground max-w-md"> Questions about pricing, onboarding, or a custom plan? Send a note and we'll get back within one business day. </p> <ul class="space-y-3"> <li class="flex items-center gap-3"> <span class="bg-muted text-foreground flex size-9 items-center justify-center rounded-lg" ><Mail class="size-4" /></span > <span class="text-sm">hello@example.com</span> </li> <li class="flex items-center gap-3"> <span class="bg-muted text-foreground flex size-9 items-center justify-center rounded-lg" ><Phone class="size-4" /></span > <span class="text-sm">+1 (555) 010-2030</span> </li> <li class="flex items-center gap-3"> <span class="bg-muted text-foreground flex size-9 items-center justify-center rounded-lg" ><MapPin class="size-4" /></span > <span class="text-sm">{locationLabel}</span> </li> </ul> <div class="h-56 overflow-hidden rounded-xl border"> {#if accessToken} <Map {accessToken} center={location} zoom={11} muted class="size-full"> <MapMarker lngLat={location} anchor="bottom"> <svg viewBox="0 0 24 24" width="26" height="34" class="text-primary drop-shadow"> <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z" fill="currentColor" stroke="currentColor" stroke-width="1.5" /> <circle cx="12" cy="9" r="2.6" fill="var(--background)" /> </svg> </MapMarker> </Map> {:else} <div class="bg-muted text-muted-foreground flex size-full items-center justify-center gap-2 text-sm"> <MapPin class="size-4" /> {locationLabel} </div> {/if} </div> </div> <!-- Right: form --> <Card> {#if !sent} <CardHeader> <CardTitle>Send a message</CardTitle> <CardDescription>We'll route it to the right person.</CardDescription> </CardHeader> <CardContent class="space-y-4"> <div class="grid gap-4 sm:grid-cols-2"> <div class="space-y-1.5"> <Label for="cu-name">Name</Label> <Input id="cu-name" bind:value={name} placeholder="Jane Cooper" /> </div> <div class="space-y-1.5"> <Label for="cu-email">Email</Label> <Input id="cu-email" bind:value={email} type="email" placeholder="[email protected]" /> </div> </div> <div class="space-y-1.5"> <Label for="cu-company">Company</Label> <Input id="cu-company" bind:value={company} placeholder="Acme Inc." /> </div> <div class="space-y-1.5"> <Label>Subject</Label> <Select bind:value={subject}> <SelectTrigger><SelectValue placeholder="Choose a topic" /></SelectTrigger> <SelectContent> <SelectItem value="sales">Sales</SelectItem> <SelectItem value="support">Support</SelectItem> <SelectItem value="partnership">Partnership</SelectItem> </SelectContent> </Select> </div> <div class="space-y-1.5"> <Label for="cu-message">Message</Label> <Textarea id="cu-message" bind:value={message} rows={4} placeholder="How can we help?" /> </div> <Button class="w-full" disabled={!canSubmit} onclick={submit}> <Send class="size-4" /> Send message </Button> </CardContent> {:else} <CardContent class="flex flex-col items-center gap-3 py-16 text-center"> <span class="bg-success/10 text-success flex size-12 items-center justify-center rounded-full" ><CircleCheckBig class="size-6" /></span > <p class="text-lg font-semibold">Message sent</p> <p class="text-muted-foreground max-w-xs text-sm"> Thanks, {name} — we'll reply to {email} within one business day. </p> <Button variant="outline" onclick={() => (sent = false)}>Send another</Button> </CardContent> {/if} </Card> </div> </div> </section>
Raw manifest:https://uipkge.dev/r/svelte/contact-us.json