@kotao/storefront 0.2.1 → 0.2.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/{chunk-U5677AEA.js → chunk-7XYWHWT4.js} +16 -6
- package/dist/chunk-7XYWHWT4.js.map +1 -0
- package/dist/{chunk-GCQI6OKH.js → chunk-H3D7BAOL.js} +3 -26
- package/dist/chunk-H3D7BAOL.js.map +1 -0
- package/dist/chunk-M7BPQ54D.js +26 -0
- package/dist/chunk-M7BPQ54D.js.map +1 -0
- package/dist/{chunk-ISAFEOR2.js → chunk-PXVDVUFX.js} +3 -2
- package/dist/chunk-PXVDVUFX.js.map +1 -0
- package/dist/{client-D9YYA2w6.d.ts → client-DiPdlvPu.d.ts} +1 -1
- package/dist/fetch-B6TIc6lI.d.ts +47 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/react-router.d.ts +5 -3
- package/dist/react-router.js +3 -2
- package/dist/react-router.js.map +1 -1
- package/dist/react.js +271 -154
- package/dist/react.js.map +1 -1
- package/dist/{routing-BfUp49o8.d.ts → routing-BxRlep_-.d.ts} +11 -1
- package/dist/seo.d.ts +3 -1
- package/dist/seo.js +1 -1
- package/dist/settings.d.ts +3 -37
- package/dist/settings.js +2 -1
- package/package.json +1 -1
- package/dist/chunk-GCQI6OKH.js.map +0 -1
- package/dist/chunk-ISAFEOR2.js.map +0 -1
- package/dist/chunk-U5677AEA.js.map +0 -1
package/dist/react.js
CHANGED
|
@@ -437,6 +437,12 @@ function useGlobalThemeTokens() {
|
|
|
437
437
|
|
|
438
438
|
// ../smart-cart/src/format.ts
|
|
439
439
|
var formatMoney2 = (m) => {
|
|
440
|
+
if (m.currency === "EUR" && Number.isFinite(m.amount)) {
|
|
441
|
+
const negative = m.amount < 0;
|
|
442
|
+
const abs = Math.round(Math.abs(m.amount));
|
|
443
|
+
const units = Math.floor(abs / 100).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
444
|
+
return `${negative ? "-" : ""}\u20AC${units},${String(abs % 100).padStart(2, "0")}`;
|
|
445
|
+
}
|
|
440
446
|
if (m.currency && /^[A-Za-z]{3}$/.test(m.currency)) {
|
|
441
447
|
try {
|
|
442
448
|
return new Intl.NumberFormat(void 0, {
|
|
@@ -448,6 +454,10 @@ var formatMoney2 = (m) => {
|
|
|
448
454
|
}
|
|
449
455
|
return new Intl.NumberFormat(void 0, { minimumFractionDigits: 2 }).format(m.amount / 100);
|
|
450
456
|
};
|
|
457
|
+
var formatMoneyCompact = (m) => {
|
|
458
|
+
const formatted = formatMoney2(m);
|
|
459
|
+
return Number.isFinite(m.amount) && Math.round(Math.abs(m.amount)) % 100 === 0 ? formatted.replace(/[.,]00(?=\D*$)/, "") : formatted;
|
|
460
|
+
};
|
|
451
461
|
var escapeHtml = (s) => String(s ?? "").replace(
|
|
452
462
|
/[&<>"']/g,
|
|
453
463
|
(c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]
|
|
@@ -456,7 +466,7 @@ var formatCountdown = (ms) => {
|
|
|
456
466
|
const total = Number.isFinite(ms) && ms > 0 ? Math.floor(ms / 1e3) : 0;
|
|
457
467
|
const minutes = Math.floor(total / 60);
|
|
458
468
|
const seconds = total % 60;
|
|
459
|
-
return `${minutes}:${String(seconds).padStart(2, "0")}`;
|
|
469
|
+
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
|
|
460
470
|
};
|
|
461
471
|
|
|
462
472
|
// ../smart-cart/src/widgets/add-on.ts
|
|
@@ -478,10 +488,10 @@ function findAddOnLine(state, variantId) {
|
|
|
478
488
|
var css = `
|
|
479
489
|
.ksc-addon { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center;
|
|
480
490
|
gap: 2px 12px; padding: 14px 18px; border-top: 1px solid var(--ksc-border); font: inherit; color: var(--ksc-text); }
|
|
481
|
-
.ksc-addon__icon { grid-row: 1 / span 2; width:
|
|
491
|
+
.ksc-addon__icon { grid-row: 1 / span 2; width: 44px; height: 44px; display: flex; align-items: center;
|
|
482
492
|
justify-content: center; color: var(--ksc-accent); }
|
|
483
|
-
.ksc-addon__icon svg { width:
|
|
484
|
-
.ksc-addon__img { grid-row: 1 / span 2; width:
|
|
493
|
+
.ksc-addon__icon svg { width: 34px; height: 34px; }
|
|
494
|
+
.ksc-addon__img { grid-row: 1 / span 2; width: 44px; height: 44px; object-fit: cover; border-radius: 8px;
|
|
485
495
|
background: var(--ksc-border); }
|
|
486
496
|
.ksc-addon__text { grid-column: 2; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
|
|
487
497
|
.ksc-addon__title { font-size: .875rem; font-weight: 600; }
|
|
@@ -549,12 +559,11 @@ function readMessage(config) {
|
|
|
549
559
|
return typeof raw === "string" && raw.trim() !== "" ? raw : null;
|
|
550
560
|
}
|
|
551
561
|
var css2 = `
|
|
552
|
-
.ksc-rt { display: flex; align-items: center; justify-content: center; gap:
|
|
553
|
-
padding:
|
|
554
|
-
color:
|
|
555
|
-
background:
|
|
556
|
-
.ksc-rt__count { font-variant-numeric: tabular-nums; font-weight: 700;
|
|
557
|
-
color: color-mix(in oklab, var(--ksc-positive, #0e9f6e) 85%, var(--ksc-text, #111)); }
|
|
562
|
+
.ksc-rt { display: flex; align-items: center; justify-content: center; gap: 4px;
|
|
563
|
+
padding: 9px 16px; font: inherit; font-size: 0.8125rem; font-weight: 400;
|
|
564
|
+
color: var(--ksc-text, #111);
|
|
565
|
+
background: rgb(215, 254, 218); }
|
|
566
|
+
.ksc-rt__count { font-variant-numeric: tabular-nums; font-weight: 700; }
|
|
558
567
|
.ksc-rt__icon { font-size: 0.95em; line-height: 1; }
|
|
559
568
|
@media (prefers-reduced-motion: reduce) { .ksc-rt { transition: none; } }
|
|
560
569
|
`;
|
|
@@ -567,10 +576,10 @@ var reservationTimer = {
|
|
|
567
576
|
if (minutes === null) return "";
|
|
568
577
|
void readMode(config);
|
|
569
578
|
const seed = formatCountdown(minutes * MS_PER_MINUTE);
|
|
570
|
-
const message = readMessage(config) ?? "Your cart
|
|
579
|
+
const message = readMessage(config) ?? "Your cart will expire in";
|
|
571
580
|
return `<div class="ksc-rt">
|
|
572
581
|
<span>${escapeHtml(message)}</span>
|
|
573
|
-
<span class="ksc-rt__count" data-ksc-countdown data-ksc-end-text="
|
|
582
|
+
<span class="ksc-rt__count" data-ksc-countdown data-ksc-end-text="00:00">${seed}</span>
|
|
574
583
|
<span class="ksc-rt__icon" aria-hidden="true">\u23F0</span>
|
|
575
584
|
</div>`;
|
|
576
585
|
}
|
|
@@ -591,78 +600,121 @@ function readVariantIds(config) {
|
|
|
591
600
|
}
|
|
592
601
|
return [...new Set(ids)];
|
|
593
602
|
}
|
|
603
|
+
function readTitle(config) {
|
|
604
|
+
const raw = config.title;
|
|
605
|
+
return typeof raw === "string" && raw.trim() !== "" ? raw : "You might also like";
|
|
606
|
+
}
|
|
594
607
|
function cartVariantIds(state) {
|
|
595
608
|
if (state === null) return /* @__PURE__ */ new Set();
|
|
596
609
|
const ids = /* @__PURE__ */ new Set();
|
|
597
610
|
for (const line of state.lines) {
|
|
598
611
|
const tag = line.attributes?.[UPSELL_VARIANT_ATTR];
|
|
599
612
|
if (typeof tag === "string") ids.add(tag);
|
|
613
|
+
if (line.variantId !== null && line.variantId !== void 0) ids.add(String(line.variantId));
|
|
600
614
|
}
|
|
601
615
|
return ids;
|
|
602
616
|
}
|
|
617
|
+
var ARROW_LEFT_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 12H5M11 6l-6 6 6 6"/></svg>`;
|
|
618
|
+
var ARROW_RIGHT_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg>`;
|
|
603
619
|
var css3 = `
|
|
604
|
-
.ksc-up { padding:
|
|
605
|
-
.ksc-up__title { margin: 0 0
|
|
606
|
-
|
|
620
|
+
.ksc-up { padding: 14px 6px 16px; font: inherit; color: var(--ksc-text); }
|
|
621
|
+
.ksc-up__title { margin: 0 0 10px; font-size: 0.9375rem; font-weight: 700; text-align: center; }
|
|
622
|
+
.ksc-up__row { display: grid; grid-template-columns: 28px minmax(0, 1fr) 28px; align-items: center; gap: 2px; }
|
|
623
|
+
.ksc-up__arrow { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px;
|
|
624
|
+
padding: 0; border: none; background: none; cursor: pointer; color: rgb(52, 64, 84); border-radius: 8px; }
|
|
625
|
+
.ksc-up__arrow:hover { background: var(--ksc-border); }
|
|
626
|
+
.ksc-up__arrow svg { width: 18px; height: 18px; }
|
|
607
627
|
.ksc-up__track { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory;
|
|
608
|
-
-webkit-overflow-scrolling: touch;
|
|
609
|
-
.ksc-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
.ksc-
|
|
618
|
-
.ksc-
|
|
619
|
-
.ksc-
|
|
620
|
-
|
|
621
|
-
|
|
628
|
+
scroll-behavior: smooth; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
|
|
629
|
+
.ksc-up__track::-webkit-scrollbar { display: none; }
|
|
630
|
+
.ksc-up__card { scroll-snap-align: start; flex: 0 0 100%; display: grid;
|
|
631
|
+
grid-template-columns: 64px minmax(0, 1fr); gap: 4px 12px; align-items: start;
|
|
632
|
+
border-radius: 12px; padding: 12px; background: rgb(242, 244, 247); box-sizing: border-box; }
|
|
633
|
+
.ksc-up__img { grid-row: 1 / span 4; width: 64px; height: 64px; object-fit: cover; border-radius: 8px;
|
|
634
|
+
background: var(--ksc-surface); }
|
|
635
|
+
.ksc-up__name { font-size: 0.9375rem; font-weight: 700; line-height: 1.25; display: -webkit-box;
|
|
636
|
+
-webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
637
|
+
.ksc-up__prices { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: 0.875rem; }
|
|
638
|
+
.ksc-up__price { font-weight: 700; }
|
|
639
|
+
.ksc-up__compare { color: rgb(152, 162, 179); text-decoration: line-through; }
|
|
640
|
+
.ksc-up__save { font-size: 0.75rem; font-weight: 500; color: rgb(7, 148, 85);
|
|
641
|
+
background: rgb(220, 250, 230); padding: 2px 8px; border-radius: 6px; white-space: nowrap; }
|
|
642
|
+
.ksc-up__variant { display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
|
|
643
|
+
font-size: 0.78rem; color: rgb(152, 162, 179); }
|
|
644
|
+
.ksc-up__select { font: inherit; font-size: 0.8125rem; color: var(--ksc-text); padding: 4px 24px 4px 10px;
|
|
645
|
+
border: 1px solid var(--ksc-border); border-radius: 8px; background-color: var(--ksc-surface); cursor: pointer;
|
|
646
|
+
appearance: none; -webkit-appearance: none;
|
|
647
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none' stroke='%23999' stroke-width='1.5'%3E%3Cpath d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
|
|
648
|
+
background-repeat: no-repeat; background-position: right 8px center; }
|
|
649
|
+
.ksc-up__add { justify-self: start; margin-top: 6px; padding: 8px 14px; font: inherit; font-size: 0.8125rem;
|
|
650
|
+
font-weight: 600; cursor: pointer; border: none; border-radius: 8px; background: rgb(7, 148, 85);
|
|
651
|
+
color: #fff; transition: opacity .15s ease; }
|
|
622
652
|
.ksc-up__add:hover { opacity: 0.9; }
|
|
623
|
-
.ksc-up__add:focus-visible { outline: 2px solid
|
|
653
|
+
.ksc-up__add:focus-visible { outline: 2px solid rgb(7, 148, 85); outline-offset: 2px; }
|
|
624
654
|
@media (prefers-reduced-motion: reduce) { .ksc-up__track { scroll-behavior: auto; } .ksc-up__add { transition: none; } }
|
|
625
655
|
`;
|
|
626
|
-
function card(variant, currency) {
|
|
656
|
+
function card(variant, currency, siblings) {
|
|
627
657
|
const name = escapeHtml(variant.productTitle);
|
|
628
658
|
const img = variant.imageUrl !== null ? `<img class="ksc-up__img" src="${escapeHtml(variant.imageUrl)}" alt="${escapeHtml(variant.imageAltText ?? "")}" loading="lazy" />` : `<div class="ksc-up__img" role="presentation"></div>`;
|
|
629
|
-
const variantTitle = variant.title !== null && variant.title.trim() !== "" && variant.title !== DEFAULT_VARIANT_TITLE ? `<span class="ksc-up__variant">${escapeHtml(variant.title)}</span>` : "";
|
|
630
659
|
const price = escapeHtml(formatMoney2({ amount: variant.price.amount, currency }));
|
|
631
660
|
const showCompare = variant.compareAtPrice !== null && variant.compareAtPrice.amount > variant.price.amount;
|
|
632
|
-
const
|
|
661
|
+
const compare = showCompare ? `<s class="ksc-up__compare">${escapeHtml(formatMoney2({ amount: variant.compareAtPrice.amount, currency }))}</s>` : "";
|
|
662
|
+
const savePct = showCompare ? Math.round(
|
|
663
|
+
(variant.compareAtPrice.amount - variant.price.amount) / variant.compareAtPrice.amount * 100
|
|
664
|
+
) : 0;
|
|
665
|
+
const save = savePct > 0 ? `<span class="ksc-up__save">You save ${savePct}%</span>` : "";
|
|
666
|
+
const hasMeaningfulTitle = variant.title !== null && variant.title.trim() !== "" && variant.title !== DEFAULT_VARIANT_TITLE;
|
|
667
|
+
const variantHtml = siblings !== void 0 && siblings.length > 1 ? `<span class="ksc-up__variant"><span>Size:</span><select class="ksc-up__select" data-smart-cart-upsell-variant aria-label="Size">${siblings.map(
|
|
668
|
+
(v) => `<option value="${escapeHtml(v.id)}"${v.id === variant.id ? " selected" : ""}>${escapeHtml(v.title ?? "")}</option>`
|
|
669
|
+
).join("")}</select></span>` : hasMeaningfulTitle ? `<span class="ksc-up__variant"><span>Size:</span><span>${escapeHtml(variant.title)}</span></span>` : "";
|
|
633
670
|
return `<div class="ksc-up__card" role="listitem">
|
|
634
671
|
${img}
|
|
635
672
|
<span class="ksc-up__name">${name}</span>
|
|
636
|
-
${
|
|
637
|
-
${
|
|
638
|
-
<button type="button" class="ksc-up__add" data-smart-cart-upsell-add data-variant-id="${escapeHtml(variant.id)}" aria-label="Add ${name} to cart">Add</button>
|
|
673
|
+
<span class="ksc-up__prices"><span class="ksc-up__price">${price}</span>${compare}${save}</span>
|
|
674
|
+
${variantHtml}
|
|
675
|
+
<button type="button" class="ksc-up__add" data-smart-cart-upsell-add data-variant-id="${escapeHtml(variant.id)}" aria-label="Add ${name} to cart">Add to cart</button>
|
|
639
676
|
</div>`;
|
|
640
677
|
}
|
|
641
678
|
var upsellCarousel = {
|
|
642
679
|
key: UPSELL_KEY,
|
|
643
680
|
zone: "after-items",
|
|
644
681
|
css: css3,
|
|
645
|
-
render({ config, state, variants }) {
|
|
682
|
+
render({ config, state, variants, productVariants }) {
|
|
646
683
|
if (variants === void 0 || variants.size === 0) return "";
|
|
647
684
|
const inCart = cartVariantIds(state);
|
|
648
|
-
const cards = readVariantIds(config).filter((id) => !inCart.has(id)).map((id) => variants.get(id)).filter((variant) => variant !== void 0).map(
|
|
685
|
+
const cards = readVariantIds(config).filter((id) => !inCart.has(id)).map((id) => variants.get(id)).filter((variant) => variant !== void 0).map(
|
|
686
|
+
(variant) => card(
|
|
687
|
+
variant,
|
|
688
|
+
state?.currency ?? variant.price.currency,
|
|
689
|
+
variant.productHandle !== null ? productVariants?.get(variant.productHandle) : void 0
|
|
690
|
+
)
|
|
691
|
+
).join("");
|
|
649
692
|
if (cards === "") return "";
|
|
650
693
|
return `<section class="ksc-up" aria-label="Recommended add-ons">
|
|
651
|
-
<p class="ksc-up__title"
|
|
652
|
-
<div class="ksc-
|
|
694
|
+
<p class="ksc-up__title">${escapeHtml(readTitle(config))}</p>
|
|
695
|
+
<div class="ksc-up__row">
|
|
696
|
+
<button type="button" class="ksc-up__arrow" data-smart-cart-upsell-prev aria-label="Previous item">${ARROW_LEFT_SVG}</button>
|
|
697
|
+
<div class="ksc-up__track" role="list">${cards}</div>
|
|
698
|
+
<button type="button" class="ksc-up__arrow" data-smart-cart-upsell-next aria-label="Next item">${ARROW_RIGHT_SVG}</button>
|
|
699
|
+
</div>
|
|
653
700
|
</section>`;
|
|
654
701
|
}
|
|
655
702
|
};
|
|
656
703
|
|
|
657
704
|
// ../smart-cart/src/widgets/discount-code.ts
|
|
658
705
|
var css4 = `
|
|
659
|
-
.ksc-discount { padding:
|
|
660
|
-
.ksc-discount__row { display: flex; gap:
|
|
661
|
-
|
|
662
|
-
.ksc-
|
|
663
|
-
.ksc-
|
|
706
|
+
.ksc-discount { padding: 10px 20px; display: flex; flex-direction: column; gap: 8px; }
|
|
707
|
+
.ksc-discount__row { display: flex; align-items: center; gap: 6px; padding: 5px 5px 5px 14px;
|
|
708
|
+
border: 1px solid rgb(190, 190, 190); border-radius: 10px; background: var(--ksc-surface); }
|
|
709
|
+
.ksc-discount__row:focus-within { border-color: var(--ksc-text); }
|
|
710
|
+
.ksc-discount__input { flex: 1; min-width: 0; padding: 6px 0; border: none; background: none;
|
|
711
|
+
color: var(--ksc-text); font: inherit; font-size: 0.875rem; outline: none; }
|
|
712
|
+
.ksc-discount__apply { padding: 8px 16px; border: none; border-radius: 8px;
|
|
713
|
+
background: rgb(220, 250, 230); color: var(--ksc-text); font: inherit; font-size: 0.875rem;
|
|
714
|
+
font-weight: 500; cursor: pointer; white-space: nowrap; }
|
|
715
|
+
.ksc-discount__apply:hover { filter: brightness(0.97); }
|
|
664
716
|
.ksc-discount__chips { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
665
|
-
.ksc-discount__chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px 3px 10px; background:
|
|
717
|
+
.ksc-discount__chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px 3px 10px; background: rgb(242, 244, 247); border-radius: 999px; font-size: 0.8125rem; color: var(--ksc-text); }
|
|
666
718
|
.ksc-discount__chip-remove { display: inline-flex; align-items: center; justify-content: center; background: none; border: none; cursor: pointer; padding: 2px; color: color-mix(in oklab, var(--ksc-text) 60%, transparent); line-height: 1; font-size: 1rem; }
|
|
667
719
|
.ksc-discount__chip-remove:hover { color: var(--ksc-text); }
|
|
668
720
|
`;
|
|
@@ -695,11 +747,26 @@ function readMessage2(config, key) {
|
|
|
695
747
|
const raw = config[key];
|
|
696
748
|
return typeof raw === "string" && raw.trim() !== "" ? raw : null;
|
|
697
749
|
}
|
|
750
|
+
function renderTemplate(template, amount) {
|
|
751
|
+
return template.split(/\{amount\}/g).map((part) => escapeHtml(part)).join(`<b>${escapeHtml(amount)}</b>`);
|
|
752
|
+
}
|
|
753
|
+
var TRUCK_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M1 5h14v11H1zM15 9h4l3 3v4h-7z"/><circle cx="6" cy="18.5" r="1.8"/><circle cx="18" cy="18.5" r="1.8"/></svg>`;
|
|
698
754
|
var css5 = `
|
|
699
|
-
.ksc-fsb { padding:
|
|
700
|
-
.ksc-fsb__msg { margin: 0 0
|
|
701
|
-
.ksc-
|
|
702
|
-
.ksc-
|
|
755
|
+
.ksc-fsb { padding: 14px 20px 10px; font: inherit; color: var(--ksc-text); }
|
|
756
|
+
.ksc-fsb__msg { margin: 0 0 10px; font-size: 0.8125rem; text-align: center; }
|
|
757
|
+
.ksc-fsb__msg b { font-weight: 700; }
|
|
758
|
+
.ksc-fsb__track { position: relative; height: 8px; border-radius: 999px;
|
|
759
|
+
background: rgb(234, 236, 240); }
|
|
760
|
+
.ksc-fsb__fill { height: 100%; border-radius: 999px; background: rgb(29, 41, 57);
|
|
761
|
+
transition: width .3s ease; }
|
|
762
|
+
.ksc-fsb__step { position: absolute; right: -2px; top: 50%; transform: translateY(-50%);
|
|
763
|
+
width: 14px; height: 14px; border-radius: 4px; border: 2px solid rgb(29, 41, 57);
|
|
764
|
+
background: var(--ksc-surface); box-sizing: border-box; }
|
|
765
|
+
.ksc-fsb--unlocked .ksc-fsb__step { background: rgb(29, 41, 57); }
|
|
766
|
+
.ksc-fsb__tier { display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
|
|
767
|
+
margin-top: 6px; font-size: 0.78rem; color: rgb(152, 162, 179); }
|
|
768
|
+
.ksc-fsb__tier svg { width: 20px; height: 20px; }
|
|
769
|
+
.ksc-fsb--unlocked .ksc-fsb__tier { color: rgb(29, 41, 57); }
|
|
703
770
|
@media (prefers-reduced-motion: reduce) { .ksc-fsb__fill { transition: none; } }
|
|
704
771
|
`;
|
|
705
772
|
var freeShippingBar = {
|
|
@@ -709,20 +776,22 @@ var freeShippingBar = {
|
|
|
709
776
|
render({ config, state }) {
|
|
710
777
|
const threshold = readThreshold(config);
|
|
711
778
|
if (threshold === null || state === null) return "";
|
|
712
|
-
const
|
|
779
|
+
const discountTotal = state.discountTotal?.amount ?? 0;
|
|
780
|
+
const subtotal = Math.max(0, state.subtotal.amount - discountTotal);
|
|
713
781
|
const remaining = Math.max(0, threshold - subtotal);
|
|
714
782
|
const unlocked = remaining === 0;
|
|
715
783
|
const pct = Math.min(100, Math.round(subtotal / threshold * 100));
|
|
716
|
-
const remainingMoney =
|
|
784
|
+
const remainingMoney = formatMoneyCompact({
|
|
785
|
+
amount: remaining,
|
|
786
|
+
currency: state.subtotal.currency
|
|
787
|
+
});
|
|
717
788
|
const beforeTemplate = readMessage2(config, "messageBefore");
|
|
718
789
|
const afterTemplate = readMessage2(config, "messageAfter");
|
|
719
|
-
const message = unlocked ? afterTemplate
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
<p class="ksc-fsb__msg">${escapeHtml(message)}</p>
|
|
725
|
-
<div class="ksc-fsb__track"><div class="ksc-fsb__fill" style="width: ${pct}%"></div></div>
|
|
790
|
+
const message = unlocked ? afterTemplate !== null ? renderTemplate(afterTemplate, remainingMoney) : `<b>Free shipping</b> unlocked!` : beforeTemplate !== null ? renderTemplate(beforeTemplate, remainingMoney) : `Add <b>${escapeHtml(remainingMoney)}</b> to unlock <b>Free shipping</b>!`;
|
|
791
|
+
return `<div class="ksc-fsb${unlocked ? " ksc-fsb--unlocked" : ""}">
|
|
792
|
+
<p class="ksc-fsb__msg">${message}</p>
|
|
793
|
+
<div class="ksc-fsb__track"><div class="ksc-fsb__fill" style="width: ${pct}%"></div><span class="ksc-fsb__step" aria-hidden="true"></span></div>
|
|
794
|
+
<div class="ksc-fsb__tier">${TRUCK_SVG}<span>${unlocked ? "" : "\u{1F512} "}Free shipping</span></div>
|
|
726
795
|
</div>`;
|
|
727
796
|
}
|
|
728
797
|
};
|
|
@@ -889,6 +958,23 @@ var PAYMENT_ICON_SVGS = {
|
|
|
889
958
|
<path d="M228.897012,82.7490197 C216.569147,146.069792 174.366398,167.970272 120.46841,167.970272 L93.0241367,167.970272 C86.4398419,167.970272 80.8794007,172.764903 79.8555471,179.265958 L61.8174095,293.621258 C61.1431644,297.883153 64.4394738,301.745495 68.7513129,301.745495 L117.421821,301.745495 C123.182038,301.745495 128.084882,297.550192 128.983876,291.864891 L129.458344,289.384335 L138.631407,231.249423 L139.222412,228.036354 C140.121406,222.351053 145.02425,218.15575 150.784467,218.15575 L158.067979,218.15575 C205.215193,218.15575 242.132193,199.002194 252.920115,143.605884 C257.423406,120.456802 255.092683,101.128442 243.181019,87.5519756 C239.568397,83.4399129 235.081754,80.0437153 229.854273,77.2718188 C229.571257,79.0614817 229.263268,80.8761167 228.897012,82.7490197 L228.897012,82.7490197 Z" fill="#2790C3"></path>
|
|
890
959
|
<path d="M216.952052,72.1275783 C215.070825,71.5781934 213.13133,71.0787526 211.133566,70.6375799 C209.135803,70.1964071 207.071448,69.8051785 204.957148,69.4638939 C197.548776,68.265236 189.457835,67.699203 180.767565,67.699203 L107.457976,67.699203 C105.651665,67.699203 103.936919,68.1070797 102.4053,68.8479169 C99.0174265,70.4710996 96.5118984,73.6675208 95.8959214,77.5881313 L80.3133678,176.385849 L79.8638711,179.265958 C80.8877248,172.764903 86.4481659,167.970272 93.0324607,167.970272 L120.476734,167.970272 C174.374722,167.970272 216.577471,146.078116 228.905336,82.7490197 C229.271592,80.8761167 229.579581,79.0614817 229.862597,77.2718188 C226.741092,75.623664 223.361542,74.2002577 219.723948,72.9932757 C218.816631,72.6936112 217.892665,72.4022708 216.952052,72.1275783" fill="#1F264F"></path>
|
|
891
960
|
</g>
|
|
961
|
+
</svg>`,
|
|
962
|
+
"apple-pay": `<svg width="512px" height="211px" viewBox="0 0 512 211" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
|
963
|
+
<g>
|
|
964
|
+
<path d="M93.5520633,27.1031049 C87.5513758,34.2039183 77.9502759,39.8045599 68.349176,39.0044683 C67.1490386,29.4033684 71.849577,19.2021998 77.3502072,12.901478 C83.3508946,5.6006416 93.8520976,0.400045829 102.353071,0 C103.353186,10.0011457 99.4527392,19.8022685 93.5520633,27.1031049 Z M102.25306,40.904686 C88.3514675,40.1045943 76.4501041,48.8055911 69.8493479,48.8055911 C63.1485803,48.8055911 53.0474231,41.3047318 42.0461628,41.5047547 C27.7445244,41.7047776 14.4430006,49.8057057 7.14216427,62.7071836 C-7.8595543,88.5101396 3.24171744,126.714516 17.7433787,147.716922 C24.8441922,158.118114 33.345166,169.51942 44.5464492,169.119374 C55.1476637,168.719328 59.3481449,162.218584 72.1496114,162.218584 C85.0510894,162.218584 88.7515133,169.119374 99.9527965,168.919351 C111.554126,168.719328 118.854962,158.51816 125.955775,148.116968 C134.056703,136.315616 137.357081,124.814299 137.557104,124.21423 C137.357081,124.014207 115.154538,115.513233 114.954515,89.9103 C114.754492,68.5078482 132.45652,58.3066795 133.256612,57.7066108 C123.255466,42.9049151 107.653679,41.3047318 102.25306,40.904686 Z M182.56226,11.9013634 L182.56226,167.819225 L206.765033,167.819225 L206.765033,114.513118 L240.268871,114.513118 C270.872377,114.513118 292.37484,93.5107124 292.37484,63.1072295 C292.37484,32.7037465 271.272423,11.9013634 241.068963,11.9013634 L182.56226,11.9013634 Z M206.765033,32.3037007 L234.668229,32.3037007 C255.670635,32.3037007 267.67201,43.5049839 267.67201,63.2072409 C267.67201,82.909498 255.670635,94.2107926 234.568218,94.2107926 L206.765033,94.2107926 L206.765033,32.3037007 Z M336.579904,169.019363 C351.781646,169.019363 365.883261,161.31848 372.283994,149.117083 L372.784052,149.117083 L372.784052,167.819225 L395.186618,167.819225 L395.186618,90.2103344 C395.186618,67.7077565 377.184556,53.2060952 349.481382,53.2060952 C323.778438,53.2060952 304.776261,67.9077794 304.076181,88.1100938 L325.878678,88.1100938 C327.678884,78.5089939 336.579904,72.2082721 348.781302,72.2082721 C363.582998,72.2082721 371.883949,79.1090626 371.883949,91.8105177 L371.883949,100.411503 L341.680488,102.211709 C313.577269,103.911904 298.375528,115.413222 298.375528,135.415513 C298.375528,155.617827 314.077326,169.019363 336.579904,169.019363 Z M343.080649,150.517243 C330.179171,150.517243 321.978231,144.316533 321.978231,134.815444 C321.978231,125.014321 329.879137,119.313668 344.980867,118.413565 L371.883949,116.713371 L371.883949,125.514379 C371.883949,140.116051 359.482528,150.517243 343.080649,150.517243 Z M425.090044,210.224083 C448.692748,210.224083 459.794019,201.223052 469.495131,173.919924 L512,54.7062671 L487.397182,54.7062671 L458.893916,146.816819 L458.393859,146.816819 L429.890594,54.7062671 L404.587695,54.7062671 L445.592392,168.219271 L443.39214,175.120061 C439.691716,186.821402 433.691029,191.321918 422.989803,191.321918 C421.089585,191.321918 417.389162,191.121895 415.88899,190.921872 L415.88899,209.624014 C417.28915,210.02406 423.289838,210.224083 425.090044,210.224083 Z" fill="#000000"></path>
|
|
965
|
+
</g>
|
|
966
|
+
</svg>`,
|
|
967
|
+
"google-pay": `<svg width="512px" height="204px" viewBox="0 0 512 204" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
|
968
|
+
<title>Google Pay</title>
|
|
969
|
+
<g>
|
|
970
|
+
<path d="M362.926585,55.0572275 C377.002187,55.0572275 387.878788,58.8960279 396.196189,66.5736286 C404.51359,74.2512294 408.35239,84.4880304 408.35239,97.2840316 L408.35239,158.704838 L390.437988,158.704838 L390.437988,144.629236 L389.798188,144.629236 C382.120587,156.145637 371.243986,161.903838 358.447985,161.903838 C347.571384,161.903838 337.974383,158.704838 330.296782,152.306837 C323.258982,145.908836 318.780381,136.951636 318.780381,127.354635 C318.780381,117.117834 322.619182,108.800433 330.296782,102.402432 C337.974383,96.0044315 348.850984,93.4452313 361.646985,93.4452313 C373.163386,93.4452313 382.120587,95.3646315 389.158388,99.8432319 L389.158388,95.3646315 C389.158388,89.3931642 386.92904,83.421697 382.470345,79.5309543 L381.480787,78.7298298 C376.362387,74.2512294 369.964386,71.6920291 362.926585,71.6920291 C352.049984,71.6920291 343.732584,76.1706296 337.974383,85.1278305 L321.339581,74.8910295 C331.576382,61.4552281 345.012184,55.0572275 362.926585,55.0572275 Z M272.714777,11.5508233 C284.195633,11.5508233 295.105804,15.5456243 303.828346,22.9962452 L305.34458,24.3468245 C314.301781,32.0244253 318.780381,43.5408264 318.780381,55.6970276 C318.780381,67.8532288 314.301781,78.7298298 305.34458,87.0472306 C296.387379,95.3646315 285.510778,99.8432319 272.714777,99.8432319 L242.004374,99.2034318 L242.004374,158.704838 L222.810372,158.704838 L222.810372,11.5508233 L272.714777,11.5508233 Z M365.485786,108.800433 C357.808185,108.800433 351.410184,110.719833 346.291784,114.558633 C341.173383,117.757634 338.614183,122.236234 338.614183,127.994435 C338.614183,133.112835 341.173383,137.591436 345.012184,140.150636 C349.490784,143.349636 354.609185,145.269036 359.727585,145.269036 C366.893346,145.269036 374.059107,142.482352 379.664324,137.429163 L380.840987,136.311835 C387.238988,130.553635 390.437988,123.515834 390.437988,115.838233 C384.679788,111.359633 376.362387,108.800433 365.485786,108.800433 Z M273.994377,29.465225 L242.004374,29.465225 L242.004374,80.64923 L273.994377,80.64923 C281.032177,80.64923 288.069978,78.0900298 292.548579,72.9716293 C302.78538,63.3746283 302.78538,47.3796268 293.188379,37.7826258 L292.548579,37.1428258 C287.430178,32.0244253 281.032177,28.825425 273.994377,29.465225 Z M512,58.2562278 L448.659794,203.490842 L429.465792,203.490842 L453.138394,152.946637 L411.55139,58.8960279 L432.024992,58.8960279 L462.095595,131.193435 L462.735395,131.193435 L492.166198,58.8960279 L512,58.8960279 L512,58.2562278 Z" fill="#5F6368"></path>
|
|
971
|
+
<g>
|
|
972
|
+
<path d="M165.868166,86.4074306 C165.868166,80.64923 165.228366,74.8910295 164.588566,69.1328289 L84.6135583,69.1328289 L84.6135583,101.762632 L130.039363,101.762632 C128.119963,111.999433 122.361762,121.596434 113.404561,127.354635 L113.404561,148.468037 L140.915964,148.468037 C156.910965,133.752635 165.868166,111.999433 165.868166,86.4074306 Z" fill="#4285F4"></path>
|
|
973
|
+
<path d="M84.6135583,168.941639 C107.646361,168.941639 126.840362,161.264038 140.915964,148.468037 L113.404561,127.354635 C105.72696,132.473035 96.1299594,135.672035 84.6135583,135.672035 C62.8603561,135.672035 43.6663543,120.956634 37.2683536,100.483032 L9.11715089,100.483032 L9.11715089,122.236234 C23.8325523,151.027237 52.6235551,168.941639 84.6135583,168.941639 Z" fill="#34A853"></path>
|
|
974
|
+
<path d="M37.2683536,100.483032 C33.4295533,90.246231 33.4295533,78.7298298 37.2683536,67.8532288 L37.2683536,46.1000266 L9.11715089,46.1000266 C-3.0390503,69.772629 -3.0390503,97.9238317 9.11715089,122.236234 L37.2683536,100.483032 Z" fill="#FBBC04"></path>
|
|
975
|
+
<path d="M84.6135583,33.3040254 C96.7697595,33.3040254 108.286161,37.7826258 117.243361,46.1000266 L117.243361,46.1000266 L141.555764,21.7876243 C126.200562,7.71202289 105.72696,-0.60537792 85.2533583,0.0344221425 C53.2633552,0.0344221425 23.8325523,17.9488239 9.75695095,46.7398267 L37.9081537,68.4930288 C43.6663543,48.0194268 62.8603561,33.3040254 84.6135583,33.3040254 Z" fill="#EA4335"></path>
|
|
976
|
+
</g>
|
|
977
|
+
</g>
|
|
892
978
|
</svg>`
|
|
893
979
|
};
|
|
894
980
|
|
|
@@ -909,10 +995,11 @@ function readBadges(config) {
|
|
|
909
995
|
return valid.length > 0 ? valid : null;
|
|
910
996
|
}
|
|
911
997
|
var css7 = `
|
|
912
|
-
.ksc-tb { display: flex; flex-wrap: wrap; gap:
|
|
998
|
+
.ksc-tb { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: center;
|
|
913
999
|
padding: 10px 16px 4px; }
|
|
914
|
-
.ksc-tb__icon { display: flex; align-items: center;
|
|
915
|
-
|
|
1000
|
+
.ksc-tb__icon { display: flex; align-items: center; justify-content: center; width: 38px; height: 26px;
|
|
1001
|
+
border: 1px solid rgb(234, 236, 240); border-radius: 5px; background: #fff; box-sizing: border-box; }
|
|
1002
|
+
.ksc-tb__icon svg { max-height: 15px; max-width: 28px; width: auto; height: auto; display: block; }
|
|
916
1003
|
`;
|
|
917
1004
|
var trustBadges = {
|
|
918
1005
|
key: "trustBadges",
|
|
@@ -960,7 +1047,7 @@ var STYLES2 = `
|
|
|
960
1047
|
--ksc-border: color-mix(in oklab, var(--ksc-text) 12%, transparent); }
|
|
961
1048
|
.overlay { position: absolute; inset: 0; background: rgba(0,0,0,.45); opacity: 0;
|
|
962
1049
|
transition: opacity .25s ease; }
|
|
963
|
-
.panel { position: absolute; top: 0; right: 0; height: 100%; width: min(
|
|
1050
|
+
.panel { position: absolute; top: 0; right: 0; height: 100%; width: min(520px, 100vw);
|
|
964
1051
|
background: var(--ksc-surface); color: var(--ksc-text); font-family: var(--ksc-font);
|
|
965
1052
|
transform: translateX(100%); transition: transform .25s ease; display: flex; flex-direction: column;
|
|
966
1053
|
box-shadow: -8px 0 40px rgba(0,0,0,.14); }
|
|
@@ -969,12 +1056,13 @@ var STYLES2 = `
|
|
|
969
1056
|
:host(:not([open])) { pointer-events: none; }
|
|
970
1057
|
:host([open]) { pointer-events: auto; }
|
|
971
1058
|
|
|
972
|
-
/* Header */
|
|
973
|
-
.ksc-head { display: flex; align-items: center;
|
|
974
|
-
|
|
975
|
-
.ksc-head__title { font-size:
|
|
976
|
-
.ksc-head__count {
|
|
977
|
-
.ksc-head__close {
|
|
1059
|
+
/* Header \u2014 centered "My cart \xB7 N" with the close control pinned right (original cart layout). */
|
|
1060
|
+
.ksc-head { position: relative; display: flex; align-items: center; justify-content: center;
|
|
1061
|
+
gap: 6px; flex: 0 0 auto; padding: 16px 52px; }
|
|
1062
|
+
.ksc-head__title { font-size: 1.125rem; font-weight: 600; letter-spacing: .01em; }
|
|
1063
|
+
.ksc-head__count { font-weight: 600; font-size: 1.125rem; }
|
|
1064
|
+
.ksc-head__close { position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
|
|
1065
|
+
display: flex; align-items: center; justify-content: center;
|
|
978
1066
|
width: 32px; height: 32px; padding: 0; border: none; background: none; cursor: pointer;
|
|
979
1067
|
color: var(--ksc-text); border-radius: 8px; }
|
|
980
1068
|
.ksc-head__close:hover { background: var(--ksc-border); }
|
|
@@ -986,63 +1074,66 @@ var STYLES2 = `
|
|
|
986
1074
|
gap: 14px; padding: 56px 24px; text-align: center; color: var(--ksc-muted); }
|
|
987
1075
|
.ksc-empty svg { width: 44px; height: 44px; opacity: .5; }
|
|
988
1076
|
.ksc-empty p { margin: 0; font-size: .95rem; }
|
|
989
|
-
.ksc-line { display: grid; grid-template-columns:
|
|
990
|
-
padding:
|
|
991
|
-
.ksc-
|
|
1077
|
+
.ksc-line { display: grid; grid-template-columns: 80px 1fr; gap: 14px;
|
|
1078
|
+
padding: 14px 20px; }
|
|
1079
|
+
.ksc-line + .ksc-line { border-top: 1px solid var(--ksc-border); }
|
|
1080
|
+
.ksc-line__img { width: 80px; height: 80px; object-fit: cover; border-radius: 8px;
|
|
992
1081
|
background: var(--ksc-border); }
|
|
993
1082
|
.ksc-line__img--ph { display: block; }
|
|
994
|
-
.ksc-line__body { display: flex; flex-direction: column; gap:
|
|
995
|
-
.ksc-line__top { display: flex; align-items: flex-start; justify-content: space-between; gap:
|
|
996
|
-
.ksc-
|
|
997
|
-
.ksc-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
.ksc-
|
|
1083
|
+
.ksc-line__body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
|
|
1084
|
+
.ksc-line__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
|
|
1085
|
+
.ksc-line__main { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
|
|
1086
|
+
.ksc-line__title { font-size: .9375rem; font-weight: 700; line-height: 1.3; }
|
|
1087
|
+
.ksc-line__compare { color: rgb(152, 162, 179); text-decoration: line-through;
|
|
1088
|
+
font-size: .875rem; white-space: nowrap; }
|
|
1089
|
+
.ksc-line__meta { display: flex; flex-direction: column; gap: 3px; }
|
|
1090
|
+
.ksc-line__opt { font-size: .8125rem; color: rgb(152, 162, 179); line-height: 1.35;
|
|
1001
1091
|
overflow: hidden; text-overflow: ellipsis; }
|
|
1002
|
-
.ksc-line__opt b { font-weight:
|
|
1003
|
-
.ksc-line__variant { display: flex;
|
|
1004
|
-
|
|
1005
|
-
.ksc-line__discount
|
|
1006
|
-
.ksc-
|
|
1092
|
+
.ksc-line__opt b { font-weight: 700; color: var(--ksc-text); }
|
|
1093
|
+
.ksc-line__variant { display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
|
|
1094
|
+
font-size: .8125rem; color: rgb(152, 162, 179); }
|
|
1095
|
+
.ksc-line__discount { font-size: .8125rem; font-weight: 500; color: var(--ksc-positive); line-height: 1.35; }
|
|
1096
|
+
.ksc-line__discount s { color: rgb(152, 162, 179); text-decoration: line-through; }
|
|
1097
|
+
.ksc-line__select { font: inherit; font-size: .8125rem; color: var(--ksc-text); padding: 4px 24px 4px 10px;
|
|
1007
1098
|
border: 1px solid var(--ksc-border); border-radius: 8px; background: var(--ksc-surface); cursor: pointer;
|
|
1008
1099
|
appearance: none; -webkit-appearance: none;
|
|
1009
1100
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none' stroke='%23999' stroke-width='1.5'%3E%3Cpath d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
|
|
1010
1101
|
background-repeat: no-repeat; background-position: right 8px center; }
|
|
1011
1102
|
.ksc-line__select:focus { outline: none; border-color: var(--ksc-accent); }
|
|
1012
1103
|
.ksc-line__bottom { display: flex; align-items: center; justify-content: space-between;
|
|
1013
|
-
gap: 10px; margin-top:
|
|
1104
|
+
gap: 10px; margin-top: 4px; }
|
|
1014
1105
|
.ksc-qty { display: inline-flex; align-items: center; border: 1px solid var(--ksc-border);
|
|
1015
|
-
border-radius:
|
|
1016
|
-
.ksc-qty button { width:
|
|
1106
|
+
border-radius: 8px; }
|
|
1107
|
+
.ksc-qty button { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
|
|
1017
1108
|
padding: 0; border: none; background: none; cursor: pointer; color: var(--ksc-text);
|
|
1018
|
-
font-size: 16px; line-height: 1; border-radius:
|
|
1109
|
+
font-size: 16px; line-height: 1; border-radius: 8px; }
|
|
1019
1110
|
.ksc-qty button:hover { background: var(--ksc-border); }
|
|
1020
|
-
.ksc-qty__n { min-width:
|
|
1021
|
-
.ksc-
|
|
1022
|
-
.ksc-
|
|
1023
|
-
.ksc-
|
|
1024
|
-
|
|
1025
|
-
background:
|
|
1026
|
-
.ksc-
|
|
1111
|
+
.ksc-qty__n { min-width: 26px; text-align: center; font-size: .875rem; font-variant-numeric: tabular-nums; }
|
|
1112
|
+
.ksc-line__prices { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: 0 0 auto; }
|
|
1113
|
+
.ksc-line__price { font-size: .9375rem; font-weight: 700; }
|
|
1114
|
+
.ksc-line__save { display: inline-flex; align-items: center; gap: 4px; font-size: .75rem;
|
|
1115
|
+
font-weight: 500; color: rgb(7, 148, 85); white-space: nowrap;
|
|
1116
|
+
background: rgb(220, 250, 230); padding: 3px 8px; border-radius: 6px; }
|
|
1117
|
+
.ksc-line__save svg { width: 12px; height: 12px; }
|
|
1118
|
+
.ksc-line__remove { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px;
|
|
1027
1119
|
padding: 0; border: none; background: none; cursor: pointer; color: var(--ksc-muted); border-radius: 8px; }
|
|
1028
1120
|
.ksc-line__remove:hover { color: var(--ksc-text); background: var(--ksc-border); }
|
|
1029
|
-
.ksc-line__remove svg { width:
|
|
1121
|
+
.ksc-line__remove svg { width: 17px; height: 17px; }
|
|
1030
1122
|
|
|
1031
1123
|
/* Footer / summary / checkout */
|
|
1032
1124
|
.footer { flex: 0 0 auto; border-top: 1px solid var(--ksc-border); }
|
|
1033
|
-
.ksc-summary { display: flex; flex-direction: column; gap:
|
|
1125
|
+
.ksc-summary { display: flex; flex-direction: column; gap: 6px; padding: 12px 20px 2px; }
|
|
1034
1126
|
.ksc-summary__row { display: flex; align-items: center; justify-content: space-between;
|
|
1035
|
-
font-size: .
|
|
1036
|
-
.ksc-summary__row--
|
|
1037
|
-
.
|
|
1038
|
-
.checkout { display: block; text-align: center; margin: 8px 18px 0; padding: 15px;
|
|
1127
|
+
font-size: .875rem; color: rgb(71, 84, 103); }
|
|
1128
|
+
.ksc-summary__row--total { font-size: 1rem; font-weight: 700; color: var(--ksc-text); }
|
|
1129
|
+
.checkout { display: block; text-align: center; margin: 10px 20px 0; padding: 16px;
|
|
1039
1130
|
background: var(--ksc-accent); color: var(--ksc-accent-text); text-decoration: none;
|
|
1040
|
-
border-radius:
|
|
1131
|
+
border-radius: 10px; font-weight: 700; font-size: 1rem; }
|
|
1041
1132
|
.checkout:hover { opacity: .92; }
|
|
1042
1133
|
.ksc-continue { display: block; width: 100%; padding: 8px 18px 16px; text-align: center;
|
|
1043
|
-
border: none; background: none; cursor: pointer; color: var(--ksc-
|
|
1044
|
-
font-size: .
|
|
1045
|
-
.ksc-continue:hover {
|
|
1134
|
+
border: none; background: none; cursor: pointer; color: var(--ksc-text); font: inherit;
|
|
1135
|
+
font-size: .875rem; font-weight: 700; }
|
|
1136
|
+
.ksc-continue:hover { opacity: .7; }
|
|
1046
1137
|
|
|
1047
1138
|
@media (prefers-reduced-motion: reduce) { .overlay, .panel { transition: none; } }
|
|
1048
1139
|
.chrome { position: absolute; inset: 0; pointer-events: none; }
|
|
@@ -1052,6 +1143,7 @@ var STYLES2 = `
|
|
|
1052
1143
|
var CLOSE_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg>`;
|
|
1053
1144
|
var TRASH_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M7 7l1 13h8l1-13"/></svg>`;
|
|
1054
1145
|
var BAG_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 8h12l1 12H5L6 8zM9 8a3 3 0 0 1 6 0"/></svg>`;
|
|
1146
|
+
var TAG_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 13l-7 7-9-9V4h7l9 9z"/><circle cx="7.5" cy="7.5" r="1" fill="currentColor"/></svg>`;
|
|
1055
1147
|
var Base = typeof HTMLElement !== "undefined" ? HTMLElement : class {
|
|
1056
1148
|
};
|
|
1057
1149
|
var SmartCartElement = class _SmartCartElement extends Base {
|
|
@@ -1145,6 +1237,13 @@ var SmartCartElement = class _SmartCartElement extends Base {
|
|
|
1145
1237
|
}
|
|
1146
1238
|
const upsellBtn = target?.closest("[data-smart-cart-upsell-add]");
|
|
1147
1239
|
if (upsellBtn) void this.#onUpsellAdd(upsellBtn);
|
|
1240
|
+
const upsellNav = target?.closest(
|
|
1241
|
+
"[data-smart-cart-upsell-prev], [data-smart-cart-upsell-next]"
|
|
1242
|
+
);
|
|
1243
|
+
if (upsellNav) {
|
|
1244
|
+
this.#onUpsellNav(upsellNav);
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1148
1247
|
const discountApply = target?.closest("[data-smart-cart-discount-apply]");
|
|
1149
1248
|
if (discountApply) {
|
|
1150
1249
|
void this.#onDiscountApply(discountApply);
|
|
@@ -1155,7 +1254,12 @@ var SmartCartElement = class _SmartCartElement extends Base {
|
|
|
1155
1254
|
});
|
|
1156
1255
|
this.#root.querySelector(".panel")?.addEventListener("change", (e) => {
|
|
1157
1256
|
const select = e.target?.closest("[data-smart-cart-variant]");
|
|
1158
|
-
if (select)
|
|
1257
|
+
if (select) {
|
|
1258
|
+
void this.#onVariantSelect(select);
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
const upsellSelect = e.target?.closest("[data-smart-cart-upsell-variant]");
|
|
1262
|
+
if (upsellSelect) this.#onUpsellVariantSelect(upsellSelect);
|
|
1159
1263
|
});
|
|
1160
1264
|
}
|
|
1161
1265
|
connectedCallback() {
|
|
@@ -1200,8 +1304,7 @@ var SmartCartElement = class _SmartCartElement extends Base {
|
|
|
1200
1304
|
this.#renderCart(state);
|
|
1201
1305
|
this.#renderChrome(state);
|
|
1202
1306
|
}
|
|
1203
|
-
void this.#resolveUpsellVariants();
|
|
1204
|
-
void this.#resolveProductVariants();
|
|
1307
|
+
void this.#resolveUpsellVariants().then(() => this.#resolveProductVariants());
|
|
1205
1308
|
}
|
|
1206
1309
|
/** Add a line (from a theme add-to-cart submit intercepted by mountSmartCart) and open the drawer on
|
|
1207
1310
|
* the result. Opens first for instant feedback, then adds and reconciles against the server cart.
|
|
@@ -1223,8 +1326,9 @@ var SmartCartElement = class _SmartCartElement extends Base {
|
|
|
1223
1326
|
}
|
|
1224
1327
|
}
|
|
1225
1328
|
/** Lazily fetch sibling variants for every cart line that has a product handle and a real variant
|
|
1226
|
-
* title (single-variant lines have none → no switcher)
|
|
1227
|
-
*
|
|
1329
|
+
* title (single-variant lines have none → no switcher), plus every resolved upsell/add-on
|
|
1330
|
+
* product (the upsell card's size select). Caches per handle, never re-fetches, and re-renders
|
|
1331
|
+
* the cart once new variants land so the `<select>`s appear. Fail-closed per the lookup. */
|
|
1228
1332
|
async #resolveProductVariants() {
|
|
1229
1333
|
const lookup = this.#variantLookup;
|
|
1230
1334
|
if (!lookup?.fetchProductVariants || this.#lastState === null) return;
|
|
@@ -1235,6 +1339,12 @@ var SmartCartElement = class _SmartCartElement extends Base {
|
|
|
1235
1339
|
handles.add(handle);
|
|
1236
1340
|
}
|
|
1237
1341
|
}
|
|
1342
|
+
for (const variant of this.#upsellVariants?.values() ?? []) {
|
|
1343
|
+
const handle = variant.productHandle;
|
|
1344
|
+
if (handle !== null && handle.length > 0 && !this.#productVariants.has(handle) && !this.#productVariantsFetching.has(handle)) {
|
|
1345
|
+
handles.add(handle);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1238
1348
|
if (handles.size === 0) return;
|
|
1239
1349
|
await Promise.all(
|
|
1240
1350
|
[...handles].map(async (handle) => {
|
|
@@ -1379,6 +1489,20 @@ var SmartCartElement = class _SmartCartElement extends Base {
|
|
|
1379
1489
|
this.#addOnPending = false;
|
|
1380
1490
|
}
|
|
1381
1491
|
}
|
|
1492
|
+
/** Scroll the upsell track one card left/right (the arrows sit outside the track). */
|
|
1493
|
+
#onUpsellNav(btn) {
|
|
1494
|
+
const track = btn.closest(".ksc-up")?.querySelector(".ksc-up__track");
|
|
1495
|
+
if (!track) return;
|
|
1496
|
+
const direction = btn.hasAttribute("data-smart-cart-upsell-prev") ? -1 : 1;
|
|
1497
|
+
track.scrollBy({ left: direction * track.clientWidth, behavior: "smooth" });
|
|
1498
|
+
}
|
|
1499
|
+
/** Retarget an upsell card's add button when the shopper picks a different size — the select
|
|
1500
|
+
* carries no other intent (no re-render, no network). */
|
|
1501
|
+
#onUpsellVariantSelect(select) {
|
|
1502
|
+
if (!(select instanceof HTMLSelectElement)) return;
|
|
1503
|
+
const addBtn = select.closest(".ksc-up__card")?.querySelector("[data-smart-cart-upsell-add]");
|
|
1504
|
+
if (addBtn && select.value) addBtn.setAttribute("data-variant-id", select.value);
|
|
1505
|
+
}
|
|
1382
1506
|
async #onUpsellAdd(btn) {
|
|
1383
1507
|
if (!this.#adapter || this.#upsellPending) return;
|
|
1384
1508
|
const variantId = btn.getAttribute("data-variant-id");
|
|
@@ -1554,7 +1678,8 @@ ${css8}`);
|
|
|
1554
1678
|
config: cfg,
|
|
1555
1679
|
state,
|
|
1556
1680
|
formatMoney: formatMoney2,
|
|
1557
|
-
...this.#upsellVariants !== null && { variants: this.#upsellVariants }
|
|
1681
|
+
...this.#upsellVariants !== null && { variants: this.#upsellVariants },
|
|
1682
|
+
...this.#productVariants.size > 0 && { productVariants: this.#productVariants }
|
|
1558
1683
|
});
|
|
1559
1684
|
} catch (err) {
|
|
1560
1685
|
console.error(`[kotao-smart-cart] widget render failed`, widget.key, err);
|
|
@@ -1612,33 +1737,34 @@ ${css8}`);
|
|
|
1612
1737
|
const hasSwitcher = variants !== void 0 && variants.length > 1;
|
|
1613
1738
|
const optName = l.options?.[0]?.name ?? "";
|
|
1614
1739
|
const propLines = (l.properties ?? []).map(
|
|
1615
|
-
(p) => `<span class="ksc-line__opt"
|
|
1740
|
+
(p) => `<span class="ksc-line__opt">${escapeHtml(p.name)}: <b>${escapeHtml(p.value)}</b></span>`
|
|
1616
1741
|
);
|
|
1617
1742
|
const optLines = hasSwitcher ? [] : opts.map(
|
|
1618
|
-
(o) => o.name ? `<span class="ksc-line__opt"
|
|
1743
|
+
(o) => o.name ? `<span class="ksc-line__opt">${escapeHtml(o.name)}: <b>${escapeHtml(o.value)}</b></span>` : `<span class="ksc-line__opt">${escapeHtml(o.value)}</span>`
|
|
1619
1744
|
);
|
|
1620
|
-
const switcher = hasSwitcher ? `<div class="ksc-line__variant">${optName ? `<span
|
|
1745
|
+
const switcher = hasSwitcher ? `<div class="ksc-line__variant">${optName ? `<span>${escapeHtml(optName)}:</span>` : ""}<select class="ksc-line__select" data-smart-cart-variant data-line-id="${id}" data-qty="${l.quantity}" aria-label="${escapeHtml(optName || "Variant")}">${variants.map(
|
|
1621
1746
|
(v) => `<option value="${escapeHtml(v.id)}"${v.title === l.variantTitle ? " selected" : ""}>${escapeHtml(v.title ?? "")}</option>`
|
|
1622
1747
|
).join("")}</select></div>` : "";
|
|
1623
1748
|
const metaParts = [...propLines, ...optLines, ...switcher ? [switcher] : []];
|
|
1624
1749
|
const meta = metaParts.length ? `<div class="ksc-line__meta">${metaParts.join("")}</div>` : "";
|
|
1625
|
-
const
|
|
1626
|
-
const
|
|
1627
|
-
|
|
1628
|
-
|
|
1750
|
+
const hasLineDiscount = (l.discountAllocations?.length ?? 0) > 0;
|
|
1751
|
+
const struck = l.compareAtLinePrice && l.compareAtLinePrice.amount > l.linePrice.amount ? l.compareAtLinePrice : hasLineDiscount && l.originalLinePrice && l.originalLinePrice.amount > l.linePrice.amount ? l.originalLinePrice : void 0;
|
|
1752
|
+
const compare = struck ? `<span class="ksc-line__compare">${escapeHtml(formatMoney2(struck))}</span>` : "";
|
|
1753
|
+
const save = struck && struck.amount - l.linePrice.amount > 0 ? `<span class="ksc-line__save">${TAG_SVG}You save ${escapeHtml(
|
|
1754
|
+
formatMoneyCompact({
|
|
1755
|
+
amount: struck.amount - l.linePrice.amount,
|
|
1629
1756
|
currency: l.linePrice.currency
|
|
1630
1757
|
})
|
|
1631
1758
|
)}</span>` : "";
|
|
1632
|
-
const
|
|
1633
|
-
const displayPrice = hasLineDiscount ? l.originalLinePrice ?? l.linePrice : l.linePrice;
|
|
1759
|
+
const displayPrice = l.linePrice;
|
|
1634
1760
|
const discountRows = hasLineDiscount ? l.discountAllocations.map((a) => {
|
|
1635
1761
|
const code = escapeHtml(a.code);
|
|
1636
1762
|
if (typeof a.quantity === "number" && a.quantity > 0) {
|
|
1637
1763
|
const unit = Math.round((l.originalLinePrice ?? l.linePrice).amount / l.quantity);
|
|
1638
|
-
const
|
|
1764
|
+
const struck2 = escapeHtml(
|
|
1639
1765
|
formatMoney2({ amount: unit * a.quantity, currency: l.linePrice.currency })
|
|
1640
1766
|
);
|
|
1641
|
-
return `<div class="ksc-line__discount"><span>\u{1F381} ${a.quantity}\xD7 ${code} \u2014 <s>${
|
|
1767
|
+
return `<div class="ksc-line__discount"><span>\u{1F381} ${a.quantity}\xD7 ${code} \u2014 <s>${struck2}</s> FREE \xB7 You save 100%</span></div>`;
|
|
1642
1768
|
}
|
|
1643
1769
|
return `<div class="ksc-line__discount"><span>\u{1F3F7} ${code} \u2212${escapeHtml(formatMoney2(a.amount))}</span></div>`;
|
|
1644
1770
|
}).join("") : "";
|
|
@@ -1646,24 +1772,24 @@ ${css8}`);
|
|
|
1646
1772
|
${image}
|
|
1647
1773
|
<div class="ksc-line__body">
|
|
1648
1774
|
<div class="ksc-line__top">
|
|
1649
|
-
<
|
|
1650
|
-
|
|
1775
|
+
<div class="ksc-line__main">
|
|
1776
|
+
<span class="ksc-line__title">${escapeHtml(l.title)}</span>
|
|
1777
|
+
${meta}
|
|
1778
|
+
${discountRows}
|
|
1779
|
+
</div>
|
|
1780
|
+
<div class="ksc-line__prices">
|
|
1781
|
+
${compare}
|
|
1782
|
+
<span class="ksc-line__price">${escapeHtml(formatMoney2(displayPrice))}</span>
|
|
1783
|
+
${save}
|
|
1784
|
+
</div>
|
|
1651
1785
|
</div>
|
|
1652
|
-
${meta}
|
|
1653
|
-
${discountRows}
|
|
1654
1786
|
<div class="ksc-line__bottom">
|
|
1655
1787
|
<div class="ksc-qty">
|
|
1656
1788
|
<button type="button" data-smart-cart-qty-dec data-qty="${l.quantity}" aria-label="Decrease quantity">\u2212</button>
|
|
1657
1789
|
<span class="ksc-qty__n">${l.quantity}</span>
|
|
1658
1790
|
<button type="button" data-smart-cart-qty-inc data-qty="${l.quantity}" aria-label="Increase quantity">+</button>
|
|
1659
1791
|
</div>
|
|
1660
|
-
<
|
|
1661
|
-
<div class="ksc-line__prices">
|
|
1662
|
-
<span class="ksc-line__price">${escapeHtml(formatMoney2(displayPrice))}</span>
|
|
1663
|
-
${save}
|
|
1664
|
-
</div>
|
|
1665
|
-
<button type="button" class="ksc-line__remove" data-smart-cart-line-remove aria-label="Remove item">${TRASH_SVG}</button>
|
|
1666
|
-
</div>
|
|
1792
|
+
<button type="button" class="ksc-line__remove" data-smart-cart-line-remove aria-label="Remove item">${TRASH_SVG}</button>
|
|
1667
1793
|
</div>
|
|
1668
1794
|
</div>
|
|
1669
1795
|
</div>`;
|
|
@@ -1683,7 +1809,7 @@ ${css8}`);
|
|
|
1683
1809
|
}
|
|
1684
1810
|
try {
|
|
1685
1811
|
if (displayLines.length === 0) {
|
|
1686
|
-
items.innerHTML = `<div class="ksc-empty">${BAG_SVG}<p data-empty>Your cart is empty
|
|
1812
|
+
items.innerHTML = `<div class="ksc-empty">${BAG_SVG}<p data-empty>Your cart is empty</p></div>`;
|
|
1687
1813
|
checkoutWrap.innerHTML = "";
|
|
1688
1814
|
if (continueWrap)
|
|
1689
1815
|
continueWrap.innerHTML = `<button type="button" class="ksc-continue" data-smart-cart-close>Continue shopping</button>`;
|
|
@@ -1693,30 +1819,21 @@ ${css8}`);
|
|
|
1693
1819
|
return;
|
|
1694
1820
|
}
|
|
1695
1821
|
items.innerHTML = displayLines.map((l) => this.#renderLine(l)).join("");
|
|
1696
|
-
const
|
|
1697
|
-
|
|
1698
|
-
const displayTotal = {
|
|
1699
|
-
amount: Math.max(0, state.subtotal.amount - cartDiscount),
|
|
1822
|
+
const finalSubtotal = {
|
|
1823
|
+
amount: state.lines.reduce((sum, l) => sum + l.linePrice.amount, 0),
|
|
1700
1824
|
currency: state.subtotal.currency
|
|
1701
1825
|
};
|
|
1702
|
-
const
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
rows.push(
|
|
1711
|
-
`<div class="ksc-summary__row ksc-summary__row--discount" data-savings><span>Discounts</span><span>\u2212${escapeHtml(formatMoney2(state.discountTotal))}</span></div>`
|
|
1712
|
-
);
|
|
1713
|
-
}
|
|
1714
|
-
rows.push(
|
|
1715
|
-
`<div class="ksc-summary__row ksc-summary__row--total"><span>Subtotal</span><span>${escapeHtml(formatMoney2(state.subtotal))}</span></div>`
|
|
1716
|
-
);
|
|
1826
|
+
const discountsTotal = state.discountTotal?.amount ?? state.discountAllocations?.reduce((sum, a) => sum + a.amount.amount, 0) ?? 0;
|
|
1827
|
+
const displayTotal = finalSubtotal;
|
|
1828
|
+
const rows = [
|
|
1829
|
+
...discountsTotal > 0 ? [
|
|
1830
|
+
`<div class="ksc-summary__row ksc-summary__row--discount"><span>Discounts</span><span>-${escapeHtml(formatMoney2({ amount: discountsTotal, currency: state.subtotal.currency }))}</span></div>`
|
|
1831
|
+
] : [],
|
|
1832
|
+
`<div class="ksc-summary__row ksc-summary__row--total"><span>Subtotal</span><span>${escapeHtml(formatMoney2(finalSubtotal))}</span></div>`
|
|
1833
|
+
];
|
|
1717
1834
|
const totalLabel = escapeHtml(formatMoney2(displayTotal));
|
|
1718
1835
|
checkoutWrap.innerHTML = `<div class="ksc-summary">${rows.join("")}</div>
|
|
1719
|
-
<a class="checkout" data-checkout href="${escapeHtml(state.checkoutUrl)}">Checkout${totalLabel ? ` \
|
|
1836
|
+
<a class="checkout" data-checkout href="${escapeHtml(state.checkoutUrl)}">Checkout${totalLabel ? ` \u2022 ${totalLabel}` : ""}</a>`;
|
|
1720
1837
|
if (continueWrap)
|
|
1721
1838
|
continueWrap.innerHTML = `<button type="button" class="ksc-continue" data-smart-cart-close>or continue shopping</button>`;
|
|
1722
1839
|
} catch (err) {
|