@develemit/storefront 0.0.0-stage → 0.3.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.
Files changed (40) hide show
  1. package/README.md +265 -2
  2. package/dist/cart/cart-provider.d.ts +24 -0
  3. package/dist/cart/cart-reducer.d.ts +31 -0
  4. package/dist/cart/cart-storage.d.ts +6 -0
  5. package/dist/client/commerce-client.d.ts +13 -0
  6. package/dist/client/errors.d.ts +12 -0
  7. package/dist/client/index.d.ts +2 -0
  8. package/dist/client/index.js +64 -0
  9. package/dist/client/index.js.map +1 -0
  10. package/dist/components/add-to-cart-button/add-to-cart-button.d.ts +14 -0
  11. package/dist/components/availability-badge/availability-badge.d.ts +15 -0
  12. package/dist/components/cart-button/cart-button.d.ts +9 -0
  13. package/dist/components/cart-drawer/cart-drawer.d.ts +18 -0
  14. package/dist/components/cart-drawer/use-drawer-presence.d.ts +5 -0
  15. package/dist/components/cart-line-item/cart-line-item.d.ts +11 -0
  16. package/dist/components/cart-summary/cart-summary.d.ts +10 -0
  17. package/dist/components/category-filter/category-filter.d.ts +11 -0
  18. package/dist/components/fixtures.d.ts +2 -0
  19. package/dist/components/price-tag/price-tag.d.ts +7 -0
  20. package/dist/components/product-card/product-card.d.ts +9 -0
  21. package/dist/components/product-gallery/product-gallery.d.ts +6 -0
  22. package/dist/components/product-grid/product-grid.d.ts +10 -0
  23. package/dist/components/render-with-cart.d.ts +3 -0
  24. package/dist/format/index.d.ts +2 -0
  25. package/dist/format/index.js +1 -0
  26. package/dist/index.d.ts +22 -0
  27. package/dist/index.js +686 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/lib/format-price.d.ts +1 -0
  30. package/dist/lib/parse-duration.d.ts +1 -0
  31. package/dist/lib/provider.d.ts +28 -0
  32. package/dist/lib/theme.d.ts +15 -0
  33. package/dist/sort-for-display-Cj6GMeCY.js +15 -0
  34. package/dist/sort-for-display-Cj6GMeCY.js.map +1 -0
  35. package/dist/styles.css +476 -0
  36. package/dist/views/featured-products.d.ts +8 -0
  37. package/dist/views/product-detail-view.d.ts +13 -0
  38. package/dist/views/shop-view.d.ts +21 -0
  39. package/dist/views/sort-for-display.d.ts +2 -0
  40. package/package.json +46 -3
