@nex125/seatmap-viewer 0.1.8 → 0.1.11

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,97 +1,29 @@
1
- import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
1
+ import { useMemo, useState, useRef, useEffect, useCallback } from 'react';
2
2
  import { AVAILABLE_STATUS_ID } from '@nex125/seatmap-core';
3
- import { SeatmapProvider, useSelection, SeatmapCanvas, TooltipOverlay } from '@nex125/seatmap-react';
3
+ import { useSelection, SeatmapCanvas, TooltipOverlay, SeatmapProvider } from '@nex125/seatmap-react';
4
4
  export { useSeatStatus } from '@nex125/seatmap-react';
5
- import { jsx, jsxs } from 'react/jsx-runtime';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
6
 
7
7
  // src/SeatmapViewer.tsx
8
- var legendContainerStyle = {
9
- position: "absolute",
10
- top: 12,
11
- left: 12,
12
- zIndex: 10,
13
- pointerEvents: "none",
14
- background: "rgba(18, 18, 34, 0.88)",
15
- border: "1px solid rgba(110, 110, 150, 0.45)",
16
- borderRadius: 8,
17
- padding: "10px 12px",
18
- minWidth: 150,
19
- color: "#e0e0e0",
20
- fontFamily: "system-ui",
21
- fontSize: 12,
22
- backdropFilter: "blur(2px)"
23
- };
24
- var legendHeadingStyle = {
25
- margin: 0,
26
- fontSize: 11,
27
- fontWeight: 600,
28
- letterSpacing: 0.2,
29
- color: "#b9b9d6"
30
- };
31
- var legendListStyle = {
32
- listStyle: "none",
33
- margin: "6px 0 0",
34
- padding: 0,
35
- display: "flex",
36
- flexDirection: "column",
37
- gap: 4
38
- };
39
- var legendItemStyle = {
40
- display: "flex",
41
- alignItems: "center",
42
- gap: 6,
43
- minWidth: 0
44
- };
45
- var legendSwatchStyle = {
46
- width: 10,
47
- height: 10,
48
- borderRadius: 2,
49
- flexShrink: 0,
50
- border: "1px solid rgba(255, 255, 255, 0.25)"
51
- };
52
- var cartChipStyle = {
53
- position: "absolute",
54
- right: 12,
55
- bottom: 12,
56
- zIndex: 20,
57
- border: "1px solid rgba(110, 110, 150, 0.65)",
58
- background: "rgba(24, 24, 42, 0.95)",
59
- color: "#ececff",
60
- borderRadius: 999,
61
- padding: "8px 14px",
62
- fontSize: 12,
63
- fontWeight: 600,
64
- fontFamily: "system-ui",
65
- cursor: "pointer",
66
- boxShadow: "0 8px 18px rgba(0, 0, 0, 0.35)"
67
- };
68
- var cartPopupStyle = {
69
- position: "absolute",
70
- right: 0,
71
- bottom: 0,
72
- zIndex: 30,
73
- maxHeight: "72vh",
74
- display: "flex",
75
- flexDirection: "column",
76
- background: "rgba(17, 17, 34, 0.98)",
77
- borderTop: "1px solid rgba(110, 110, 150, 0.65)",
78
- borderLeft: "1px solid rgba(110, 110, 150, 0.65)",
79
- borderTopLeftRadius: 12,
80
- overflow: "hidden",
81
- boxShadow: "-8px -8px 20px rgba(0, 0, 0, 0.35)"
82
- };
83
- var cartIconButtonStyle = {
84
- width: 24,
85
- height: 24,
86
- display: "inline-flex",
87
- alignItems: "center",
88
- justifyContent: "center",
89
- borderRadius: 5,
90
- border: "1px solid #4a4a6a",
91
- background: "#262648",
92
- color: "#ececff",
93
- fontSize: 14,
94
- cursor: "pointer"
8
+ var defaultSeatmapViewerMessages = {
9
+ uncategorizedCategoryName: "Uncategorized",
10
+ sectionFallbackLabel: "Section",
11
+ tableLabel: (tableLabel) => `Table ${tableLabel}`,
12
+ legendAriaLabel: "Seatmap legend",
13
+ legendStatusesTitle: "Seat statuses",
14
+ legendPricesTitle: "Prices",
15
+ cartChipLabel: (selectedCount) => `Cart (${selectedCount})`,
16
+ cartAriaLabel: "Selected seats cart",
17
+ cartHeaderTitle: "Selected seats cart",
18
+ cartCloseLabel: "Close cart",
19
+ cartEmptyState: "No seats selected yet.",
20
+ cartGroupMeta: (count, unitPrice) => `${count} tickets - ${unitPrice} each`,
21
+ cartRemoveOneAriaLabel: (categoryName) => `Remove one seat from ${categoryName}`,
22
+ cartAddOneAriaLabel: (categoryName) => `Add one seat to ${categoryName}`,
23
+ cartRemoveSeatTitle: "Remove seat",
24
+ cartRemoveSeatAriaLabel: (seatLabel) => `Remove seat ${seatLabel}`,
25
+ cartSummary: (count, totalCost) => `${count} seats - Total ${totalCost}`,
26
+ cartProceedButton: "Proceed"
95
27
  };
96
28
  function getEffectiveCategoryPrice(category) {
97
29
  if (!category) return 0;
@@ -100,8 +32,11 @@ function getEffectiveCategoryPrice(category) {
100
32
  }
101
33
  return Number.isFinite(category.backendPrice) ? category.backendPrice : 0;
102
34
  }
103
- function formatMoney(value) {
104
- return `$${value.toFixed(2)}`;
35
+ function formatMoney(value, locale, currency) {
36
+ return new Intl.NumberFormat(locale, {
37
+ style: "currency",
38
+ currency
39
+ }).format(value);
105
40
  }
106
41
  function TrashIcon() {
107
42
  return /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
@@ -112,15 +47,32 @@ function TrashIcon() {
112
47
  }
113
48
  ) });
