SeatpanoDocs

SDK reference — @seatpano/sdk 0.1

Seatpano.version is the loaded release. Everything below applies to both the script build (seatpano.global.js, global Seatpano) and the npm package.

load(options): Promise<VenueMap>

Option Type Default Notes
container string | HTMLElement required Mounted in a shadow root; theme via CSS variables on the element
venue string required Venue slug
apiBase string — Hosted API root. Preferred in production
apiKey string — Sent as X-Api-Key
baseUrl string "" Static host containing /venues/{slug}/manifest.json. Used when apiBase is absent
assetBase string derived Prefix for image paths
event string — Your event id. With apiBase, the map fetches /v1/venues/{venue}/availability?event=… on load and shades the sellable sections (fail-open: everything shows if the inventory source is unreachable). Pass availability to skip the fetch and shade from your own data
product string first Event configuration (e.g. bulls, blackhawks). Pass it from the event; it selects renders, geometry and surface, and hides the in-map dropdown
level string first Map level id
view string "seat" seat or interior
theme "flat" | "aerial" "flat" Flat polygons with a painted playing surface, or polygons over the aerial render. Venues that ship a team-supplied chart render that chart in both themes
surface "auto" | "baseball" | "basketball" | "hockey" | "football" | "soccer" | "stage" | "none" "auto" Flat theme only. auto follows the manifest's per-product surface. Fitted to the seating hole; baseball snaps to HomePlate / CenterField / PitchersMound hotspots and, when the manifest carries surfaceSpec, draws the real fence line, warning track, batter's eye, bullpens and pool from feet-based dimensions
showProductSwitch boolean auto Event-configuration dropdown (e.g. Bulls / Blackhawks). Shown only when the venue has more than one product and no product was passed
availability string[] | null null Sellable section keys. null = everything in the manifest
popover { enabled, thumbnail, view3d, view3dLabel, galleryScope, loadingMs, source3d } enabled, thumbnail on, "viewer", "product", 3000, "auto" view3d: "viewer" opens the section viewer (below), "image" a lightbox of the still, "iomedia" the venue's own viewer in a new tab, "none" only emits view3d. thumbnail: false gives a compact one-row card with a View 3D button. galleryScope: "product" (this configuration's views), "all", "none" (viewer only). source3d: "auto" (native 360° when the build has faces, else iframe), "pano", "iframe". Venues whose manifest declares presentation.views: "iomedia" default to source3d: "iframe" and galleryScope: "none"
showLevelTabs boolean auto Shown when the product has more than one level
showZoom boolean true
accent string #1f5eff Shortcut for --vm-accent
rows "all" | "front" | "central" | "back" "all" Which row band a section click shows and which rows the gallery lists. all: the build's central row is the default view and every row is in the gallery. front / back: the section's lowest / highest row (closest to the floor / furthest back) is the view and the gallery is limited to it. central: the central row only. select(section, row) overrides per call
vantages "single" | "bands" "single" single: one shape per section; a click selects it and the section's central vantage (median row) drives the popover thumbnail, gallery and 3D viewer. bands: for sections with several row-band renders, a click zooms in to reveal the bands for a second, row-level pick
branding string — Small "Powered by …" badge in the viewer
embedOrigin string — Used by the iframe embed page only: the embedding page's origin, forwarded to the API so the key's domain binding applies to your page, not to embed.seatpano.com

Instance methods

Method Description
on(name, fn) → unsubscribe / off(name, fn) Subscribe to events
select(section, row?) → boolean Select a section; with row (a vantage row such as "16"), that row's view drives the popover and the viewer opens on that row. Switches level if needed. A section drawn only inside a named area selects that area. False if unknown or unavailable
clearSelection()
setAvailability(sections | null) Re-shade; null shows everything; clears the selection if it became unavailable (a named area stays selected while any member is available)
setLevel(id), setProduct(id), setView(view)
getViews(section) → SectionViews | null { section, displayName, category, totalSeats, stills, vantages, thumb, thumbs, iomediaUrl, iomediaUrls, panos } with the asset base applied; null for an unknown key or a named-area id
getSelection() → Selection | null
getLevels(), getProducts()
openViewer(section?) Runs the configured view3d action and emits view3d; opens on the selected row when select was called with one
destroy()

Events

Event Payload
ready { venue, build_id, levels, products, sections } — sections is every section key in the build
select Selection — { section, vantage, row, sections?, level, product, view, image, mode, views }; vantage is the row the user or host picked explicitly (null for a plain click), row the row band whose view is shown. For a named area (a club or lounge band on a team chart) section is the area id and sections lists every member section: filter your listing by sel.sections ?? [sel.section]
deselect {}
hover { section | null, label, vantage }
view3d Selection
viewerClose {} — the section viewer was closed
level { level }
product { product }
error { message }

