@develemit/storefront 0.3.0 → 0.6.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.js CHANGED
@@ -399,7 +399,7 @@ function F(e = "sf-cart") {
399
399
  }
400
400
  // src/cart/cart-provider.tsx
401
401
  var I = n(null), L = F();
402
- function R({ storage: e = L, children: t }) {
402
+ function ee({ storage: e = L, children: t }) {
403
403
  let [n, i] = s(M, A), [u, f] = l(!1), [p, m] = l(!1), h = c(n);
404
404
  a(() => {
405
405
  h.current = n;
@@ -457,20 +457,81 @@ function R({ storage: e = L, children: t }) {
457
457
  children: t
458
458
  });
459
459
  }
460
- function z() {
460
+ function R() {
461
461
  let e = i(I);
462
462
  if (!e) throw Error("useCart must be used inside <CartProvider>");
463
463
  return e;
464
464
  }
465
+ // src/components/cart-summary/discount-types.ts
466
+ var z = {
467
+ toggle: "Have a code?",
468
+ field: "Discount code",
469
+ apply: "Apply",
470
+ remove: "Remove",
471
+ line: "Discount",
472
+ unavailable: "We could not check that code. Please try again.",
473
+ reasons: {
474
+ not_found: "That code is not valid.",
475
+ inactive: "That code is not valid.",
476
+ not_started: "That code is not active yet.",
477
+ expired: "That code has expired.",
478
+ min_subtotal: "Your cart is below the minimum for that code.",
479
+ exhausted: "That code is no longer available.",
480
+ currency: "That code does not apply to this cart."
481
+ }
482
+ };
483
+ function B(e, t) {
484
+ return t?.[e] ?? z.reasons[e];
485
+ }
486
+ // src/cart/use-checkout.ts
487
+ var V = {
488
+ outOfStock: "Some items just sold or are on hold, so we removed them from your cart.",
489
+ unavailable: "Checkout is unavailable right now. Please try again."
490
+ }, te = (e) => window.location.assign(e);
491
+ function ne({ startCheckout: e, onRedirect: t = te, onDiscountInvalid: n, labels: i }) {
492
+ let a = R(), [o, s] = l(!1), [c, u] = l(null), { lines: d, remove: f } = a, p = {
493
+ ...V,
494
+ ...i
495
+ };
496
+ return {
497
+ checkout: r(async (r = {}) => {
498
+ s(!0), u(null);
499
+ try {
500
+ let i = await e(d.map((e) => ({
501
+ productId: e.productId,
502
+ quantity: e.quantity
503
+ })), r);
504
+ if ("url" in i) {
505
+ t(i.url);
506
+ return;
507
+ }
508
+ i.error === "discount_invalid" ? (u(B(i.reason, p.discountReasons)), n?.(i.reason)) : (i.productIds.forEach(f), u(p.outOfStock));
509
+ } catch {
510
+ u(p.unavailable);
511
+ }
512
+ s(!1);
513
+ }, [
514
+ e,
515
+ t,
516
+ n,
517
+ d,
518
+ f,
519
+ i
520
+ ]),
521
+ busy: o,
522
+ message: c,
523
+ clearMessage: r(() => u(null), [])
524
+ };
525
+ }
465
526
  // src/components/add-to-cart-button/add-to-cart-button.tsx
466
- var B = {
527
+ var H = {
467
528
  add: "Add to cart",
468
529
  inCart: "In your cart",
469
530
  unavailable: "Unavailable"
470
531
  };
471
- function V({ product: e, labels: t, openOnAdd: n = !0, className: r }) {
472
- let i = z(), a = {
473
- ...B,
532
+ function U({ product: e, labels: t, openOnAdd: n = !0, className: r }) {
533
+ let i = R(), a = {
534
+ ...H,
474
535
  ...t
475
536
  }, o = i.lines.find((t) => t.productId === e.id)?.quantity ?? 0, s = e.availability !== "available", c = o >= e.quantity, l = !i.hydrated || s || c, u = s ? a.unavailable : c ? a.inCart : a.add;
476
537
  function f() {
@@ -494,13 +555,13 @@ function V({ product: e, labels: t, openOnAdd: n = !0, className: r }) {
494
555
  });
495
556
  }
496
557
  // src/components/cart-line-item/cart-line-item.tsx
497
- var H = {
558
+ var W = {
498
559
  remove: "Remove",
499
560
  quantity: "Quantity"
500
561
  };
501
- function U({ line: t, labels: n }) {
502
- let { remove: r, setQuantity: i } = z(), { locale: a, renderLink: o, renderImage: s, hrefs: c } = y(), l = {
503
- ...H,
562
+ function G({ line: t, labels: n }) {
563
+ let { remove: r, setQuantity: i } = R(), { locale: a, renderLink: o, renderImage: s, hrefs: c } = y(), l = {
564
+ ...W,
504
565
  ...n
505
566
  }, u = t.maxQuantity > 1;
506
567
  return /* @__PURE__ */ f("li", {
@@ -544,17 +605,17 @@ function U({ line: t, labels: n }) {
544
605
  });
545
606
  }
546
607
  // src/lib/parse-duration.ts
547
- function W(e) {
608
+ function K(e) {
548
609
  let t = /^\s*(-?\d*\.?\d+)\s*(ms|s)\s*$/.exec(e);
549
610
  if (!t) return 0;
550
611
  let n = Number(t[1]);
551
612
  return Math.max(0, t[2] === "s" ? n * 1e3 : n);
552
613
  }
553
614
  // src/components/cart-drawer/use-drawer-presence.ts
554
- function G(e, t) {
615
+ function q(e, t) {
555
616
  let [n, r] = l(0), [i, o] = l(e), [s, c] = l(!1);
556
617
  return i !== e && (o(e), c(!e && n > 0)), a(() => {
557
- e && t.current && r(W(getComputedStyle(t.current).getPropertyValue("--sf-motion-duration")));
618
+ e && t.current && r(K(getComputedStyle(t.current).getPropertyValue("--sf-motion-duration")));
558
619
  }, [e, t]), a(() => {
559
620
  if (!s) return;
560
621
  let e = setTimeout(() => c(!1), n);
@@ -564,41 +625,179 @@ function G(e, t) {
564
625
  state: e ? "open" : "closed"
565
626
  };
566
627
  }
567
- // src/components/cart-summary/cart-summary.tsx
568
- function K({ onCheckout: t, checkoutLabel: n = "Checkout", checkoutDisabled: r = !1, labels: i }) {
569
- let a = z(), { locale: o } = y(), s = i?.subtotal ?? "Subtotal";
628
+ // src/components/cart-summary/discount-field.tsx
629
+ function J({ labels: t, applied: n, error: r, pending: i, currency: a, locale: o, onApply: s, onRemove: c }) {
630
+ let [u, p] = l(!1), [m, h] = l("");
631
+ function g(e) {
632
+ e.preventDefault();
633
+ let t = m.trim();
634
+ t && s(t);
635
+ }
636
+ if (n) return /* @__PURE__ */ f("p", {
637
+ className: "sf-cart-summary__row sf-cart-summary__discount",
638
+ children: [/* @__PURE__ */ f("span", { children: [
639
+ t.line,
640
+ " (",
641
+ n.code,
642
+ ")",
643
+ " ",
644
+ /* @__PURE__ */ d("button", {
645
+ type: "button",
646
+ className: "sf-link-button",
647
+ onClick: c,
648
+ children: t.remove
649
+ })
650
+ ] }), /* @__PURE__ */ f("span", {
651
+ className: "sf-price",
652
+ children: ["−", e(n.discountCents, a, o)]
653
+ })]
654
+ });
655
+ let _ = r === "unavailable" ? t.unavailable : r ? t.reasons[r] : null;
570
656
  return /* @__PURE__ */ f("div", {
571
- className: "sf-cart-summary",
572
- children: [/* @__PURE__ */ f("p", {
573
- className: "sf-cart-summary__row",
574
- children: [/* @__PURE__ */ d("span", { children: s }), /* @__PURE__ */ d("span", {
575
- className: "sf-price",
576
- children: e(a.subtotalCents, a.currency ?? "USD", o)
657
+ className: "sf-cart-summary__code",
658
+ children: [u ? /* @__PURE__ */ f("form", {
659
+ onSubmit: g,
660
+ className: "sf-cart-summary__code-form",
661
+ children: [/* @__PURE__ */ d("input", {
662
+ "aria-label": t.field,
663
+ value: m,
664
+ onChange: (e) => h(e.target.value),
665
+ autoCapitalize: "characters",
666
+ autoComplete: "off"
667
+ }), /* @__PURE__ */ d("button", {
668
+ type: "submit",
669
+ className: "sf-button",
670
+ disabled: i,
671
+ children: t.apply
577
672
  })]
578
- }), /* @__PURE__ */ d("button", {
673
+ }) : /* @__PURE__ */ d("button", {
579
674
  type: "button",
580
- className: "sf-button",
581
- disabled: r || !t || a.lines.length === 0,
582
- onClick: t,
583
- children: n
675
+ className: "sf-link-button",
676
+ "aria-expanded": !1,
677
+ onClick: () => p(!0),
678
+ children: t.toggle
679
+ }), _ && /* @__PURE__ */ d("p", {
680
+ role: "alert",
681
+ className: "sf-cart-summary__code-error",
682
+ children: _
584
683
  })]
585
684
  });
586
685
  }
686
+ // src/components/cart-summary/use-discount.ts
687
+ function Y(e) {
688
+ let { lines: t } = R(), n = t.map((e) => ({
689
+ productId: e.productId,
690
+ quantity: e.quantity
691
+ })), i = n.map((e) => `${e.productId}:${e.quantity}`).join(","), [o, s] = l(null), [u, d] = l(null), [f, p] = l(!1), m = c({
692
+ discount: e,
693
+ items: n
694
+ });
695
+ a(() => {
696
+ m.current = {
697
+ discount: e,
698
+ items: n
699
+ };
700
+ });
701
+ let h = c(0), g = c(i), _ = r(() => {
702
+ h.current += 1, s(null), m.current.discount?.onApply?.(null);
703
+ }, []), v = r(async (e, t) => {
704
+ let n = m.current;
705
+ if (!n.discount) return;
706
+ let r = ++h.current;
707
+ g.current = n.items.map((e) => `${e.productId}:${e.quantity}`).join(","), p(!0);
708
+ let i;
709
+ try {
710
+ i = await n.discount.onPreview(e, n.items);
711
+ } catch {
712
+ i = {
713
+ ok: !1,
714
+ reason: "unavailable"
715
+ };
716
+ }
717
+ r === h.current && (p(!1), i.ok ? (d(null), s({
718
+ code: i.code,
719
+ discountCents: i.discountCents
720
+ }), n.discount.onApply?.(i.code)) : t(i.reason));
721
+ }, []), y = r((e) => v(e, (e) => d(e)), [v]), b = r(() => {
722
+ d(null), p(!1), _();
723
+ }, [_]), x = o?.code, S = e?.debounceMs ?? 300;
724
+ return a(() => {
725
+ if (!x || i === g.current) return;
726
+ let e = setTimeout(() => {
727
+ m.current.items.length === 0 ? _() : v(x, (e) => {
728
+ d(e), _();
729
+ });
730
+ }, S);
731
+ return () => clearTimeout(e);
732
+ }, [
733
+ x,
734
+ i,
735
+ S,
736
+ v,
737
+ _
738
+ ]), {
739
+ applied: o,
740
+ error: u,
741
+ pending: f,
742
+ apply: y,
743
+ remove: b
744
+ };
745
+ }
746
+ // src/components/cart-summary/cart-summary.tsx
747
+ function X({ onCheckout: t, checkoutLabel: n = "Checkout", checkoutDisabled: r = !1, labels: i, discount: a }) {
748
+ let o = R(), { locale: s } = y(), c = i?.subtotal ?? "Subtotal", l = Y(a), u = {
749
+ ...z,
750
+ ...i?.discount,
751
+ reasons: {
752
+ ...z.reasons,
753
+ ...i?.discount?.reasons
754
+ }
755
+ };
756
+ return /* @__PURE__ */ f("div", {
757
+ className: "sf-cart-summary",
758
+ children: [
759
+ /* @__PURE__ */ f("p", {
760
+ className: "sf-cart-summary__row",
761
+ children: [/* @__PURE__ */ d("span", { children: c }), /* @__PURE__ */ d("span", {
762
+ className: "sf-price",
763
+ children: e(o.subtotalCents, o.currency ?? "USD", s)
764
+ })]
765
+ }),
766
+ a && o.lines.length > 0 && /* @__PURE__ */ d(J, {
767
+ labels: u,
768
+ currency: o.currency ?? "USD",
769
+ locale: s,
770
+ onApply: (e) => void l.apply(e),
771
+ onRemove: l.remove,
772
+ applied: l.applied,
773
+ error: l.error,
774
+ pending: l.pending
775
+ }),
776
+ /* @__PURE__ */ d("button", {
777
+ type: "button",
778
+ className: "sf-button",
779
+ disabled: r || !t || o.lines.length === 0,
780
+ onClick: t,
781
+ children: n
782
+ })
783
+ ]
784
+ });
785
+ }
587
786
  // src/components/cart-drawer/cart-drawer.tsx
588
- var q = {
787
+ var Z = {
589
788
  title: "Your cart",
590
789
  close: "Close",
591
790
  empty: "Your cart is empty."
592
- }, J = "a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
593
- function Y({ labels: e, summary: t, slots: n }) {
594
- let r = z(), i = {
595
- ...q,
791
+ }, Q = "a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
792
+ function re({ labels: e, summary: t, slots: n }) {
793
+ let r = R(), i = {
794
+ ...Z,
596
795
  ...e
597
- }, o = c(null), s = c(null), { isOpen: l } = r, p = G(l, s);
796
+ }, o = c(null), s = c(null), { isOpen: l } = r, p = q(l, s);
598
797
  if (a(() => {
599
798
  if (!l) return;
600
799
  let e = document.activeElement;
601
- return o.current?.querySelector(J)?.focus(), () => e?.focus();
800
+ return o.current?.querySelector(Q)?.focus(), () => e?.focus();
602
801
  }, [l]), !p.mounted) return null;
603
802
  function m(e) {
604
803
  if (e.key === "Escape") {
@@ -606,7 +805,7 @@ function Y({ labels: e, summary: t, slots: n }) {
606
805
  return;
607
806
  }
608
807
  if (e.key !== "Tab") return;
609
- let t = Array.from(o.current?.querySelectorAll(J) ?? []);
808
+ let t = Array.from(o.current?.querySelectorAll(Q) ?? []);
610
809
  if (t.length === 0) return;
611
810
  let n = t[0], i = t[t.length - 1];
612
811
  e.shiftKey && document.activeElement === n ? (e.preventDefault(), i.focus()) : !e.shiftKey && document.activeElement === i && (e.preventDefault(), n.focus());
@@ -647,9 +846,9 @@ function Y({ labels: e, summary: t, slots: n }) {
647
846
  }) : /* @__PURE__ */ f(u, { children: [
648
847
  /* @__PURE__ */ d("ul", {
649
848
  className: "sf-drawer__lines",
650
- children: r.lines.map((e) => /* @__PURE__ */ d(U, { line: e }, e.productId))
849
+ children: r.lines.map((e) => /* @__PURE__ */ d(G, { line: e }, e.productId))
651
850
  }),
652
- /* @__PURE__ */ d(K, { ...t }),
851
+ /* @__PURE__ */ d(X, { ...t }),
653
852
  n?.summaryNote && /* @__PURE__ */ d("div", {
654
853
  className: "sf-drawer__note",
655
854
  children: n.summaryNote
@@ -659,8 +858,8 @@ function Y({ labels: e, summary: t, slots: n }) {
659
858
  });
660
859
  }
661
860
  // src/components/cart-button/cart-button.tsx
662
- function X({ label: e = "Cart", className: t, icon: n, labelHidden: r = !1, hideZeroCount: i = !1 }) {
663
- let a = z(), o = a.hydrated ? a.itemCount : 0, s = !(i && o === 0), c = s ? r ? `${e}, ${a.itemCount} items` : void 0 : `${e}, empty`;
861
+ function ie({ label: e = "Cart", className: t, icon: n, labelHidden: r = !1, hideZeroCount: i = !1 }) {
862
+ let a = R(), o = a.hydrated ? a.itemCount : 0, s = !(i && o === 0), c = s ? r ? `${e}, ${a.itemCount} items` : void 0 : `${e}, empty`;
664
863
  return /* @__PURE__ */ f("button", {
665
864
  type: "button",
666
865
  className: ["sf-cart-button", t].filter(Boolean).join(" "),
@@ -681,6 +880,124 @@ function X({ label: e = "Cart", className: t, icon: n, labelHidden: r = !1, hide
681
880
  ]
682
881
  });
683
882
  }
684
- export { V as AddToCartButton, S as AvailabilityBadge, X as CartButton, Y as CartDrawer, U as CartLineItem, R as CartProvider, K as CartSummary, T as CategoryFilter, k as FeaturedProducts, b as PriceTag, C as ProductCard, O as ProductDetailView, E as ProductGallery, w as ProductGrid, D as ShopView, v as StorefrontProvider, j as addLine, M as cartReducer, B as defaultAddToCartLabels, x as defaultAvailabilityLabels, q as defaultCartDrawerLabels, H as defaultCartLineItemLabels, A as emptyCart, e as formatPrice, P as itemCount, F as localStorageCartStorage, t as sortForDisplay, N as subtotalCents, h as themeToCssVars, z as useCart, y as useStorefront };
883
+ // src/components/checkout-success/labels.ts
884
+ var $ = {
885
+ heading: "Order received",
886
+ subtotal: "Subtotal",
887
+ discount: "Discount",
888
+ shipping: "Shipping",
889
+ total: "Total",
890
+ shipTo: "Ship to",
891
+ tracking: "Track",
892
+ status: {
893
+ pending: "We're confirming your payment and will email you once it's done.",
894
+ paid: "Payment received. Thank you!",
895
+ shipped: "Your order is on its way.",
896
+ cancelled: "This checkout was cancelled.",
897
+ expired: "This checkout expired before payment.",
898
+ refunded: "This order has been refunded.",
899
+ needs_attention: "We couldn't confirm one of your items. We'll be in touch about a refund."
900
+ }
901
+ };
902
+ // src/components/checkout-success/checkout-success-view.tsx
903
+ function ae(e) {
904
+ let t = [
905
+ e.city,
906
+ e.state,
907
+ e.postalCode
908
+ ].filter(Boolean).join(" ");
909
+ return [
910
+ e.name,
911
+ e.line1,
912
+ e.line2,
913
+ t,
914
+ e.country
915
+ ].filter((e) => !!e);
916
+ }
917
+ function oe({ order: t, locale: n, labels: r, className: i }) {
918
+ let a = {
919
+ ...$,
920
+ ...r,
921
+ status: {
922
+ ...$.status,
923
+ ...r?.status
924
+ }
925
+ }, o = (r) => e(r, t.currency, n), s = t.shippingAddress ? ae(t.shippingAddress) : [], { fulfillment: c } = t;
926
+ return /* @__PURE__ */ f("section", {
927
+ className: ["sf-checkout-success", i].filter(Boolean).join(" "),
928
+ "data-status": t.status,
929
+ children: [
930
+ /* @__PURE__ */ d("h1", {
931
+ className: "sf-checkout-success__heading",
932
+ children: a.heading
933
+ }),
934
+ /* @__PURE__ */ d("p", {
935
+ className: "sf-checkout-success__status",
936
+ children: a.status[t.status]
937
+ }),
938
+ /* @__PURE__ */ d("ul", {
939
+ className: "sf-checkout-success__lines",
940
+ children: t.items.map((e) => /* @__PURE__ */ f("li", {
941
+ className: "sf-checkout-success__line",
942
+ children: [/* @__PURE__ */ f("span", { children: [
943
+ e.name,
944
+ " × ",
945
+ e.quantity
946
+ ] }), /* @__PURE__ */ d("span", { children: o(e.priceCents * e.quantity) })]
947
+ }, e.productId))
948
+ }),
949
+ /* @__PURE__ */ f("dl", {
950
+ className: "sf-checkout-success__totals",
951
+ children: [
952
+ /* @__PURE__ */ f("div", {
953
+ className: "sf-checkout-success__row",
954
+ children: [/* @__PURE__ */ d("dt", { children: a.subtotal }), /* @__PURE__ */ d("dd", { children: o(t.subtotalCents) })]
955
+ }),
956
+ t.discountCents > 0 && /* @__PURE__ */ f("div", {
957
+ className: "sf-checkout-success__row sf-checkout-success__row--discount",
958
+ "data-discount": !0,
959
+ children: [/* @__PURE__ */ f("dt", { children: [a.discount, t.discountCode && ` (${t.discountCode})`] }), /* @__PURE__ */ f("dd", { children: ["−", o(t.discountCents)] })]
960
+ }),
961
+ t.shippingLabel && /* @__PURE__ */ f("div", {
962
+ className: "sf-checkout-success__row",
963
+ children: [/* @__PURE__ */ f("dt", { children: [
964
+ a.shipping,
965
+ " (",
966
+ t.shippingLabel,
967
+ ")"
968
+ ] }), /* @__PURE__ */ d("dd", { children: o(t.shippingCents) })]
969
+ }),
970
+ /* @__PURE__ */ f("div", {
971
+ className: "sf-checkout-success__row sf-checkout-success__row--total",
972
+ children: [/* @__PURE__ */ d("dt", { children: a.total }), /* @__PURE__ */ d("dd", { children: o(t.totalCents) })]
973
+ })
974
+ ]
975
+ }),
976
+ s.length > 0 && /* @__PURE__ */ f("address", {
977
+ className: "sf-checkout-success__address",
978
+ children: [/* @__PURE__ */ d("strong", { children: a.shipTo }), s.map((e) => /* @__PURE__ */ d("span", { children: e }, e))]
979
+ }),
980
+ c?.trackingNumber && /* @__PURE__ */ f("p", {
981
+ className: "sf-checkout-success__tracking",
982
+ children: [c.carrier && `${c.carrier} · `, c.trackingUrl ? /* @__PURE__ */ f("a", {
983
+ href: c.trackingUrl,
984
+ children: [
985
+ a.tracking,
986
+ " ",
987
+ c.trackingNumber
988
+ ]
989
+ }) : c.trackingNumber]
990
+ })
991
+ ]
992
+ });
993
+ }
994
+ // src/cart/clear-cart-on-mount.tsx
995
+ function se() {
996
+ let { hydrated: e, clear: t } = R(), n = c(!1);
997
+ return a(() => {
998
+ e && !n.current && (n.current = !0, t());
999
+ }, [e, t]), null;
1000
+ }
1001
+ export { U as AddToCartButton, S as AvailabilityBadge, ie as CartButton, re as CartDrawer, G as CartLineItem, ee as CartProvider, X as CartSummary, T as CategoryFilter, oe as CheckoutSuccessView, se as ClearCartOnMount, k as FeaturedProducts, b as PriceTag, C as ProductCard, O as ProductDetailView, E as ProductGallery, w as ProductGrid, D as ShopView, v as StorefrontProvider, j as addLine, M as cartReducer, H as defaultAddToCartLabels, x as defaultAvailabilityLabels, Z as defaultCartDrawerLabels, W as defaultCartLineItemLabels, V as defaultCheckoutLabels, $ as defaultCheckoutSuccessLabels, B as discountReasonMessage, A as emptyCart, e as formatPrice, P as itemCount, F as localStorageCartStorage, t as sortForDisplay, N as subtotalCents, h as themeToCssVars, R as useCart, ne as useCheckout, y as useStorefront };
685
1002
 
686
1003
  //# sourceMappingURL=index.js.map