114
49
  }
115
- function ViewerContent({
50
+ function mergeStyles(base, override) {
51
+ if (!override) return base;
52
+ return { ...base, ...override };
53
+ }
54
+ function mergeClassNames(...classNames) {
55
+ const merged = classNames.filter(Boolean).join(" ").trim();
56
+ return merged.length > 0 ? merged : void 0;
57
+ }
58
+ function SeatmapViewerContent({
116
59
  venue,
117
60
  onSeatClick,
118
61
  onSeatHover,
119
62
  onSelectionChange,
120
63
  renderTooltip,
121
64
  showLabels,
122
- onCartEvent
65
+ onCartEvent,
66
+ locale = "en-US",
67
+ currency = "BYN",
68
+ styles = {},
69
+ classNames = {},
70
+ messages: messagesOverride = {}
123
71
  }) {
72
+ const messages = useMemo(
73
+ () => ({ ...defaultSeatmapViewerMessages, ...messagesOverride }),
74
+ [messagesOverride]
75
+ );
124
76
  const { selectedSeatIds, setSelection } = useSelection();
125
77
  const [isCartOpen, setIsCartOpen] = useState(false);
126
78
  const [lastUserAnchorByCategory, setLastUserAnchorByCategory] = useState({});
@@ -148,7 +100,7 @@ function ViewerContent({
148
100
  sectionId: section.id,
149
101
  sectionLabel: section.label,
150
102
  categoryId: seat.categoryId,
151
- categoryName: category?.name ?? "Unknown",
103
+ categoryName: category?.name ?? messages.uncategorizedCategoryName,
152
104
  unitPrice: getEffectiveCategoryPrice(category),
153
105
  status: seat.status,
154
106
  x: section.position.x + seat.position.x * cos - seat.position.y * sin,
@@ -165,9 +117,9 @@ function ViewerContent({
165
117
  seatLabel: seat.label,
166
118
  rowLabel: null,
167
119
  sectionId: table.id,
168
- sectionLabel: `Table ${table.label}`,
120
+ sectionLabel: messages.tableLabel(table.label),
169
121
  categoryId: seat.categoryId,
170
- categoryName: category?.name ?? "Unknown",
122
+ categoryName: category?.name ?? messages.uncategorizedCategoryName,
171
123
  unitPrice: getEffectiveCategoryPrice(category),
172
124
  status: seat.status,
173
125
  x: table.position.x + seat.position.x,
@@ -176,7 +128,7 @@ function ViewerContent({
176
128
  }
177
129
  }
178
130
  return next;
179
- }, [venue]);
131
+ }, [venue, messages]);
180
132
  const selectedSeats = useMemo(() => {
181
133
  const ordered = [];
182
134
  for (const selectedSeatId of selectedSeatIdArray) {
@@ -290,10 +242,14 @@ function ViewerContent({
290
242
  );
291
243
  const removeSeatFromSelection = useCallback(
292
244
  (seatId) => {
245
+ const seat = seatDetailsById.get(seatId);
246
+ if (seat?.sectionId) {
247
+ onSeatClick?.(seatId, seat.sectionId);
248
+ }
293
249
  const next = selectedSeatIdArray.filter((id) => id !== seatId);
294
250
  setSelection(next);
295
251
  },
296
- [selectedSeatIdArray, setSelection]
252
+ [seatDetailsById, onSeatClick, selectedSeatIdArray, setSelection]
297
253
  );
298
254
  const handleSeatCanvasClick = useCallback(
299
255
  (seatId, sectionId) => {
@@ -323,8 +279,11 @@ function ViewerContent({
323
279
  }, candidates[0]);
324
280
  }
325
281
  setSelection([...selectedSeatIdArray, nextSeat.seatId]);
282
+ if (nextSeat.sectionId) {
283
+ onSeatClick?.(nextSeat.seatId, nextSeat.sectionId);
284
+ }
326
285
  },
327
- [lastUserAnchorByCategory, seatDetailsById, selectedSeatIdArray, setSelection]
286
+ [lastUserAnchorByCategory, seatDetailsById, selectedSeatIdArray, setSelection, onSeatClick]
328
287
  );
329
288
  const handleRemoveLastInCategory = useCallback(
330
289
  (categoryId) => {
@@ -333,198 +292,276 @@ function ViewerContent({
333
292
  );
334
293
  const seatIdToRemove = selectedInCategory[selectedInCategory.length - 1];
335
294
  if (!seatIdToRemove) return;
295
+ const seat = seatDetailsById.get(seatIdToRemove);
296
+ if (seat?.sectionId) {
297
+ onSeatClick?.(seatIdToRemove, seat.sectionId);
298
+ }
336
299
  setSelection(selectedSeatIdArray.filter((selectedSeatId) => selectedSeatId !== seatIdToRemove));
337
300
  },
338
- [seatDetailsById, selectedSeatIdArray, setSelection]
301
+ [seatDetailsById, selectedSeatIdArray, setSelection, onSeatClick]
339
302
  );
340
303
  const handleProceed = useCallback(() => {
341
304
  if (cartPayload.seats.length === 0) return;
342
305
  emitCartEvent({ type: "cart-proceed-clicked", payload: cartPayload });
343
306
  }, [cartPayload, emitCartEvent]);
344
307
  const cartWidth = viewportWidth > 1200 ? Math.floor(viewportWidth / 5) : viewportWidth;
345
- return /* @__PURE__ */ jsxs("div", { style: { width: "100%", height: "100%", position: "relative" }, children: [
346
- /* @__PURE__ */ jsx(
347
- SeatmapCanvas,
348
- {
349
- onSeatClick: handleSeatCanvasClick,
350
- onSeatHover,
351
- showSectionLabels: showLabels,
352
- enableSeatHover: showLabels
353
- }
354
- ),
355
- (showStatuses || showCategories) && /* @__PURE__ */ jsxs("aside", { "aria-label": "Seatmap legend", style: legendContainerStyle, children: [
356
- showStatuses && /* @__PURE__ */ jsxs("section", { children: [
357
- /* @__PURE__ */ jsx("p", { style: legendHeadingStyle, children: "Seat Status" }),
358
- /* @__PURE__ */ jsx("ul", { style: legendListStyle, children: venue.seatStatuses.map((status) => /* @__PURE__ */ jsxs("li", { style: legendItemStyle, children: [
359
- /* @__PURE__ */ jsx("span", { style: { ...legendSwatchStyle, background: status.color } }),
360
- /* @__PURE__ */ jsx("span", { children: status.name })
361
- ] }, status.id)) })
362
- ] }),
363
- showStatuses && showCategories && /* @__PURE__ */ jsx("div", { style: { height: 1, background: "rgba(123, 123, 165, 0.45)", margin: "8px 0" } }),
364
- showCategories && /* @__PURE__ */ jsxs("section", { children: [
365
- /* @__PURE__ */ jsx("p", { style: legendHeadingStyle, children: "Pricing" }),
366
- /* @__PURE__ */ jsx("ul", { style: legendListStyle, children: venue.categories.map((category) => /* @__PURE__ */ jsxs("li", { style: legendItemStyle, children: [
367
- /* @__PURE__ */ jsx("span", { style: { ...legendSwatchStyle, background: category.color } }),
368
- /* @__PURE__ */ jsx("span", { children: category.name })
369
- ] }, category.id)) })
370
- ] })
371
- ] }),
372
- !isCartOpen && /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => setIsCartOpen(true), style: cartChipStyle, children: [
373
- "Cart (",
374
- totalSelectedSeats,
375
- ")"
376
- ] }),
377
- isCartOpen && /* @__PURE__ */ jsxs("aside", { "aria-label": "Selected seats cart", style: { ...cartPopupStyle, width: cartWidth, maxWidth: "100%" }, children: [
378
- /* @__PURE__ */ jsxs(
379
- "div",
380
- {
381
- style: {
382
- display: "flex",
383
- alignItems: "center",
384
- justifyContent: "space-between",
385
- gap: 8,
386
- padding: "10px 12px",
387
- borderBottom: "1px solid rgba(110, 110, 150, 0.35)"
388
- },
389
- children: [
390
- /* @__PURE__ */ jsx("strong", { style: { color: "#ececff", fontSize: 13, fontFamily: "system-ui" }, children: "Selected Seats Cart" }),
391
- /* @__PURE__ */ jsx(
392
- "button",
393
- {
394
- type: "button",
395
- onClick: () => setIsCartOpen(false),
396
- style: { ...cartIconButtonStyle, width: 22, height: 22 },
397
- title: "Close cart",
398
- "aria-label": "Close cart",
399
- children: "x"
400
- }
401
- )
402
- ]
403
- }
404
- ),
405
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 8, overflow: "auto", padding: 12, flex: 1 }, children: groupedSeatsList.length === 0 ? /* @__PURE__ */ jsx("div", { style: { color: "#9e9eb8", fontSize: 12, fontFamily: "system-ui" }, children: "No seats selected yet." }) : groupedSeatsList.map((group) => /* @__PURE__ */ jsxs(
406
- "article",
407
- {
408
- style: {
409
- background: "#242447",
410
- border: "1px solid #3b3b61",
411
- borderRadius: 8,
412
- padding: 8,
413
- display: "flex",
414
- flexDirection: "column",
415
- gap: 6
416
- },
417
- children: [
418
- /* @__PURE__ */ jsx("div", { style: { color: "#ececff", fontSize: 12, fontFamily: "system-ui", fontWeight: 600 }, children: group.categoryName }),
419
- /* @__PURE__ */ jsxs("div", { style: { color: "#adb0d2", fontSize: 11, fontFamily: "system-ui" }, children: [
420
- group.seats.length,
421
- " ticket",
422
- group.seats.length === 1 ? "" : "s",
423
- " - ",
424
- formatMoney(group.unitPrice),
425
- " each"
426
- ] }),
427
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 }, children: [
428
- /* @__PURE__ */ jsxs("div", { style: { display: "inline-flex", alignItems: "center", gap: 6 }, children: [
429
- /* @__PURE__ */ jsx(
430
- "button",
431
- {
432
- type: "button",
433
- style: cartIconButtonStyle,
434
- onClick: () => handleRemoveLastInCategory(group.categoryId),
435
- disabled: group.seats.length === 0,
436
- "aria-label": `Remove one ${group.categoryName} seat`,
437
- children: "-"
438
- }
439
- ),
440
- /* @__PURE__ */ jsx("span", { style: { minWidth: 20, textAlign: "center", color: "#ececff", fontSize: 12 }, children: group.seats.length }),
441
- /* @__PURE__ */ jsx(
442
- "button",
443
- {
444
- type: "button",
445
- style: cartIconButtonStyle,
446
- onClick: () => handleAddSeatInCategory(group.categoryId),
447
- disabled: group.availableToAdd === 0,
448
- "aria-label": `Add one ${group.categoryName} seat`,
449
- children: "+"
450
- }
451
- )
308
+ return /* @__PURE__ */ jsxs(
309
+ "div",
310
+ {
311
+ className: classNames.root,
312
+ style: mergeStyles({ width: "100%", height: "100%", position: "relative" }, styles.root),
313
+ children: [
314
+ /* @__PURE__ */ jsx(
315
+ SeatmapCanvas,
316
+ {
317
+ onSeatClick: handleSeatCanvasClick,
318
+ onSeatHover,
319
+ showSectionLabels: showLabels,
320
+ enableSeatHover: showLabels
321
+ }
322
+ ),
323
+ (showStatuses || showCategories) && /* @__PURE__ */ jsxs(
324
+ "aside",
325
+ {
326
+ "aria-label": messages.legendAriaLabel,
327
+ className: mergeClassNames("seatmap-viewer__legend", classNames.legendContainer),
328
+ style: styles.legendContainer,
329
+ children: [
330
+ showStatuses && /* @__PURE__ */ jsxs("section", { className: "seatmap-viewer__legend-section", children: [
331
+ /* @__PURE__ */ jsx("p", { className: mergeClassNames("seatmap-viewer__legend-heading-base", classNames.legendHeading), style: styles.legendHeading, children: messages.legendStatusesTitle }),
332
+ /* @__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: [
333
+ /* @__PURE__ */ jsx(
334
+ "span",
335
+ {
336
+ className: mergeClassNames("seatmap-viewer__legend-swatch-base", classNames.legendSwatch),
337
+ style: mergeStyles({ background: status.color }, styles.legendSwatch)
338
+ }
339
+ ),
340
+ /* @__PURE__ */ jsx("span", { children: status.name })
341
+ ] }, status.id)) })
452
342
  ] }),
453
- /* @__PURE__ */ jsx("span", { style: { color: "#ececff", fontSize: 12, fontFamily: "system-ui", fontWeight: 600 }, children: formatMoney(group.seats.reduce((sum, seat) => sum + seat.unitPrice, 0)) })
454
- ] }),
455
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: group.seats.map((seat) => /* @__PURE__ */ jsxs(
456
- "div",
457
- {
458
- style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 },
459
- children: [
460
- /* @__PURE__ */ jsxs("span", { style: { color: "#c8c8df", fontSize: 11, fontFamily: "system-ui" }, children: [
461
- seat.sectionLabel ?? "Section",
462
- " ",
463
- seat.rowLabel ? `- ${seat.rowLabel}${seat.seatLabel}` : `- ${seat.seatLabel}`
464
- ] }),
343
+ showStatuses && showCategories && /* @__PURE__ */ jsx(
344
+ "div",
345
+ {
346
+ className: mergeClassNames("seatmap-viewer__legend-divider-base", classNames.legendDivider),
347
+ style: styles.legendDivider
348
+ }
349
+ ),
350
+ showCategories && /* @__PURE__ */ jsxs("section", { className: "seatmap-viewer__legend-section", children: [
351
+ /* @__PURE__ */ jsx("p", { className: mergeClassNames("seatmap-viewer__legend-heading-base", classNames.legendHeading), style: styles.legendHeading, children: messages.legendPricesTitle }),
352
+ /* @__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: [
465
353
  /* @__PURE__ */ jsx(
466
- "button",
354
+ "span",
467
355
  {
468
- type: "button",
469
- style: cartIconButtonStyle,
470
- onClick: () => removeSeatFromSelection(seat.seatId),
471
- title: "Remove seat",
472
- "aria-label": `Remove seat ${seat.seatLabel}`,
473
- children: /* @__PURE__ */ jsx(TrashIcon, {})
356
+ className: mergeClassNames("seatmap-viewer__legend-swatch-base", classNames.legendSwatch),
357
+ style: mergeStyles({ background: category.color }, styles.legendSwatch)
474
358
  }
475
- )
476
- ]
477
- },
478
- seat.seatId
479
- )) })
480
- ]
481
- },
482
- group.categoryId
483
- )) }),
484
- /* @__PURE__ */ jsxs(
485
- "div",
486
- {
487
- style: {
488
- borderTop: "1px solid rgba(110, 110, 150, 0.35)",
489
- padding: 12,
490
- display: "flex",
491
- flexDirection: "column",
492
- gap: 8
493
- },
494
- children: [
495
- /* @__PURE__ */ jsxs("div", { style: { color: "#d4d4ee", fontSize: 12, fontFamily: "system-ui" }, children: [
496
- totalSelectedSeats,
497
- " seat",
498
- totalSelectedSeats === 1 ? "" : "s",
499
- " - Total ",
500
- formatMoney(totalCost)
501
- ] }),
502
- /* @__PURE__ */ jsx(
503
- "button",
504
- {
505
- type: "button",
506
- disabled: cartSeats.length === 0,
507
- onClick: handleProceed,
508
- style: {
509
- border: "1px solid #2f7b44",
510
- background: cartSeats.length === 0 ? "#30543d" : "#2f7b44",
511
- color: "#ecfff2",
512
- borderRadius: 8,
513
- padding: "8px 12px",
514
- fontSize: 13,
515
- fontWeight: 600,
516
- fontFamily: "system-ui",
517
- cursor: cartSeats.length === 0 ? "not-allowed" : "pointer"
518
- },
519
- children: "Proceed"
520
- }
521
- )
522
- ]
523
- }
524
- )
525
- ] }),
526
- showLabels && /* @__PURE__ */ jsx(TooltipOverlay, { renderTooltip })
527
- ] });
359
+ ),
360
+ /* @__PURE__ */ jsx("span", { children: category.name })
361
+ ] }, category.id)) })
362
+ ] })
363
+ ]
364
+ }
365
+ ),
366
+ !isCartOpen && /* @__PURE__ */ jsx(
367
+ "button",
368
+ {
369
+ type: "button",
370
+ className: mergeClassNames("seatmap-viewer__cart-chip-base", classNames.cartChip),
371
+ onClick: () => setIsCartOpen(true),
372
+ style: styles.cartChip,
373
+ children: messages.cartChipLabel(totalSelectedSeats)
374
+ }
375
+ ),
376
+ isCartOpen && /* @__PURE__ */ jsxs(
377
+ "aside",
378
+ {
379
+ "aria-label": messages.cartAriaLabel,
380
+ className: mergeClassNames("seatmap-viewer__cart-popup-base", classNames.cartPopup),
381
+ style: mergeStyles({ width: cartWidth, maxWidth: "100%" }, styles.cartPopup),
382
+ children: [
383
+ /* @__PURE__ */ jsxs(
384
+ "div",
385
+ {
386
+ className: mergeClassNames("seatmap-viewer__cart-header-base", classNames.cartHeader),
387
+ style: styles.cartHeader,
388
+ children: [
389
+ /* @__PURE__ */ jsx(
390
+ "strong",
391
+ {
392
+ className: mergeClassNames("seatmap-viewer__cart-header-title-base", classNames.cartHeaderTitle),
393
+ style: styles.cartHeaderTitle,
394
+ children: messages.cartHeaderTitle
395
+ }
396
+ ),
397
+ /* @__PURE__ */ jsx(
398
+ "button",
399
+ {
400
+ type: "button",
401
+ onClick: () => setIsCartOpen(false),
402
+ className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
403
+ style: styles.cartIconButton,
404
+ title: messages.cartCloseLabel,
405
+ "aria-label": messages.cartCloseLabel,
406
+ children: "x"
407
+ }
408
+ )
409
+ ]
410
+ }
411
+ ),
412
+ /* @__PURE__ */ jsx(
413
+ "div",
414
+ {
415
+ className: mergeClassNames("seatmap-viewer__cart-body-base", classNames.cartBody),
416
+ style: styles.cartBody,
417
+ children: groupedSeatsList.length === 0 ? /* @__PURE__ */ jsx(
418
+ "div",
419
+ {
420
+ className: mergeClassNames("seatmap-viewer__cart-empty-state-base", classNames.cartEmptyState),
421
+ style: styles.cartEmptyState,
422
+ children: messages.cartEmptyState
423
+ }
424
+ ) : groupedSeatsList.map((group) => /* @__PURE__ */ jsxs(
425
+ "article",
426
+ {
427
+ className: mergeClassNames("seatmap-viewer__cart-group-base", classNames.cartGroup),
428
+ style: styles.cartGroup,
429
+ children: [
430
+ /* @__PURE__ */ jsx(
431
+ "div",
432
+ {
433
+ className: mergeClassNames("seatmap-viewer__cart-group-title-base", classNames.cartGroupTitle),
434
+ style: styles.cartGroupTitle,
435
+ children: group.categoryName
436
+ }
437
+ ),
438
+ /* @__PURE__ */ jsx(
439
+ "div",
440
+ {
441
+ className: mergeClassNames("seatmap-viewer__cart-group-meta-base", classNames.cartGroupMeta),
442
+ style: styles.cartGroupMeta,
443
+ children: messages.cartGroupMeta(group.seats.length, formatMoney(group.unitPrice, locale, currency))
444
+ }
445
+ ),
446
+ /* @__PURE__ */ jsxs("div", { className: mergeClassNames("seatmap-viewer__cart-quantity-row-base", classNames.cartQuantityRow), style: styles.cartQuantityRow, children: [
447
+ /* @__PURE__ */ jsxs("div", { className: "seatmap-viewer__cart-quantity-controls", children: [
448
+ /* @__PURE__ */ jsx(
449
+ "button",
450
+ {
451
+ type: "button",
452
+ className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
453
+ style: styles.cartIconButton,
454
+ onClick: () => handleRemoveLastInCategory(group.categoryId),
455
+ disabled: group.seats.length === 0,
456
+ "aria-label": messages.cartRemoveOneAriaLabel(group.categoryName),
457
+ children: "-"
458
+ }
459
+ ),
460
+ /* @__PURE__ */ jsx(
461
+ "span",
462
+ {
463
+ className: mergeClassNames("seatmap-viewer__cart-quantity-value-base", classNames.cartQuantityValue),
464
+ style: styles.cartQuantityValue,
465
+ children: group.seats.length
466
+ }
467
+ ),
468
+ /* @__PURE__ */ jsx(
469
+ "button",
470
+ {
471
+ type: "button",
472
+ className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
473
+ style: styles.cartIconButton,
474
+ onClick: () => handleAddSeatInCategory(group.categoryId),
475
+ disabled: group.availableToAdd === 0,
476
+ "aria-label": messages.cartAddOneAriaLabel(group.categoryName),
477
+ children: "+"
478
+ }
479
+ )
480
+ ] }),
481
+ /* @__PURE__ */ jsx(
482
+ "span",
483
+ {
484
+ className: mergeClassNames("seatmap-viewer__cart-group-total-base", classNames.cartGroupTotal),
485
+ style: styles.cartGroupTotal,
486
+ children: formatMoney(group.seats.reduce((sum, seat) => sum + seat.unitPrice, 0), locale, currency)
487
+ }
488
+ )
489
+ ] }),
490
+ /* @__PURE__ */ jsx("div", { className: "seatmap-viewer__cart-seat-list", children: group.seats.map((seat) => /* @__PURE__ */ jsxs(
491
+ "div",
492
+ {
493
+ className: mergeClassNames("seatmap-viewer__cart-seat-row-base", classNames.cartSeatRow),
494
+ style: styles.cartSeatRow,
495
+ children: [
496
+ /* @__PURE__ */ jsxs(
497
+ "span",
498
+ {
499
+ className: mergeClassNames("seatmap-viewer__cart-seat-label-base", classNames.cartSeatLabel),
500
+ style: styles.cartSeatLabel,
501
+ children: [
502
+ seat.sectionLabel ?? messages.sectionFallbackLabel,
503
+ " ",
504
+ seat.rowLabel ? `- ${seat.rowLabel}${seat.seatLabel}` : `- ${seat.seatLabel}`
505
+ ]
506
+ }
507
+ ),
508
+ /* @__PURE__ */ jsx(
509
+ "button",
510
+ {
511
+ type: "button",
512
+ className: mergeClassNames("seatmap-viewer__cart-icon-button-base", classNames.cartIconButton),
513
+ style: styles.cartIconButton,
514
+ onClick: () => removeSeatFromSelection(seat.seatId),
515
+ title: messages.cartRemoveSeatTitle,
516
+ "aria-label": messages.cartRemoveSeatAriaLabel(seat.seatLabel),
517
+ children: /* @__PURE__ */ jsx(TrashIcon, {})
518
+ }
519
+ )
520
+ ]
521
+ },
522
+ seat.seatId
523
+ )) })
524
+ ]
525
+ },
526
+ group.categoryId
527
+ ))
528
+ }
529
+ ),
530
+ /* @__PURE__ */ jsxs(
531
+ "div",
532
+ {
533
+ className: mergeClassNames("seatmap-viewer__cart-footer-base", classNames.cartFooter),
534
+ style: styles.cartFooter,
535
+ children: [
536
+ /* @__PURE__ */ jsx(
537
+ "div",
538
+ {
539
+ className: mergeClassNames("seatmap-viewer__cart-summary-base", classNames.cartSummary),
540
+ style: styles.cartSummary,
541
+ children: messages.cartSummary(totalSelectedSeats, formatMoney(totalCost, locale, currency))
542
+ }
543
+ ),
544
+ /* @__PURE__ */ jsx(
545
+ "button",
546
+ {
547
+ type: "button",
548
+ disabled: cartSeats.length === 0,
549
+ onClick: handleProceed,
550
+ className: mergeClassNames("seatmap-viewer__cart-proceed-button-base", classNames.cartProceedButton),
551
+ style: styles.cartProceedButton,
552
+ children: messages.cartProceedButton
553
+ }
554
+ )
555
+ ]
556
+ }
557
+ )
558
+ ]
559
+ }
560
+ ),
561
+ showLabels && /* @__PURE__ */ jsx(TooltipOverlay, { renderTooltip })
562
+ ]
563
+ }
564
+ );
528
565
  }
