Arc
ComponentsBlocksDocsPricingTry the demo
Get Pro
Introduction
Installation
Theming
Motion
AI and MCP
Changelog
Metrics dashboardPro
KPI drilldownPro
Metric explorerPro
Revenue explorerPro
MRR waterfallPro
Cohort retentionPro
Usage forecastPro
Journey flowPro
Uptime statusPro
Choropleth explorerPro
Connected scatterPro
Horizon chartPro
Account healthPro
Market terminalPro
Budget variancePro
Small multiplesPro
Line replayPro
AI chatPro
AI composerPro
AI answerPro
Model pickerPro
Model arenaPro
Prompt studioPro
Document extractionPro
Agent memoryPro
AI side panelPro
AI inline editNewPro
Research runPro
AI insight cardPro
Catch upPro
AI feature launchPro
AI search barPro
AI setup wizardPro
Call insightsPro
Lead scoringPro
Agent runPro
Agent tasksPro
Agent approvalsPro
Agent routinesPro
Agent orchestratorPro
MCP serversPro
Knowledge basePro
Eval suitePro
Agent builderPro
Agent galleryPro
SidebarPro4
Page header
Command palette
Notification center
Selection toolbarPro
Empty states
Search resultsPro
Login and sign up5, free and Pro variants
Onboarding illustrationPro
OTP input
Multi-step formPro
Two-factor setupPro
Magic linkPro
Settings pagePro
Settings commandPro
Security settingsPro
Billing overviewPro
Usage billingPro
Cancel flowPro
Onboarding surveyPro
Spend alertPro
Team membersPro
Invite peoplePro
Team directoryPro
Roles and permissionsPro
Profile pagePro
API keysPro
WebhooksPro
IntegrationsPro
Environment variablesPro
Domain verifyPro
Webhook testerPro
Plan comparison
Pricing calculatorPro
Usage pricingPro
Cart drawerPro
Checkout summaryPro
Live checkoutPro
Seat managerPro
Credit top-upPro
Invoice studioPro
Wallet cardPro
Delivery trackerPro
Product listingPro
Product detailPro
Seat mapNewPro
Activity feedPro
Inbox triagePro
Support conversationPro
Support widgetPro
Help centerPro
Feature votingPro
File upload
Media playerPro
Week calendarPro
Availability pickerPro
Project boardPro
Release readinessPro
Kanban boardPro
Feedback boardPro
Smart schedulerPro
Task breakdownPro
Goal trackerPro
Hero section
Hero signupPro
Scroll storyPro
Spotlight gridPro
Feature bentoPro
Comparison table
Logo marquee
Studio perspectivesPro
Stats band
Changelog feed
FAQ section
Contact section
Team showcasePro
Blog grid
Site header
Site footer
CTA section
Newsletter signup
Activity terrainPro
Revenue globePro
Customer galaxyPro
Semantic zoomPro
Layout morphPro
Exploded viewPro
What’s new4 new
BlocksSeat map

Seat map

Pro

An event seat picker with a curved concert hall map, price tiers, zoom and pan, sold, held and wheelchair seats, and a live summary with fees and a hold countdown.

Live block · sample data

When to use

  • Reserved seating for concerts, theatre, sports and conferences where the buyer picks exact seats.
  • Any spatial picker with priced places: tables in a restaurant plan, desks in an office, cabins on a deck.
  • Checkout flows that need a live total and a short hold before payment.

When not to use

  • Use a quantity stepper with best available when seats are general admission or assigned by the box office.
  • Use availability-picker for choosing times rather than places.
  • Use choropleth-explorer to compare values across regions without selecting them.

Installation

Pro source and install commands unlock with a Pro plan.

Usage

Render <SeatMap /> for the demo, or pass event, venue (seats with x, y, rotate, tier, status), tiers, maxSeats and an onHold promise that reserves the chosen seats. onSelectionChange reports the picked seats in order.

example.tsx
1import { SeatMap } from "@/components/arc/blocks/seat-map/seat-map";2 3export function ChooseSeats({ performance, hall, prices }) {4  return (5    <SeatMap6      event={performance}7      venue={hall}8      tiers={prices}9      maxSeats={8}10      onHold={seats => fetch("/api/holds", { method: "POST", body: JSON.stringify(seats.map(seat => seat.id)) }).then(response => {11        if (!response.ok) throw new Error("Hold failed");12      })}13    />14  );15}
Built fromButtonAnimated counter

API reference

SeatMap

An event seat picker. The hall is drawn as curved rows that face the stage, colored by price tier, with sold, held and wheelchair seats marked. Buyers zoom and pan the map, pick up to a set number of seats, and see a running summary with fees and a hold countdown.

PropTypeDefaultDescription
eventSeatEventseatEventThe performance: name, venue, a preformatted date string and an optional thumbnail image.
venueSeatVenueseatVenueThe hall in its own map units: width, height, the stage path and label position, sections with label positions, seats (id, section, row, number, x, y, rotate, tier, status, access, note) and row labels.
tiersSeatTier[]seatTiersPrice tiers in filter order. Each has an id, name, price and a CSS color; the demo uses --series-1 to --series-4 so tiers follow the accent and theme.
maxSeatsnumber6Most seats one buyer can pick. Picking past it shows an inline notice on the map instead of adding the seat.
serviceFeenumber4.5Fee added per ticket, shown as its own line in the summary.
currencystring"USD"ISO currency code. Prices are formatted with the en-US locale so server and client render the same text.
holdMinutesnumber10Length of the hold that starts after the hold button succeeds. The countdown releases the seats when it reaches zero.
defaultSelectedstring[]seatDefaultSelectionSeat ids selected on first render. Ids that are not available, or past maxSeats, are ignored.
titlestring"Your seats"Heading of the summary panel.
onSelectionChange(seats: Seat[]) => void–Called after every change to the selection, with the seats in the order they were picked.
onHold(seats: Seat[]) => void | Promise<void>–Called by the hold button. Return a promise to show the pending state; a rejection keeps the selection and shows an inline error with a retry. Without it the demo simulates a short request.
classNamestring–Class on the root section.