Theming

Set CSS custom properties on the container. Defaults in packages/sdk/src/styles.ts.

#venue-map {
  --vm-accent: #1f5eff;            /* selected section */
  --vm-fill: #9ec5fb;              /* available (blue) */
  --vm-fill-hover: #6ea8f7;
  --vm-fill-unavailable: #d7dae0;  /* nothing on sale */
  --vm-context: #e3e6ea;           /* stage, clubs, concourse */
  --vm-label: #2f3640;
  --vm-grass: #7cb864; --vm-grass-2: #86c26c; --vm-dirt: #e7c98f;
  --vm-court: #dcae70; --vm-ice: #eef6ff; --vm-line: #fff;
  --vm-radius: 12px;
  --vm-font: Inter, sans-serif;
}

The map has no background of its own on team-supplied charts (the page shows through). When it detects a dark host background it outlines the chart's ink so the black bands and lettering keep their edges; white cells stay white and available cells light blue on any background.

Team-supplied charts

When a venue's build carries a digitized team seating chart, the flat and aerial themes both render that chart: its lines, numbers, ADA marks and court are vector artwork over a transparent background, section polygons are invisible at rest and tint blue when available, grey when not, accent when selected. Level tabs are hidden when the chart is the only level. Everything else (popover, viewer, events, rows, availability) behaves as on the aerial-derived maps.

Named areas. Bands the chart labels with a name instead of numbers (a club, a lounge, "Banner Seats") are clickable areas standing for several sections. The area is live when any member is; clicking it selects the group: select fires with section = the area id (e.g. bmo-club), views.displayName = its label and sections = every member section key. Filter by sections. The popover shows the area's name and, where the venue allows imagery, a representative member's view.

Presentation policy

A venue may require its own seat-view viewer. When the build's manifest sets presentation.views: "iomedia", the SDK defaults change for that venue: "View 3D" opens the venue's IOMEDIA Virtual Venue in an iframe (with its watermark) and the viewer has no gallery of stills or native panoramas (galleryScope: "none"). The popover keeps its preview image. Hosts can still pass popover options explicitly; the manifest only sets the defaults.

Rows within a section

Many bowl sections have renders from several row bands (Row 4, Row 16). The build marks one as the section's central vantage (its median row); that row provides the popover thumbnail and the default view.

Zoom is continuous (−/+ buttons, ×1.4 per step, 1–4×) and scales about the view centre; the map box keeps a fixed height.

Popover

Thumbnail + "Click to View 3D", the section name (or the area name, for a named area), and a Seat / Interior toggle when the section offers both views for the current product. With thumbnail: false the card collapses to one row: name, a View 3D button and the close control.

Section viewer (view3d: "viewer")

Overlay with Back, fullscreen, prev/next arrows, and a gallery strip:

  1. 3D tile — source3d: "auto" (default) prefers the native 360° panorama: the SDK's own WebGL cube-map viewer (mountPano, no dependencies) rendering the six cube faces the build ships under panos. Drag / touch to look around, wheel or pinch to zoom, arrow keys, double-click to reset. No third-party UI, no pricing, no branding. When a build has no faces for the view, it falls back to the IOMEDIA Virtual Venue in an iframe. The route comes from the manifest's products[].embed: "direct" is the app's chromeless panorama-only router (works on newer IOMEDIA app builds), "full" is the whole sales app (United Center hosts, where /direct stalls). A loading cover (blurred thumbnail + spinner) hides the frame for at least popover.loadingMs (default 3 s) and until it has loaded.
  2. Gallery grouped by row — one line per row band in seating order (Row 1, Row 3, Row 13), each with that row's 360° view and photo, captions on every tile; the highlighted tile is the view that is open. Views that are not row-specific (suite interiors) and, with galleryScope: "all", other event configurations appear under More views. galleryScope: "product" (default) limits the gallery to the current configuration. The viewer opens on the selected row (or the central row); every row is always listed.

Keyboard: Esc closes, ←/→ step through every view in order. Events: view3d on open, viewerClose on close. buildGallery(views, manifest, product, mode, { scope, direct, source3d, vantage, rows }), toEmbedUrl(vrUrl) and mountPano(container, faces, opts) are exported for hosts that render their own viewer with view3d: "none".

Accessibility

Sections are focusable buttons with labels; Enter/Space selects. Level tabs use role="tablist". The lightbox closes on Escape or click.