@vio-live/web-sdk 0.6.0 → 0.8.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.
@@ -1,4 +1,4 @@
1
- import { Vio, __decorateClass, primaryImageUrl, displayPrice, getGlobalCurrency, formatPrice } from './chunk-MOKVTWQW.js';
1
+ import { Vio, __decorateClass, primaryImageUrl, displayPrice, getGlobalCurrency, formatPrice } from './chunk-4ZEN4J7I.js';
2
2
  import { LitElement, css, html } from 'lit';
3
3
  import { property, state, query } from 'lit/decorators.js';
4
4
 
@@ -69,6 +69,8 @@ var VioTokens = {
69
69
  sm: "2px",
70
70
  md: "4px",
71
71
  lg: "8px",
72
+ /** Sheet/drawer corners — the largest surface radius in the checkout. */
73
+ xl: "16px",
72
74
  full: "9999px"
73
75
  }
74
76
  };
@@ -117,6 +119,7 @@ var VIO_TOKENS_CSS = `
117
119
  --vio-radius-sm: ${VioTokens.radius.sm};
118
120
  --vio-radius-md: ${VioTokens.radius.md};
119
121
  --vio-radius-lg: ${VioTokens.radius.lg};
122
+ --vio-radius-xl: ${VioTokens.radius.xl};
120
123
  }
121
124
  `;