Keyboard interactions

Tab
Moves into the map on one seat at a time (a roving tab stop), then on to the zoom controls and the summary.
Arrow keys
Left and right move along the row and cross the aisle to the next section; up and down move toward or away from the stage. The map pans to keep the seat in view.
HomeorEnd
Jumps to the first or last seat in the row.
EnterorSpace
Chooses or removes the seat. Sold and held seats explain why they cannot be chosen.
+or-
Zooms in or out around the middle of the map.
0
Shows the whole hall again.

Accessibility

  • Every seat is a checkbox with a full name, such as "Row G, seat 7, Stalls centre. Stalls, $112. Aisle seat", and sold or held seats are marked disabled.
  • Seats are grouped by section, and the map carries instructions for its keys through aria-describedby.
  • Keyboard position shows as a soft fill behind the seat and a tooltip with the seat details, never a focus ring.
  • Selections, removals, the seat limit, holds and expiry are announced in a polite live region.
  • Tier, status and access never rely on color alone: sold seats shrink, held seats are outlined with a dot, selected seats carry a check, and wheelchair spaces are square with a glyph. The key under the map names each mark.
  • Zoom buttons, the tier filter and each summary row are real buttons with specific names; remove buttons name the seat they remove.

Motion

  • The camera moves on one critically damped spring, so zooming, choosing a tier and following the keyboard glide without overshoot and can be interrupted by a drag at any point.
  • Choosing a price tier dims the other tiers and flies the camera to where those seats sit; choosing it again returns to the whole hall.
  • A picked seat fills and its check scales in; summary rows open and close their height on the smooth spring, and totals roll to their new values with tabular digits.
  • Pan, pinch and ctrl or cmd scroll write straight to motion values and a single transform per frame, with no React state per frame.
  • Reduced motion jumps the camera and swaps every transition for an instant change while keeping focus and announcements.

Responsive behavior

  • From 860px the map and the summary sit side by side with a 320px summary; below that the summary stacks under the map.
  • Below 560px the map is 340px tall, the price filter scrolls sideways, and section labels hide until there is room for them.
  • On touch, a tap on the whole hall zooms to that spot first, so seats are 44px apart before one can be chosen; one finger pans and two fingers pinch once zoomed, while the page still scrolls at the full view.
  • Zoom buttons, price chips and remove buttons grow to 44px on coarse pointers.

Performance

  • Seats are plain SVG groups in a memoized component, so a selection repaints the changed seats rather than the hall. The demo draws about 500 seats.
  • Camera motion is one transform on a single group, batched to one write per frame with Motion's frame loop.
  • Tooltip position is written directly to its style when the camera or seat changes, without re-rendering.
  • For halls of many thousands of seats, split sections into separate layers or render seats to canvas and keep the same props.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Generate seat positions from your venue plan in any unit system; the camera fits whatever bounds the seats cover. Rotation turns each seat toward the stage.
  • Map your inventory to status: available, held (in another buyer's cart) or sold. Only available seats can be chosen.
  • Tier colors are plain CSS values. Keep them to the chart series or other semantic tokens so both themes stay legible.
  • Wire onHold to your reservation API and return its promise. The countdown only reflects the local hold length; take the real expiry from your server if it differs.
  • The first render uses the venue view box and no camera transform, then measures the viewport after mount, so the markup matches on server and client.
/components/blocks/seat-map/markdown

The full library index for assistants is at /llms.txt.

Related

Availability pickerProBlockFind a meeting time across people and see the choice come together.Choropleth explorerProBlockA filled-region map that shades every state or region by revenue, growth or penetration on a stepped scale, with a country switch (United States, Canada, Brazil, United Kingdom, France, Germany, Italy, Australia), a hoverable legend, a synced ranked list and a camera zoom into local detail.
PreviousExploded viewNextAI answer
Arc · 132 block pagesllms.txt

On this page

  • Preview
  • When to use
  • When not to use
  • Installation
  • Usage
  • API reference
  • Keyboard
  • Accessibility
  • Motion
  • Responsive behavior
  • Performance
  • Notes for AI
  • Related
View as Markdown

Lena Ostrova plays the Nocturnes

Sat 14 Nov, 7:30 pmHarbour Hall, main auditorium

StageStalls leftStalls centreStalls rightCircle leftCircle centreCircle rightABCDEFGHJKLMABCDEFGHJKLMABCDEFABCDEF
  • Selected
  • On hold
  • Sold
  • Wheelchair space

Use the arrow keys to move between seats, Home and End for the ends of a row, Enter or Space to choose a seat, plus and minus to zoom, and 0 to show the whole hall.

Your seats

2 of 6
Tickets
$224.00$001234567890012345678900123456789.0012345678900123456789
Service fee
$9.00$00123456789.0012345678900123456789
Total
$233.00$001234567890012345678900123456789.0012345678900123456789
$4.50 service fee per ticket