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