@nex125/seatmap-viewer 0.1.21 → 0.1.23

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.
package/dist/index.js CHANGED
@@ -1,903 +1,784 @@
1
- import { useMemo, useState, useRef, useEffect, useCallback } from 'react';
2
- import { AVAILABLE_STATUS_ID } from '@nex125/seatmap-core';
3
- import { useSelection, SeatmapCanvas, TooltipOverlay, SeatmapProvider } from '@nex125/seatmap-react';
4
- export { useSeatStatus } from '@nex125/seatmap-react';
5
- import { jsx, jsxs } from 'react/jsx-runtime';
6
-
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { AVAILABLE_STATUS_ID } from "@nex125/seatmap-core";
3
+ import { SeatmapCanvas, SeatmapProvider, TooltipOverlay, useSeatStatus, useSelection } from "@nex125/seatmap-react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
7
5
  // src/SeatmapViewer.tsx
8
- var defaultSeatmapViewerMessages = {
9
- uncategorizedCategoryName: "Uncategorized",
10
- sectionFallbackLabel: "Section",
11
- tableLabel: (tableLabel) => `Table ${tableLabel}`,
12
- tooltipSeatLabel: (rowLabel, seatLabel) => `Row ${rowLabel}, Seat ${seatLabel}`,
13
- tooltipStatusAvailable: "Available",
14
- tooltipPriceLabel: (price) => `Price: ${price}`,
15
- tooltipPriceUnavailable: "Price unavailable",
16
- legendAriaLabel: "Seatmap legend",
17
- legendStatusesTitle: "Seat statuses",
18
- legendPricesTitle: "Prices",
19
- cartChipLabel: (selectedCount) => `Cart (${selectedCount})`,
20
- cartAriaLabel: "Selected seats cart",
21
- cartHeaderTitle: "Selected seats cart",
22
- cartCloseLabel: "Close cart",
23
- cartEmptyState: "No seats selected yet.",
24
- cartGroupMeta: (count, unitPrice) => `${count} tickets - ${unitPrice} each`,
25
- cartGroupFee: (basePrice, serviceFee, serviceFeePercent) => serviceFeePercent ? `Base ${basePrice} + service fee ${serviceFee} (${serviceFeePercent})` : `Base ${basePrice} + service fee ${serviceFee}`,
26
- cartRemoveOneAriaLabel: (categoryName) => `Remove one seat from ${categoryName}`,
27
- cartAddOneAriaLabel: (categoryName) => `Add one seat to ${categoryName}`,
28
- cartRemoveSeatTitle: "Remove seat",
29
- cartRemoveSeatAriaLabel: (seatLabel) => `Remove seat ${seatLabel}`,
30
- cartServiceFeeSummary: (serviceFeeTotal) => `Service fee included: ${serviceFeeTotal}`,
31
- cartSummary: (count, totalCost) => `${count} seats - Total ${totalCost}`,
32
- cartProceedButton: "Proceed"
6
+ const defaultSeatmapViewerMessages = {
7
+ uncategorizedCategoryName: "Uncategorized",
8
+ sectionFallbackLabel: "Section",
9
+ tableLabel: (tableLabel) => `Table ${tableLabel}`,
10
+ tooltipSeatLabel: (rowLabel, seatLabel) => `Row ${rowLabel}, Seat ${seatLabel}`,
11
+ tooltipStatusAvailable: "Available",
12
+ tooltipPriceLabel: (price) => `Price: ${price}`,
13
+ tooltipPriceUnavailable: "Price unavailable",
14
+ legendAriaLabel: "Seatmap legend",
15
+ legendStatusesTitle: "Seat statuses",
16
+ legendPricesTitle: "Prices",
17
+ cartChipLabel: (selectedCount) => `Cart (${selectedCount})`,
18
+ cartAriaLabel: "Selected seats cart",
19
+ cartHeaderTitle: "Selected seats cart",
20
+ cartCloseLabel: "Close cart",
21
+ cartEmptyState: "No seats selected yet.",
22
+ cartGroupMeta: (count, unitPrice) => `${count} tickets - ${unitPrice} each`,
23
+ cartGroupFee: (basePrice, serviceFee, serviceFeePercent) => serviceFeePercent ? `Base ${basePrice} + service fee ${serviceFee} (${serviceFeePercent})` : `Base ${basePrice} + service fee ${serviceFee}`,
24
+ cartRemoveOneAriaLabel: (categoryName) => `Remove one seat from ${categoryName}`,
25
+ cartAddOneAriaLabel: (categoryName) => `Add one seat to ${categoryName}`,
26
+ cartRemoveSeatTitle: "Remove seat",
27
+ cartRemoveSeatAriaLabel: (seatLabel) => `Remove seat ${seatLabel}`,
28
+ cartServiceFeeSummary: (serviceFeeTotal) => `Service fee included: ${serviceFeeTotal}`,
29
+ cartSummary: (count, totalCost) => `${count} seats - Total ${totalCost}`,
30
+ cartProceedButton: "Proceed"
33
31
  };
34
32
  function getCategoryPriceBreakdown(category) {
35
- if (!category) {
36
- return { unitPrice: 0, baseUnitPrice: 0, serviceFee: 0 };
37
- }
38
- const baseUnitPrice = Number.isFinite(category.basePrice) ? category.basePrice : 0;
39
- const serviceFee = Number.isFinite(category.serviceFee) ? category.serviceFee : 0;
40
- if (category.isPriceOverridden && Number.isFinite(category.overriddenPrice)) {
41
- return {
42
- unitPrice: category.overriddenPrice ?? 0,
43
- baseUnitPrice,
44
- serviceFee
45
- };
46
- }
47
- if (Number.isFinite(category.backendPrice)) {
48
- return {
49
- unitPrice: category.backendPrice,
50
- baseUnitPrice,
51
- serviceFee
52
- };
53
- }
54
- return {
55
- unitPrice: baseUnitPrice + serviceFee,
56
- baseUnitPrice,
57
- serviceFee
58
- };
33
+ if (!category) return {
34
+ unitPrice: 0,
35
+ baseUnitPrice: 0,
36
+ serviceFee: 0
37
+ };
38
+ const baseUnitPrice = Number.isFinite(category.basePrice) ? category.basePrice : 0;
39
+ const serviceFee = Number.isFinite(category.serviceFee) ? category.serviceFee : 0;
40
+ if (category.isPriceOverridden && Number.isFinite(category.overriddenPrice)) return {
41
+ unitPrice: category.overriddenPrice ?? 0,
42
+ baseUnitPrice,
43
+ serviceFee
44
+ };
45
+ if (Number.isFinite(category.backendPrice)) return {
46
+ unitPrice: category.backendPrice,
47
+ baseUnitPrice,
48
+ serviceFee
49
+ };
50
+ return {
51
+ unitPrice: baseUnitPrice + serviceFee,
52
+ baseUnitPrice,
53
+ serviceFee
54
+ };
59
55
  }
60
56
  function formatPercent(value, locale) {
61
- return new Intl.NumberFormat(locale, {
62
- style: "percent",
63
- maximumFractionDigits: 2
64
- }).format(value);
57
+ return new Intl.NumberFormat(locale, {
58
+ style: "percent",
59
+ maximumFractionDigits: 2
60
+ }).format(value);
65
61
  }
66
62
  function formatMoney(value, locale, currency) {
67
- return new Intl.NumberFormat(locale, {
68
- style: "currency",
69
- currency
70
- }).format(value);
63
+ return new Intl.NumberFormat(locale, {
64
+ style: "currency",
65
+ currency
66
+ }).format(value);
71
67
  }
72
- function DefaultSeatmapViewerTooltip({
73
- data,
74
- locale,
75
- currency,
76
- messages
77
- }) {
78
- const statusLabel = data.statusName ?? (data.seat.status === AVAILABLE_STATUS_ID ? messages.tooltipStatusAvailable : data.seat.status);
79
- const priceLabel = typeof data.price === "number" ? messages.tooltipPriceLabel(formatMoney(data.price, locale, currency)) : messages.tooltipPriceUnavailable;
80
- return /* @__PURE__ */ jsxs(
81
- "div",
82
- {
83
- style: {
84
- background: "var(--seatmap-tooltip-surface, color-mix(in srgb, var(--seatmap-surface-container-low, #181818) 94%, transparent))",
85
- border: "1px solid var(--seatmap-tooltip-border, var(--seatmap-outline, #353331))",
86
- borderRadius: 10,
87
- padding: "8px 14px",
88
- color: "var(--seatmap-tooltip-text, var(--seatmap-on-surface, #e5e2e1))",
89
- fontSize: 13,
90
- fontFamily: "system-ui",
91
- pointerEvents: "none",
92
- whiteSpace: "nowrap"
93
- },
94
- children: [
95
- /* @__PURE__ */ jsx("div", { style: { fontWeight: 600, marginBottom: 2 }, children: data.section.label }),
96
- /* @__PURE__ */ jsx("div", { children: messages.tooltipSeatLabel(data.row.label, data.seat.label) }),
97
- /* @__PURE__ */ jsx(
98
- "div",
99
- {
100
- style: {
101
- color: "var(--seatmap-tooltip-muted-text, var(--seatmap-on-surface-variant, #9a9694))",
102
- fontSize: 12,
103
- marginTop: 2
104
- },
105
- children: statusLabel
106
- }
107
- ),
108
- /* @__PURE__ */ jsx(
109
- "div",
110
- {
111
- style: {
112
- color: "var(--seatmap-tooltip-muted-text, var(--seatmap-on-surface-variant, #9a9694))",
113
- fontSize: 12,
114
- marginTop: 2
115
- },
116
- children: priceLabel
117
- }
118
- )
119
- ]
120
- }
121
- );
68
+ function DefaultSeatmapViewerTooltip({ data, locale, currency, messages }) {
69
+ const statusLabel = data.statusName ?? (data.seat.status === AVAILABLE_STATUS_ID ? messages.tooltipStatusAvailable : data.seat.status);
70
+ const priceLabel = typeof data.price === "number" ? messages.tooltipPriceLabel(formatMoney(data.price, locale, currency)) : messages.tooltipPriceUnavailable;
71
+ return /* @__PURE__ */ jsxs("div", {
72
+ style: {
73
+ background: "var(--seatmap-tooltip-surface, color-mix(in srgb, var(--seatmap-surface-container-low, #181818) 94%, transparent))",
74
+ border: "1px solid var(--seatmap-tooltip-border, var(--seatmap-outline, #353331))",
75
+ borderRadius: 10,
76
+ padding: "8px 14px",
77
+ color: "var(--seatmap-tooltip-text, var(--seatmap-on-surface, #e5e2e1))",
78
+ fontSize: 13,
79
+ fontFamily: "system-ui",
80
+ pointerEvents: "none",
81
+ whiteSpace: "nowrap"
82
+ },
83
+ children: [
84
+ /* @__PURE__ */ jsx("div", {
85
+ style: {
86
+ fontWeight: 600,
87
+ marginBottom: 2
88
+ },
89
+ children: data.section.label
90
+ }),
91
+ /* @__PURE__ */ jsx("div", { children: messages.tooltipSeatLabel(data.row.label, data.seat.label) }),
92
+ /* @__PURE__ */ jsx("div", {
93
+ style: {
94
+ color: "var(--seatmap-tooltip-muted-text, var(--seatmap-on-surface-variant, #9a9694))",
95
+ fontSize: 12,
96
+ marginTop: 2
97
+ },
98
+ children: statusLabel
99
+ }),
100
+ /* @__PURE__ */ jsx("div", {
101
+ style: {
102
+ color: "var(--seatmap-tooltip-muted-text, var(--seatmap-on-surface-variant, #9a9694))",
103
+ fontSize: 12,
104
+ marginTop: 2
105
+ },
106
+ children: priceLabel
107
+ })
108
+ ]
109
+ });
122
110
  }
123
111
  function TrashIcon() {
124
- return /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
125
- "path",
126
- {
127
- d: "M9 3h6l1 2h4v2H4V5h4l1-2Zm1 7h2v8h-2v-8Zm4 0h2v8h-2v-8ZM7 10h2v8H7v-8Zm-1 12h12a2 2 0 0 0 2-2V8H4v12a2 2 0 0 0 2 2Z",
128
- fill: "currentColor"
129
- }
130
- ) });
112
+ return /* @__PURE__ */ jsx("svg", {
113
+ width: "12",
114
+ height: "12",
115
+ viewBox: "0 0 24 24",
116
+ fill: "none",
117
+ "aria-hidden": "true",
118
+ children: /* @__PURE__ */ jsx("path", {
119
+ d: "M9 3h6l1 2h4v2H4V5h4l1-2Zm1 7h2v8h-2v-8Zm4 0h2v8h-2v-8ZM7 10h2v8H7v-8Zm-1 12h12a2 2 0 0 0 2-2V8H4v12a2 2 0 0 0 2 2Z",
120
+ fill: "currentColor"
121
+ })
122
+ });
131
123
  }
