Seat Map

Pro

Seat picker for cinemas, cabins and arenas, built from your own seating data. Picked seats light up and settle, and trying to pick more than the limit briefly flickers the seat.

Preview

Installation

npx @lumioui/cli add pro/seat-map

Usage

import { SeatSections, SeatMap } from "@/components/ui/seat-map/seat-map";
<SeatMap />

Also exported: SeatSections.

Examples

Cinema

An indie cinema's booking step.

Flight cabin

A two-passenger cabin pick on a 3-3 narrowbody.

Stadium sections

The arena overview step of a ticketing app.

API reference

SeatMap

Prop Type Default
rows* SeatRow[]

Rows top to bottom.

—
tiers SeatTier[]

Price tiers for tint, legend and totals.

—
value string[]

Controlled selected seat ids.

—
defaultValue string[]

Uncontrolled initial selection.

—
onValueChange
(ids: string[], detail: SeatSelectionDet … (ids: string[], detail: SeatSelectionDetail) => void

Fires with the new ids plus the resolved seats and price total.

—
maxSeats number

Maximum seats. Past it the map shakes; with 1, a new pick replaces the old one. Default 8.

—
onMaxReached () => void

Fires when a pick is refused by maxSeats.

—
shape "chair" | "cabin" | "square"

Seat silhouette: chair (cinema/theatre), cabin (aircraft, with headrest), square (coach/bus). Default "chair".

—
screen string

Draws a curved screen/stage line above the rows with this label ("Screen").

—
columnLabels (string | null)[]

Column letters above the grid, one per cell (use null for aisle columns) — the aircraft "A B C D E F" header.

—
showRowLabels boolean

Show row labels in both gutters. Default true when rows have labels.

—
showLegend boolean

Show the legend below the grid. Default true.

—
maxSeatSize number

Largest seat edge in pt; seats shrink to fit narrower columns. Default 30.

—
gap number

Gap between seats in pt. Default 6.

—
formatPrice (price: number) => string

Price formatter for the legend. Default $18.

—
disabled boolean

Freeze the map (e.g. while holding seats).

—
sheen number

Bump (e.g. increment) to seal the picks: one sheen crosses them in order.

—
className string —

SeatSections

Prop Type Default
sections* SeatSection[] —
x* number —
y* number —
w* number —
h* number —
stage { label: string

Stage / pitch / court block in the same normalised space.

—
round boolean } —
tiers SeatTier[] []
value string | null

Controlled selected section id.

—
defaultValue string | null

Uncontrolled initial section.

—
onValueChange
(id: string | null … (id: string | null, section: SeatSection | null) => void

Fires with the picked section (or null when tapped again).

—
aspectRatio number

Venue width / height. Default 1.

1
showLegend boolean

Show the tier legend. Default true.

true
formatPrice (price: number) => string defaultFormat
className string —