@seatlayer/js 0.40.0 → 0.41.0

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
@@ -1329,6 +1329,7 @@ var SeatingChart = class {
1329
1329
  this.mount = null;
1330
1330
  this.hostEl = null;
1331
1331
  this.rendered = false;
1332
+ this.retryBtn = null;
1332
1333
  this.mode_ = null;
1333
1334
  this.tipEl = null;
1334
1335
  this.tipPos = { x: 0, y: 0 };
@@ -1390,6 +1391,7 @@ var SeatingChart = class {
1390
1391
  const info = await this.controller.render(host);
1391
1392
  if (!info) {
1392
1393
  this.rendered = false;
1394
+ if (this.opts.errorDisplay !== "none") this.showLoadFailure(host);
1393
1395
  return this;
1394
1396
  }
1395
1397
  this.controller.setViewMode(this.opts.initialView ?? "flat");
@@ -1680,10 +1682,36 @@ var SeatingChart = class {
1680
1682
  }
1681
1683
  return ok;
1682
1684
  }
1685
+ /**
1686
+ * The visible failure state. Deliberately inline-styled and dependency-free:
1687
+ * this renders on a stranger's website, where our stylesheet may not have
1688
+ * loaded (the chart fetch just failed) and where inheriting the host's own
1689
+ * styles is likelier to produce something unreadable than something on-brand.
1690
+ */
1691
+ showLoadFailure(host) {
1692
+ const box = document.createElement("div");
1693
+ box.setAttribute("role", "status");
1694
+ box.style.cssText = 'display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;width:100%;height:100%;min-height:180px;box-sizing:border-box;padding:24px;text-align:center;font:500 14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#3b4256;';
1695
+ const text = document.createElement("div");
1696
+ text.textContent = "The seat map didn\u2019t load.";
1697
+ box.appendChild(text);
1698
+ const btn = document.createElement("button");
1699
+ btn.type = "button";
1700
+ btn.textContent = "Try again";
1701
+ btn.style.cssText = "appearance:none;border:1px solid #c9cede;background:#fff;color:#10162a;border-radius:8px;padding:8px 16px;font:600 13px/1 inherit;cursor:pointer;";
1702
+ btn.addEventListener("click", () => {
1703
+ this.destroy();
1704
+ void this.render().catch((err) => this.opts.onError?.(err));
1705
+ });
1706
+ box.appendChild(btn);
1707
+ this.retryBtn = btn;
1708
+ host.appendChild(box);
1709
+ }
1683
1710
  destroy() {
1684
1711
  this.realtime?.stop();
1685
1712
  this.realtime = null;
1686
1713
  this.access?.clear();
1714
+ this.retryBtn = null;
1687
1715
  if (this.hostEl && this.onTipMove) this.hostEl.removeEventListener("mousemove", this.onTipMove);
1688
1716
  this.tipEl = null;
1689
1717
  this.onTipMove = null;
@@ -5862,7 +5890,15 @@ var SeatPicker = class _SeatPicker {
5862
5890
  this.checkoutPanel = mountCheckout2({
5863
5891
  root: this.root,
5864
5892
  state,
5865
- startSession: (input) => this.pubApi.startCheckout(this.opts.event, input),
5893
+ // `returnUrl` rides along so a redirecting gateway can come back to the
5894
+ // HOST's page. The server validates its origin against the organizer's
5895
+ // declared embed domains and silently falls back to our own buyer page
5896
+ // when it does not match, so passing one can never redirect a paid buyer
5897
+ // somewhere the organizer did not sanction.
5898
+ startSession: (input) => this.pubApi.startCheckout(this.opts.event, {
5899
+ ...input,
5900
+ ...this.opts.returnUrl ? { returnUrl: this.opts.returnUrl } : {}
5901
+ }),
5866
5902
  orderStatus: (orderId) => this.pubApi.orderStatus(orderId),
5867
5903
  onCancel: () => {
5868
5904
  this.checkoutPanel = null;