@seatlayer/js 0.50.0 → 0.50.2

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
@@ -3979,6 +3979,8 @@ var SeatPicker = class _SeatPicker {
3979
3979
  this.fsEscHandler = null;
3980
3980
  /** Host-level event chrome owns the duplicate identity outside full screen. */
3981
3981
  this.eventDetailsHidden = false;
3982
+ /** True while the hold note reads "N more selected" — the tick must not overwrite it. */
3983
+ this.holdCopyPending = false;
3982
3984
  /** Wide-layout ticket panel collapsed (map owns the full width). */
3983
3985
  this.sideCollapsed = false;
3984
3986
  this.sideToggleEl = null;
@@ -4561,7 +4563,7 @@ var SeatPicker = class _SeatPicker {
4561
4563
  <div class="sl-foot" data-ref="foot">
4562
4564
  <div class="sl-hold-note" data-ref="holdNote" role="status" aria-live="polite">
4563
4565
  <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
4564
- <span><b data-ref="holdTitle">Seats secured</b><span class="sl-hold-copy" data-ref="holdCopy">Checkout timer is running.</span></span>
4566
+ <span><b data-ref="holdTitle">Seats secured</b><span class="sl-hold-copy" data-ref="holdCopy">You won\u2019t be charged yet.</span></span>
4565
4567
  <button type="button" class="sl-hold-change" data-ref="holdChange" aria-label="Release held tickets and choose different seats">Change</button>
4566
4568
  </div>
4567
4569
  <div class="sl-total"><span data-ref="count"></span><b data-ref="total"></b></div>
@@ -5168,7 +5170,7 @@ var SeatPicker = class _SeatPicker {
5168
5170
  }
5169
5171
  if (this.ctaPhase === "checkout") {
5170
5172
  cta.disabled = true;
5171
- cta.innerHTML = '<span class="sl-cta-spin" aria-hidden="true"></span>Opening checkout\u2026';
5173
+ cta.innerHTML = '<span class="sl-cta-spin" aria-hidden="true"></span>Opening secure checkout\u2026';
5172
5174
  return;
5173
5175
  }
5174
5176
  cta.disabled = count === 0;
@@ -5177,11 +5179,13 @@ var SeatPicker = class _SeatPicker {
5177
5179
  setCtaPhase(phase) {
5178
5180
  this.ctaPhase = phase;
5179
5181
  this.syncCta();
5182
+ this.renderPeek(this.lastTrayCount, this.lastTrayTotal, this.pendingSelectionCount());
5180
5183
  if (phase === "checkout") {
5181
5184
  this.scheduleMotion(() => {
5182
5185
  if (this.ctaPhase !== "checkout") return;
5183
5186
  this.ctaPhase = "idle";
5184
5187
  this.syncCta();
5188
+ this.renderPeek(this.lastTrayCount, this.lastTrayTotal, this.pendingSelectionCount());
5185
5189
  }, 1100);
5186
5190
  }
5187
5191
  }
@@ -6589,7 +6593,8 @@ var SeatPicker = class _SeatPicker {
6589
6593
  this.els.holdTitle.textContent = `${securedCount} secured`;
6590
6594
  }
6591
6595
  if (this.els.holdCopy) {
6592
- this.els.holdCopy.textContent = pendingCount ? `${pendingCount} more selected` : "Checkout timer running";
6596
+ this.holdCopyPending = pendingCount > 0;
6597
+ this.els.holdCopy.textContent = pendingCount ? `${pendingCount} more selected` : this.holdReassuranceText();
6593
6598
  }
6594
6599
  const change = this.els.holdChange;
6595
6600
  if (change) {
@@ -6603,21 +6608,39 @@ var SeatPicker = class _SeatPicker {
6603
6608
  this.animateOnce(this.els.cta, "sl-ready", 520);
6604
6609
  if (this.sideCollapsed && this.root?.dataset.layout !== "narrow") this.setPanelCollapsed(false);
6605
6610
  }
6606
- if (this.els.peek) {
6607
- if (count) {
6608
- const holding = !!this.hold && !pendingCount;
6609
- this.els.peek.innerHTML = `<span>${count} ${count === 1 ? "ticket" : "tickets"} \xB7 ${this.money(total)}</span><button type="button" class="go sl-sheet-go" data-act="${holding ? "checkout" : "open"}">${this.hold ? pendingCount ? "Secure more" : "Continue" : "Review"}</button>`;
6610
- } else if (this.salesClosed) {
6611
- this.els.peek.innerHTML = `<span>${this.tf("picker.salesClosedPill", "Sales are closed")}</span>`;
6612
- } else {
6613
- const prices = (this.controller.doc?.categories ?? []).map((c) => this.catPrice(c)).filter((p) => p != null);
6614
- this.els.peek.innerHTML = (prices.length ? `<span>From ${this.money(Math.min(...prices))}</span>` : "<span>Pick your seats</span>") + `<button type="button" class="go sl-sheet-go" data-act="open">\u2726 Best seats</button>`;
6615
- }
6616
- }
6611
+ this.renderPeek(count, total, pendingCount);
6617
6612
  this.lastTrayCount = count;
6618
6613
  this.lastTrayTotal = total;
6619
6614
  this.opts.onSelectionChange?.(seats);
6620
6615
  }
6616
+ /**
6617
+ * The bottom-sheet's collapsed one-liner. Called from syncTray on every
6618
+ * repaint AND from setCtaPhase: while the widget is securing seats or
6619
+ * opening checkout, the peek is the phone buyer's ONLY line of sight, and a
6620
+ * pill still reading "Continue" at the moment money is about to move is the
6621
+ * emotional trapdoor the audit flagged. The phase lines restate what is
6622
+ * secured and promise no charge yet.
6623
+ */
6624
+ renderPeek(count, total, pendingCount) {
6625
+ if (!this.els.peek) return;
6626
+ if (count && this.ctaPhase === "holding") {
6627
+ this.els.peek.innerHTML = `<span>Securing your seats\u2026</span>`;
6628
+ return;
6629
+ }
6630
+ if (count && this.ctaPhase === "checkout") {
6631
+ this.els.peek.innerHTML = `<span>\u2713 ${count} ${count === 1 ? "ticket" : "tickets"} secured \xB7 ${this.money(total)} \u2014 you won\u2019t be charged yet</span>`;
6632
+ return;
6633
+ }
6634
+ if (count) {
6635
+ const holding = !!this.hold && !pendingCount;
6636
+ this.els.peek.innerHTML = `<span>${count} ${count === 1 ? "ticket" : "tickets"} \xB7 ${this.money(total)}</span><button type="button" class="go sl-sheet-go" data-act="${holding ? "checkout" : "open"}">${this.hold ? pendingCount ? "Secure more" : "Continue" : "Review"}</button>`;
6637
+ } else if (this.salesClosed) {
6638
+ this.els.peek.innerHTML = `<span>${this.tf("picker.salesClosedPill", "Sales are closed")}</span>`;
6639
+ } else {
6640
+ const prices = (this.controller.doc?.categories ?? []).map((c) => this.catPrice(c)).filter((p) => p != null);
6641
+ this.els.peek.innerHTML = (prices.length ? `<span>From ${this.money(Math.min(...prices))}</span>` : "<span>Pick your seats</span>") + `<button type="button" class="go sl-sheet-go" data-act="open">\u2726 Best seats</button>`;
6642
+ }
6643
+ }
6621
6644
  async removeHeldLabel(label, chip) {
6622
6645
  if (!label || this.releasingLabels.has(label)) return false;
6623
6646
  this.releasingLabels.add(label);
@@ -6726,6 +6749,13 @@ var SeatPicker = class _SeatPicker {
6726
6749
  this.syncTray();
6727
6750
  }
6728
6751
  }
6752
+ /** "Yours for m:ss — you won't be charged yet." — the hold note's promise. */
6753
+ holdReassuranceText() {
6754
+ const ms = Math.max(0, this.holdExpiresAt - Date.now());
6755
+ const m = Math.floor(ms / 6e4);
6756
+ const s = String(Math.floor(ms % 6e4 / 1e3)).padStart(2, "0");
6757
+ return `Yours for ${m}:${s} \u2014 you won\u2019t be charged yet.`;
6758
+ }
6729
6759
  startHoldTimer(expiresAt) {
6730
6760
  this.stopHoldTimer();
6731
6761
  this.holdExpiresAt = expiresAt;
@@ -6739,6 +6769,9 @@ var SeatPicker = class _SeatPicker {
6739
6769
  const m = Math.floor(ms / 6e4);
6740
6770
  const s = String(Math.floor(ms % 6e4 / 1e3)).padStart(2, "0");
6741
6771
  if (time) time.textContent = `${m}:${s}`;
6772
+ if (!this.holdCopyPending && this.els.holdCopy) {
6773
+ this.els.holdCopy.textContent = this.holdReassuranceText();
6774
+ }
6742
6775
  pill.classList.add("on");
6743
6776
  pill.classList.toggle("is-expiring", ms > 0 && ms <= EXTEND_PROMPT_MS);
6744
6777
  this.setExtendPrompt(ms > 0 && ms <= EXTEND_PROMPT_MS, ms);
@@ -6758,8 +6791,10 @@ var SeatPicker = class _SeatPicker {
6758
6791
  setExtendPrompt(show, ms) {
6759
6792
  if (!this.extendEl) return;
6760
6793
  if (show && this.controller.currentHold() && !this.bookedShown) {
6761
- const secs = Math.ceil(ms / 1e3);
6762
- this.els.extendTxt.innerHTML = `Your seats are held for <b>0:${String(secs).padStart(2, "0")}</b>. Need more time?`;
6794
+ const totalSecs = Math.ceil(ms / 1e3);
6795
+ const m = Math.floor(totalSecs / 60);
6796
+ const s = String(totalSecs % 60).padStart(2, "0");
6797
+ this.els.extendTxt.innerHTML = `Your seats are held for <b>${m}:${s}</b>. Need more time?`;
6763
6798
  this.extendEl.classList.add("on");
6764
6799
  } else {
6765
6800
  this.extendEl.classList.remove("on");