@vio-live/web-sdk 0.4.1 → 0.5.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, KLARNA_SHIPPING_OPTIONS } from './chunk-NP2KCM7X.js';
1
+ import { Vio, __decorateClass, primaryImageUrl, displayPrice, getGlobalCurrency, formatPrice } from './chunk-HNQG56SD.js';
2
2
  import { LitElement, css, html } from 'lit';
3
3
  import { property, state, query } from 'lit/decorators.js';
4
4
 
@@ -460,6 +460,13 @@ var VioProductCarousel = class extends LitElement {
460
460
  this.fetched = null;
461
461
  this.isLoading = false;
462
462
  this.fetchError = "";
463
+ // ── Analytics (auto) ──────────────────────────────────────────────
464
+ // component_impression on the contract rule (≥50% visible ≥1s, once per
465
+ // session) + view_item_list with the rendered products. No-ops unless
466
+ // Vio.analytics.start() ran.
467
+ this.unobserveImpression = null;
468
+ this.impressed = false;
469
+ this.listTracked = false;
463
470
  }
464
471
  static {
465
472
  this.styles = css`
@@ -608,10 +615,16 @@ var VioProductCarousel = class extends LitElement {
608
615
  }
609
616
  connectedCallback() {
610
617
  super.connectedCallback();
618
+ this.observeForAnalytics();
611
619
  if (this.productRefs.trim() || this.productIds.trim()) {
612
620
  void this.autoFetch();
613
621
  }
614
622
  }
623
+ disconnectedCallback() {
624
+ this.unobserveImpression?.();
625
+ this.unobserveImpression = null;
626
+ super.disconnectedCallback();
627
+ }
615
628
  updated(changed) {
616
629
  const propChanged = changed.has("productRefs") || changed.has("productIds") || changed.has("commerceKey") || changed.has("sponsorId");
617
630
  if (propChanged && (this.productRefs.trim() || this.productIds.trim())) {
@@ -656,12 +669,61 @@ var VioProductCarousel = class extends LitElement {
656
669
  const product = lookup.get(`${sponsorId}:${productId}`);
657
670
  return product ? { product, sponsorId } : null;
658
671
  }).filter((x) => x !== null);
672
+ this.maybeTrackList();
659
673
  } catch (err) {
660
674
  this.fetchError = err instanceof Error ? err.message : String(err);
661
675
  } finally {
662
676
  this.isLoading = false;
663
677
  }
664
678
  }
679
+ observeForAnalytics() {
680
+ if (this.unobserveImpression) return;
681
+ try {
682
+ this.unobserveImpression = Vio.analytics.observeImpression(
683
+ this,
684
+ {
685
+ sponsorId: this.sponsorId > 0 ? this.sponsorId : void 0,
686
+ componentTemplateId: "product-carousel",
687
+ locationId: this.label || void 0
688
+ },
689
+ {
690
+ key: `carousel:${this.label || this.productIds || this.productRefs || "default"}`,
691
+ onImpression: () => {
692
+ this.impressed = true;
693
+ this.maybeTrackList();
694
+ }
695
+ }
696
+ );
697
+ } catch {
698
+ }
699
+ }
700
+ /** view_item_list needs BOTH the viewport dwell and loaded products —
701
+ * whichever lands last fires it (once). */
702
+ maybeTrackList() {
703
+ if (!this.impressed || this.listTracked) return;
704
+ const entries = this.fetched ?? [];
705
+ if (entries.length === 0) return;
706
+ this.listTracked = true;
707
+ try {
708
+ Vio.analytics.track("view_item_list", {
709
+ context: {
710
+ sponsorId: this.sponsorId > 0 ? this.sponsorId : void 0,
711
+ componentTemplateId: "product-carousel",
712
+ locationId: this.label || void 0
713
+ },
714
+ commerce: {
715
+ items: entries.map(({ product, sponsorId }) => ({
716
+ productId: product.id,
717
+ name: product.title,
718
+ price: Number(product.price?.amount_incl_taxes ?? product.price?.amount) || void 0
719
+ })),
720
+ currency: entries[0]?.product.price?.currency_code
721
+ },
722
+ props: this.label ? { list_name: this.label } : void 0
723
+ });
724
+ } catch {
725
+ }
726
+ }
665
727
  parseRefs(raw) {
666
728
  return raw.split(",").map((pair) => pair.trim()).filter((s) => s.length > 0).map((pair) => {
667
729
  const [sidStr, pidStr] = pair.split(":");
@@ -1313,6 +1375,31 @@ var VioProductDetail = class extends LitElement {
1313
1375
  }
1314
1376
  this.optMapCache = /* @__PURE__ */ new WeakMap();
1315
1377
  this.product = products?.[0] ?? null;
1378
+ if (this.product) {
1379
+ try {
1380
+ const price = Number(
1381
+ this.product.price?.amount_incl_taxes ?? this.product.price?.amount
1382
+ );
1383
+ Vio.analytics.track("view_item", {
1384
+ context: {
1385
+ sponsorId: this.sponsorId > 0 ? Number(this.sponsorId) : void 0,
1386
+ componentTemplateId: "product-detail"
1387
+ },
1388
+ commerce: {
1389
+ items: [
1390
+ {
1391
+ productId: this.product.id,
1392
+ name: this.product.title,
1393
+ price: Number.isFinite(price) ? price : void 0
1394
+ }
1395
+ ],
1396
+ value: Number.isFinite(price) ? price : void 0,
1397
+ currency: this.product.price?.currency_code
1398
+ }
1399
+ });
1400
+ } catch {
1401
+ }
1402
+ }
1316
1403
  if (!this.product) {
1317
1404
  this.fetchError = "Fant ikke produktet.";
1318
1405
  }
@@ -2361,6 +2448,9 @@ var VioCart = class extends LitElement {
2361
2448
  }
2362
2449
  show() {
2363
2450
  this.open = true;
2451
+ this.dispatchEvent(
2452
+ new CustomEvent("vio:open-cart", { bubbles: true, composed: true })
2453
+ );
2364
2454
  void this.loadAvailablePaymentMethods();
2365
2455
  }
2366
2456
  /** Which payment buttons to render — backend-configured per sponsor.
@@ -2730,7 +2820,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
2730
2820
  this.klarnaCategories = [];
2731
2821
  this.klarnaSelectedCat = "";
2732
2822
  this.klarnaAuthorizing = false;
2733
- this.selectedShipping = KLARNA_SHIPPING_OPTIONS.find((o) => o.preselected)?.id ?? KLARNA_SHIPPING_OPTIONS[0]?.id ?? "";
2823
+ this.selectedShipping = "";
2734
2824
  this.availableShippingsList = [];
2735
2825
  this.availableMethods = null;
2736
2826
  this.stripeLoading = false;
@@ -3080,10 +3170,13 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3080
3170
  gap: 12px;
3081
3171
  margin-top: 4px;
3082
3172
  }
3173
+ /* Klarna remembers the customer's preferred payment_method_category
3174
+ * server-side across sessions/browsers — exposing a category-switcher
3175
+ * chip UI on top of that just confuses users. Hidden per Alan's
3176
+ * 2026-08-18 cross-browser investigation; the switching logic (onKlarnaCategory)
3177
+ * stays wired for when/if this becomes configurable again. */
3083
3178
  .klarna-cats {
3084
- display: flex;
3085
- flex-wrap: wrap;
3086
- gap: 8px;
3179
+ display: none !important;
3087
3180
  }
3088
3181
  .klarna-cat {
3089
3182
  flex: 1 1 auto;
@@ -3496,7 +3589,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3496
3589
  super.disconnectedCallback();
3497
3590
  }
3498
3591
  updated(changed) {
3499
- if (changed.has("open") && this.open && this.availableShippingsList.length === 0) {
3592
+ if (changed.has("open") && this.open && this.items.length > 0 && this.availableShippingsList.length === 0) {
3500
3593
  void this.loadAvailableShippings();
3501
3594
  }
3502
3595
  void this.mountKlarnaIfNeeded();
@@ -3508,7 +3601,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3508
3601
  }
3509
3602
  show() {
3510
3603
  this.open = true;
3511
- if (this.availableShippingsList.length === 0) {
3604
+ if (this.items.length > 0 && this.availableShippingsList.length === 0) {
3512
3605
  void this.loadAvailableShippings();
3513
3606
  }
3514
3607
  }
@@ -3516,6 +3609,7 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3516
3609
  async loadAvailableShippings() {
3517
3610
  const spId = this.checkoutState?.sponsorId;
3518
3611
  if (!spId) return;
3612
+ if (this.items.length === 0) return;
3519
3613
  if (this.loadingShippings) return;
3520
3614
  this.loadingShippings = true;
3521
3615
  this.shippingsAttempted = true;
@@ -3602,6 +3696,9 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3602
3696
  if (!this.klarnaAvailable || !this.open || !this.checkoutState) return;
3603
3697
  if (this.checkoutState.paymentMethod !== "klarna" && !this.express) return;
3604
3698
  if (this.klarnaMounting) return;
3699
+ if (this.items.length > 0 && this.availableShippingsList.length === 0 && !this.shippingsAttempted) {
3700
+ await this.loadAvailableShippings();
3701
+ }
3605
3702
  const amount = this.checkoutState.subtotal;
3606
3703
  if (this.klarnaHandle && this.klarnaMountedAmount === amount && this.klarnaMountedShipping === this.selectedShipping) {
3607
3704
  return;
@@ -3649,9 +3746,9 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3649
3746
  this.klarnaSelectedCat = "";
3650
3747
  this.klarnaAuthorizing = false;
3651
3748
  }
3652
- /** Shippings in effect: backend per-supplier when loaded, static otherwise. */
3749
+ /** Shippings in effect: backend per-supplier when loaded. */
3653
3750
  get shippingList() {
3654
- return this.availableShippingsList.length > 0 ? this.availableShippingsList : KLARNA_SHIPPING_OPTIONS;
3751
+ return this.availableShippingsList;
3655
3752
  }
3656
3753
  /** Selected shipping option (express flow). */
3657
3754
  get shippingOption() {
@@ -3679,8 +3776,11 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3679
3776
  }
3680
3777
  /** Switch the Klarna widget to a different payment_method_category. */
3681
3778
  async onKlarnaCategory(identifier) {
3682
- if (!this.klarnaHandle || this.klarnaSelectedCat === identifier) return;
3779
+ if (!this.klarnaHandle) return;
3683
3780
  this.klarnaSelectedCat = identifier;
3781
+ if (typeof console !== "undefined") {
3782
+ console.log("[VioCheckout] User selected payment_method_category:", identifier);
3783
+ }
3684
3784
  try {
3685
3785
  await this.klarnaHandle.load(identifier);
3686
3786
  } catch (err) {
@@ -3695,8 +3795,12 @@ var _VioCheckout = class _VioCheckout extends LitElement {
3695
3795
  this.paymentError = null;
3696
3796
  this.paymentNotice = null;
3697
3797
  this.klarnaAuthorizing = true;
3798
+ const cat = this.klarnaSelectedCat || this.klarnaHandle.selected || "pay_now";
3799
+ if (typeof console !== "undefined") {
3800
+ console.log("[VioCheckout] Authorizing Klarna with payment_method_category:", cat);
3801
+ }
3698
3802
  try {
3699
- await this.klarnaHandle.authorize();
3803
+ await this.klarnaHandle.authorize(cat);
3700
3804
  } finally {
3701
3805
  this.klarnaAuthorizing = false;
3702
3806
  }
@@ -4370,5 +4474,5 @@ function registerVioElements() {
4370
4474
  }
4371
4475
 
4372
4476
  export { VioCart, VioCheckout, VioProduct, VioProductCarousel, VioProductDetail, VioTokens, applyVioTheme, registerVioElements };
4373
- //# sourceMappingURL=chunk-V5ZQG2H5.js.map
4374
- //# sourceMappingURL=chunk-V5ZQG2H5.js.map
4477
+ //# sourceMappingURL=chunk-5CKG3F56.js.map
4478
+ //# sourceMappingURL=chunk-5CKG3F56.js.map