122
125
  function injectTokens() {
@@ -140,7 +143,15 @@ var THEME_KEY_TO_CSS_VAR = {
140
143
  colorBorder: "--vio-color-border",
141
144
  colorBorderDefault: "--vio-color-border-default",
142
145
  fontSerif: "--vio-font-serif",
143
- fontSans: "--vio-font-sans"
146
+ fontSans: "--vio-font-sans",
147
+ radiusSm: "--vio-radius-sm",
148
+ radiusMd: "--vio-radius-md",
149
+ radiusLg: "--vio-radius-lg",
150
+ radiusXl: "--vio-radius-xl",
151
+ spaceSm: "--vio-space-sm",
152
+ spaceMd: "--vio-space-md",
153
+ spaceLg: "--vio-space-lg",
154
+ spaceXl: "--vio-space-xl"
144
155
  };
145
156
  function applyVioTheme(overrides, target = typeof document !== "undefined" ? document.documentElement : null) {
146
157
  if (!target) return;
@@ -2823,6 +2834,10 @@ var _VioCheckout = class _VioCheckout extends LitElement {
2823
2834
  this.selectedShipping = "";
2824
2835
  this.availableShippingsList = [];
2825
2836
  this.availableMethods = null;
2837
+ this.kustomMounting = false;
2838
+ this.kustomMountedOrderId = null;
2839
+ this.qliroMounting = false;
2840
+ this.qliroMountedOrderId = null;
2826
2841
  this.stripeLoading = false;
2827
2842
  this.vippsLoading = false;
2828
2843
  this.form = {
@@ -2916,7 +2931,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
2916
2931
  max-height: 88vh;
2917
2932
  max-width: 460px;
2918
2933
  margin: 0 auto;
2919
- border-radius: 16px 16px 0 0;
2934
+ border-radius: var(--vio-radius-xl, 16px) var(--vio-radius-xl, 16px) 0 0;
2920
2935
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.18);
2921
2936
  }
2922
2937
  .modal.as-drawer .handle {
@@ -2930,7 +2945,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
2930
2945
  width: 40px;
2931
2946
  height: 4px;
2932
2947
  background: var(--vio-color-border, #e5e5e5);
2933
- border-radius: 2px;
2948
+ border-radius: var(--vio-radius-sm, 2px);
2934
2949
  }
2935
2950
 
2936
2951
  /* Express (Apple Pay-style): right-side drawer, like the cart. Slides in
@@ -2967,7 +2982,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
2967
2982
  max-width: none;
2968
2983
  height: 92vh;
2969
2984
  transform: translateY(100%);
2970
- border-radius: 16px 16px 0 0;
2985
+ border-radius: var(--vio-radius-xl, 16px) var(--vio-radius-xl, 16px) 0 0;
2971
2986
  }
2972
2987
  :host([open]) .modal.as-side { transform: translateY(0); }
2973
2988
  }
@@ -2982,7 +2997,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
2982
2997
  max-width: 440px;
2983
2998
  height: auto;
2984
2999
  max-height: 88vh;
2985
- border-radius: 16px;
3000
+ border-radius: var(--vio-radius-xl, 16px);
2986
3001
  box-shadow: 0 30px 80px -24px rgba(0, 0, 0, 0.4);
2987
3002
  transform: translate(-50%, -50%) scale(0.96);
2988
3003
  opacity: 0;
@@ -2998,7 +3013,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
2998
3013
  left: 0;
2999
3014
  width: 100%;
3000
3015
  max-width: none;
3001
- border-radius: 16px 16px 0 0;
3016
+ border-radius: var(--vio-radius-xl, 16px) var(--vio-radius-xl, 16px) 0 0;
3002
3017
  transform: translateY(100%) scale(1);
3003
3018
  opacity: 1;
3004
3019
  }
@@ -3012,7 +3027,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3012
3027
  .modal {
3013
3028
  top: auto;
3014
3029
  height: 92vh;
3015
- border-radius: 16px 16px 0 0;
3030
+ border-radius: var(--vio-radius-xl, 16px) var(--vio-radius-xl, 16px) 0 0;
3016
3031
  box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.08);
3017
3032
  }
3018
3033
  .handle {
@@ -3026,7 +3041,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3026
3041
  width: 40px;
3027
3042
  height: 4px;
3028
3043
  background: var(--vio-color-border, #e5e5e5);
3029
- border-radius: 2px;
3044
+ border-radius: var(--vio-radius-sm, 2px);
3030
3045
  }
3031
3046
  }
3032
3047
 
@@ -3182,7 +3197,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3182
3197
  flex: 1 1 auto;
3183
3198
  padding: 8px 12px;
3184
3199
  border: 1px solid var(--vio-color-border, #ddd);
3185
- border-radius: 8px;
3200
+ border-radius: var(--vio-radius-lg, 8px);
3186
3201
  background: #fff;
3187
3202
  font-size: 13px;
3188
3203
  cursor: pointer;
@@ -3206,7 +3221,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3206
3221
  .ship-opt {
3207
3222
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
3208
3223
  padding: 12px 14px; border: 1px solid var(--vio-color-border, #ddd);
3209
- border-radius: 10px; background: #fff; cursor: pointer; font-family: inherit;
3224
+ border-radius: var(--vio-radius-lg, 8px); background: #fff; cursor: pointer; font-family: inherit;
3210
3225
  text-align: left;
3211
3226
  }
3212
3227
  .ship-opt.active {
@@ -3223,7 +3238,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3223
3238
  padding: 12px 16px;
3224
3239
  background: #fdecea;
3225
3240
  border: 1px solid var(--vio-color-accent, #c14a3b);
3226
- border-radius: 8px;
3241
+ border-radius: var(--vio-radius-lg, 8px);
3227
3242
  font-size: 13px;
3228
3243
  color: var(--vio-color-accent, #c14a3b);
3229
3244
  text-align: center;
@@ -3233,7 +3248,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3233
3248
  padding: 12px 16px;
3234
3249
  background: #f4f4f2;
3235
3250
  border: 1px solid var(--vio-color-border, #ddd);
3236
- border-radius: 8px;
3251
+ border-radius: var(--vio-radius-lg, 8px);
3237
3252
  font-size: 13px;
3238
3253
  color: var(--vio-color-text, #1a1a1a);
3239
3254
  text-align: center;
@@ -3499,6 +3514,121 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3499
3514
  const sponsorId = Number(urlParams.get("vio_sponsor") || 0);
3500
3515
  const checkoutId = urlParams.get("checkout_id") || "";
3501
3516
  if (!vioPayment && !checkoutId) return;
3517
+ const kustomOrderId = urlParams.get("order_id") || "";
3518
+ if (urlParams.get("payment_processor") === "KUSTOM" && kustomOrderId) {
3519
+ if (!this.checkoutState) {
3520
+ const spIdToUse = sponsorId || [...Vio.cart.getAllCarts().keys()][0] || 0;
3521
+ if (spIdToUse) {
3522
+ try {
3523
+ Vio.checkout.open(spIdToUse);
3524
+ } catch {
3525
+ }
3526
+ }
3527
+ }
3528
+ try {
3529
+ Vio.checkout.selectPaymentMethod("kustom");
3530
+ } catch {
3531
+ }
3532
+ this.open = true;
3533
+ this.paymentNotice = "Bekrefter betalingen\u2026";
3534
+ try {
3535
+ const order = await Vio.checkout.getKustomOrder(
3536
+ kustomOrderId,
3537
+ this.checkoutState?.sponsorId
3538
+ );
3539
+ this.paymentNotice = null;
3540
+ if (order?.html_snippet) {
3541
+ this.kustomMountedOrderId = order.order_id;
3542
+ await this.updateComplete;
3543
+ const container = this.renderRoot?.querySelector(
3544
+ "#vio-kustom-checkout-container"
3545
+ );
3546
+ if (container) {
3547
+ Vio.checkout.renderKustomSnippet(container, order.html_snippet);
3548
+ }
3549
+ if (order.status === "checkout_complete") {
3550
+ this.dispatchEvent(
3551
+ new CustomEvent("vio:payment-success", {
3552
+ detail: { method: "kustom", orderId: order.order_id },
3553
+ bubbles: true,
3554
+ composed: true
3555
+ })
3556
+ );
3557
+ const spId = this.checkoutState?.sponsorId;
3558
+ if (spId) {
3559
+ try {
3560
+ Vio.cart.clearSponsorCart(spId);
3561
+ } catch {
3562
+ }
3563
+ }
3564
+ }
3565
+ }
3566
+ } catch (err) {
3567
+ this.paymentNotice = null;
3568
+ if (typeof console !== "undefined") {
3569
+ console.warn("[VioCheckout] Kustom confirmation read failed:", err);
3570
+ }
3571
+ }
3572
+ this.cleanReturnQueryParams(["order_id", "payment_processor"]);
3573
+ return;
3574
+ }
3575
+ if (urlParams.get("payment_processor") === "QLIRO" && checkoutId) {
3576
+ if (!this.checkoutState) {
3577
+ const spIdToUse = sponsorId || [...Vio.cart.getAllCarts().keys()][0] || 0;
3578
+ if (spIdToUse) {
3579
+ try {
3580
+ Vio.checkout.open(spIdToUse);
3581
+ } catch {
3582
+ }
3583
+ }
3584
+ }
3585
+ try {
3586
+ Vio.checkout.selectPaymentMethod("qliro");
3587
+ } catch {
3588
+ }
3589
+ this.open = true;
3590
+ this.paymentNotice = "Bekrefter betalingen\u2026";
3591
+ try {
3592
+ const order = await Vio.checkout.getQliroOrder(
3593
+ checkoutId,
3594
+ this.checkoutState?.sponsorId
3595
+ );
3596
+ this.paymentNotice = null;
3597
+ if (order?.html_snippet) {
3598
+ this.qliroMountedOrderId = order.order_id;
3599
+ await this.updateComplete;
3600
+ const container = this.renderRoot?.querySelector(
3601
+ "#vio-qliro-checkout-container"
3602
+ );
3603
+ if (container) {
3604
+ Vio.checkout.renderKustomSnippet(container, order.html_snippet);
3605
+ }
3606
+ if (order.status === "Completed") {
3607
+ this.dispatchEvent(
3608
+ new CustomEvent("vio:payment-success", {
3609
+ detail: { method: "qliro", orderId: order.order_id },
3610
+ bubbles: true,
3611
+ composed: true
3612
+ })
3613
+ );
3614
+ const spId = this.checkoutState?.sponsorId;
3615
+ if (spId) {
3616
+ try {
3617
+ Vio.cart.clearSponsorCart(spId);
3618
+ } catch {
3619
+ }
3620
+ }
3621
+ }
3622
+ }
3623
+ } catch (err) {
3624
+ this.paymentNotice = null;
3625
+ if (typeof console !== "undefined") {
3626
+ console.warn("[VioCheckout] Qliro confirmation read failed:", err);
3627
+ }
3628
+ }
3629
+ this.cleanReturnQueryParams(["checkout_id", "payment_processor"]);
3630
+ return;
3631
+ }
3502
3632
  if (vioMethod === "klarna" && typeof sessionStorage !== "undefined" && sessionStorage.getItem("vio.klarna.pending.v1")) {
3503
3633
  this.cleanReturnQueryParams(["vio_payment", "vio_method", "vio_sponsor", "checkout_id"]);
3504
3634
  return;
@@ -3593,6 +3723,8 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3593
3723
  void this.loadAvailableShippings();
3594
3724
  }
3595
3725
  void this.mountKlarnaIfNeeded();
3726
+ void this.mountKustomIfNeeded();
3727
+ void this.mountQliroIfNeeded();
3596
3728
  }
3597
3729
  close() {
3598
3730
  this.open = false;
@@ -3829,6 +3961,14 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3829
3961
  void this.onApplePay();
3830
3962
  return;
3831
3963
  }
3964
+ if (method === "kustom") {
3965
+ Vio.checkout.selectPaymentMethod("kustom");
3966
+ return;
3967
+ }
3968
+ if (method === "qliro") {
3969
+ Vio.checkout.selectPaymentMethod("qliro");
3970
+ return;
3971
+ }
3832
3972
  if (method === "vipps") {
3833
3973
  const email = String(this.form.email ?? "").trim();
3834
3974
  if (!email || !email.includes("@")) {
@@ -3930,6 +4070,10 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3930
4070
  return "Apple Pay";
3931
4071
  case "klarna":
3932
4072
  return "Klarna";
4073
+ case "kustom":
4074
+ return "Kustom";
4075
+ case "qliro":
4076
+ return "Qliro";
3933
4077
  case "vipps":
3934
4078
  return "Vipps";
3935
4079
  case "stripe":
@@ -3942,7 +4086,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3942
4086
  }
3943
4087
  /** True for methods that complete via a separate sheet/widget, not the CTA. */
3944
4088
  isExpressMethod(method) {
3945
- return method === "apple-pay" || method === "klarna";
4089
+ return method === "apple-pay" || method === "klarna" || method === "kustom" || method === "qliro";
3946
4090
  }
3947
4091
  orderTotal() {
3948
4092
  const s = this.checkoutState;
@@ -4014,6 +4158,92 @@ var _VioCheckout = class _VioCheckout extends LitElement {
4014
4158
  `;
4015
4159
  }
4016
4160
  /** Klarna Payments widget panel: shipping + category chips + widget + pay button. */
4161
+ /** Mount the Kustom embedded checkout once it's the chosen method. */
4162
+ async mountKustomIfNeeded() {
4163
+ if (!this.open || !this.checkoutState) return;
4164
+ if (this.checkoutState.paymentMethod !== "kustom") return;
4165
+ if (this.kustomMounting) return;
4166
+ const container = this.renderRoot?.querySelector(
4167
+ "#vio-kustom-checkout-container"
4168
+ );
4169
+ if (!container) return;
4170
+ if (this.kustomMountedOrderId && container.childElementCount > 0) return;
4171
+ this.kustomMounting = true;
4172
+ container.innerHTML = "";
4173
+ try {
4174
+ const order = await Vio.checkout.mountKustomCheckout(
4175
+ container,
4176
+ this.checkoutState.sponsorId
4177
+ );
4178
+ this.kustomMountedOrderId = order.order_id;
4179
+ } catch (err) {
4180
+ if (typeof console !== "undefined") {
4181
+ console.warn("[VioCheckout] Kustom mount failed:", err);
4182
+ }
4183
+ this.paymentError = `Kunne ikke laste Kustom: ${err instanceof Error ? err.message : String(err)}`;
4184
+ Vio.checkout.selectPaymentMethod("");
4185
+ } finally {
4186
+ this.kustomMounting = false;
4187
+ }
4188
+ }
4189
+ unmountKustom() {
4190
+ this.kustomMountedOrderId = null;
4191
+ const container = this.renderRoot?.querySelector(
4192
+ "#vio-kustom-checkout-container"
4193
+ );
4194
+ if (container) container.innerHTML = "";
4195
+ }
4196
+ renderKustomPanel() {
4197
+ return html`
4198
+ <div class="kustom-panel">
4199
+ ${this.kustomMounting ? html`<div style="font-size:13px;opacity:0.7;padding:8px 0;">Laster Kustom…</div>` : ""}
4200
+ <div id="vio-kustom-checkout-container"></div>
4201
+ </div>
4202
+ `;
4203
+ }
4204
+ /** Mount the Qliro embedded checkout once it's the chosen method. */
4205
+ async mountQliroIfNeeded() {
4206
+ if (!this.open || !this.checkoutState) return;
4207
+ if (this.checkoutState.paymentMethod !== "qliro") return;
4208
+ if (this.qliroMounting) return;
4209
+ const container = this.renderRoot?.querySelector(
4210
+ "#vio-qliro-checkout-container"
4211
+ );
4212
+ if (!container) return;
4213
+ if (this.qliroMountedOrderId && container.childElementCount > 0) return;
4214
+ this.qliroMounting = true;
4215
+ container.innerHTML = "";
4216
+ try {
4217
+ const order = await Vio.checkout.mountQliroCheckout(
4218
+ container,
4219
+ this.checkoutState.sponsorId
4220
+ );
4221
+ this.qliroMountedOrderId = order.order_id;
4222
+ } catch (err) {
4223
+ if (typeof console !== "undefined") {
4224
+ console.warn("[VioCheckout] Qliro mount failed:", err);
4225
+ }
4226
+ this.paymentError = `Kunne ikke laste Qliro: ${err instanceof Error ? err.message : String(err)}`;
4227
+ Vio.checkout.selectPaymentMethod("");
4228
+ } finally {
4229
+ this.qliroMounting = false;
4230
+ }
4231
+ }
4232
+ unmountQliro() {
4233
+ this.qliroMountedOrderId = null;
4234
+ const container = this.renderRoot?.querySelector(
4235
+ "#vio-qliro-checkout-container"
4236
+ );
4237
+ if (container) container.innerHTML = "";
4238
+ }
4239
+ renderQliroPanel() {
4240
+ return html`
4241
+ <div class="qliro-panel">
4242
+ ${this.qliroMounting ? html`<div style="font-size:13px;opacity:0.7;padding:8px 0;">Laster Qliro…</div>` : ""}
4243
+ <div id="vio-qliro-checkout-container"></div>
4244
+ </div>
4245
+ `;
4246
+ }
4017
4247
  renderKlarnaPanel() {
4018
4248
  const currency = this.checkoutState?.currency || getGlobalCurrency();
4019
4249
  return html`
@@ -4123,8 +4353,9 @@ var _VioCheckout = class _VioCheckout extends LitElement {
4123
4353
  const method = this.checkoutState?.paymentMethod;
4124
4354
  const showCompleteCta = !!method && !this.isExpressMethod(method);
4125
4355
  const isVipps = method === "vipps";
4356
+ const isKustom = method === "kustom" || method === "qliro";
4126
4357
  return html`
4127
- ${!isVipps ? html`
4358
+ ${!isVipps && !isKustom ? html`
4128
4359
  <section class="section">
4129
4360
  <div class="section-label">Steg 1</div>
4130
4361
  <h3 class="section-heading">Leveringsadresse</h3>
@@ -4241,7 +4472,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
4241
4472
  ` : ""}
4242
4473
 
4243
4474
  <section class="section">
4244
- <div class="section-label">${isVipps ? "Betaling" : "Steg 2"}</div>
4475
+ <div class="section-label">${isVipps || isKustom ? "Betaling" : "Steg 2"}</div>
4245
4476
  ${method ? html`
4246
4477
  <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px;">
4247
4478
  <h3 class="section-heading" style="margin:0;">
@@ -4252,6 +4483,8 @@ var _VioCheckout = class _VioCheckout extends LitElement {
4252
4483
  style="background:none; border:none; color:var(--vio-color-accent, #c14a3b); text-decoration:underline; font-size:13px; cursor:pointer;"
4253
4484
  @click=${() => {
4254
4485
  this.unmountKlarna();
4486
+ this.unmountKustom();
4487
+ this.unmountQliro();
4255
4488
  Vio.checkout.selectPaymentMethod("");
4256
4489
  }}
4257
4490
  >
@@ -4260,6 +4493,8 @@ var _VioCheckout = class _VioCheckout extends LitElement {
4260
4493
  </div>
4261
4494
 
4262
4495
  ${method === "klarna" ? this.renderKlarnaPanel() : ""}
4496
+ ${method === "kustom" ? this.renderKustomPanel() : ""}
4497
+ ${method === "qliro" ? this.renderQliroPanel() : ""}
4263
4498
  ${method === "stripe" ? html`
4264
4499
  <button
4265
4500
  class="payment-btn primary complete-cta"
@@ -4334,6 +4569,16 @@ var _VioCheckout = class _VioCheckout extends LitElement {
4334
4569
  Klarna
4335
4570
  </button>
4336
4571
  ` : ""}
4572
+ ${this.methodEnabled("kustom") ? html`
4573
+ <button class="payment-btn" @click=${() => this.onPay("kustom")}>
4574
+ <span style="font-weight:800;font-size:16px;letter-spacing:-0.01em">Kustom</span>
4575
+ </button>
4576
+ ` : ""}
4577
+ ${this.methodEnabled("qliro") ? html`
4578
+ <button class="payment-btn" @click=${() => this.onPay("qliro")}>
4579
+ <span style="font-weight:800;font-size:16px;letter-spacing:-0.01em">Qliro</span>
4580
+ </button>
4581
+ ` : ""}
4337
4582
  ${this.methodEnabled("vipps") ? html`
4338
4583
  <button class="payment-btn" @click=${() => this.onPay("vipps")}>
4339
4584
  <span style="color:#ff5b24;font-weight:800;font-size:17px;letter-spacing:-0.02em">vipps</span>
@@ -4446,6 +4691,12 @@ __decorateClass([
4446
4691
  __decorateClass([
4447
4692
  state()
4448
4693
  ], _VioCheckout.prototype, "availableMethods", 2);
4694
+ __decorateClass([
4695
+ state()
4696
+ ], _VioCheckout.prototype, "kustomMounting", 2);
4697
+ __decorateClass([
4698
+ state()
4699
+ ], _VioCheckout.prototype, "qliroMounting", 2);
4449
4700
  __decorateClass([
4450
4701
  state()
4451
4702
  ], _VioCheckout.prototype, "stripeLoading", 2);
@@ -4474,5 +4725,5 @@ function registerVioElements() {
4474
4725
  }
4475
4726
 
4476
4727
  export { VioCart, VioCheckout, VioProduct, VioProductCarousel, VioProductDetail, VioTokens, applyVioTheme, registerVioElements };
4477
- //# sourceMappingURL=chunk-6X225SGW.js.map
4478
- //# sourceMappingURL=chunk-6X225SGW.js.map
4728
+ //# sourceMappingURL=chunk-YNKOGPTE.js.map
4729
+ //# sourceMappingURL=chunk-YNKOGPTE.js.map