@seatlayer/core 0.17.0 → 0.18.1
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 +94 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +122 -6
- package/dist/index.d.ts +122 -6
- package/dist/index.js +90 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12,6 +12,21 @@ var ACCESSIBILITY_LABEL = new Map(ACCESSIBILITY_TYPES.map((a) => [a.key, a]));
|
|
|
12
12
|
function accessibilityMeta(key) {
|
|
13
13
|
return ACCESSIBILITY_LABEL.get(key);
|
|
14
14
|
}
|
|
15
|
+
var ACCESSIBILITY_RING_COLOR = {
|
|
16
|
+
wheelchair: "#3b82f6",
|
|
17
|
+
companion: "#8b5cf6",
|
|
18
|
+
"semi-ambulatory": "#0ea5e9",
|
|
19
|
+
hearing: "#14b8a6",
|
|
20
|
+
"sign-language": "#f59e0b",
|
|
21
|
+
"plus-size": "#ec4899",
|
|
22
|
+
"lift-armrest": "#22c55e"
|
|
23
|
+
};
|
|
24
|
+
function accessibilityRingColor(types) {
|
|
25
|
+
const primary = types?.[0];
|
|
26
|
+
return primary && ACCESSIBILITY_RING_COLOR[primary] || "#3b82f6";
|
|
27
|
+
}
|
|
28
|
+
var LABEL_STYLE_MIN_SIZE = 8;
|
|
29
|
+
var LABEL_STYLE_MAX_SIZE = 24;
|
|
15
30
|
function layerOf(obj) {
|
|
16
31
|
switch (obj.type) {
|
|
17
32
|
case "row":
|
|
@@ -158,15 +173,22 @@ function expandRowSlots(row) {
|
|
|
158
173
|
return rowSeatPositions(row).map((p, i) => {
|
|
159
174
|
const o = ov.get(i);
|
|
160
175
|
const accessibility = overrideAccessibility(o);
|
|
176
|
+
const inventoryLabel = o?.label ?? `${row.label}-${seatNumber(i)}`;
|
|
177
|
+
const displayPrefix = row.displayLabel ?? row.label;
|
|
178
|
+
const commercial = { ...row.commercial, ...o?.commercial };
|
|
161
179
|
return {
|
|
162
180
|
index: i,
|
|
163
181
|
x: p.x + (o?.dx ?? 0),
|
|
164
182
|
y: p.y + (o?.dy ?? 0),
|
|
165
|
-
label:
|
|
183
|
+
label: inventoryLabel,
|
|
184
|
+
displayLabel: o?.displayLabel ?? `${displayPrefix}-${seatNumber(i)}`,
|
|
166
185
|
categoryKey: o?.categoryKey ?? row.categoryKey,
|
|
167
186
|
skipped: !!o?.skip,
|
|
168
187
|
accessible: accessibility.length > 0,
|
|
169
|
-
accessibility
|
|
188
|
+
accessibility,
|
|
189
|
+
commercial: Object.values(commercial).some((value) => value !== void 0 && value !== false && value !== "") ? commercial : void 0,
|
|
190
|
+
viewUrl: o?.viewFromSeatUrl ?? row.viewFromSeatUrl,
|
|
191
|
+
labelStyle: o?.labelStyle
|
|
170
192
|
};
|
|
171
193
|
});
|
|
172
194
|
}
|
|
@@ -177,13 +199,16 @@ function expandRow(row) {
|
|
|
177
199
|
seats.push({
|
|
178
200
|
id: `${row.id}:${slot.index}`,
|
|
179
201
|
label: slot.label,
|
|
202
|
+
displayLabel: slot.displayLabel === slot.label ? void 0 : slot.displayLabel,
|
|
180
203
|
x: slot.x,
|
|
181
204
|
y: slot.y,
|
|
182
205
|
rowId: row.id,
|
|
183
206
|
categoryKey: slot.categoryKey,
|
|
184
207
|
accessible: slot.accessible || void 0,
|
|
185
208
|
accessibility: slot.accessibility.length ? slot.accessibility : void 0,
|
|
186
|
-
|
|
209
|
+
commercial: slot.commercial,
|
|
210
|
+
viewUrl: slot.viewUrl,
|
|
211
|
+
labelStyle: slot.labelStyle
|
|
187
212
|
});
|
|
188
213
|
}
|
|
189
214
|
return seats;
|
|
@@ -541,7 +566,7 @@ function computeSections(doc) {
|
|
|
541
566
|
}
|
|
542
567
|
nodes.set(logicalId, {
|
|
543
568
|
id: logicalId,
|
|
544
|
-
label: s.label || "Section",
|
|
569
|
+
label: s.displayLabel || s.label || "Section",
|
|
545
570
|
zone: s.zone,
|
|
546
571
|
seatCount: 0,
|
|
547
572
|
objectIds: [],
|
|
@@ -869,15 +894,6 @@ var CLOSED_SEAT_OPACITY = 0.4;
|
|
|
869
894
|
var FOCUS_DIM_OPACITY = 0.16;
|
|
870
895
|
var FOCUS_BACKDROP_FILL = "rgba(244,246,248,0.06)";
|
|
871
896
|
var CB_PALETTE = ["#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7"];
|
|
872
|
-
var ACCESS_RING = {
|
|
873
|
-
wheelchair: "#3b82f6",
|
|
874
|
-
companion: "#8b5cf6",
|
|
875
|
-
"semi-ambulatory": "#0ea5e9",
|
|
876
|
-
hearing: "#14b8a6",
|
|
877
|
-
"sign-language": "#f59e0b",
|
|
878
|
-
"plus-size": "#ec4899",
|
|
879
|
-
"lift-armrest": "#22c55e"
|
|
880
|
-
};
|
|
881
897
|
function seatMatchesAccess(seat, filter) {
|
|
882
898
|
if (filter.length === 0) return !!seat.accessible;
|
|
883
899
|
return !!seat.accessibility?.some((t2) => filter.includes(t2));
|
|
@@ -2327,13 +2343,12 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
2327
2343
|
this.paintSeat(c, seat.id);
|
|
2328
2344
|
target.add(c);
|
|
2329
2345
|
if (seat.accessible) {
|
|
2330
|
-
const primary = seat.accessibility?.[0];
|
|
2331
2346
|
target.add(
|
|
2332
2347
|
new Circle({
|
|
2333
2348
|
x: seat.x,
|
|
2334
2349
|
y: seat.y,
|
|
2335
2350
|
radius: this.seatR + 1,
|
|
2336
|
-
stroke:
|
|
2351
|
+
stroke: accessibilityRingColor(seat.accessibility),
|
|
2337
2352
|
strokeWidth: 2,
|
|
2338
2353
|
listening: false,
|
|
2339
2354
|
perfectDrawEnabled: false,
|
|
@@ -2366,7 +2381,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
2366
2381
|
const t2 = new Text({
|
|
2367
2382
|
x: seat.x,
|
|
2368
2383
|
y: seat.y,
|
|
2369
|
-
text: seat.label,
|
|
2384
|
+
text: seat.displayLabel ?? seat.label,
|
|
2370
2385
|
fontSize: BOOTH_LABEL_FONT_SIZE,
|
|
2371
2386
|
fontStyle: "600",
|
|
2372
2387
|
fontFamily: this.labelFont(),
|
|
@@ -2389,14 +2404,22 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
2389
2404
|
const idx = this.catOrder.indexOf(categoryKey);
|
|
2390
2405
|
return CB_PALETTE[(idx >= 0 ? idx : 0) % CB_PALETTE.length];
|
|
2391
2406
|
}
|
|
2392
|
-
/**
|
|
2393
|
-
*
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2407
|
+
/** Per-seat authored label size relative to the neutral default (1 = default),
|
|
2408
|
+
* mirroring the section convention (labelStyle.size ?? 18) / 18. Only real
|
|
2409
|
+
* seats carry labelStyle, so booths and unstyled seats resolve to 1. */
|
|
2410
|
+
seatLabelScale(seat) {
|
|
2411
|
+
return (seat.labelStyle?.size ?? 18) / 18;
|
|
2412
|
+
}
|
|
2413
|
+
/** Preferred label ink for a seat: the authored per-seat colour when set,
|
|
2414
|
+
* otherwise today's theme default. Fed through auto-contrast by seatLabelInk. */
|
|
2415
|
+
seatPreferredLabelInk(seat) {
|
|
2416
|
+
return seat.labelStyle?.color ?? this.theme.seatLabelColor ?? DEF_SEAT_LABEL;
|
|
2417
|
+
}
|
|
2418
|
+
/** Resolve a seat's label ink against the paint actually visible, honouring an
|
|
2419
|
+
* authored per-seat colour through the same auto-contrast rule as sections. */
|
|
2420
|
+
seatLabelInk(seat, shape) {
|
|
2398
2421
|
const fill = shape.fill();
|
|
2399
|
-
return stateAwareBookableLabelInk(typeof fill === "string" ? fill : "",
|
|
2422
|
+
return stateAwareBookableLabelInk(typeof fill === "string" ? fill : "", this.seatPreferredLabelInk(seat));
|
|
2400
2423
|
}
|
|
2401
2424
|
/** Apply fill/stroke/opacity for a seat's current status + selection. */
|
|
2402
2425
|
paintSeat(c, id) {
|
|
@@ -2480,7 +2503,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
2480
2503
|
if (this.selectionFocusId && id !== this.selectionFocusId) c.opacity(Math.min(c.opacity(), 0.16));
|
|
2481
2504
|
const bookableLabel = this.boothLabelById.get(id) ?? this.seatLabelById.get(id);
|
|
2482
2505
|
if (bookableLabel) {
|
|
2483
|
-
bookableLabel.fill(this.
|
|
2506
|
+
bookableLabel.fill(this.seatLabelInk(seat, c));
|
|
2484
2507
|
bookableLabel.visible(
|
|
2485
2508
|
isBookableLabelLegibleAtScale(bookableLabel.fontSize(), this.effScale()) && c.opacity() >= 0.5
|
|
2486
2509
|
);
|
|
@@ -3021,14 +3044,19 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3021
3044
|
listening: false
|
|
3022
3045
|
}, obj.outlinePath);
|
|
3023
3046
|
bgTarget.add(blockPoly);
|
|
3047
|
+
const labelStyle = obj.labelPresentation?.labelStyle;
|
|
3048
|
+
const preferredInk = labelStyle?.color ?? palette.sectionInk;
|
|
3049
|
+
const labelScale = (labelStyle?.size ?? 18) / 18;
|
|
3024
3050
|
const nameLabel = new Text({
|
|
3025
|
-
x: centroid.x,
|
|
3026
|
-
y: centroid.y,
|
|
3027
|
-
text: obj.label,
|
|
3028
|
-
|
|
3051
|
+
x: obj.labelPresentation?.position?.x ?? centroid.x,
|
|
3052
|
+
y: obj.labelPresentation?.position?.y ?? centroid.y,
|
|
3053
|
+
text: obj.displayLabel ?? obj.label,
|
|
3054
|
+
rotation: obj.labelPresentation?.rotation ?? 0,
|
|
3055
|
+
visible: obj.labelPresentation?.visible !== false,
|
|
3056
|
+
fontSize: 22 * labelScale,
|
|
3029
3057
|
fontStyle: "700",
|
|
3030
3058
|
fontFamily: this.labelFont(),
|
|
3031
|
-
fill: palette.
|
|
3059
|
+
fill: stateAwareBookableLabelInk(palette.sectionFill, preferredInk),
|
|
3032
3060
|
listening: false,
|
|
3033
3061
|
perfectDrawEnabled: false
|
|
3034
3062
|
});
|
|
@@ -3052,7 +3080,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3052
3080
|
const sec = {
|
|
3053
3081
|
id: obj.id,
|
|
3054
3082
|
logicalId: obj.logicalSectionId ?? obj.id,
|
|
3055
|
-
label: obj.label,
|
|
3083
|
+
label: obj.displayLabel ?? obj.label,
|
|
3056
3084
|
outline: obj.outline,
|
|
3057
3085
|
...obj.outlinePath ? { outlinePath: obj.outlinePath } : {},
|
|
3058
3086
|
holes: obj.holes ?? [],
|
|
@@ -3068,6 +3096,8 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3068
3096
|
blockPoly,
|
|
3069
3097
|
nameLabel,
|
|
3070
3098
|
subLabel,
|
|
3099
|
+
preferredInk,
|
|
3100
|
+
labelScale,
|
|
3071
3101
|
nameLabelFits: true,
|
|
3072
3102
|
subLabelFits: true,
|
|
3073
3103
|
elevation,
|
|
@@ -3236,7 +3266,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3236
3266
|
const sectionFill = sec.blockPoly.fill();
|
|
3237
3267
|
const sectionInk = stateAwareBookableLabelInk(
|
|
3238
3268
|
typeof sectionFill === "string" ? sectionFill : sec.baseFill,
|
|
3239
|
-
|
|
3269
|
+
sec.preferredInk
|
|
3240
3270
|
);
|
|
3241
3271
|
sec.nameLabel.fill(sectionInk);
|
|
3242
3272
|
sec.subLabel.fill(sectionInk);
|
|
@@ -3332,7 +3362,9 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3332
3362
|
fitSectionRungLabels(sec, sx) {
|
|
3333
3363
|
const paddingPx = 8;
|
|
3334
3364
|
sec.subLabelFits = false;
|
|
3335
|
-
|
|
3365
|
+
const maxPx = SECTION_LABEL_PX * sec.labelScale;
|
|
3366
|
+
const minPx = MIN_SECTION_LABEL_PX * sec.labelScale;
|
|
3367
|
+
for (let fontPx = maxPx; fontPx >= minPx; fontPx -= 1) {
|
|
3336
3368
|
for (const rotation of [0, -90]) {
|
|
3337
3369
|
sec.nameLabel.rotation(rotation);
|
|
3338
3370
|
this.sizeLabel(sec.nameLabel, fontPx / sx, sec.nameLabel.y());
|
|
@@ -3851,7 +3883,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
3851
3883
|
const labels = this.seats.map((seat) => {
|
|
3852
3884
|
const shape = this.circleById.get(seat.id);
|
|
3853
3885
|
const label = this.boothLabelById.get(seat.id) ?? this.seatLabelById.get(seat.id);
|
|
3854
|
-
const authoredFontSize = seat.kind === "booth" ? BOOTH_LABEL_FONT_SIZE : SEAT_LABEL_FONT_SIZE;
|
|
3886
|
+
const authoredFontSize = seat.kind === "booth" ? BOOTH_LABEL_FONT_SIZE : SEAT_LABEL_FONT_SIZE * this.seatLabelScale(seat);
|
|
3855
3887
|
const renderedFontPx = rounded((label?.fontSize() ?? authoredFontSize) * effectiveScale);
|
|
3856
3888
|
const screen = this.worldToScreen(seat);
|
|
3857
3889
|
const outside = screen.x < 0 || screen.x > viewport.width || screen.y < 0 || screen.y > viewport.height;
|
|
@@ -4168,9 +4200,10 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
4168
4200
|
minimumFont = Math.min(minimumFont, BOOTH_LABEL_FONT_SIZE);
|
|
4169
4201
|
continue;
|
|
4170
4202
|
}
|
|
4171
|
-
|
|
4172
|
-
measure.
|
|
4173
|
-
|
|
4203
|
+
const authoredFontSize = SEAT_LABEL_FONT_SIZE * this.seatLabelScale(seat);
|
|
4204
|
+
measure.fontSize(authoredFontSize);
|
|
4205
|
+
measure.text(bookableMarkerLabel(seat.displayLabel ?? seat.label));
|
|
4206
|
+
const fitted = measure.width() > maxWidth ? Math.max(MIN_FITTED_SEAT_LABEL_FONT_SIZE, authoredFontSize * maxWidth / measure.width()) : authoredFontSize;
|
|
4174
4207
|
minimumFont = Math.min(minimumFont, fitted);
|
|
4175
4208
|
}
|
|
4176
4209
|
measure.destroy();
|
|
@@ -4320,19 +4353,20 @@ var _SeatmapRenderer = class _SeatmapRenderer {
|
|
|
4320
4353
|
if (++count >= MAX_LABELS) break;
|
|
4321
4354
|
continue;
|
|
4322
4355
|
}
|
|
4356
|
+
const authoredFontSize = SEAT_LABEL_FONT_SIZE * this.seatLabelScale(seat);
|
|
4323
4357
|
const t2 = new Text({
|
|
4324
4358
|
x: seat.x,
|
|
4325
4359
|
y: seat.y,
|
|
4326
|
-
text: bookableMarkerLabel(seat.label),
|
|
4327
|
-
fontSize:
|
|
4360
|
+
text: bookableMarkerLabel(seat.displayLabel ?? seat.label),
|
|
4361
|
+
fontSize: authoredFontSize,
|
|
4328
4362
|
fontStyle: "600",
|
|
4329
4363
|
fontFamily: this.labelFont(),
|
|
4330
|
-
fill: shape ? this.
|
|
4364
|
+
fill: shape ? this.seatLabelInk(seat, shape) : this.seatPreferredLabelInk(seat),
|
|
4331
4365
|
listening: false,
|
|
4332
4366
|
perfectDrawEnabled: false
|
|
4333
4367
|
});
|
|
4334
4368
|
const maxW = this.seatR * 2 - 3;
|
|
4335
|
-
if (t2.width() > maxW) t2.fontSize(Math.max(MIN_FITTED_SEAT_LABEL_FONT_SIZE,
|
|
4369
|
+
if (t2.width() > maxW) t2.fontSize(Math.max(MIN_FITTED_SEAT_LABEL_FONT_SIZE, authoredFontSize * maxW / t2.width()));
|
|
4336
4370
|
if (t2.width() > maxW + 0.01) {
|
|
4337
4371
|
t2.destroy();
|
|
4338
4372
|
continue;
|
|
@@ -5292,6 +5326,15 @@ var PickerController = class {
|
|
|
5292
5326
|
} catch {
|
|
5293
5327
|
}
|
|
5294
5328
|
}
|
|
5329
|
+
/**
|
|
5330
|
+
* Re-pull the status snapshot on demand. Live surfaces rarely need this (the
|
|
5331
|
+
* socket keeps them fresh); local/mock transports with no socket call it
|
|
5332
|
+
* after they mutate state (e.g. the demo books a hold) so the renderer and
|
|
5333
|
+
* every onStatusChange consumer repaint from the new truth.
|
|
5334
|
+
*/
|
|
5335
|
+
async refresh() {
|
|
5336
|
+
await this.resnapshot();
|
|
5337
|
+
}
|
|
5295
5338
|
// ---- realtime socket ------------------------------------------------------
|
|
5296
5339
|
/**
|
|
5297
5340
|
* Buyer catch-up on tab regain. While a tab is hidden Chrome pauses rAF, so
|
|
@@ -5326,9 +5369,11 @@ var PickerController = class {
|
|
|
5326
5369
|
}
|
|
5327
5370
|
connect() {
|
|
5328
5371
|
if (this.closed) return;
|
|
5372
|
+
const url = this.api.socketUrl(this.key);
|
|
5373
|
+
if (!url) return;
|
|
5329
5374
|
let ws;
|
|
5330
5375
|
try {
|
|
5331
|
-
ws = new WebSocket(
|
|
5376
|
+
ws = new WebSocket(url);
|
|
5332
5377
|
} catch {
|
|
5333
5378
|
this.scheduleReconnect();
|
|
5334
5379
|
return;
|
|
@@ -5618,9 +5663,12 @@ async function loadLocale(code) {
|
|
|
5618
5663
|
}
|
|
5619
5664
|
}
|
|
5620
5665
|
export {
|
|
5666
|
+
ACCESSIBILITY_RING_COLOR,
|
|
5621
5667
|
ACCESSIBILITY_TYPES,
|
|
5622
5668
|
CHART_STORAGE_KEY,
|
|
5623
5669
|
DEFAULT_CURRENCY,
|
|
5670
|
+
LABEL_STYLE_MAX_SIZE,
|
|
5671
|
+
LABEL_STYLE_MIN_SIZE,
|
|
5624
5672
|
MAX_EVENT_INVENTORY,
|
|
5625
5673
|
MAX_GA_CAPACITY,
|
|
5626
5674
|
PickerController,
|
|
@@ -5628,6 +5676,7 @@ export {
|
|
|
5628
5676
|
SeatmapRenderer,
|
|
5629
5677
|
UNGROUPED_ID,
|
|
5630
5678
|
accessibilityMeta,
|
|
5679
|
+
accessibilityRingColor,
|
|
5631
5680
|
allObjects,
|
|
5632
5681
|
applyHidden,
|
|
5633
5682
|
chartBounds,
|