@kotao/storefront 0.2.0 → 0.2.1

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/react.js CHANGED
@@ -499,7 +499,11 @@ var css = `
499
499
  var SHIELD_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="M12 3l7 3v5c0 4.6-3 7.8-7 9-4-1.2-7-4.4-7-9V6l7-3z"/><path d="M9 12l2 2 4-4"/></svg>`;
500
500
  var addOn = {
501
501
  key: ADDON_KEY,
502
- zone: "after-items",
502
+ // Footer, not 'after-items': the add-on is a checkout-adjacent offer that must stay pinned above
503
+ // the discount code, NOT scroll away with the upsell carousel. It renders before `discountCode`
504
+ // (WIDGETS registry order) so it sits directly above the code input (#1548 moved the whole
505
+ // 'after-items' zone into the scroll region — only the upsell belongs there).
506
+ zone: "footer",
503
507
  css,
504
508
  render({ config, state, variants }) {
505
509
  const variantId = readVariantId(config);
@@ -997,6 +1001,8 @@ var STYLES2 = `
997
1001
  overflow: hidden; text-overflow: ellipsis; }
998
1002
  .ksc-line__opt b { font-weight: 500; color: color-mix(in oklab, var(--ksc-text) 78%, transparent); }
999
1003
  .ksc-line__variant { display: flex; align-items: center; gap: 6px; font-size: .78rem; color: var(--ksc-muted); }
1004
+ .ksc-line__discount { font-size: .78rem; font-weight: 500; color: var(--ksc-positive); line-height: 1.35; }
1005
+ .ksc-line__discount s { color: var(--ksc-muted); text-decoration: line-through; }
1000
1006
  .ksc-line__select { font: inherit; font-size: .78rem; color: var(--ksc-text); padding: 3px 22px 3px 8px;
1001
1007
  border: 1px solid var(--ksc-border); border-radius: 8px; background: var(--ksc-surface); cursor: pointer;
1002
1008
  appearance: none; -webkit-appearance: none;
@@ -1623,6 +1629,19 @@ ${css8}`);
1623
1629
  currency: l.linePrice.currency
1624
1630
  })
1625
1631
  )}</span>` : "";
1632
+ const hasLineDiscount = (l.discountAllocations?.length ?? 0) > 0;
1633
+ const displayPrice = hasLineDiscount ? l.originalLinePrice ?? l.linePrice : l.linePrice;
1634
+ const discountRows = hasLineDiscount ? l.discountAllocations.map((a) => {
1635
+ const code = escapeHtml(a.code);
1636
+ if (typeof a.quantity === "number" && a.quantity > 0) {
1637
+ const unit = Math.round((l.originalLinePrice ?? l.linePrice).amount / l.quantity);
1638
+ const struck = escapeHtml(
1639
+ formatMoney2({ amount: unit * a.quantity, currency: l.linePrice.currency })
1640
+ );
1641
+ return `<div class="ksc-line__discount"><span>\u{1F381} ${a.quantity}\xD7 ${code} \u2014 <s>${struck}</s> FREE \xB7 You save 100%</span></div>`;
1642
+ }
1643
+ return `<div class="ksc-line__discount"><span>\u{1F3F7} ${code} \u2212${escapeHtml(formatMoney2(a.amount))}</span></div>`;
1644
+ }).join("") : "";
1626
1645
  return `<div class="ksc-line" data-line-id="${id}">
1627
1646
  ${image}
1628
1647
  <div class="ksc-line__body">
@@ -1631,6 +1650,7 @@ ${css8}`);
1631
1650
  ${compare}
1632
1651
  </div>
1633
1652
  ${meta}
1653
+ ${discountRows}
1634
1654
  <div class="ksc-line__bottom">
1635
1655
  <div class="ksc-qty">
1636
1656
  <button type="button" data-smart-cart-qty-dec data-qty="${l.quantity}" aria-label="Decrease quantity">\u2212</button>
@@ -1639,7 +1659,7 @@ ${css8}`);
1639
1659
  </div>
1640
1660
  <div class="ksc-line__end">
1641
1661
  <div class="ksc-line__prices">
1642
- <span class="ksc-line__price">${escapeHtml(formatMoney2(l.linePrice))}</span>
1662
+ <span class="ksc-line__price">${escapeHtml(formatMoney2(displayPrice))}</span>
1643
1663
  ${save}
1644
1664
  </div>
1645
1665
  <button type="button" class="ksc-line__remove" data-smart-cart-line-remove aria-label="Remove item">${TRASH_SVG}</button>
@@ -1673,20 +1693,22 @@ ${css8}`);
1673
1693
  return;
1674
1694
  }
1675
1695
  items.innerHTML = displayLines.map((l) => this.#renderLine(l)).join("");
1676
- const compareAtSavings = state.lines.reduce(
1677
- (sum, l) => sum + (l.compareAtLinePrice && l.compareAtLinePrice.amount > l.linePrice.amount ? l.compareAtLinePrice.amount - l.linePrice.amount : 0),
1678
- 0
1679
- );
1680
- const cartDiscount = state.discountTotal?.amount ?? 0;
1681
- const savings = compareAtSavings + cartDiscount;
1696
+ const namedAllocations = state.discountAllocations ?? [];
1697
+ const cartDiscount = namedAllocations.length > 0 ? namedAllocations.reduce((sum, a) => sum + a.amount.amount, 0) : state.discountTotal?.amount ?? 0;
1682
1698
  const displayTotal = {
1683
1699
  amount: Math.max(0, state.subtotal.amount - cartDiscount),
1684
1700
  currency: state.subtotal.currency
1685
1701
  };
1686
1702
  const rows = [];
1687
- if (savings > 0) {
1703
+ if (namedAllocations.length > 0) {
1704
+ for (const a of namedAllocations) {
1705
+ rows.push(
1706
+ `<div class="ksc-summary__row ksc-summary__row--discount" data-savings><span>${escapeHtml(a.code)}</span><span>\u2212${escapeHtml(formatMoney2(a.amount))}</span></div>`
1707
+ );
1708
+ }
1709
+ } else if ((state.discountTotal?.amount ?? 0) > 0) {
1688
1710
  rows.push(
1689
- `<div class="ksc-summary__row ksc-summary__row--discount" data-savings><span>Discounts</span><span>\u2212${escapeHtml(formatMoney2({ amount: savings, currency: state.subtotal.currency }))}</span></div>`
1711
+ `<div class="ksc-summary__row ksc-summary__row--discount" data-savings><span>Discounts</span><span>\u2212${escapeHtml(formatMoney2(state.discountTotal))}</span></div>`
1690
1712
  );
1691
1713
  }
1692
1714
  rows.push(