132
124
  function mergeStyles(base, override) {
133
- if (!override) return base;
134
- return { ...base, ...override };
125
+ if (!override) return base;
126
+ return {
127
+ ...base,
128
+ ...override
129
+ };
135
130
  }
136
131
  function mergeClassNames(...classNames) {
137
- const merged = classNames.filter(Boolean).join(" ").trim();
138
- return merged.length > 0 ? merged : void 0;
132
+ const merged = classNames.filter(Boolean).join(" ").trim();
133
+ return merged.length > 0 ? merged : void 0;
139
134
  }
140
- function SeatmapViewerContent({
141
- venue,
142
- onSeatClick,
143
- onSeatHover,
144
- onSelectionChange,
145
- renderTooltip,
146
- showLabels,
147
- onCartEvent,
148
- locale = "en-US",
149
- currency = "BYN",
150
- styles = {},
151
- classNames = {},
152
- messages: messagesOverride = {}
153
- }) {
154
- const messages = useMemo(
155
- () => ({ ...defaultSeatmapViewerMessages, ...messagesOverride }),
156
- [messagesOverride]
157
- );
158
- const { selectedSeatIds, setSelection } = useSelection();
159
- const [isCartOpen, setIsCartOpen] = useState(false);
160
- const [lastUserAnchorByCategory, setLastUserAnchorByCategory] = useState({});
161
- const [viewportWidth, setViewportWidth] = useState(
162
- () => typeof window === "undefined" ? 1280 : window.innerWidth
163
- );
164
- const previousSelectedRef = useRef([]);
165
- const pendingSeatClickRef = useRef(null);
166
- const showStatuses = venue.seatStatuses.length > 0;
167
- const showCategories = venue.categories.length > 0;
168
- const selectedSeatIdArray = useMemo(() => Array.from(selectedSeatIds), [selectedSeatIds]);
169
- const seatDetailsById = useMemo(() => {
170
- const categoryMap = new Map(venue.categories.map((category) => [category.id, category]));
171
- const next = /* @__PURE__ */ new Map();
172
- for (const section of venue.sections) {
173
- const cos = Math.cos(section.rotation);
174
- const sin = Math.sin(section.rotation);
175
- for (const row of section.rows) {
176
- for (const seat of row.seats) {
177
- const category = categoryMap.get(seat.categoryId);
178
- const priceBreakdown = getCategoryPriceBreakdown(category);
179
- next.set(seat.id, {
180
- seatId: seat.id,
181
- seatLabel: seat.label,
182
- rowLabel: row.label,
183
- sectionId: section.id,
184
- sectionLabel: section.label,
185
- categoryId: seat.categoryId,
186
- categoryName: category?.name ?? messages.uncategorizedCategoryName,
187
- unitPrice: priceBreakdown.unitPrice,
188
- baseUnitPrice: priceBreakdown.baseUnitPrice,
189
- serviceFee: priceBreakdown.serviceFee,
190
- status: seat.status,
191
- x: section.position.x + seat.position.x * cos - seat.position.y * sin,
192
- y: section.position.y + seat.position.x * sin + seat.position.y * cos
193
- });
194
- }
195
- }
196
- }
197
- for (const table of venue.tables) {
198
- for (const seat of table.seats) {
199
- const category = categoryMap.get(seat.categoryId);
200
- const priceBreakdown = getCategoryPriceBreakdown(category);
201
- next.set(seat.id, {
202
- seatId: seat.id,
203
- seatLabel: seat.label,
204
- rowLabel: null,
205
- sectionId: table.id,
206
- sectionLabel: messages.tableLabel(table.label),
207
- categoryId: seat.categoryId,
208
- categoryName: category?.name ?? messages.uncategorizedCategoryName,
209
- unitPrice: priceBreakdown.unitPrice,
210
- baseUnitPrice: priceBreakdown.baseUnitPrice,
211
- serviceFee: priceBreakdown.serviceFee,
212
- status: seat.status,
213
- x: table.position.x + seat.position.x,
214
- y: table.position.y + seat.position.y
215
- });
216
- }
217
- }
218
- return next;
219
- }, [venue, messages]);
220
- const selectedSeats = useMemo(() => {
221
- const ordered = [];
222
- for (const selectedSeatId of selectedSeatIdArray) {
223
- const seat = seatDetailsById.get(selectedSeatId);
224
- if (seat) ordered.push(seat);
225
- }
226
- return ordered;
227
- }, [seatDetailsById, selectedSeatIdArray]);
228
- useEffect(() => {
229
- onSelectionChange?.(selectedSeatIdArray);
230
- }, [onSelectionChange, selectedSeatIdArray]);
231
- useEffect(() => {
232
- const previous = new Set(previousSelectedRef.current);
233
- const added = selectedSeatIdArray.filter((seatId) => !previous.has(seatId));
234
- const clickedSeatId = pendingSeatClickRef.current;
235
- if (clickedSeatId && added.includes(clickedSeatId)) {
236
- const clickedSeat = seatDetailsById.get(clickedSeatId);
237
- if (clickedSeat) {
238
- setLastUserAnchorByCategory((current) => ({
239
- ...current,
240
- [clickedSeat.categoryId]: clickedSeatId
241
- }));
242
- }
243
- }
244
- previousSelectedRef.current = selectedSeatIdArray;
245
- pendingSeatClickRef.current = null;
246
- }, [seatDetailsById, selectedSeatIdArray]);
247
- useEffect(() => {
248
- if (typeof window === "undefined") return;
249
- const onResize = () => setViewportWidth(window.innerWidth);
250
- window.addEventListener("resize", onResize);
251
- return () => window.removeEventListener("resize", onResize);
252
- }, []);
253
- const cartSeats = useMemo(
254
- () => selectedSeats.map((seat) => ({
255
- seatId: seat.seatId,
256
- seatLabel: seat.seatLabel,
257
- rowLabel: seat.rowLabel,
258
- sectionId: seat.sectionId,
259
- sectionLabel: seat.sectionLabel,
260
- categoryId: seat.categoryId,
261
- categoryName: seat.categoryName,
262
- unitPrice: seat.unitPrice,
263
- baseUnitPrice: seat.baseUnitPrice,
264
- serviceFee: seat.serviceFee
265
- })),
266
- [selectedSeats]
267
- );
268
- const totalSelectedSeats = useMemo(() => cartSeats.length, [cartSeats]);
269
- const totalCost = useMemo(() => cartSeats.reduce((sum, seat) => sum + seat.unitPrice, 0), [cartSeats]);
270
- const totalServiceFee = useMemo(() => cartSeats.reduce((sum, seat) => sum + seat.serviceFee, 0), [cartSeats]);
271
- const effectiveTooltipRenderer = useCallback(
272
- (data) => {
273
- if (renderTooltip) {
274
- return renderTooltip(data);
275
- }
276
- return /* @__PURE__ */ jsx(
277
- DefaultSeatmapViewerTooltip,
278
- {
279
- data,
280
- locale,
281
- currency,
282
- messages
283
- }
284
- );
285
- },
286
- [currency, locale, messages, renderTooltip]
287
- );
288
- const groupedSeatsList = useMemo(() => {
289
- const grouped = /* @__PURE__ */ new Map();
290
- for (const seat of cartSeats) {
291
- const existing = grouped.get(seat.categoryId);
292
- if (existing) {
293
- existing.seats.push(seat);
294
- } else {
295
- grouped.set(seat.categoryId, {
296
- categoryName: seat.categoryName,
297
- unitPrice: seat.unitPrice,
298
- baseUnitPrice: seat.baseUnitPrice,
299
- serviceFee: seat.serviceFee,
300
- seats: [seat]
301
- });
302
- }
303
- }
304
- const ordered = [];
305
- const selectedSet = new Set(selectedSeatIdArray);
306
- const availableToAddByCategory = /* @__PURE__ */ new Map();
307
- for (const seat of seatDetailsById.values()) {
308
- if (seat.status !== AVAILABLE_STATUS_ID || selectedSet.has(seat.seatId)) continue;
309
- availableToAddByCategory.set(
310
- seat.categoryId,
311
- (availableToAddByCategory.get(seat.categoryId) ?? 0) + 1
312
- );
313
- }
314
- for (const category of venue.categories) {
315
- const group = grouped.get(category.id);
316
- if (!group) continue;
317
- ordered.push({
318
- categoryId: category.id,
319
- categoryName: group.categoryName,
320
- unitPrice: group.unitPrice,
321
- baseUnitPrice: group.baseUnitPrice,
322
- serviceFee: group.serviceFee,
323
- seats: group.seats,
324
- availableToAdd: availableToAddByCategory.get(category.id) ?? 0
325
- });
326
- }
327
- for (const [categoryId, group] of grouped.entries()) {
328
- if (venue.categories.some((category) => category.id === categoryId)) continue;
329
- ordered.push({
330
- categoryId,
331
- categoryName: group.categoryName,
332
- unitPrice: group.unitPrice,
333
- baseUnitPrice: group.baseUnitPrice,
334
- serviceFee: group.serviceFee,
335
- seats: group.seats,
336
- availableToAdd: availableToAddByCategory.get(categoryId) ?? 0
337
- });
338
- }
339
- return ordered;
340
- }, [cartSeats, seatDetailsById, selectedSeatIdArray, venue.categories]);
341
- const cartPayload = useMemo(
342
- () => ({
343
- venueId: venue.id,
344
- venueName: venue.name,
345
- seats: cartSeats,
346
- totalSelectedSeats,
347
- totalCost
348
- }),
349
- [venue.id, venue.name, cartSeats, totalSelectedSeats, totalCost]
350
- );
351
- const emitCartEvent = useCallback(
352
- (event) => {
353
- onCartEvent?.(event);
354
- },
355
- [onCartEvent]
356
- );
357
- const removeSeatFromSelection = useCallback(
358
- (seatId) => {
359
- const seat = seatDetailsById.get(seatId);
360
- if (seat?.sectionId) {
361
- onSeatClick?.(seatId, seat.sectionId);
362
- }
363
- const next = selectedSeatIdArray.filter((id) => id !== seatId);
364
- setSelection(next);
365
- },
366
- [seatDetailsById, onSeatClick, selectedSeatIdArray, setSelection]
367
- );
368
- const handleSeatCanvasClick = useCallback(
369
- (seatId, sectionId) => {
370
- pendingSeatClickRef.current = seatId;
371
- onSeatClick?.(seatId, sectionId);
372
- },
373
- [onSeatClick]
374
- );
375
- const handleAddSeatInCategory = useCallback(
376
- (categoryId) => {
377
- const selectedSet = new Set(selectedSeatIdArray);
378
- const selectedInCategory = selectedSeatIdArray.filter(
379
- (selectedSeatId) => seatDetailsById.get(selectedSeatId)?.categoryId === categoryId
380
- );
381
- const anchorSeatId = (lastUserAnchorByCategory[categoryId] && seatDetailsById.has(lastUserAnchorByCategory[categoryId]) ? lastUserAnchorByCategory[categoryId] : null) ?? selectedInCategory[selectedInCategory.length - 1] ?? null;
382
- const anchorSeat = anchorSeatId ? seatDetailsById.get(anchorSeatId) : null;
383
- const candidates = Array.from(seatDetailsById.values()).filter(
384
- (seat) => seat.categoryId === categoryId && seat.status === AVAILABLE_STATUS_ID && !selectedSet.has(seat.seatId)
385
- );
386
- if (candidates.length === 0) return;
387
- let nextSeat = candidates[0];
388
- if (anchorSeat) {
389
- nextSeat = candidates.reduce((best, candidate) => {
390
- const bestDistance = (best.x - anchorSeat.x) ** 2 + (best.y - anchorSeat.y) ** 2;
391
- const candidateDistance = (candidate.x - anchorSeat.x) ** 2 + (candidate.y - anchorSeat.y) ** 2;
392
- return candidateDistance < bestDistance ? candidate : best;
393
- }, candidates[0]);
394
- }
395
- setSelection([...selectedSeatIdArray, nextSeat.seatId]);
396
- if (nextSeat.sectionId) {
397
- onSeatClick?.(nextSeat.seatId, nextSeat.sectionId);
398
- }
399
- },
400
- [lastUserAnchorByCategory, seatDetailsById, selectedSeatIdArray, setSelection, onSeatClick]
401
- );
402
- const handleRemoveLastInCategory = useCallback(
403
- (categoryId) => {
404
- const selectedInCategory = selectedSeatIdArray.filter(
405
- (selectedSeatId) => seatDetailsById.get(selectedSeatId)?.categoryId === categoryId
406
- );
407
- const seatIdToRemove = selectedInCategory[selectedInCategory.length - 1];
408
- if (!seatIdToRemove) return;
409
- const seat = seatDetailsById.get(seatIdToRemove);
410
- if (seat?.sectionId) {
411
- onSeatClick?.(seatIdToRemove, seat.sectionId);
412
- }
413
- setSelection(selectedSeatIdArray.filter((selectedSeatId) => selectedSeatId !== seatIdToRemove));
414
- },
415
- [seatDetailsById, selectedSeatIdArray, setSelection, onSeatClick]
416
- );
417
- const handleProceed = useCallback(() => {
418
- if (cartPayload.seats.length === 0) return;
419
- emitCartEvent({ type: "cart-proceed-clicked", payload: cartPayload });
420
- }, [cartPayload, emitCartEvent]);
421
- const cartWidth = viewportWidth > 1200 ? Math.floor(viewportWidth / 5) : viewportWidth;
422
- return /* @__PURE__ */ jsxs(
423
- "div",
424
- {
425
- className: classNames.root,
426
- style: mergeStyles({ width: "100%", height: "100%", position: "relative" }, styles.root),
427
- children: [
428
- /* @__PURE__ */ jsx(
429
- SeatmapCanvas,
430
- {
431
- onSeatClick: handleSeatCanvasClick,
432
- onSeatHover,
433
- showSectionLabels: showLabels,
434
- enableSeatHover: showLabels
435
- }
436
- ),
437
- (showStatuses || showCategories) && /* @__PURE__ */ jsxs(
438
- "aside",
439
- {
440
- "aria-label": messages.legendAriaLabel,
441
- className: mergeClassNames("seatmap-viewer__legend", classNames.legendContainer),
442
- style: styles.legendContainer,
443
- children: [
444
- showStatuses && /* @__PURE__ */ jsxs("section", { className: "seatmap-viewer__legend-section", children: [
445
- /* @__PURE__ */ jsx("p", { className: mergeClassNames("seatmap-viewer__legend-heading-base", classNames.legendHeading), style: styles.legendHeading, children: messages.legendStatusesTitle }),
446
- /* @__PURE__ */ jsx("ul", { className: mergeClassNames("seatmap-viewer__legend-list-base", classNames.legendList), style: styles.legendList, children: venue.seatStatuses.map((status) => /* @__PURE__ */ jsxs("li", { className: mergeClassNames("seatmap-viewer__legend-item-base", classNames.legendItem), style: styles.legendItem, children: [
447
- /* @__PURE__ */ jsx(
448
- "span",
449
- {
450
- className: mergeClassNames("seatmap-viewer__legend-swatch-base", classNames.legendSwatch),
451
- style: mergeStyles({ background: status.color }, styles.legendSwatch)
452
- }
453
- ),
454
- /* @__PURE__ */ jsx("span", { children: status.name })
455
- ] }, status.id)) })
456
- ] }),
457
- showStatuses && showCategories && /* @__PURE__ */ jsx(
458
- "div",
459
- {
460
- className: mergeClassNames("seatmap-viewer__legend-divider-base", classNames.legendDivider),
461
- style: styles.legendDivider
462
- }
463
- ),
464
- showCategories && /* @__PURE__ */ jsxs("section", { className: "seatmap-viewer__legend-section", children: [
465
- /* @__PURE__ */ jsx("p", { className: mergeClassNames("seatmap-viewer__legend-heading-base", classNames.legendHeading), style: styles.legendHeading, children: messages.legendPricesTitle }),
466
- /* @__PURE__ */ jsx("ul", { className: mergeClassNames("seatmap-viewer__legend-list-base", classNames.legendList), style: styles.legendList, children: venue.categories.map((category) => /* @__PURE__ */ jsxs("li", { className: mergeClassNames("seatmap-viewer__legend-item-base", classNames.legendItem), style: styles.legendItem, children: [
467
- /* @__PURE__ */ jsx(
468
- "span",
469
- {
470
- className: mergeClassNames("seatmap-viewer__legend-swatch-base", classNames.legendSwatch),
471
- style: mergeStyles({ background: category.color }, styles.legendSwatch)
472
- }
473
- ),
474
- /* @__PURE__ */ jsx("span", { children: category.name })
475
- ] }, category.id)) })
476
- ] })
477
- ]
478
- }
479
- ),
480
- !isCartOpen && /* @__PURE__ */ jsx(
481
- "button",
482
- {
483
- type: "button",
484
- className: mergeClassNames("seatmap-viewer__cart-chip-base", classNames.cartChip),
485
- onClick: () => setIsCartOpen(true),
486
- style: styles.cartChip,
487
- children: messages.cartChipLabel(totalSelectedSeats)
488
- }
489
- ),
490
- isCartOpen && /* @__PURE__ */ jsxs(
491
- "aside",
492
- {
493
- "aria-label": messages.cartAriaLabel,
494
- className: mergeClassNames("seatmap-viewer__cart-popup-base", classNames.cartPopup),
495
- style: mergeStyles({ width: cartWidth, maxWidth: "100%" }, styles.cartPopup),
496
- children: [
497
- /* @__PURE__ */ jsxs(
498
- "div",
499
- {
500
- className: mergeClassNames("seatmap-viewer__cart-header-base", classNames.cartHeader),
501
- style: styles.cartHeader,
502
- children: [
503
- /* @__PURE__ */ jsx(
504
- "strong",
505
- {
506
- className: mergeClassNames("seatmap-viewer__cart-header-title-base", classNames.cartHeaderTitle),
507
- style: styles.cartHeaderTitle,
508
- children: messages.cartHeaderTitle
509
- }
510
- ),
511
- /* @__PURE__ */ jsx(
512
- "button",
513
- {
514
- type: "button",
515
- onClick: () => setIsCartOpen(false),
516
- className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
517
- style: styles.cartIconButton,
518
- title: messages.cartCloseLabel,
519
- "aria-label": messages.cartCloseLabel,
520
- children: "x"
521
- }
522
- )
523
- ]
524
- }
525
- ),
526
- /* @__PURE__ */ jsx(
527
- "div",
528
- {
529
- className: mergeClassNames("seatmap-viewer__cart-body-base", classNames.cartBody),
530
- style: styles.cartBody,
531
- children: groupedSeatsList.length === 0 ? /* @__PURE__ */ jsx(
532
- "div",
533
- {
534
- className: mergeClassNames("seatmap-viewer__cart-empty-state-base", classNames.cartEmptyState),
535
- style: styles.cartEmptyState,
536
- children: messages.cartEmptyState
537
- }
538
- ) : groupedSeatsList.map((group) => /* @__PURE__ */ jsxs(
539
- "article",
540
- {
541
- className: mergeClassNames("seatmap-viewer__cart-group-base", classNames.cartGroup),
542
- style: styles.cartGroup,
543
- children: [
544
- /* @__PURE__ */ jsx(
545
- "div",
546
- {
547
- className: mergeClassNames("seatmap-viewer__cart-group-title-base", classNames.cartGroupTitle),
548
- style: styles.cartGroupTitle,
549
- children: group.categoryName
550
- }
551
- ),
552
- /* @__PURE__ */ jsx(
553
- "div",
554
- {
555
- className: mergeClassNames("seatmap-viewer__cart-group-meta-base", classNames.cartGroupMeta),
556
- style: styles.cartGroupMeta,
557
- children: messages.cartGroupMeta(group.seats.length, formatMoney(group.unitPrice, locale, currency))
558
- }
559
- ),
560
- group.serviceFee > 0 && /* @__PURE__ */ jsx(
561
- "div",
562
- {
563
- className: mergeClassNames("seatmap-viewer__cart-group-meta-base", classNames.cartGroupMeta),
564
- style: styles.cartGroupMeta,
565
- children: messages.cartGroupFee(
566
- formatMoney(group.baseUnitPrice, locale, currency),
567
- formatMoney(group.serviceFee, locale, currency),
568
- group.baseUnitPrice > 0 ? formatPercent(group.serviceFee / group.baseUnitPrice, locale) : null
569
- )
570
- }
571
- ),
572
- /* @__PURE__ */ jsxs("div", { className: mergeClassNames("seatmap-viewer__cart-quantity-row-base", classNames.cartQuantityRow), style: styles.cartQuantityRow, children: [
573
- /* @__PURE__ */ jsxs("div", { className: "seatmap-viewer__cart-quantity-controls", children: [
574
- /* @__PURE__ */ jsx(
575
- "button",
576
- {
577
- type: "button",
578
- className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
579
- style: styles.cartIconButton,
580
- onClick: () => handleRemoveLastInCategory(group.categoryId),
581
- disabled: group.seats.length === 0,
582
- "aria-label": messages.cartRemoveOneAriaLabel(group.categoryName),
583
- children: "-"
584
- }
585
- ),
586
- /* @__PURE__ */ jsx(
587
- "span",
588
- {
589
- className: mergeClassNames("seatmap-viewer__cart-quantity-value-base", classNames.cartQuantityValue),
590
- style: styles.cartQuantityValue,
591
- children: group.seats.length
592
- }
593
- ),
594
- /* @__PURE__ */ jsx(
595
- "button",
596
- {
597
- type: "button",
598
- className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
599
- style: styles.cartIconButton,
600
- onClick: () => handleAddSeatInCategory(group.categoryId),
601
- disabled: group.availableToAdd === 0,
602
- "aria-label": messages.cartAddOneAriaLabel(group.categoryName),
603
- children: "+"
604
- }
605
- )
606
- ] }),
607
- /* @__PURE__ */ jsx(
608
- "span",
609
- {
610
- className: mergeClassNames("seatmap-viewer__cart-group-total-base", classNames.cartGroupTotal),
611
- style: styles.cartGroupTotal,
612
- children: formatMoney(group.seats.reduce((sum, seat) => sum + seat.unitPrice, 0), locale, currency)
613
- }
614
- )
615
- ] }),
616
- /* @__PURE__ */ jsx("div", { className: "seatmap-viewer__cart-seat-list", children: group.seats.map((seat) => /* @__PURE__ */ jsxs(
617
- "div",
618
- {
619
- className: mergeClassNames("seatmap-viewer__cart-seat-row-base", classNames.cartSeatRow),
620
- style: styles.cartSeatRow,
621
- children: [
622
- /* @__PURE__ */ jsxs(
623
- "span",
624
- {
625
- className: mergeClassNames("seatmap-viewer__cart-seat-label-base", classNames.cartSeatLabel),
626
- style: styles.cartSeatLabel,
627
- children: [
628
- seat.sectionLabel ?? messages.sectionFallbackLabel,
629
- " ",
630
- seat.rowLabel ? `- ${seat.rowLabel}${seat.seatLabel}` : `- ${seat.seatLabel}`
631
- ]
632
- }
633
- ),
634
- /* @__PURE__ */ jsx(
635
- "button",
636
- {
637
- type: "button",
638
- className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
639
- style: styles.cartIconButton,
640
- onClick: () => removeSeatFromSelection(seat.seatId),
641
- title: messages.cartRemoveSeatTitle,
642
- "aria-label": messages.cartRemoveSeatAriaLabel(seat.seatLabel),
643
- children: /* @__PURE__ */ jsx(TrashIcon, {})
644
- }
645
- )
646
- ]
647
- },
648
- seat.seatId
649
- )) })
650
- ]
651
- },
652
- group.categoryId
653
- ))
654
- }
655
- ),
656
- /* @__PURE__ */ jsxs(
657
- "div",
658
- {
659
- className: mergeClassNames("seatmap-viewer__cart-footer-base", classNames.cartFooter),
660
- style: styles.cartFooter,
661
- children: [
662
- /* @__PURE__ */ jsxs(
663
- "div",
664
- {
665
- className: mergeClassNames("seatmap-viewer__cart-summary-base", classNames.cartSummary),
666
- style: styles.cartSummary,
667
- children: [
668
- totalServiceFee > 0 && /* @__PURE__ */ jsx("div", { children: messages.cartServiceFeeSummary(formatMoney(totalServiceFee, locale, currency)) }),
669
- /* @__PURE__ */ jsx("div", { children: messages.cartSummary(totalSelectedSeats, formatMoney(totalCost, locale, currency)) })
670
- ]
671
- }
672
- ),
673
- /* @__PURE__ */ jsx(
674
- "button",
675
- {
676
- type: "button",
677
- disabled: cartSeats.length === 0,
678
- onClick: handleProceed,
679
- className: mergeClassNames("seatmap-viewer__cart-proceed-button-base", classNames.cartProceedButton),
680
- style: styles.cartProceedButton,
681
- children: messages.cartProceedButton
682
- }
683
- )
684
- ]
685
- }
686
- )
687
- ]
688
- }
689
- ),
690
- showLabels && /* @__PURE__ */ jsx(TooltipOverlay, { renderTooltip: effectiveTooltipRenderer })
691
- ]
692
- }
693
- );
135
+ function SeatmapViewerContent({ venue, onSeatClick, onSeatHover, onSelectionChange, renderTooltip, showLabels, onCartEvent, locale = "en-US", currency = "BYN", maxSelectedSeats, styles = {}, classNames = {}, messages: messagesOverride = {} }) {
136
+ const messages = useMemo(() => ({
137
+ ...defaultSeatmapViewerMessages,
138
+ ...messagesOverride
139
+ }), [messagesOverride]);
140
+ const { selectedSeatIds, setSelection } = useSelection();
141
+ const [isCartOpen, setIsCartOpen] = useState(false);
142
+ const [lastUserAnchorByCategory, setLastUserAnchorByCategory] = useState({});
143
+ const [viewportWidth, setViewportWidth] = useState(() => typeof window === "undefined" ? 1280 : window.innerWidth);
144
+ const previousSelectedRef = useRef([]);
145
+ const pendingSeatClickRef = useRef(null);
146
+ const showStatuses = venue.seatStatuses.length > 0;
147
+ const showCategories = venue.categories.length > 0;
148
+ const selectedSeatIdArray = useMemo(() => Array.from(selectedSeatIds), [selectedSeatIds]);
149
+ const seatDetailsById = useMemo(() => {
150
+ const categoryMap = new Map(venue.categories.map((category) => [category.id, category]));
151
+ const next = /* @__PURE__ */ new Map();
152
+ for (const section of venue.sections) {
153
+ const cos = Math.cos(section.rotation);
154
+ const sin = Math.sin(section.rotation);
155
+ for (const row of section.rows) for (const seat of row.seats) {
156
+ const category = categoryMap.get(seat.categoryId);
157
+ const priceBreakdown = getCategoryPriceBreakdown(category);
158
+ next.set(seat.id, {
159
+ seatId: seat.id,
160
+ seatLabel: seat.label,
161
+ rowLabel: row.label,
162
+ sectionId: section.id,
163
+ sectionLabel: section.label,
164
+ categoryId: seat.categoryId,
165
+ categoryName: category?.name ?? messages.uncategorizedCategoryName,
166
+ unitPrice: priceBreakdown.unitPrice,
167
+ baseUnitPrice: priceBreakdown.baseUnitPrice,
168
+ serviceFee: priceBreakdown.serviceFee,
169
+ status: seat.status,
170
+ x: section.position.x + seat.position.x * cos - seat.position.y * sin,
171
+ y: section.position.y + seat.position.x * sin + seat.position.y * cos
172
+ });
173
+ }
174
+ }
175
+ for (const table of venue.tables) for (const seat of table.seats) {
176
+ const category = categoryMap.get(seat.categoryId);
177
+ const priceBreakdown = getCategoryPriceBreakdown(category);
178
+ next.set(seat.id, {
179
+ seatId: seat.id,
180
+ seatLabel: seat.label,
181
+ rowLabel: null,
182
+ sectionId: table.id,
183
+ sectionLabel: messages.tableLabel(table.label),
184
+ categoryId: seat.categoryId,
185
+ categoryName: category?.name ?? messages.uncategorizedCategoryName,
186
+ unitPrice: priceBreakdown.unitPrice,
187
+ baseUnitPrice: priceBreakdown.baseUnitPrice,
188
+ serviceFee: priceBreakdown.serviceFee,
189
+ status: seat.status,
190
+ x: table.position.x + seat.position.x,
191
+ y: table.position.y + seat.position.y
192
+ });
193
+ }
194
+ return next;
195
+ }, [venue, messages]);
196
+ const selectedSeats = useMemo(() => {
197
+ const ordered = [];
198
+ for (const selectedSeatId of selectedSeatIdArray) {
199
+ const seat = seatDetailsById.get(selectedSeatId);
200
+ if (seat) ordered.push(seat);
201
+ }
202
+ return ordered;
203
+ }, [seatDetailsById, selectedSeatIdArray]);
204
+ useEffect(() => {
205
+ onSelectionChange?.(selectedSeatIdArray);
206
+ }, [onSelectionChange, selectedSeatIdArray]);
207
+ useEffect(() => {
208
+ const previous = new Set(previousSelectedRef.current);
209
+ const added = selectedSeatIdArray.filter((seatId) => !previous.has(seatId));
210
+ const clickedSeatId = pendingSeatClickRef.current;
211
+ if (clickedSeatId && added.includes(clickedSeatId)) {
212
+ const clickedSeat = seatDetailsById.get(clickedSeatId);
213
+ if (clickedSeat) setLastUserAnchorByCategory((current) => ({
214
+ ...current,
215
+ [clickedSeat.categoryId]: clickedSeatId
216
+ }));
217
+ }
218
+ previousSelectedRef.current = selectedSeatIdArray;
219
+ pendingSeatClickRef.current = null;
220
+ }, [seatDetailsById, selectedSeatIdArray]);
221
+ useEffect(() => {
222
+ if (typeof window === "undefined") return;
223
+ const onResize = () => setViewportWidth(window.innerWidth);
224
+ window.addEventListener("resize", onResize);
225
+ return () => window.removeEventListener("resize", onResize);
226
+ }, []);
227
+ const cartSeats = useMemo(() => selectedSeats.map((seat) => ({
228
+ seatId: seat.seatId,
229
+ seatLabel: seat.seatLabel,
230
+ rowLabel: seat.rowLabel,
231
+ sectionId: seat.sectionId,
232
+ sectionLabel: seat.sectionLabel,
233
+ categoryId: seat.categoryId,
234
+ categoryName: seat.categoryName,
235
+ unitPrice: seat.unitPrice,
236
+ baseUnitPrice: seat.baseUnitPrice,
237
+ serviceFee: seat.serviceFee
238
+ })), [selectedSeats]);
239
+ const totalSelectedSeats = useMemo(() => cartSeats.length, [cartSeats]);
240
+ const isSelectionOverLimit = typeof maxSelectedSeats === "number" && totalSelectedSeats > maxSelectedSeats;
241
+ const totalCost = useMemo(() => cartSeats.reduce((sum, seat) => sum + seat.unitPrice, 0), [cartSeats]);
242
+ const totalServiceFee = useMemo(() => cartSeats.reduce((sum, seat) => sum + seat.serviceFee, 0), [cartSeats]);
243
+ const effectiveTooltipRenderer = useCallback((data) => {
244
+ if (renderTooltip) return renderTooltip(data);
245
+ return /* @__PURE__ */ jsx(DefaultSeatmapViewerTooltip, {
246
+ data,
247
+ locale,
248
+ currency,
249
+ messages
250
+ });
251
+ }, [
252
+ currency,
253
+ locale,
254
+ messages,
255
+ renderTooltip
256
+ ]);
257
+ const groupedSeatsList = useMemo(() => {
258
+ const grouped = /* @__PURE__ */ new Map();
259
+ for (const seat of cartSeats) {
260
+ const existing = grouped.get(seat.categoryId);
261
+ if (existing) existing.seats.push(seat);
262
+ else grouped.set(seat.categoryId, {
263
+ categoryName: seat.categoryName,
264
+ unitPrice: seat.unitPrice,
265
+ baseUnitPrice: seat.baseUnitPrice,
266
+ serviceFee: seat.serviceFee,
267
+ seats: [seat]
268
+ });
269
+ }
270
+ const ordered = [];
271
+ const selectedSet = new Set(selectedSeatIdArray);
272
+ const availableToAddByCategory = /* @__PURE__ */ new Map();
273
+ for (const seat of seatDetailsById.values()) {
274
+ if (seat.status !== AVAILABLE_STATUS_ID || selectedSet.has(seat.seatId)) continue;
275
+ availableToAddByCategory.set(seat.categoryId, (availableToAddByCategory.get(seat.categoryId) ?? 0) + 1);
276
+ }
277
+ for (const category of venue.categories) {
278
+ const group = grouped.get(category.id);
279
+ if (!group) continue;
280
+ ordered.push({
281
+ categoryId: category.id,
282
+ categoryName: group.categoryName,
283
+ unitPrice: group.unitPrice,
284
+ baseUnitPrice: group.baseUnitPrice,
285
+ serviceFee: group.serviceFee,
286
+ seats: group.seats,
287
+ availableToAdd: availableToAddByCategory.get(category.id) ?? 0
288
+ });
289
+ }
290
+ for (const [categoryId, group] of grouped.entries()) {
291
+ if (venue.categories.some((category) => category.id === categoryId)) continue;
292
+ ordered.push({
293
+ categoryId,
294
+ categoryName: group.categoryName,
295
+ unitPrice: group.unitPrice,
296
+ baseUnitPrice: group.baseUnitPrice,
297
+ serviceFee: group.serviceFee,
298
+ seats: group.seats,
299
+ availableToAdd: availableToAddByCategory.get(categoryId) ?? 0
300
+ });
301
+ }
302
+ return ordered;
303
+ }, [
304
+ cartSeats,
305
+ seatDetailsById,
306
+ selectedSeatIdArray,
307
+ venue.categories
308
+ ]);
309
+ const cartPayload = useMemo(() => ({
310
+ venueId: venue.id,
311
+ venueName: venue.name,
312
+ seats: cartSeats,
313
+ totalSelectedSeats,
314
+ totalCost
315
+ }), [
316
+ venue.id,
317
+ venue.name,
318
+ cartSeats,
319
+ totalSelectedSeats,
320
+ totalCost
321
+ ]);
322
+ const emitCartEvent = useCallback((event) => {
323
+ onCartEvent?.(event);
324
+ }, [onCartEvent]);
325
+ const removeSeatFromSelection = useCallback((seatId) => {
326
+ const seat = seatDetailsById.get(seatId);
327
+ if (seat?.sectionId) onSeatClick?.(seatId, seat.sectionId);
328
+ const next = selectedSeatIdArray.filter((id) => id !== seatId);
329
+ setSelection(next);
330
+ }, [
331
+ seatDetailsById,
332
+ onSeatClick,
333
+ selectedSeatIdArray,
334
+ setSelection
335
+ ]);
336
+ const handleSeatCanvasClick = useCallback((seatId, sectionId) => {
337
+ pendingSeatClickRef.current = seatId;
338
+ onSeatClick?.(seatId, sectionId);
339
+ }, [onSeatClick]);
340
+ const handleAddSeatInCategory = useCallback((categoryId) => {
341
+ const selectedSet = new Set(selectedSeatIdArray);
342
+ const selectedInCategory = selectedSeatIdArray.filter((selectedSeatId) => seatDetailsById.get(selectedSeatId)?.categoryId === categoryId);
343
+ const anchorSeatId = (lastUserAnchorByCategory[categoryId] && seatDetailsById.has(lastUserAnchorByCategory[categoryId]) ? lastUserAnchorByCategory[categoryId] : null) ?? selectedInCategory[selectedInCategory.length - 1] ?? null;
344
+ const anchorSeat = anchorSeatId ? seatDetailsById.get(anchorSeatId) : null;
345
+ const candidates = Array.from(seatDetailsById.values()).filter((seat) => seat.categoryId === categoryId && seat.status === AVAILABLE_STATUS_ID && !selectedSet.has(seat.seatId));
346
+ if (candidates.length === 0) return;
347
+ let nextSeat = candidates[0];
348
+ if (anchorSeat) nextSeat = candidates.reduce((best, candidate) => {
349
+ const bestDistance = (best.x - anchorSeat.x) ** 2 + (best.y - anchorSeat.y) ** 2;
350
+ return (candidate.x - anchorSeat.x) ** 2 + (candidate.y - anchorSeat.y) ** 2 < bestDistance ? candidate : best;
351
+ }, candidates[0]);
352
+ setSelection([...selectedSeatIdArray, nextSeat.seatId]);
353
+ if (nextSeat.sectionId) onSeatClick?.(nextSeat.seatId, nextSeat.sectionId);
354
+ }, [
355
+ lastUserAnchorByCategory,
356
+ seatDetailsById,
357
+ selectedSeatIdArray,
358
+ setSelection,
359
+ onSeatClick
360
+ ]);
361
+ const handleRemoveLastInCategory = useCallback((categoryId) => {
362
+ const selectedInCategory = selectedSeatIdArray.filter((selectedSeatId) => seatDetailsById.get(selectedSeatId)?.categoryId === categoryId);
363
+ const seatIdToRemove = selectedInCategory[selectedInCategory.length - 1];
364
+ if (!seatIdToRemove) return;
365
+ const seat = seatDetailsById.get(seatIdToRemove);
366
+ if (seat?.sectionId) onSeatClick?.(seatIdToRemove, seat.sectionId);
367
+ setSelection(selectedSeatIdArray.filter((selectedSeatId) => selectedSeatId !== seatIdToRemove));
368
+ }, [
369
+ seatDetailsById,
370
+ selectedSeatIdArray,
371
+ setSelection,
372
+ onSeatClick
373
+ ]);
374
+ const handleProceed = useCallback(() => {
375
+ if (cartPayload.seats.length === 0 || isSelectionOverLimit) return;
376
+ emitCartEvent({
377
+ type: "cart-proceed-clicked",
378
+ payload: cartPayload
379
+ });
380
+ }, [
381
+ cartPayload,
382
+ emitCartEvent,
383
+ isSelectionOverLimit
384
+ ]);
385
+ const cartWidth = viewportWidth > 1200 ? Math.floor(viewportWidth / 5) : viewportWidth;
386
+ return /* @__PURE__ */ jsxs("div", {
387
+ className: classNames.root,
388
+ style: mergeStyles({
389
+ width: "100%",
390
+ height: "100%",
391
+ position: "relative"
392
+ }, styles.root),
393
+ children: [
394
+ /* @__PURE__ */ jsx(SeatmapCanvas, {
395
+ onSeatClick: handleSeatCanvasClick,
396
+ onSeatHover,
397
+ showSectionLabels: showLabels,
398
+ enableSeatHover: showLabels
399
+ }),
400
+ (showStatuses || showCategories) && /* @__PURE__ */ jsxs("aside", {
401
+ "aria-label": messages.legendAriaLabel,
402
+ className: mergeClassNames("seatmap-viewer__legend", classNames.legendContainer),
403
+ style: styles.legendContainer,
404
+ children: [
405
+ showStatuses && /* @__PURE__ */ jsxs("section", {
406
+ className: "seatmap-viewer__legend-section",
407
+ children: [/* @__PURE__ */ jsx("p", {
408
+ className: mergeClassNames("seatmap-viewer__legend-heading-base", classNames.legendHeading),
409
+ style: styles.legendHeading,
410
+ children: messages.legendStatusesTitle
411
+ }), /* @__PURE__ */ jsx("ul", {
412
+ className: mergeClassNames("seatmap-viewer__legend-list-base", classNames.legendList),
413
+ style: styles.legendList,
414
+ children: venue.seatStatuses.map((status) => /* @__PURE__ */ jsxs("li", {
415
+ className: mergeClassNames("seatmap-viewer__legend-item-base", classNames.legendItem),
416
+ style: styles.legendItem,
417
+ children: [/* @__PURE__ */ jsx("span", {
418
+ className: mergeClassNames("seatmap-viewer__legend-swatch-base", classNames.legendSwatch),
419
+ style: mergeStyles({ background: status.color }, styles.legendSwatch)
420
+ }), /* @__PURE__ */ jsx("span", { children: status.name })]
421
+ }, status.id))
422
+ })]
423
+ }),
424
+ showStatuses && showCategories && /* @__PURE__ */ jsx("div", {
425
+ className: mergeClassNames("seatmap-viewer__legend-divider-base", classNames.legendDivider),
426
+ style: styles.legendDivider
427
+ }),
428
+ showCategories && /* @__PURE__ */ jsxs("section", {
429
+ className: "seatmap-viewer__legend-section",
430
+ children: [/* @__PURE__ */ jsx("p", {
431
+ className: mergeClassNames("seatmap-viewer__legend-heading-base", classNames.legendHeading),
432
+ style: styles.legendHeading,
433
+ children: messages.legendPricesTitle
434
+ }), /* @__PURE__ */ jsx("ul", {
435
+ className: mergeClassNames("seatmap-viewer__legend-list-base", classNames.legendList),
436
+ style: styles.legendList,
437
+ children: venue.categories.map((category) => /* @__PURE__ */ jsxs("li", {
438
+ className: mergeClassNames("seatmap-viewer__legend-item-base", classNames.legendItem),
439
+ style: styles.legendItem,
440
+ children: [/* @__PURE__ */ jsx("span", {
441
+ className: mergeClassNames("seatmap-viewer__legend-swatch-base", classNames.legendSwatch),
442
+ style: mergeStyles({ background: category.color }, styles.legendSwatch)
443
+ }), /* @__PURE__ */ jsx("span", { children: category.name })]
444
+ }, category.id))
445
+ })]
446
+ })
447
+ ]
448
+ }),
449
+ !isCartOpen && /* @__PURE__ */ jsx("button", {
450
+ type: "button",
451
+ className: mergeClassNames("seatmap-viewer__cart-chip-base", classNames.cartChip),
452
+ onClick: () => setIsCartOpen(true),
453
+ disabled: isSelectionOverLimit,
454
+ style: styles.cartChip,
455
+ children: messages.cartChipLabel(totalSelectedSeats)
456
+ }),
457
+ isCartOpen && /* @__PURE__ */ jsxs("aside", {
458
+ "aria-label": messages.cartAriaLabel,
459
+ className: mergeClassNames("seatmap-viewer__cart-popup-base", classNames.cartPopup),
460
+ style: mergeStyles({
461
+ width: cartWidth,
462
+ maxWidth: "100%"
463
+ }, styles.cartPopup),
464
+ children: [
465
+ /* @__PURE__ */ jsxs("div", {
466
+ className: mergeClassNames("seatmap-viewer__cart-header-base", classNames.cartHeader),
467
+ style: styles.cartHeader,
468
+ children: [/* @__PURE__ */ jsx("strong", {
469
+ className: mergeClassNames("seatmap-viewer__cart-header-title-base", classNames.cartHeaderTitle),
470
+ style: styles.cartHeaderTitle,
471
+ children: messages.cartHeaderTitle
472
+ }), /* @__PURE__ */ jsx("button", {
473
+ type: "button",
474
+ onClick: () => setIsCartOpen(false),
475
+ className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
476
+ style: styles.cartIconButton,
477
+ title: messages.cartCloseLabel,
478
+ "aria-label": messages.cartCloseLabel,
479
+ children: "x"
480
+ })]
481
+ }),
482
+ /* @__PURE__ */ jsx("div", {
483
+ className: mergeClassNames("seatmap-viewer__cart-body-base", classNames.cartBody),
484
+ style: styles.cartBody,
485
+ children: groupedSeatsList.length === 0 ? /* @__PURE__ */ jsx("div", {
486
+ className: mergeClassNames("seatmap-viewer__cart-empty-state-base", classNames.cartEmptyState),
487
+ style: styles.cartEmptyState,
488
+ children: messages.cartEmptyState
489
+ }) : groupedSeatsList.map((group) => /* @__PURE__ */ jsxs("article", {
490
+ className: mergeClassNames("seatmap-viewer__cart-group-base", classNames.cartGroup),
491
+ style: styles.cartGroup,
492
+ children: [
493
+ /* @__PURE__ */ jsx("div", {
494
+ className: mergeClassNames("seatmap-viewer__cart-group-title-base", classNames.cartGroupTitle),
495
+ style: styles.cartGroupTitle,
496
+ children: group.categoryName
497
+ }),
498
+ /* @__PURE__ */ jsx("div", {
499
+ className: mergeClassNames("seatmap-viewer__cart-group-meta-base", classNames.cartGroupMeta),
500
+ style: styles.cartGroupMeta,
501
+ children: messages.cartGroupMeta(group.seats.length, formatMoney(group.unitPrice, locale, currency))
502
+ }),
503
+ group.serviceFee > 0 && /* @__PURE__ */ jsx("div", {
504
+ className: mergeClassNames("seatmap-viewer__cart-group-meta-base", classNames.cartGroupMeta),
505
+ style: styles.cartGroupMeta,
506
+ children: messages.cartGroupFee(formatMoney(group.baseUnitPrice, locale, currency), formatMoney(group.serviceFee, locale, currency), group.baseUnitPrice > 0 ? formatPercent(group.serviceFee / group.baseUnitPrice, locale) : null)
507
+ }),
508
+ /* @__PURE__ */ jsxs("div", {
509
+ className: mergeClassNames("seatmap-viewer__cart-quantity-row-base", classNames.cartQuantityRow),
510
+ style: styles.cartQuantityRow,
511
+ children: [/* @__PURE__ */ jsxs("div", {
512
+ className: "seatmap-viewer__cart-quantity-controls",
513
+ children: [
514
+ /* @__PURE__ */ jsx("button", {
515
+ type: "button",
516
+ className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
517
+ style: styles.cartIconButton,
518
+ onClick: () => handleRemoveLastInCategory(group.categoryId),
519
+ disabled: group.seats.length === 0,
520
+ "aria-label": messages.cartRemoveOneAriaLabel(group.categoryName),
521
+ children: "-"
522
+ }),
523
+ /* @__PURE__ */ jsx("span", {
524
+ className: mergeClassNames("seatmap-viewer__cart-quantity-value-base", classNames.cartQuantityValue),
525
+ style: styles.cartQuantityValue,
526
+ children: group.seats.length
527
+ }),
528
+ /* @__PURE__ */ jsx("button", {
529
+ type: "button",
530
+ className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
531
+ style: styles.cartIconButton,
532
+ onClick: () => handleAddSeatInCategory(group.categoryId),
533
+ disabled: group.availableToAdd === 0,
534
+ "aria-label": messages.cartAddOneAriaLabel(group.categoryName),
535
+ children: "+"
536
+ })
537
+ ]
538
+ }), /* @__PURE__ */ jsx("span", {
539
+ className: mergeClassNames("seatmap-viewer__cart-group-total-base", classNames.cartGroupTotal),
540
+ style: styles.cartGroupTotal,
541
+ children: formatMoney(group.seats.reduce((sum, seat) => sum + seat.unitPrice, 0), locale, currency)
542
+ })]
543
+ }),
544
+ /* @__PURE__ */ jsx("div", {
545
+ className: "seatmap-viewer__cart-seat-list",
546
+ children: group.seats.map((seat) => /* @__PURE__ */ jsxs("div", {
547
+ className: mergeClassNames("seatmap-viewer__cart-seat-row-base", classNames.cartSeatRow),
548
+ style: styles.cartSeatRow,
549
+ children: [/* @__PURE__ */ jsxs("span", {
550
+ className: mergeClassNames("seatmap-viewer__cart-seat-label-base", classNames.cartSeatLabel),
551
+ style: styles.cartSeatLabel,
552
+ children: [
553
+ seat.sectionLabel ?? messages.sectionFallbackLabel,
554
+ " ",
555
+ seat.rowLabel ? `- ${seat.rowLabel}${seat.seatLabel}` : `- ${seat.seatLabel}`
556
+ ]
557
+ }), /* @__PURE__ */ jsx("button", {
558
+ type: "button",
559
+ className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
560
+ style: styles.cartIconButton,
561
+ onClick: () => removeSeatFromSelection(seat.seatId),
562
+ title: messages.cartRemoveSeatTitle,
563
+ "aria-label": messages.cartRemoveSeatAriaLabel(seat.seatLabel),
564
+ children: /* @__PURE__ */ jsx(TrashIcon, {})
565
+ })]
566
+ }, seat.seatId))
567
+ })
568
+ ]
569
+ }, group.categoryId))
570
+ }),
571
+ /* @__PURE__ */ jsxs("div", {
572
+ className: mergeClassNames("seatmap-viewer__cart-footer-base", classNames.cartFooter),
573
+ style: styles.cartFooter,
574
+ children: [/* @__PURE__ */ jsxs("div", {
575
+ className: mergeClassNames("seatmap-viewer__cart-summary-base", classNames.cartSummary),
576
+ style: styles.cartSummary,
577
+ children: [/* @__PURE__ */ jsx("div", { children: messages.cartSummary(totalSelectedSeats, formatMoney(totalCost, locale, currency)) }), totalServiceFee > 0 && /* @__PURE__ */ jsx("div", { children: messages.cartServiceFeeSummary(formatMoney(totalServiceFee, locale, currency)) })]
578
+ }), /* @__PURE__ */ jsx("button", {
579
+ type: "button",
580
+ disabled: cartSeats.length === 0 || isSelectionOverLimit,
581
+ onClick: handleProceed,
582
+ className: mergeClassNames("seatmap-viewer__cart-proceed-button-base", classNames.cartProceedButton),
583
+ style: styles.cartProceedButton,
584
+ children: messages.cartProceedButton
585
+ })]
586
+ })
587
+ ]
588
+ }),
589
+ showLabels && /* @__PURE__ */ jsx(TooltipOverlay, { renderTooltip: effectiveTooltipRenderer })
590
+ ]
591
+ });
694
592
  }
695
- function SeatmapViewer({
696
- venue,
697
- onSeatClick,
698
- onSeatHover,
699
- onSelectionChange,
700
- renderTooltip,
701
- showLabels = true,
702
- className,
703
- onCartEvent,
704
- locale,
705
- currency,
706
- styles,
707
- classNames,
708
- messages
709
- }) {
710
- return /* @__PURE__ */ jsx(SeatmapProvider, { venue, children: /* @__PURE__ */ jsx(
711
- "div",
712
- {
713
- className: mergeClassNames(className, classNames?.root),
714
- style: mergeStyles({ width: "100%", height: "100%", position: "relative" }, styles?.root),
715
- children: /* @__PURE__ */ jsx(
716
- SeatmapViewerContent,
717
- {
718
- venue,
719
- onSeatClick,
720
- onSeatHover,
721
- onSelectionChange,
722
- renderTooltip,
723
- showLabels,
724
- onCartEvent,
725
- locale,
726
- currency,
727
- styles,
728
- classNames,
729
- messages
730
- }
731
- )
732
- }
733
- ) });
593
+ function SeatmapViewer({ venue, onSeatClick, onSeatHover, onSelectionChange, renderTooltip, showLabels = true, className, onCartEvent, locale, currency, maxSelectedSeats, styles, classNames, messages }) {
594
+ return /* @__PURE__ */ jsx(SeatmapProvider, {
595
+ venue,
596
+ children: /* @__PURE__ */ jsx("div", {
597
+ className: mergeClassNames(className, classNames?.root),
598
+ style: mergeStyles({
599
+ width: "100%",
600
+ height: "100%",
601
+ position: "relative"
602
+ }, styles?.root),
603
+ children: /* @__PURE__ */ jsx(SeatmapViewerContent, {
604
+ venue,
605
+ onSeatClick,
606
+ onSeatHover,
607
+ onSelectionChange,
608
+ renderTooltip,
609
+ showLabels,
610
+ onCartEvent,
611
+ locale,
612
+ currency,
613
+ maxSelectedSeats,
614
+ styles,
615
+ classNames,
616
+ messages
617
+ })
618
+ })
619
+ });
734
620
  }
735
-
736
621
  // src/styleContract.ts
737
- var seatmapViewerStyleSlots = [
738
- "root",
739
- "legendContainer",
740
- "legendHeading",
741
- "legendList",
742
- "legendItem",
743
- "legendSwatch",
744
- "legendDivider",
745
- "cartChip",
746
- "cartPopup",
747
- "cartHeader",
748
- "cartHeaderTitle",
749
- "cartIconButton",
750
- "cartBody",
751
- "cartEmptyState",
752
- "cartGroup",
753
- "cartGroupTitle",
754
- "cartGroupMeta",
755
- "cartQuantityRow",
756
- "cartQuantityValue",
757
- "cartGroupTotal",
758
- "cartSeatRow",
759
- "cartSeatLabel",
760
- "cartFooter",
761
- "cartSummary",
762
- "cartProceedButton"
622
+ const seatmapViewerStyleSlots = [
623
+ "root",
624
+ "legendContainer",
625
+ "legendHeading",
626
+ "legendList",
627
+ "legendItem",
628
+ "legendSwatch",
629
+ "legendDivider",
630
+ "cartChip",
631
+ "cartPopup",
632
+ "cartHeader",
633
+ "cartHeaderTitle",
634
+ "cartIconButton",
635
+ "cartBody",
636
+ "cartEmptyState",
637
+ "cartGroup",
638
+ "cartGroupTitle",
639
+ "cartGroupMeta",
640
+ "cartQuantityRow",
641
+ "cartQuantityValue",
642
+ "cartGroupTotal",
643
+ "cartSeatRow",
644
+ "cartSeatLabel",
645
+ "cartFooter",
646
+ "cartSummary",
647
+ "cartProceedButton"
763
648
  ];
764
- var STYLE_CONTRACT_CLASS_PREFIX = "seatmap-viewer";
765
- var seatmapViewerDefaultClassNames = {
766
- root: `${STYLE_CONTRACT_CLASS_PREFIX}__root`,
767
- legendContainer: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-container`,
768
- legendHeading: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-heading`,
769
- legendList: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-list`,
770
- legendItem: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-item`,
771
- legendSwatch: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-swatch`,
772
- legendDivider: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-divider`,
773
- cartChip: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-chip`,
774
- cartPopup: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-popup`,
775
- cartHeader: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-header`,
776
- cartHeaderTitle: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-header-title`,
777
- cartIconButton: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-icon-button`,
778
- cartBody: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-body`,
779
- cartEmptyState: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-empty-state`,
780
- cartGroup: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group`,
781
- cartGroupTitle: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-title`,
782
- cartGroupMeta: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-meta`,
783
- cartQuantityRow: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-quantity-row`,
784
- cartQuantityValue: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-quantity-value`,
785
- cartGroupTotal: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-total`,
786
- cartSeatRow: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-seat-row`,
787
- cartSeatLabel: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-seat-label`,
788
- cartFooter: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-footer`,
789
- cartSummary: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-summary`,
790
- cartProceedButton: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-proceed-button`
649
+ const STYLE_CONTRACT_CLASS_PREFIX = "seatmap-viewer";
650
+ const seatmapViewerDefaultClassNames = {
651
+ root: `${STYLE_CONTRACT_CLASS_PREFIX}__root`,
652
+ legendContainer: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-container`,
653
+ legendHeading: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-heading`,
654
+ legendList: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-list`,
655
+ legendItem: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-item`,
656
+ legendSwatch: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-swatch`,
657
+ legendDivider: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-divider`,
658
+ cartChip: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-chip`,
659
+ cartPopup: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-popup`,
660
+ cartHeader: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-header`,
661
+ cartHeaderTitle: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-header-title`,
662
+ cartIconButton: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-icon-button`,
663
+ cartBody: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-body`,
664
+ cartEmptyState: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-empty-state`,
665
+ cartGroup: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group`,
666
+ cartGroupTitle: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-title`,
667
+ cartGroupMeta: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-meta`,
668
+ cartQuantityRow: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-quantity-row`,
669
+ cartQuantityValue: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-quantity-value`,
670
+ cartGroupTotal: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-total`,
671
+ cartSeatRow: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-seat-row`,
672
+ cartSeatLabel: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-seat-label`,
673
+ cartFooter: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-footer`,
674
+ cartSummary: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-summary`,
675
+ cartProceedButton: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-proceed-button`
791
676
  };
792
- var seatmapViewerCssVariables = [
793
- "--seatmap-surface",
794
- "--seatmap-surface-elevated",
795
- "--seatmap-surface-muted",
796
- "--seatmap-on-surface",
797
- "--seatmap-on-surface-variant",
798
- "--seatmap-outline",
799
- "--seatmap-outline-variant",
800
- "--seatmap-primary",
801
- "--seatmap-on-primary",
802
- "--seatmap-error",
803
- "--seatmap-on-error",
804
- "--seatmap-state-layer-hover",
805
- "--seatmap-state-layer-pressed",
806
- "--seatmap-focus-ring",
807
- "--seatmap-radius-sm",
808
- "--seatmap-radius-md",
809
- "--seatmap-radius-lg",
810
- "--seatmap-shadow-raised",
811
- "--seatmap-shadow-elevated",
812
- "--seatmap-shadow-floating",
813
- "--seatmap-viewer-surface",
814
- "--seatmap-viewer-surface-elevated",
815
- "--seatmap-viewer-surface-muted",
816
- "--seatmap-viewer-border",
817
- "--seatmap-viewer-border-subtle",
818
- "--seatmap-viewer-text",
819
- "--seatmap-viewer-text-muted",
820
- "--seatmap-viewer-accent",
821
- "--seatmap-viewer-accent-disabled",
822
- "--seatmap-viewer-accent-text",
823
- "--seatmap-viewer-danger",
824
- "--seatmap-viewer-danger-text",
825
- "--seatmap-viewer-state-layer-hover",
826
- "--seatmap-viewer-state-layer-pressed",
827
- "--seatmap-viewer-focus-ring",
828
- "--seatmap-viewer-radius-sm",
829
- "--seatmap-viewer-radius-md",
830
- "--seatmap-viewer-radius-lg",
831
- "--seatmap-viewer-shadow-raised",
832
- "--seatmap-viewer-shadow-elevated",
833
- "--seatmap-viewer-shadow-floating"
677
+ const seatmapViewerCssVariables = [
678
+ "--seatmap-surface",
679
+ "--seatmap-surface-elevated",
680
+ "--seatmap-surface-muted",
681
+ "--seatmap-on-surface",
682
+ "--seatmap-on-surface-variant",
683
+ "--seatmap-outline",
684
+ "--seatmap-outline-variant",
685
+ "--seatmap-primary",
686
+ "--seatmap-on-primary",
687
+ "--seatmap-error",
688
+ "--seatmap-on-error",
689
+ "--seatmap-state-layer-hover",
690
+ "--seatmap-state-layer-pressed",
691
+ "--seatmap-focus-ring",
692
+ "--seatmap-radius-sm",
693
+ "--seatmap-radius-md",
694
+ "--seatmap-radius-lg",
695
+ "--seatmap-shadow-raised",
696
+ "--seatmap-shadow-elevated",
697
+ "--seatmap-shadow-floating",
698
+ "--seatmap-viewer-surface",
699
+ "--seatmap-viewer-surface-elevated",
700
+ "--seatmap-viewer-surface-muted",
701
+ "--seatmap-viewer-border",
702
+ "--seatmap-viewer-border-subtle",
703
+ "--seatmap-viewer-text",
704
+ "--seatmap-viewer-text-muted",
705
+ "--seatmap-viewer-accent",
706
+ "--seatmap-viewer-accent-disabled",
707
+ "--seatmap-viewer-accent-text",
708
+ "--seatmap-viewer-danger",
709
+ "--seatmap-viewer-danger-text",
710
+ "--seatmap-viewer-state-layer-hover",
711
+ "--seatmap-viewer-state-layer-pressed",
712
+ "--seatmap-viewer-focus-ring",
713
+ "--seatmap-viewer-radius-sm",
714
+ "--seatmap-viewer-radius-md",
715
+ "--seatmap-viewer-radius-lg",
716
+ "--seatmap-viewer-shadow-raised",
717
+ "--seatmap-viewer-shadow-elevated",
718
+ "--seatmap-viewer-shadow-floating"
834
719
  ];
835
- var seatmapViewerStyleContract = {
836
- slots: seatmapViewerStyleSlots,
837
- defaultClassNames: seatmapViewerDefaultClassNames,
838
- cssVariables: seatmapViewerCssVariables
720
+ const seatmapViewerStyleContract = {
721
+ slots: seatmapViewerStyleSlots,
722
+ defaultClassNames: seatmapViewerDefaultClassNames,
723
+ cssVariables: seatmapViewerCssVariables
839
724
  };
840
-
841
725
  // src/theme/seatmapViewerTheme.ts
842
- var seatmapViewerSharedThemeRootClassName = "seatmap-viewer-theme";
843
- var seatmapViewerSharedThemeClassNames = {
844
- ...seatmapViewerDefaultClassNames
845
- };
846
- var seatmapViewerSharedThemeVariables = {
847
- "--seatmap-surface": "var(--ds-surface-container-low, rgba(24, 24, 24, 0.94))",
848
- "--seatmap-surface-elevated": "var(--ds-surface-container, rgba(28, 28, 28, 0.98))",
849
- "--seatmap-surface-muted": "var(--ds-surface-container-high, rgba(33, 33, 33, 1))",
850
- "--seatmap-on-surface": "var(--ds-on-surface, #e5e2e1)",
851
- "--seatmap-on-surface-variant": "var(--ds-on-surface-variant, #9a9694)",
852
- "--seatmap-outline": "var(--ds-input-border, rgba(92, 89, 87, 0.65))",
853
- "--seatmap-outline-variant": "var(--ds-border-subtle, rgba(92, 89, 87, 0.45))",
854
- "--seatmap-primary": "var(--ds-primary, #6f663a)",
855
- "--seatmap-on-primary": "var(--ds-on-primary, #f5edc7)",
856
- "--seatmap-error": "var(--ds-error, #ad3f3f)",
857
- "--seatmap-on-error": "var(--ds-on-error, #ffffff)",
858
- "--seatmap-state-layer-hover": "var(--ds-primary-wash, color-mix(in srgb, var(--ds-primary, #6f663a) 12%, transparent))",
859
- "--seatmap-state-layer-pressed": "var(--ds-primary-wash-strong, color-mix(in srgb, var(--ds-primary, #6f663a) 16%, transparent))",
860
- "--seatmap-focus-ring": "var(--ds-primary-ring, color-mix(in srgb, var(--ds-primary, #6f663a) 55%, transparent))",
861
- "--seatmap-radius-sm": "var(--ds-radius-structural-sm, 8px)",
862
- "--seatmap-radius-md": "var(--ds-radius-structural, 10px)",
863
- "--seatmap-radius-lg": "calc(var(--ds-radius-structural, 10px) + 6px)",
864
- "--seatmap-shadow-raised": "var(--ds-shadow-ambient-sm, 0 8px 20px rgba(0, 0, 0, 0.22))",
865
- "--seatmap-shadow-elevated": "var(--ds-shadow-ambient, 0 10px 24px rgba(0, 0, 0, 0.28))",
866
- "--seatmap-shadow-floating": "var(--ds-shadow-ambient-lg, 0 14px 34px rgba(0, 0, 0, 0.32))",
867
- "--seatmap-viewer-surface": "var(--seatmap-surface)",
868
- "--seatmap-viewer-surface-elevated": "var(--seatmap-surface-elevated)",
869
- "--seatmap-viewer-surface-muted": "var(--seatmap-surface-muted)",
870
- "--seatmap-viewer-border": "var(--seatmap-outline)",
871
- "--seatmap-viewer-border-subtle": "var(--seatmap-outline-variant)",
872
- "--seatmap-viewer-text": "var(--seatmap-on-surface)",
873
- "--seatmap-viewer-text-muted": "var(--seatmap-on-surface-variant)",
874
- "--seatmap-viewer-accent": "var(--seatmap-primary)",
875
- "--seatmap-viewer-accent-disabled": "color-mix(in srgb, var(--seatmap-primary) 28%, var(--seatmap-surface-muted))",
876
- "--seatmap-viewer-accent-text": "var(--seatmap-on-primary)",
877
- "--seatmap-viewer-danger": "var(--seatmap-error)",
878
- "--seatmap-viewer-danger-text": "var(--seatmap-on-error)",
879
- "--seatmap-viewer-state-layer-hover": "var(--seatmap-state-layer-hover)",
880
- "--seatmap-viewer-state-layer-pressed": "var(--seatmap-state-layer-pressed)",
881
- "--seatmap-viewer-focus-ring": "var(--seatmap-focus-ring)",
882
- "--seatmap-viewer-radius-sm": "var(--seatmap-radius-sm)",
883
- "--seatmap-viewer-radius-md": "var(--seatmap-radius-md)",
884
- "--seatmap-viewer-radius-lg": "var(--seatmap-radius-lg)",
885
- "--seatmap-viewer-shadow-raised": "var(--seatmap-shadow-raised)",
886
- "--seatmap-viewer-shadow-elevated": "var(--seatmap-shadow-elevated)",
887
- "--seatmap-viewer-shadow-floating": "var(--seatmap-shadow-floating)"
726
+ const seatmapViewerSharedThemeRootClassName = "seatmap-viewer-theme";
727
+ const seatmapViewerSharedThemeClassNames = { ...seatmapViewerDefaultClassNames };
728
+ const seatmapViewerSharedThemeVariables = {
729
+ "--seatmap-surface": "var(--ds-surface-container-low, rgba(24, 24, 24, 0.94))",
730
+ "--seatmap-surface-elevated": "var(--ds-surface-container, rgba(28, 28, 28, 0.98))",
731
+ "--seatmap-surface-muted": "var(--ds-surface-container-high, rgba(33, 33, 33, 1))",
732
+ "--seatmap-on-surface": "var(--ds-on-surface, #e5e2e1)",
733
+ "--seatmap-on-surface-variant": "var(--ds-on-surface-variant, #9a9694)",
734
+ "--seatmap-outline": "var(--ds-input-border, rgba(92, 89, 87, 0.65))",
735
+ "--seatmap-outline-variant": "var(--ds-border-subtle, rgba(92, 89, 87, 0.45))",
736
+ "--seatmap-primary": "var(--ds-primary, #6f663a)",
737
+ "--seatmap-on-primary": "var(--ds-on-primary, #f5edc7)",
738
+ "--seatmap-error": "var(--ds-error, #ad3f3f)",
739
+ "--seatmap-on-error": "var(--ds-on-error, #ffffff)",
740
+ "--seatmap-state-layer-hover": "var(--ds-primary-wash, color-mix(in srgb, var(--ds-primary, #6f663a) 12%, transparent))",
741
+ "--seatmap-state-layer-pressed": "var(--ds-primary-wash-strong, color-mix(in srgb, var(--ds-primary, #6f663a) 16%, transparent))",
742
+ "--seatmap-focus-ring": "var(--ds-primary-ring, color-mix(in srgb, var(--ds-primary, #6f663a) 55%, transparent))",
743
+ "--seatmap-radius-sm": "var(--ds-radius-structural-sm, 8px)",
744
+ "--seatmap-radius-md": "var(--ds-radius-structural, 10px)",
745
+ "--seatmap-radius-lg": "calc(var(--ds-radius-structural, 10px) + 6px)",
746
+ "--seatmap-shadow-raised": "var(--ds-shadow-ambient-sm, 0 8px 20px rgba(0, 0, 0, 0.22))",
747
+ "--seatmap-shadow-elevated": "var(--ds-shadow-ambient, 0 10px 24px rgba(0, 0, 0, 0.28))",
748
+ "--seatmap-shadow-floating": "var(--ds-shadow-ambient-lg, 0 14px 34px rgba(0, 0, 0, 0.32))",
749
+ "--seatmap-viewer-surface": "var(--seatmap-surface)",
750
+ "--seatmap-viewer-surface-elevated": "var(--seatmap-surface-elevated)",
751
+ "--seatmap-viewer-surface-muted": "var(--seatmap-surface-muted)",
752
+ "--seatmap-viewer-border": "var(--seatmap-outline)",
753
+ "--seatmap-viewer-border-subtle": "var(--seatmap-outline-variant)",
754
+ "--seatmap-viewer-text": "var(--seatmap-on-surface)",
755
+ "--seatmap-viewer-text-muted": "var(--seatmap-on-surface-variant)",
756
+ "--seatmap-viewer-accent": "var(--seatmap-primary)",
757
+ "--seatmap-viewer-accent-disabled": "color-mix(in srgb, var(--seatmap-primary) 28%, var(--seatmap-surface-muted))",
758
+ "--seatmap-viewer-accent-text": "var(--seatmap-on-primary)",
759
+ "--seatmap-viewer-danger": "var(--seatmap-error)",
760
+ "--seatmap-viewer-danger-text": "var(--seatmap-on-error)",
761
+ "--seatmap-viewer-state-layer-hover": "var(--seatmap-state-layer-hover)",
762
+ "--seatmap-viewer-state-layer-pressed": "var(--seatmap-state-layer-pressed)",
763
+ "--seatmap-viewer-focus-ring": "var(--seatmap-focus-ring)",
764
+ "--seatmap-viewer-radius-sm": "var(--seatmap-radius-sm)",
765
+ "--seatmap-viewer-radius-md": "var(--seatmap-radius-md)",
766
+ "--seatmap-viewer-radius-lg": "var(--seatmap-radius-lg)",
767
+ "--seatmap-viewer-shadow-raised": "var(--seatmap-shadow-raised)",
768
+ "--seatmap-viewer-shadow-elevated": "var(--seatmap-shadow-elevated)",
769
+ "--seatmap-viewer-shadow-floating": "var(--seatmap-shadow-floating)"
888
770
  };
889
- var seatmapViewerSharedTheme = {
890
- rootClassName: seatmapViewerSharedThemeRootClassName,
891
- classNames: seatmapViewerSharedThemeClassNames,
892
- variables: seatmapViewerSharedThemeVariables
771
+ const seatmapViewerSharedTheme = {
772
+ rootClassName: seatmapViewerSharedThemeRootClassName,
773
+ classNames: seatmapViewerSharedThemeClassNames,
774
+ variables: seatmapViewerSharedThemeVariables
893
775
  };
894
776
  function getSeatmapViewerSharedThemeRootStyle(overrides) {
895
- return {
896
- ...seatmapViewerSharedThemeVariables,
897
- ...overrides ?? {}
898
- };
777
+ return {
778
+ ...seatmapViewerSharedThemeVariables,
779
+ ...overrides ?? {}
780
+ };
899
781
  }
782
+ export { SeatmapViewer, SeatmapViewerContent, defaultSeatmapViewerMessages, getSeatmapViewerSharedThemeRootStyle, seatmapViewerCssVariables, seatmapViewerDefaultClassNames, seatmapViewerSharedTheme, seatmapViewerSharedThemeClassNames, seatmapViewerSharedThemeRootClassName, seatmapViewerSharedThemeVariables, seatmapViewerStyleContract, seatmapViewerStyleSlots, useSeatStatus };
900
783
 
901
- export { SeatmapViewer, SeatmapViewerContent, defaultSeatmapViewerMessages, getSeatmapViewerSharedThemeRootStyle, seatmapViewerCssVariables, seatmapViewerDefaultClassNames, seatmapViewerSharedTheme, seatmapViewerSharedThemeClassNames, seatmapViewerSharedThemeRootClassName, seatmapViewerSharedThemeVariables, seatmapViewerStyleContract, seatmapViewerStyleSlots };
902
- //# sourceMappingURL=index.js.map
903
784
  //# sourceMappingURL=index.js.map