package/dist/index.js ADDED
@@ -0,0 +1,686 @@
1
+ "use client";
2
+ import { n as e, t } from "./sort-for-display-Cj6GMeCY.js";
3
+ import { createContext as n, useCallback as r, useContext as i, useEffect as a, useMemo as o, useReducer as s, useRef as c, useState as l } from "react";
4
+ import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
5
+ import { cartLineSchema as p } from "@develemit/commerce-contracts";
6
+ // src/lib/theme.ts
7
+ var m = {
8
+ colorBg: "--sf-color-bg",
9
+ colorSurface: "--sf-color-surface",
10
+ colorFg: "--sf-color-fg",
11
+ colorMuted: "--sf-color-muted",
12
+ colorAccent: "--sf-color-accent",
13
+ colorAccentFg: "--sf-color-accent-fg",
14
+ colorBorder: "--sf-color-border",
15
+ colorSold: "--sf-color-sold",
16
+ radius: "--sf-radius",
17
+ fontDisplay: "--sf-font-display",
18
+ fontBody: "--sf-font-body",
19
+ spaceUnit: "--sf-space-unit"
20
+ };
21
+ function h(e) {
22
+ let t = {};
23
+ for (let n of Object.keys(m)) {
24
+ let r = e[n];
25
+ r !== void 0 && (t[m[n]] = r);
26
+ }
27
+ return t;
28
+ }
29
+ // src/lib/provider.tsx
30
+ var g = {
31
+ renderLink: ({ href: e, children: t, className: n }) => /* @__PURE__ */ d("a", {
32
+ href: e,
33
+ className: n,
34
+ children: t
35
+ }),
36
+ renderImage: ({ src: e, alt: t, sizes: n, className: r, priority: i }) => /* @__PURE__ */ d("img", {
37
+ src: e,
38
+ alt: t,
39
+ sizes: n,
40
+ className: r,
41
+ loading: i ? "eager" : "lazy",
42
+ decoding: "async",
43
+ fetchPriority: i ? "high" : void 0
44
+ }),
45
+ locale: "en-US",
46
+ hrefs: {
47
+ product: (e) => `/shop/${e}`,
48
+ category: (e) => `/shop?category=${e}`
49
+ }
50
+ }, _ = n(g);
51
+ function v({ children: e, hrefs: t, ...n }) {
52
+ let r = {
53
+ ...g,
54
+ ...n,
55
+ hrefs: {
56
+ ...g.hrefs,
57
+ ...t
58
+ }
59
+ };
60
+ return /* @__PURE__ */ d(_.Provider, {
61
+ value: r,
62
+ children: e
63
+ });
64
+ }
65
+ function y() {
66
+ return i(_);
67
+ }
68
+ // src/components/price-tag/price-tag.tsx
69
+ function b({ priceCents: t, currency: n, sold: r = !1, className: i }) {
70
+ let { locale: a } = y(), o = [
71
+ "sf-price",
72
+ r && "sf-price--sold",
73
+ i
74
+ ].filter(Boolean).join(" ");
75
+ return /* @__PURE__ */ d("span", {
76
+ className: o,
77
+ children: e(t, n, a)
78
+ });
79
+ }
80
+ // src/components/availability-badge/availability-badge.tsx
81
+ var x = {
82
+ oneOfAKind: "One of a kind",
83
+ sold: "Sold",
84
+ reserved: "On hold",
85
+ available: "Available"
86
+ };
87
+ function S({ availability: e, quantity: t, labels: n, className: r }) {
88
+ let i = {
89
+ ...x,
90
+ ...n
91
+ }, a, o;
92
+ e === "sold" ? (a = "sold", o = i.sold) : e === "reserved" ? (a = "reserved", o = i.reserved) : t === 1 ? (a = "unique", o = i.oneOfAKind) : (a = "available", o = i.available);
93
+ let s = [
94
+ "sf-badge",
95
+ `sf-badge--${a}`,
96
+ r
97
+ ].filter(Boolean).join(" ");
98
+ return /* @__PURE__ */ d("span", {
99
+ role: "status",
100
+ className: s,
101
+ children: o
102
+ });
103
+ }
104
+ // src/components/product-card/product-card.tsx
105
+ function C({ product: e, labels: t, sizes: n, priority: r }) {
106
+ let { renderLink: i, renderImage: a, hrefs: o } = y(), s = e.availability === "sold", c = e.images[0], l = ["sf-card", s && "sf-card--sold"].filter(Boolean).join(" ");
107
+ return /* @__PURE__ */ d("article", {
108
+ className: l,
109
+ children: i({
110
+ href: o.product(e.slug),
111
+ className: "sf-card__link",
112
+ children: /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("div", {
113
+ className: "sf-card__media",
114
+ children: c ? a({
115
+ src: c.url,
116
+ alt: c.alt,
117
+ sizes: n,
118
+ className: "sf-card__image",
119
+ priority: r
120
+ }) : /* @__PURE__ */ d("div", {
121
+ className: "sf-card__placeholder",
122
+ "aria-hidden": "true"
123
+ })
124
+ }), /* @__PURE__ */ f("div", {
125
+ className: "sf-card__body",
126
+ children: [
127
+ /* @__PURE__ */ d("h3", {
128
+ className: "sf-card__title",
129
+ children: e.name
130
+ }),
131
+ /* @__PURE__ */ d(b, {
132
+ priceCents: e.priceCents,
133
+ currency: e.currency,
134
+ sold: s
135
+ }),
136
+ /* @__PURE__ */ d(S, {
137
+ availability: e.availability,
138
+ quantity: e.quantity,
139
+ labels: t
140
+ })
141
+ ]
142
+ })] })
143
+ })
144
+ });
145
+ }
146
+ // src/components/product-grid/product-grid.tsx
147
+ function w({ products: e, emptyState: t, labels: n, priorityCount: r = 0 }) {
148
+ return e.length === 0 ? /* @__PURE__ */ d("div", {
149
+ className: "sf-grid-empty",
150
+ children: t ?? "No products found."
151
+ }) : /* @__PURE__ */ d("ul", {
152
+ className: "sf-grid",
153
+ children: e.map((e, t) => /* @__PURE__ */ d("li", {
154
+ className: "sf-grid__item",
155
+ children: /* @__PURE__ */ d(C, {
156
+ product: e,
157
+ labels: n,
158
+ priority: t < r
159
+ })
160
+ }, e.id))
161
+ });
162
+ }
163
+ // src/components/category-filter/category-filter.tsx
164
+ function T({ categories: e, selected: t, onSelect: n, allLabel: r = "All", label: i = "Categories", formatLabel: a, sortCategories: o }) {
165
+ let { renderLink: s, hrefs: c } = y(), l = o ? [...e].sort(o) : e, u = n !== void 0, p = (e, r, i) => {
166
+ let a = t === e, o = `sf-filter__item${a ? " sf-filter__item--active" : ""}`;
167
+ return /* @__PURE__ */ d("li", { children: u ? /* @__PURE__ */ d("button", {
168
+ type: "button",
169
+ className: o,
170
+ "aria-pressed": a,
171
+ onClick: () => n(e),
172
+ children: r
173
+ }) : s({
174
+ href: i,
175
+ className: o,
176
+ children: r
177
+ }) }, e ?? "__all");
178
+ };
179
+ return /* @__PURE__ */ d("nav", {
180
+ "aria-label": i,
181
+ className: "sf-filter",
182
+ children: /* @__PURE__ */ f("ul", {
183
+ className: "sf-filter__list",
184
+ children: [p(void 0, r, c.category("")), l.map((e) => p(e.slug, a ? a(e) : e.label, c.category(e.slug)))]
185
+ })
186
+ });
187
+ }
188
+ // src/components/product-gallery/product-gallery.tsx
189
+ function E({ images: e, sizes: t }) {
190
+ let { renderImage: n } = y(), [r, i] = l(0);
191
+ return e.length === 0 ? null : /* @__PURE__ */ f("div", {
192
+ className: "sf-gallery",
193
+ role: "group",
194
+ "aria-roledescription": "carousel",
195
+ "aria-label": "Product images",
196
+ tabIndex: 0,
197
+ onKeyDown: (t) => {
198
+ if (t.key === "ArrowRight") i((t) => (t + 1) % e.length);
199
+ else if (t.key === "ArrowLeft") i((t) => (t - 1 + e.length) % e.length);
200
+ else if (t.key === "Home") i(0);
201
+ else if (t.key === "End") i(e.length - 1);
202
+ else return;
203
+ t.preventDefault();
204
+ },
205
+ children: [/* @__PURE__ */ d("div", {
206
+ className: "sf-gallery__stage",
207
+ children: e.map((e, i) => /* @__PURE__ */ d("div", {
208
+ className: "sf-gallery__slide",
209
+ hidden: i !== r,
210
+ children: n({
211
+ src: e.url,
212
+ alt: e.alt,
213
+ sizes: t,
214
+ priority: i === r,
215
+ className: "sf-gallery__image"
216
+ })
217
+ }, e.url))
218
+ }), e.length > 1 && /* @__PURE__ */ d("div", {
219
+ className: "sf-gallery__thumbs",
220
+ children: e.map((t, a) => /* @__PURE__ */ d("button", {
221
+ type: "button",
222
+ className: `sf-gallery__thumb${a === r ? " sf-gallery__thumb--active" : ""}`,
223
+ "aria-label": `Show image ${a + 1} of ${e.length}`,
224
+ "aria-current": a === r,
225
+ onClick: () => i(a),
226
+ children: n({
227
+ src: t.url,
228
+ alt: "",
229
+ className: "sf-gallery__thumb-image"
230
+ })
231
+ }, t.url))
232
+ })]
233
+ });
234
+ }
235
+ // src/views/shop-view.tsx
236
+ function D({ products: e, categories: n, activeCategory: r, slots: i = {}, labels: a, allLabel: o, formatCategoryLabel: s, sortCategories: c, nextHref: l, loadMoreLabel: u = "Load more" }) {
237
+ let { renderLink: p } = y();
238
+ return /* @__PURE__ */ f("div", {
239
+ className: "sf-shop",
240
+ children: [
241
+ i.header,
242
+ i.intro,
243
+ /* @__PURE__ */ d(T, {
244
+ categories: n,
245
+ selected: r,
246
+ allLabel: o,
247
+ formatLabel: s,
248
+ sortCategories: c
249
+ }),
250
+ /* @__PURE__ */ d(w, {
251
+ products: t(e),
252
+ emptyState: i.emptyState,
253
+ labels: a,
254
+ priorityCount: 6
255
+ }),
256
+ l && /* @__PURE__ */ d("div", {
257
+ className: "sf-shop__pager",
258
+ children: p({
259
+ href: l,
260
+ className: "sf-shop__more",
261
+ children: u
262
+ })
263
+ })
264
+ ]
265
+ });
266
+ }
267
+ // src/views/product-detail-view.tsx
268
+ function O({ product: e, slots: t = {}, labels: n }) {
269
+ return /* @__PURE__ */ f("article", {
270
+ className: "sf-detail",
271
+ children: [/* @__PURE__ */ d(E, { images: e.images }), /* @__PURE__ */ f("div", {
272
+ className: "sf-detail__body",
273
+ children: [
274
+ /* @__PURE__ */ d("h1", {
275
+ className: "sf-detail__title",
276
+ children: e.name
277
+ }),
278
+ /* @__PURE__ */ d(b, {
279
+ priceCents: e.priceCents,
280
+ currency: e.currency
281
+ }),
282
+ /* @__PURE__ */ d(S, {
283
+ availability: e.availability,
284
+ quantity: e.quantity,
285
+ labels: n
286
+ }),
287
+ /* @__PURE__ */ d("p", {
288
+ className: "sf-detail__description",
289
+ children: e.description
290
+ }),
291
+ (e.materials || e.dimensions) && /* @__PURE__ */ f("dl", {
292
+ className: "sf-detail__specs",
293
+ children: [e.materials && /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("dt", { children: "Materials" }), /* @__PURE__ */ d("dd", { children: e.materials })] }), e.dimensions && /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("dt", { children: "Dimensions" }), /* @__PURE__ */ d("dd", { children: e.dimensions })] })]
294
+ }),
295
+ t.actions && /* @__PURE__ */ d("div", {
296
+ className: "sf-detail__actions",
297
+ children: t.actions
298
+ }),
299
+ t.afterDetails
300
+ ]
301
+ })]
302
+ });
303
+ }
304
+ // src/views/featured-products.tsx
305
+ function k({ products: e, heading: t = "Featured", labels: n }) {
306
+ return e.length === 0 ? null : /* @__PURE__ */ f("section", {
307
+ className: "sf-featured",
308
+ children: [/* @__PURE__ */ d("h2", {
309
+ className: "sf-featured__heading",
310
+ children: t
311
+ }), /* @__PURE__ */ d(w, {
312
+ products: e,
313
+ labels: n,
314
+ priorityCount: 6
315
+ })]
316
+ });
317
+ }
318
+ // src/cart/cart-reducer.ts
319
+ var A = { lines: [] };
320
+ function j(e, t) {
321
+ let n = e.lines[0];
322
+ if (n && n.currency !== t.currency) return {
323
+ state: e,
324
+ added: !1,
325
+ capped: !1,
326
+ reason: "currency-mismatch"
327
+ };
328
+ let r = e.lines.find((e) => e.productId === t.productId);
329
+ if (!r) {
330
+ let n = Math.min(t.quantity, t.maxQuantity);
331
+ return {
332
+ state: { lines: [...e.lines, {
333
+ ...t,
334
+ quantity: n
335
+ }] },
336
+ added: !0,
337
+ capped: n < t.quantity
338
+ };
339
+ }
340
+ if (r.quantity >= r.maxQuantity) return {
341
+ state: e,
342
+ added: !1,
343
+ capped: !0
344
+ };
345
+ let i = Math.min(r.quantity + t.quantity, r.maxQuantity);
346
+ return {
347
+ state: { lines: e.lines.map((e) => e.productId === t.productId ? {
348
+ ...e,
349
+ quantity: i
350
+ } : e) },
351
+ added: !0,
352
+ capped: r.quantity + t.quantity > r.maxQuantity
353
+ };
354
+ }
355
+ function M(e, t) {
356
+ switch (t.type) {
357
+ case "add": return j(e, t.line).state;
358
+ case "remove": return { lines: e.lines.filter((e) => e.productId !== t.productId) };
359
+ case "setQuantity": return t.quantity <= 0 ? M(e, {
360
+ type: "remove",
361
+ productId: t.productId
362
+ }) : { lines: e.lines.map((e) => e.productId === t.productId ? {
363
+ ...e,
364
+ quantity: Math.min(t.quantity, e.maxQuantity)
365
+ } : e) };
366
+ case "clear": return A;
367
+ case "hydrate": return t.state;
368
+ }
369
+ }
370
+ function N(e) {
371
+ return e.lines.reduce((e, t) => e + t.priceCents * t.quantity, 0);
372
+ }
373
+ function P(e) {
374
+ return e.lines.reduce((e, t) => e + t.quantity, 0);
375
+ }
376
+ // src/cart/cart-storage.ts
377
+ function F(e = "sf-cart") {
378
+ return {
379
+ load() {
380
+ if (typeof window > "u") return A;
381
+ try {
382
+ let t = window.localStorage.getItem(e);
383
+ if (!t) return A;
384
+ let n = JSON.parse(t);
385
+ return { lines: (Array.isArray(n?.lines) ? n.lines : []).flatMap((e) => {
386
+ let t = p.safeParse(e);
387
+ return t.success ? [t.data] : [];
388
+ }) };
389
+ } catch {
390
+ return A;
391
+ }
392
+ },
393
+ save(t) {
394
+ if (typeof window < "u") try {
395
+ window.localStorage.setItem(e, JSON.stringify(t));
396
+ } catch {}
397
+ }
398
+ };
399
+ }
400
+ // src/cart/cart-provider.tsx
401
+ var I = n(null), L = F();
402
+ function R({ storage: e = L, children: t }) {
403
+ let [n, i] = s(M, A), [u, f] = l(!1), [p, m] = l(!1), h = c(n);
404
+ a(() => {
405
+ h.current = n;
406
+ }, [n]), a(() => {
407
+ let t = !1;
408
+ return Promise.resolve(e.load()).then((e) => {
409
+ t || (i({
410
+ type: "hydrate",
411
+ state: e
412
+ }), f(!0));
413
+ }), () => {
414
+ t = !0;
415
+ };
416
+ }, [e]), a(() => {
417
+ u && e.save(n);
418
+ }, [
419
+ u,
420
+ n,
421
+ e
422
+ ]);
423
+ let g = r((e) => {
424
+ let t = j(h.current, e);
425
+ return t.added && (h.current = t.state, i({
426
+ type: "add",
427
+ line: e
428
+ })), t;
429
+ }, []), _ = o(() => ({
430
+ lines: n.lines,
431
+ itemCount: P(n),
432
+ subtotalCents: N(n),
433
+ currency: n.lines[0]?.currency ?? null,
434
+ hydrated: u,
435
+ isOpen: p,
436
+ open: () => m(!0),
437
+ close: () => m(!1),
438
+ add: g,
439
+ remove: (e) => i({
440
+ type: "remove",
441
+ productId: e
442
+ }),
443
+ setQuantity: (e, t) => i({
444
+ type: "setQuantity",
445
+ productId: e,
446
+ quantity: t
447
+ }),
448
+ clear: () => i({ type: "clear" })
449
+ }), [
450
+ n,
451
+ u,
452
+ p,
453
+ g
454
+ ]);
455
+ return /* @__PURE__ */ d(I.Provider, {
456
+ value: _,
457
+ children: t
458
+ });
459
+ }
460
+ function z() {
461
+ let e = i(I);
462
+ if (!e) throw Error("useCart must be used inside <CartProvider>");
463
+ return e;
464
+ }
465
+ // src/components/add-to-cart-button/add-to-cart-button.tsx
466
+ var B = {
467
+ add: "Add to cart",
468
+ inCart: "In your cart",
469
+ unavailable: "Unavailable"
470
+ };
471
+ function V({ product: e, labels: t, openOnAdd: n = !0, className: r }) {
472
+ let i = z(), a = {
473
+ ...B,
474
+ ...t
475
+ }, 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
+ function f() {
477
+ i.add({
478
+ productId: e.id,
479
+ slug: e.slug,
480
+ name: e.name,
481
+ priceCents: e.priceCents,
482
+ currency: e.currency,
483
+ imageUrl: e.images[0]?.url,
484
+ quantity: 1,
485
+ maxQuantity: e.quantity
486
+ }).added && n && i.open();
487
+ }
488
+ return /* @__PURE__ */ d("button", {
489
+ type: "button",
490
+ className: ["sf-button", r].filter(Boolean).join(" "),
491
+ disabled: l,
492
+ onClick: f,
493
+ children: u
494
+ });
495
+ }
496
+ // src/components/cart-line-item/cart-line-item.tsx
497
+ var H = {
498
+ remove: "Remove",
499
+ quantity: "Quantity"
500
+ };
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,
504
+ ...n
505
+ }, u = t.maxQuantity > 1;
506
+ return /* @__PURE__ */ f("li", {
507
+ className: "sf-cart-line",
508
+ children: [t.imageUrl && s({
509
+ src: t.imageUrl,
510
+ alt: "",
511
+ sizes: "80px",
512
+ className: "sf-cart-line__image"
513
+ }), /* @__PURE__ */ f("div", {
514
+ className: "sf-cart-line__body",
515
+ children: [
516
+ o({
517
+ href: c.product(t.slug),
518
+ className: "sf-cart-line__name",
519
+ children: t.name
520
+ }),
521
+ /* @__PURE__ */ d("span", {
522
+ className: "sf-cart-line__price",
523
+ children: e(t.priceCents * t.quantity, t.currency, a)
524
+ }),
525
+ u && /* @__PURE__ */ f("label", {
526
+ className: "sf-cart-line__qty",
527
+ children: [l.quantity, /* @__PURE__ */ d("input", {
528
+ type: "number",
529
+ min: 1,
530
+ max: t.maxQuantity,
531
+ value: t.quantity,
532
+ onChange: (e) => i(t.productId, Number(e.target.value))
533
+ })]
534
+ }),
535
+ /* @__PURE__ */ d("button", {
536
+ type: "button",
537
+ className: "sf-link-button sf-cart-line__remove",
538
+ onClick: () => r(t.productId),
539
+ "aria-label": `${l.remove} ${t.name}`,
540
+ children: l.remove
541
+ })
542
+ ]
543
+ })]
544
+ });
545
+ }
546
+ // src/lib/parse-duration.ts
547
+ function W(e) {
548
+ let t = /^\s*(-?\d*\.?\d+)\s*(ms|s)\s*$/.exec(e);
549
+ if (!t) return 0;
550
+ let n = Number(t[1]);
551
+ return Math.max(0, t[2] === "s" ? n * 1e3 : n);
552
+ }
553
+ // src/components/cart-drawer/use-drawer-presence.ts
554
+ function G(e, t) {
555
+ let [n, r] = l(0), [i, o] = l(e), [s, c] = l(!1);
556
+ return i !== e && (o(e), c(!e && n > 0)), a(() => {
557
+ e && t.current && r(W(getComputedStyle(t.current).getPropertyValue("--sf-motion-duration")));
558
+ }, [e, t]), a(() => {
559
+ if (!s) return;
560
+ let e = setTimeout(() => c(!1), n);
561
+ return () => clearTimeout(e);
562
+ }, [s, n]), {
563
+ mounted: e || s,
564
+ state: e ? "open" : "closed"
565
+ };
566
+ }
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";
570
+ 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)
577
+ })]
578
+ }), /* @__PURE__ */ d("button", {
579
+ type: "button",
580
+ className: "sf-button",
581
+ disabled: r || !t || a.lines.length === 0,
582
+ onClick: t,
583
+ children: n
584
+ })]
585
+ });
586
+ }
587
+ // src/components/cart-drawer/cart-drawer.tsx
588
+ var q = {
589
+ title: "Your cart",
590
+ close: "Close",
591
+ 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,
596
+ ...e
597
+ }, o = c(null), s = c(null), { isOpen: l } = r, p = G(l, s);
598
+ if (a(() => {
599
+ if (!l) return;
600
+ let e = document.activeElement;
601
+ return o.current?.querySelector(J)?.focus(), () => e?.focus();
602
+ }, [l]), !p.mounted) return null;
603
+ function m(e) {
604
+ if (e.key === "Escape") {
605
+ e.stopPropagation(), r.close();
606
+ return;
607
+ }
608
+ if (e.key !== "Tab") return;
609
+ let t = Array.from(o.current?.querySelectorAll(J) ?? []);
610
+ if (t.length === 0) return;
611
+ let n = t[0], i = t[t.length - 1];
612
+ e.shiftKey && document.activeElement === n ? (e.preventDefault(), i.focus()) : !e.shiftKey && document.activeElement === i && (e.preventDefault(), n.focus());
613
+ }
614
+ return /* @__PURE__ */ d("div", {
615
+ ref: s,
616
+ className: "sf-drawer-backdrop",
617
+ "data-state": p.state,
618
+ onClick: r.close,
619
+ children: /* @__PURE__ */ f("div", {
620
+ ref: o,
621
+ className: "sf-drawer",
622
+ "data-state": p.state,
623
+ role: "dialog",
624
+ "aria-modal": "true",
625
+ "aria-labelledby": "sf-drawer-title",
626
+ onKeyDown: m,
627
+ onClick: (e) => e.stopPropagation(),
628
+ children: [/* @__PURE__ */ f("div", {
629
+ className: "sf-drawer__header",
630
+ children: [/* @__PURE__ */ d("h2", {
631
+ id: "sf-drawer-title",
632
+ className: "sf-drawer__title",
633
+ children: i.title
634
+ }), /* @__PURE__ */ d("button", {
635
+ type: "button",
636
+ className: "sf-drawer__close",
637
+ "aria-label": i.close,
638
+ onClick: r.close,
639
+ children: /* @__PURE__ */ d("span", {
640
+ "aria-hidden": "true",
641
+ children: "×"
642
+ })
643
+ })]
644
+ }), r.lines.length === 0 ? /* @__PURE__ */ d("div", {
645
+ className: "sf-drawer__empty",
646
+ children: n?.empty ?? /* @__PURE__ */ d("p", { children: i.empty })
647
+ }) : /* @__PURE__ */ f(u, { children: [
648
+ /* @__PURE__ */ d("ul", {
649
+ className: "sf-drawer__lines",
650
+ children: r.lines.map((e) => /* @__PURE__ */ d(U, { line: e }, e.productId))
651
+ }),
652
+ /* @__PURE__ */ d(K, { ...t }),
653
+ n?.summaryNote && /* @__PURE__ */ d("div", {
654
+ className: "sf-drawer__note",
655
+ children: n.summaryNote
656
+ })
657
+ ] })]
658
+ })
659
+ });
660
+ }
661
+ // 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`;
664
+ return /* @__PURE__ */ f("button", {
665
+ type: "button",
666
+ className: ["sf-cart-button", t].filter(Boolean).join(" "),
667
+ "aria-haspopup": "dialog",
668
+ "aria-label": c,
669
+ onClick: a.open,
670
+ children: [
671
+ n,
672
+ /* @__PURE__ */ d("span", {
673
+ className: r ? "sf-visually-hidden" : void 0,
674
+ children: e
675
+ }),
676
+ s && /* @__PURE__ */ d("span", {
677
+ className: "sf-cart-button__count",
678
+ "aria-label": `${a.itemCount} items`,
679
+ children: o
680
+ })
681
+ ]
682
+ });
683
+ }
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 };
685
+
686
+ //# sourceMappingURL=index.js.map