@seatlayer/react 0.65.0 → 0.67.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +226 -27
  2. package/package.json +15 -6
package/README.md CHANGED
@@ -1,19 +1,49 @@
1
- # @seatlayer/react
1
+ # SeatLayer React Seat Map SDK for Reserved Seating
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@seatlayer/react)](https://www.npmjs.com/package/@seatlayer/react)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@seatlayer/react)](https://www.npmjs.com/package/@seatlayer/react)
5
5
  [![React](https://img.shields.io/badge/React-%E2%89%A517-61DAFB.svg)](https://react.dev/)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-types%20included-3178C6.svg)](https://www.typescriptlang.org/)
6
7
  [![License: MIT](https://img.shields.io/badge/license-MIT-111827.svg)](../../LICENSE)
7
8
 
8
- The official React components for SeatLayer reserved seating. Render the
9
- complete buyer picker or a headless interactive chart, hold inventory in the
10
- browser, and complete the booking from your trusted server.
11
-
12
- [Package on npm](https://www.npmjs.com/package/@seatlayer/react) ·
13
- [SeatPicker docs](https://docs.seatlayer.io/buyer-sdk/seat-picker/) ·
14
- [Live demo](https://app.seatlayer.io/demo/play) ·
15
- [Website](https://seatlayer.io/developers/) ·
16
- [AI Toolkit](https://github.com/seatlayer/seatlayer-ai-toolkit)
9
+ The official React components for SeatLayer reserved seating. Drop an
10
+ interactive seating chart or a complete seat picker into a ticketing app, show
11
+ live seat availability, and let buyers take temporary holds on the inventory
12
+ they choose.
13
+
14
+ Everything is a real React component with a typed imperative handle: the browser
15
+ selects and **holds**, and your trusted server **books** the hold.
16
+
17
+ [SeatLayer React SDK on npm](https://www.npmjs.com/package/@seatlayer/react) ·
18
+ [React seat-map documentation](https://docs.seatlayer.io/buyer-sdk/seat-picker/) ·
19
+ [SeatLayer reserved-seating platform](https://seatlayer.io/) ·
20
+ [Buyer seat-map demo](https://app.seatlayer.io/demo/play/grand-theatre) ·
21
+ [SeatLayer JavaScript seat map SDK](https://www.npmjs.com/package/@seatlayer/js) ·
22
+ [SeatLayer Vue seat map SDK](https://www.npmjs.com/package/@seatlayer/vue) ·
23
+ [SeatLayer Angular seat map SDK](https://www.npmjs.com/package/@seatlayer/angular) ·
24
+ [SeatLayer React Native SDK](https://github.com/seatlayer/seatlayer-react-native) ·
25
+ [SeatLayer AI Toolkit](https://github.com/seatlayer/seatlayer-ai-toolkit)
26
+
27
+ ## What is included
28
+
29
+ - `SeatingChart` — the headless interactive chart, mounted into a plain `<div>`
30
+ your styles own.
31
+ - `SeatPicker` — the complete buyer experience: map, legend, tray, pricing, and
32
+ the checkout hand-off.
33
+ - `SeatManager` — the organizer control room, for dashboards that monitor and
34
+ block live inventory.
35
+ - `EmbeddedDesigner` — a hosted chart Designer inside your own application.
36
+ - `SeatPickerWidget` and `attachPickerFrame` — the framework-agnostic modal and
37
+ iframe helpers, re-exported so a React host depends on this package alone.
38
+ - TypeScript declarations for ESM (`dist/index.d.ts`) and CommonJS
39
+ (`dist/index.d.cts`), plus the `@seatlayer/react/manager` subpath.
40
+
41
+ ## Requirements
42
+
43
+ - React 17 or newer (declared as a peer dependency).
44
+ - A browser DOM. The chart is created inside an effect, and this package ships
45
+ no `'use client'` banner of its own — in the Next.js App Router, mark the
46
+ component that imports it.
17
47
 
18
48
  ## Install
19
49
 
@@ -21,7 +51,7 @@ browser, and complete the booking from your trusted server.
21
51
  npm install @seatlayer/react
22
52
  ```
23
53
 
24
- ## Usage
54
+ ## Quick start
25
55
 
26
56
  ```tsx
27
57
  import { useRef } from 'react';
@@ -52,6 +82,28 @@ await chart.current?.releaseLabels(['A-12']); // keep the remainder hel
52
82
  await chart.current?.release(); // release the current hold
53
83
  ```
54
84
 
85
+ For the complete buyer experience — map, legend, priced tray, and the checkout
86
+ hand-off — render `SeatPicker` instead:
87
+
88
+ ```tsx
89
+ import { SeatPicker } from '@seatlayer/react';
90
+
91
+ export function Tickets() {
92
+ return (
93
+ <SeatPicker
94
+ event="ev_9f3a"
95
+ style={{ width: '100%', height: 640 }}
96
+ selectionValidators={[
97
+ { type: 'minimumSelectedPlaces', minimum: 2 },
98
+ { type: 'consecutiveSeats' },
99
+ { type: 'noOrphanSeats' },
100
+ ]}
101
+ onCheckout={(hold, seats, handoff) => myServerTakesPayment(handoff)}
102
+ />
103
+ );
104
+ }
105
+ ```
106
+
55
107
  ### Full SeatPicker imperative contract
56
108
 
57
109
  The full-experience `SeatPicker` exposes the canonical safe widget controls through
@@ -97,13 +149,34 @@ Changing a callback prop does **not** rebuild the canvas. `selectedObjects` and
97
149
  `selectableObjects` are initial values; use the imperative methods for later
98
150
  changes. Exact count and validator props rebuild the chart.
99
151
 
100
- ## The model
152
+ ## Security boundary
153
+
154
+ The React app **selects and holds** inventory. Your trusted backend **inspects
155
+ and books** the hold after payment or order validation.
156
+
157
+ - Never ship a SeatLayer secret key in browser code or in a bundled environment
158
+ variable.
159
+ - Send only the `holdId` and your normal checkout context to your backend.
160
+ - Calculate the charge from server-inspected hold items, not from browser input.
161
+ - Reuse your stable order id as `bookingRef` so a retried booking is idempotent.
162
+ - Organizer surfaces take a short-lived, event-scoped `mse_` browser grant —
163
+ never a tenant `sk_` secret.
101
164
 
102
- The browser **holds**; your **server books** with a secret key — a browser never
103
- books directly. See
104
- [how the integration works](https://docs.seatlayer.io/start/how-it-works/).
165
+ Read [how the integration works](https://docs.seatlayer.io/start/how-it-works/)
166
+ before connecting checkout.
105
167
 
106
- Built on [`@seatlayer/js`](https://www.npmjs.com/package/@seatlayer/js).
168
+ ## Architecture
169
+
170
+ These components are a thin React layer over
171
+ [`@seatlayer/js`](https://www.npmjs.com/package/@seatlayer/js), the
172
+ framework-agnostic browser runtime. The wrapper mounts a plain `<div>`, builds
173
+ the chart inside an effect, forwards every prop and callback, and exposes the
174
+ runtime's imperative handle through `ref`. Chart geometry, availability, and
175
+ holds all come from the SeatLayer API at runtime, so the same event renders
176
+ identically on web and on the mobile SDKs.
177
+
178
+ Callback props are read through a ref, so changing one never tears the chart
179
+ down. Only the identity props listed above rebuild it.
107
180
 
108
181
  ## Embed the live control room
109
182
 
@@ -246,17 +319,143 @@ export function VenueEditor({ chartId }: { chartId: string }) {
246
319
  }
247
320
  ```
248
321
 
249
- ## Related resources
250
-
251
- - [Buyer SDK documentation](https://docs.seatlayer.io/buyer-sdk/install/)
252
- - [SeatPicker reference](https://docs.seatlayer.io/buyer-sdk/seat-picker/)
253
- - [Holds and checkout](https://docs.seatlayer.io/buyer-sdk/holds-and-checkout/)
254
- - [Complete checkout example](https://docs.seatlayer.io/examples/complete-checkout/)
255
- - [`@seatlayer/js`](https://www.npmjs.com/package/@seatlayer/js)
256
- - [React Native SDK](https://github.com/seatlayer/seatlayer-react-native)
257
- - [iOS SDK](https://github.com/seatlayer/seatlayer-ios)
258
- - [Flutter package](https://pub.dev/packages/seatlayer)
259
- - [Agent-readable documentation](https://docs.seatlayer.io/llms.txt)
322
+ ## SeatingChart imperative handle
323
+
324
+ Every method the runtime exposes to a wrapper, reachable through the `ref`:
325
+
326
+ `hold` · `resumeHold` · `getCurrentHold` · `getGAAreas` · `holdGA` ·
327
+ `bestAvailable` · `release` · `releaseLabels` · `getSelection` ·
328
+ `selectObjects` · `deselectObjects` · `clearSelection` · `selectCategories` ·
329
+ `deselectCategories` · `setSelectableObjects` · `setMaxSelection` ·
330
+ `getSelectionValidity` · `setSeatTier` · `getFloors` · `setFloor` ·
331
+ `setColorblindSafe` · `zoomIn` · `zoomOut` · `zoomToFit` · `refreshAccess`
332
+
333
+ Calling any of them before the chart exists returns an empty answer rather than
334
+ throwing, so a ref used one frame early is safe.
335
+
336
+ ## Callback props
337
+
338
+ | Prop | Payload |
339
+ | --- | --- |
340
+ | `onSelectionChange` | `SelectedSeat[]` |
341
+ | `onSelectionValidityChange` | Rule state with typed `violations` |
342
+ | `onSelectionValid` / `onSelectionInvalid` | Rule-validity transition |
343
+ | `onSelectionLimit` | Active numeric cap |
344
+ | `onHold` | `HoldResult` |
345
+ | `onHoldRestored` | `HoldResult` |
346
+ | `onHoldExpired` | — |
347
+ | `onGAClick` | `GAAreaAvailability` |
348
+ | `onError` | `unknown` |
349
+ | `onDeckTap` | `string` (floor id) |
350
+ | `onHint` | `string \| null` — `null` clears the hint |
351
+ | `onSeatHover` | `SeatHoverDetails \| null` — `null` when the pointer leaves |
352
+ | `onAccessExpired` | `BuyerAccessExpiredEvent` |
353
+ | `onAccessUnavailable` | `BuyerAccessUnavailableEvent` |
354
+ | `onSelectedObjectUnavailable` | `SelectedObjectUnavailableEvent` |
355
+
356
+ ## Frequently asked questions
357
+
358
+ ### How do I add a seat map to a React app?
359
+
360
+ Install `@seatlayer/react`, render `<SeatingChart event="ev_…" />` inside a
361
+ container with a definite height, and read the buyer's choice from
362
+ `onSelectionChange`. That is a complete interactive seating chart with live
363
+ availability; the quick start above is the whole integration, and the
364
+ [seat-picker documentation](https://docs.seatlayer.io/buyer-sdk/seat-picker/)
365
+ covers props, events, holds, and checkout in depth.
366
+
367
+ ### Is this a real React component or an iframe?
368
+
369
+ `SeatingChart`, `SeatPicker`, and `SeatManager` are real React components that
370
+ render a plain `<div>` into your own tree — no iframe, no portal, and no
371
+ stylesheet of their own to fight with. `EmbeddedDesigner` is the one exception:
372
+ the organizer Designer is deliberately hosted in a sandboxed iframe so no
373
+ Designer credential ever reaches your bundle. If you *want* an iframe for the
374
+ buyer picker, `attachPickerFrame` is exported for that.
375
+
376
+ ### What is the difference between `SeatPicker` and `SeatingChart`?
377
+
378
+ `SeatingChart` is the chart alone: it draws the venue, manages selection, and
379
+ hands you the seats — you build the surrounding UI. `SeatPicker` is the complete
380
+ buyer experience with legend, priced tray, hold timer, and checkout hand-off
381
+ already built. Start with `SeatPicker` if you want a working ticket flow today,
382
+ and drop to `SeatingChart` when your design system owns the chrome.
383
+
384
+ ### How do temporary seat holds work?
385
+
386
+ When a buyer commits to a selection, `hold()` reserves that inventory against
387
+ concurrent buyers for a limited checkout window and returns an opaque `holdId`.
388
+ The hold lapses on its own if checkout never completes — `onHoldExpired` tells
389
+ the app to return the buyer to the map — and `resumeHold()` restores it after a
390
+ same-tab checkout navigation or a reload. This is what prevents double-selling
391
+ without locking seats forever.
392
+
393
+ ### Can I use my own payment provider?
394
+
395
+ Yes. Nothing in this package takes a payment. The browser hands you a `holdId`
396
+ and a self-contained `CheckoutHandoff` with the priced line items, your backend
397
+ charges through whatever provider you already use, and it then books the hold
398
+ through the
399
+ [server-side checkout flow](https://docs.seatlayer.io/buyer-sdk/holds-and-checkout/).
400
+ The opt-in `checkout: 'hosted'` mode exists for hosts with no backend at all;
401
+ without it, no payment code is downloaded.
402
+
403
+ ### Can I evaluate it without a SeatLayer account?
404
+
405
+ You can explore a live seating chart in the browser at the
406
+ [buyer seat-map demo](https://app.seatlayer.io/demo/play/grand-theatre) with no
407
+ account. Rendering your own venue needs an event key, because the chart and its
408
+ availability are served by the SeatLayer API — create a free test event for
409
+ that, which books no real inventory.
410
+
411
+ ### Does it work with Next.js and other React frameworks?
412
+
413
+ Yes, on the client. The chart is built inside an effect and touches the DOM only
414
+ there, so a server render emits the empty container. This package ships no
415
+ `'use client'` banner of its own, so in the App Router mark your own component
416
+ that imports it, or load it through `next/dynamic` with `ssr: false`.
417
+
418
+ ## Continue your React integration
419
+
420
+ - [Follow the buyer SDK installation guide](https://docs.seatlayer.io/buyer-sdk/install/)
421
+ for the full browser integration, options, and events.
422
+ - [Connect seat holds to secure server-side checkout](https://docs.seatlayer.io/buyer-sdk/holds-and-checkout/)
423
+ without putting booking credentials in the browser.
424
+ - [Run the complete checkout example](https://docs.seatlayer.io/examples/complete-checkout/)
425
+ to connect a buyer hold id to payment and idempotent booking.
426
+ - [Compare SeatLayer's mobile seat map SDKs](https://docs.seatlayer.io/buyer-sdk/mobile/)
427
+ when the same event also has to render in native iOS, Android, Flutter, or
428
+ React Native apps.
429
+ - [Read the embedded Designer guide](https://docs.seatlayer.io/platform/embedded-designer/)
430
+ to let organizers draw their own venues inside your product.
431
+ - [Explore the 3D seating chart](https://seatlayer.io/3d-seat-map/) for the
432
+ interactive venue view buyers can switch to from the map.
433
+ - [Point AI coding agents at the SeatLayer docs index](https://docs.seatlayer.io/llms.txt)
434
+ (`llms.txt`) for an agent-readable map of the documentation.
435
+
436
+ ## SeatLayer SDK ecosystem
437
+
438
+ | Surface | Package or source |
439
+ | --- | --- |
440
+ | JavaScript | [`@seatlayer/js`](https://www.npmjs.com/package/@seatlayer/js) |
441
+ | React | [`@seatlayer/react`](https://www.npmjs.com/package/@seatlayer/react) (this package) |
442
+ | Vue | [`@seatlayer/vue`](https://www.npmjs.com/package/@seatlayer/vue) |
443
+ | Angular | [`@seatlayer/angular`](https://www.npmjs.com/package/@seatlayer/angular) |
444
+ | React Native | [`@seatlayer/react-native`](https://www.npmjs.com/package/@seatlayer/react-native) |
445
+ | iOS | [`seatlayer-ios`](https://github.com/seatlayer/seatlayer-ios) |
446
+ | Flutter | [`seatlayer`](https://pub.dev/packages/seatlayer) |
447
+ | Android | [`seatlayer-android`](https://github.com/seatlayer/seatlayer-android) |
448
+ | Server SDKs | [Node.js, Python, PHP, Ruby, .NET, Java, and Go](https://docs.seatlayer.io/server-sdk/install/) |
449
+
450
+ ## Development
451
+
452
+ ```bash
453
+ pnpm install
454
+ pnpm verify
455
+ ```
456
+
457
+ Source, issues, and contribution guidance live in
458
+ [seatlayer/seatlayer-sdk](https://github.com/seatlayer/seatlayer-sdk).
260
459
 
261
460
  ## License
262
461
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@seatlayer/react",
3
- "version": "0.65.0",
4
- "description": "React component for the SeatLayer embed SDK — render an interactive seat picker and hold seats.",
3
+ "version": "0.67.15",
4
+ "description": "SeatLayer's official React seating chart and seat map SDK — live availability, seat selection, temporary holds, and a typed TypeScript API for ticketing apps.",
5
5
  "license": "MIT",
6
6
  "author": {
7
7
  "name": "SeatLayer",
@@ -55,17 +55,26 @@
55
55
  ],
56
56
  "sideEffects": false,
57
57
  "keywords": [
58
- "seating",
58
+ "seat map",
59
+ "seating chart",
59
60
  "seat-map",
60
61
  "seating-chart",
61
62
  "seat-picker",
63
+ "seat-selection",
64
+ "seat-reservation",
65
+ "reserved-seating",
66
+ "seat-booking",
67
+ "event-ticketing",
68
+ "ticketing",
69
+ "live-inventory",
70
+ "seating",
62
71
  "seatlayer",
63
72
  "react",
64
- "ticketing"
73
+ "typescript"
65
74
  ],
66
75
  "dependencies": {
67
- "@seatlayer/core": "0.65.0",
68
- "@seatlayer/js": "0.65.0"
76
+ "@seatlayer/core": "0.67.15",
77
+ "@seatlayer/js": "0.67.15"
69
78
  },
70
79
  "peerDependencies": {
71
80
  "react": ">=17.0.0"