529
566
  function SeatmapViewer({
530
567
  venue,
@@ -534,22 +571,204 @@ function SeatmapViewer({
534
571
  renderTooltip,
535
572
  showLabels = true,
536
573
  className,
537
- onCartEvent
574
+ onCartEvent,
575
+ locale,
576
+ currency,
577
+ styles,
578
+ classNames,
579
+ messages
538
580
  }) {
539
- return /* @__PURE__ */ jsx(SeatmapProvider, { venue, children: /* @__PURE__ */ jsx("div", { className, style: { width: "100%", height: "100%", position: "relative" }, children: /* @__PURE__ */ jsx(
540
- ViewerContent,
581
+ return /* @__PURE__ */ jsx(SeatmapProvider, { venue, children: /* @__PURE__ */ jsx(
582
+ "div",
541
583
  {
542
- venue,
543
- onSeatClick,
544
- onSeatHover,
545
- onSelectionChange,
546
- renderTooltip,
547
- showLabels,
548
- onCartEvent
584
+ className: mergeClassNames(className, classNames?.root),
585
+ style: mergeStyles({ width: "100%", height: "100%", position: "relative" }, styles?.root),
586
+ children: /* @__PURE__ */ jsx(
587
+ SeatmapViewerContent,
588
+ {
589
+ venue,
590
+ onSeatClick,
591
+ onSeatHover,
592
+ onSelectionChange,
593
+ renderTooltip,
594
+ showLabels,
595
+ onCartEvent,
596
+ locale,
597
+ currency,
598
+ styles,
599
+ classNames,
600
+ messages
601
+ }
602
+ )
549
603
  }
550
- ) }) });
604
+ ) });
605
+ }
606
+
607
+ // src/styleContract.ts
608
+ var seatmapViewerStyleSlots = [
609
+ "root",
610
+ "legendContainer",
611
+ "legendHeading",
612
+ "legendList",
613
+ "legendItem",
614
+ "legendSwatch",
615
+ "legendDivider",
616
+ "cartChip",
617
+ "cartPopup",
618
+ "cartHeader",
619
+ "cartHeaderTitle",
620
+ "cartIconButton",
621
+ "cartBody",
622
+ "cartEmptyState",
623
+ "cartGroup",
624
+ "cartGroupTitle",
625
+ "cartGroupMeta",
626
+ "cartQuantityRow",
627
+ "cartQuantityValue",
628
+ "cartGroupTotal",
629
+ "cartSeatRow",
630
+ "cartSeatLabel",
631
+ "cartFooter",
632
+ "cartSummary",
633
+ "cartProceedButton"
634
+ ];
635
+ var STYLE_CONTRACT_CLASS_PREFIX = "seatmap-viewer";
636
+ var seatmapViewerDefaultClassNames = {
637
+ root: `${STYLE_CONTRACT_CLASS_PREFIX}__root`,
638
+ legendContainer: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-container`,
639
+ legendHeading: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-heading`,
640
+ legendList: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-list`,
641
+ legendItem: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-item`,
642
+ legendSwatch: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-swatch`,
643
+ legendDivider: `${STYLE_CONTRACT_CLASS_PREFIX}__legend-divider`,
644
+ cartChip: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-chip`,
645
+ cartPopup: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-popup`,
646
+ cartHeader: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-header`,
647
+ cartHeaderTitle: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-header-title`,
648
+ cartIconButton: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-icon-button`,
649
+ cartBody: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-body`,
650
+ cartEmptyState: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-empty-state`,
651
+ cartGroup: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group`,
652
+ cartGroupTitle: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-title`,
653
+ cartGroupMeta: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-meta`,
654
+ cartQuantityRow: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-quantity-row`,
655
+ cartQuantityValue: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-quantity-value`,
656
+ cartGroupTotal: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-group-total`,
657
+ cartSeatRow: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-seat-row`,
658
+ cartSeatLabel: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-seat-label`,
659
+ cartFooter: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-footer`,
660
+ cartSummary: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-summary`,
661
+ cartProceedButton: `${STYLE_CONTRACT_CLASS_PREFIX}__cart-proceed-button`
662
+ };
663
+ var seatmapViewerCssVariables = [
664
+ "--seatmap-surface",
665
+ "--seatmap-surface-elevated",
666
+ "--seatmap-surface-muted",
667
+ "--seatmap-on-surface",
668
+ "--seatmap-on-surface-variant",
669
+ "--seatmap-outline",
670
+ "--seatmap-outline-variant",
671
+ "--seatmap-primary",
672
+ "--seatmap-on-primary",
673
+ "--seatmap-error",
674
+ "--seatmap-on-error",
675
+ "--seatmap-state-layer-hover",
676
+ "--seatmap-state-layer-pressed",
677
+ "--seatmap-focus-ring",
678
+ "--seatmap-radius-sm",
679
+ "--seatmap-radius-md",
680
+ "--seatmap-radius-lg",
681
+ "--seatmap-shadow-raised",
682
+ "--seatmap-shadow-elevated",
683
+ "--seatmap-shadow-floating",
684
+ "--seatmap-viewer-surface",
685
+ "--seatmap-viewer-surface-elevated",
686
+ "--seatmap-viewer-surface-muted",
687
+ "--seatmap-viewer-border",
688
+ "--seatmap-viewer-border-subtle",
689
+ "--seatmap-viewer-text",
690
+ "--seatmap-viewer-text-muted",
691
+ "--seatmap-viewer-accent",
692
+ "--seatmap-viewer-accent-disabled",
693
+ "--seatmap-viewer-accent-text",
694
+ "--seatmap-viewer-danger",
695
+ "--seatmap-viewer-danger-text",
696
+ "--seatmap-viewer-state-layer-hover",
697
+ "--seatmap-viewer-state-layer-pressed",
698
+ "--seatmap-viewer-focus-ring",
699
+ "--seatmap-viewer-radius-sm",
700
+ "--seatmap-viewer-radius-md",
701
+ "--seatmap-viewer-radius-lg",
702
+ "--seatmap-viewer-shadow-raised",
703
+ "--seatmap-viewer-shadow-elevated",
704
+ "--seatmap-viewer-shadow-floating"
705
+ ];
706
+ var seatmapViewerStyleContract = {
707
+ slots: seatmapViewerStyleSlots,
708
+ defaultClassNames: seatmapViewerDefaultClassNames,
709
+ cssVariables: seatmapViewerCssVariables
710
+ };
711
+
712
+ // src/theme/seatmapViewerTheme.ts
713
+ var seatmapViewerSharedThemeRootClassName = "seatmap-viewer-theme";
714
+ var seatmapViewerSharedThemeClassNames = {
715
+ ...seatmapViewerDefaultClassNames
716
+ };
717
+ var seatmapViewerSharedThemeVariables = {
718
+ "--seatmap-surface": "var(--ds-surface-container-low, rgba(24, 24, 24, 0.94))",
719
+ "--seatmap-surface-elevated": "var(--ds-surface-container, rgba(28, 28, 28, 0.98))",
720
+ "--seatmap-surface-muted": "var(--ds-surface-container-high, rgba(33, 33, 33, 1))",
721
+ "--seatmap-on-surface": "var(--ds-on-surface, #e5e2e1)",
722
+ "--seatmap-on-surface-variant": "var(--ds-on-surface-variant, #9a9694)",
723
+ "--seatmap-outline": "var(--ds-input-border, rgba(92, 89, 87, 0.65))",
724
+ "--seatmap-outline-variant": "var(--ds-border-subtle, rgba(92, 89, 87, 0.45))",
725
+ "--seatmap-primary": "var(--ds-primary, #6f663a)",
726
+ "--seatmap-on-primary": "var(--ds-on-primary, #f5edc7)",
727
+ "--seatmap-error": "var(--ds-error, #ad3f3f)",
728
+ "--seatmap-on-error": "var(--ds-on-error, #ffffff)",
729
+ "--seatmap-state-layer-hover": "var(--ds-primary-wash, color-mix(in srgb, var(--ds-primary, #6f663a) 12%, transparent))",
730
+ "--seatmap-state-layer-pressed": "var(--ds-primary-wash-strong, color-mix(in srgb, var(--ds-primary, #6f663a) 16%, transparent))",
731
+ "--seatmap-focus-ring": "var(--ds-primary-ring, color-mix(in srgb, var(--ds-primary, #6f663a) 55%, transparent))",
732
+ "--seatmap-radius-sm": "var(--ds-radius-structural-sm, 8px)",
733
+ "--seatmap-radius-md": "var(--ds-radius-structural, 10px)",
734
+ "--seatmap-radius-lg": "calc(var(--ds-radius-structural, 10px) + 6px)",
735
+ "--seatmap-shadow-raised": "var(--ds-shadow-ambient-sm, 0 8px 20px rgba(0, 0, 0, 0.22))",
736
+ "--seatmap-shadow-elevated": "var(--ds-shadow-ambient, 0 10px 24px rgba(0, 0, 0, 0.28))",
737
+ "--seatmap-shadow-floating": "var(--ds-shadow-ambient-lg, 0 14px 34px rgba(0, 0, 0, 0.32))",
738
+ "--seatmap-viewer-surface": "var(--seatmap-surface)",
739
+ "--seatmap-viewer-surface-elevated": "var(--seatmap-surface-elevated)",
740
+ "--seatmap-viewer-surface-muted": "var(--seatmap-surface-muted)",
741
+ "--seatmap-viewer-border": "var(--seatmap-outline)",
742
+ "--seatmap-viewer-border-subtle": "var(--seatmap-outline-variant)",
743
+ "--seatmap-viewer-text": "var(--seatmap-on-surface)",
744
+ "--seatmap-viewer-text-muted": "var(--seatmap-on-surface-variant)",
745
+ "--seatmap-viewer-accent": "var(--seatmap-primary)",
746
+ "--seatmap-viewer-accent-disabled": "color-mix(in srgb, var(--seatmap-primary) 28%, var(--seatmap-surface-muted))",
747
+ "--seatmap-viewer-accent-text": "var(--seatmap-on-primary)",
748
+ "--seatmap-viewer-danger": "var(--seatmap-error)",
749
+ "--seatmap-viewer-danger-text": "var(--seatmap-on-error)",
750
+ "--seatmap-viewer-state-layer-hover": "var(--seatmap-state-layer-hover)",
751
+ "--seatmap-viewer-state-layer-pressed": "var(--seatmap-state-layer-pressed)",
752
+ "--seatmap-viewer-focus-ring": "var(--seatmap-focus-ring)",
753
+ "--seatmap-viewer-radius-sm": "var(--seatmap-radius-sm)",
754
+ "--seatmap-viewer-radius-md": "var(--seatmap-radius-md)",
755
+ "--seatmap-viewer-radius-lg": "var(--seatmap-radius-lg)",
756
+ "--seatmap-viewer-shadow-raised": "var(--seatmap-shadow-raised)",
757
+ "--seatmap-viewer-shadow-elevated": "var(--seatmap-shadow-elevated)",
758
+ "--seatmap-viewer-shadow-floating": "var(--seatmap-shadow-floating)"
759
+ };
760
+ var seatmapViewerSharedTheme = {
761
+ rootClassName: seatmapViewerSharedThemeRootClassName,
762
+ classNames: seatmapViewerSharedThemeClassNames,
763
+ variables: seatmapViewerSharedThemeVariables
764
+ };
765
+ function getSeatmapViewerSharedThemeRootStyle(overrides) {
766
+ return {
767
+ ...seatmapViewerSharedThemeVariables,
768
+ ...overrides ?? {}
769
+ };
551
770
  }
552
771
 
553
- export { SeatmapViewer };
772
+ export { SeatmapViewer, SeatmapViewerContent, defaultSeatmapViewerMessages, getSeatmapViewerSharedThemeRootStyle, seatmapViewerCssVariables, seatmapViewerDefaultClassNames, seatmapViewerSharedTheme, seatmapViewerSharedThemeClassNames, seatmapViewerSharedThemeRootClassName, seatmapViewerSharedThemeVariables, seatmapViewerStyleContract, seatmapViewerStyleSlots };
554
773
  //# sourceMappingURL=index.js.map
555
774
  //# sourceMappingURL=index.js.map