@numueg/theme-sdk 0.10.1 → 0.13.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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  export { resolveThemeSettings } from './chunk-XF2FGIVS.mjs';
2
- export { KNOWN_SETTING_TYPES, KNOWN_TEMPLATES, REQUIRED_TEMPLATES, SDK_VERSION, THEME_CONTRACT_VERSION, mergeResults, validateBuiltManifest, validateManifest, validateSectionSchema, validateSettingsAgainstSchema } from './chunk-QFFTHIFZ.mjs';
2
+ export { KNOWN_SETTING_TYPES, KNOWN_TEMPLATES, REQUIRED_TEMPLATES, SDK_VERSION, THEME_CONTRACT_VERSION, mergeResults, validateBuiltManifest, validateManifest, validateSectionSchema, validateSettingsAgainstSchema } from './chunk-QPXMBK5U.mjs';
3
3
  import { ShopContext, ThemeSettingsContext, CurrentTemplateContext, PageContext, LocalizationContext, CurrencyContext, CartContext, CustomerContext, NavigationContext, CollectionContext, ProductContext, useShop, useLocalization, useCustomer, useThemeSettings } from './chunk-ZYZZG4JR.mjs';
4
4
  export { CartContext, CollectionContext, CurrencyContext, CustomerContext, LocalizationContext, NavigationContext, PageContext, ProductContext, ShopContext, ThemeSettingsContext, useCollections, useCustomer, useDirection, useFieldTranslation, useLocale, useLocalization, useNumberFormat, usePage, useProducts, useShop, useThemeSettings, useTranslation } from './chunk-ZYZZG4JR.mjs';
5
5
  import { createContext, forwardRef, useState, useImperativeHandle, useEffect, useCallback, useMemo, useRef, useContext, useSyncExternalStore, StrictMode, createElement, Component } from 'react';
@@ -24,6 +24,20 @@ function useCollection() {
24
24
  function useCollectionOptional() {
25
25
  return useContext(CollectionContext);
26
26
  }
27
+ function useListingHeading(options = {}) {
28
+ const collection = useContext(CollectionContext);
29
+ const clean = (v) => typeof v === "string" && v.trim() !== "" ? v.trim() : "";
30
+ const collectionName = clean(collection?.name);
31
+ const collectionDescription = clean(
32
+ collection?.description
33
+ );
34
+ return {
35
+ collection: collection ?? null,
36
+ isCollection: collectionName !== "",
37
+ title: collectionName || clean(options.title) || clean(options.defaultTitle) || "",
38
+ description: collectionDescription || clean(options.description) || ""
39
+ };
40
+ }
27
41
  function useCart() {
28
42
  const ctx = useContext(CartContext);
29
43
  if (!ctx) throw new Error("useCart must be used within NuMuProvider");
@@ -32,6 +46,59 @@ function useCart() {
32
46
  function useCurrentTemplate() {
33
47
  return useContext(CurrentTemplateContext);
34
48
  }
49
+ function isMetafield(value) {
50
+ return typeof value === "object" && value !== null && typeof value.namespace === "string" && typeof value.key === "string";
51
+ }
52
+ function pageMetafields(data) {
53
+ if (!data) return [];
54
+ const record = data.page;
55
+ for (const candidate of [record?.metafields, data.metafields]) {
56
+ if (Array.isArray(candidate)) return candidate.filter(isMetafield);
57
+ }
58
+ return [];
59
+ }
60
+ function useMetafields(owner) {
61
+ const product = useContext(ProductContext);
62
+ const collection = useContext(CollectionContext);
63
+ const page = useContext(PageContext);
64
+ switch (owner) {
65
+ case "product":
66
+ return product?.metafields ?? [];
67
+ case "collection":
68
+ return collection?.metafields ?? [];
69
+ case "page":
70
+ return pageMetafields(page?.data);
71
+ default:
72
+ return [];
73
+ }
74
+ }
75
+ function useMetafield(owner, namespace, key) {
76
+ const fields = useMetafields(owner);
77
+ return fields.find((m) => m.namespace === namespace && m.key === key) ?? null;
78
+ }
79
+ function pageData() {
80
+ return useContext(PageContext)?.data;
81
+ }
82
+ function useBlogs() {
83
+ const data = pageData();
84
+ const blogs = data?.blogs;
85
+ return Array.isArray(blogs) ? blogs : [];
86
+ }
87
+ function useBlog() {
88
+ const data = pageData();
89
+ const blog = data?.blog ?? data?.article?.blog;
90
+ return blog && typeof blog === "object" ? blog : null;
91
+ }
92
+ function useArticles() {
93
+ const data = pageData();
94
+ const articles = data?.articles;
95
+ return Array.isArray(articles) ? articles : [];
96
+ }
97
+ function useArticle() {
98
+ const data = pageData();
99
+ const article = data?.article;
100
+ return article && typeof article === "object" ? article : null;
101
+ }
35
102
  var SectionContext = createContext(null);
36
103
  function useSection() {
37
104
  const ctx = useContext(SectionContext);
@@ -81,16 +148,16 @@ function useCurrency() {
81
148
 
82
149
  // src/hooks/useMoney.ts
83
150
  function useMoney(currencyOverride) {
84
- const { formatMoney } = useLocalization();
151
+ const { formatMoney: formatMoney2 } = useLocalization();
85
152
  const shop = useShop();
86
153
  const { selected, base, autoConvert, convert } = useCurrency();
87
154
  return (amount) => {
88
155
  const shouldConvert = autoConvert && !currencyOverride && !!selected && selected !== base;
89
156
  if (shouldConvert) {
90
157
  const converted = convert(Math.round(amount * 100), selected) / 100;
91
- return formatMoney(converted, selected);
158
+ return formatMoney2(converted, selected);
92
159
  }
93
- return formatMoney(amount, currencyOverride || shop?.currency);
160
+ return formatMoney2(amount, currencyOverride || shop?.currency);
94
161
  };
95
162
  }
96
163
  var DEFAULT_WIDTHS = [320, 480, 640, 768, 1024, 1280, 1600, 1920];
@@ -955,6 +1022,133 @@ function useRelatedProducts(productId, options = {}) {
955
1022
  });
956
1023
  return { items: data ?? EMPTY4, loading: isLoading, error: error ?? null };
957
1024
  }
1025
+ function useActivePromotions(page = "/", locale = "ar") {
1026
+ const key = `numu:promotions:${page}:${locale}`;
1027
+ const fetcher = useCallback(
1028
+ async (signal) => {
1029
+ const qs = new URLSearchParams({ page, locale });
1030
+ const res = await fetch(`/api/storefront/promotions?${qs.toString()}`, {
1031
+ credentials: "include",
1032
+ cache: "no-store",
1033
+ signal
1034
+ });
1035
+ if (!res.ok) return null;
1036
+ const json = await res.json();
1037
+ if (!json) return null;
1038
+ return (json.data ?? json) || null;
1039
+ },
1040
+ [page, locale]
1041
+ );
1042
+ const { data } = useCachedResource(
1043
+ key,
1044
+ fetcher,
1045
+ { initialData: null }
1046
+ );
1047
+ return data ?? null;
1048
+ }
1049
+
1050
+ // src/utils/money.ts
1051
+ function resolveLocale(locale) {
1052
+ return locale === "ar" ? "ar-EG" : "en-EG";
1053
+ }
1054
+ function formatMoney(cents, options = {}) {
1055
+ const { currency, locale, fractionDigits = 0 } = options;
1056
+ const safe = Number.isFinite(cents) ? cents : 0;
1057
+ return new Intl.NumberFormat(resolveLocale(locale), {
1058
+ style: "currency",
1059
+ currency: currency || "EGP",
1060
+ maximumFractionDigits: fractionDigits
1061
+ }).format(safe / 100);
1062
+ }
1063
+ function formatMoneyMajor(amount, options = {}) {
1064
+ return formatMoney(
1065
+ (Number.isFinite(amount) ? amount : 0) * 100,
1066
+ options
1067
+ );
1068
+ }
1069
+ function centsToMajor(cents) {
1070
+ return (Number.isFinite(cents) ? cents : 0) / 100;
1071
+ }
1072
+ function majorToCents(amount) {
1073
+ return Math.round((Number.isFinite(amount) ? amount : 0) * 100);
1074
+ }
1075
+
1076
+ // src/lib/promotions.ts
1077
+ function multibuyOffers(promotions) {
1078
+ if (!promotions) return [];
1079
+ const list = Array.isArray(promotions) ? promotions : promotions.auto_discounts ?? [];
1080
+ const offers = [];
1081
+ for (const promo of list) {
1082
+ const rule = promo?.discount_rule;
1083
+ if (!rule || rule.kind !== "multibuy") continue;
1084
+ const quantity = rule.multibuy_quantity;
1085
+ const groupPriceCents = rule.multibuy_price_cents;
1086
+ if (typeof quantity !== "number" || quantity < 2) continue;
1087
+ if (typeof groupPriceCents !== "number" || groupPriceCents <= 0) continue;
1088
+ const eligibleProductIds = promo.eligible_product_ids ?? [];
1089
+ const eligibleCategoryIds = promo.eligible_category_ids ?? [];
1090
+ offers.push({
1091
+ promotionId: promo.promotion_id,
1092
+ quantity,
1093
+ groupPriceCents,
1094
+ groupPriceMajor: centsToMajor(groupPriceCents),
1095
+ headline: promo.translated_content?.headline,
1096
+ eligibleProductIds,
1097
+ eligibleCategoryIds,
1098
+ // No scoping rows at all ⇒ every product qualifies. Note an older
1099
+ // backend that doesn't send these fields also lands here, which is the
1100
+ // right default: counting everything is what themes did before.
1101
+ isStoreWide: eligibleProductIds.length === 0 && eligibleCategoryIds.length === 0,
1102
+ raw: promo
1103
+ });
1104
+ }
1105
+ return offers;
1106
+ }
1107
+ function offerIncludesProduct(offer, product) {
1108
+ if (!offer) return false;
1109
+ if (offer.isStoreWide) return true;
1110
+ const id = product?.product_id ?? product?.id;
1111
+ if (id && offer.eligibleProductIds.includes(id)) return true;
1112
+ const category = product?.category_id;
1113
+ return Boolean(category && offer.eligibleCategoryIds.includes(category));
1114
+ }
1115
+ function eligibleUnitsInCart(offer, cart) {
1116
+ if (!offer) return 0;
1117
+ return (cart?.items ?? []).reduce((sum, item) => {
1118
+ if (!item) return sum;
1119
+ if (!offerIncludesProduct(offer, item)) return sum;
1120
+ return sum + (item.quantity || 0);
1121
+ }, 0);
1122
+ }
1123
+ function offerProgress(offer, cart, eligibleUnits) {
1124
+ const empty = {
1125
+ unitsInCart: 0,
1126
+ unitsNeeded: 0,
1127
+ groupsUnlocked: 0,
1128
+ savingMajor: 0
1129
+ };
1130
+ if (!offer) return empty;
1131
+ const unitsInCart = typeof eligibleUnits === "number" ? Math.max(0, eligibleUnits) : eligibleUnitsInCart(offer, cart);
1132
+ const groupsUnlocked = Math.floor(unitsInCart / offer.quantity);
1133
+ const remainder = unitsInCart % offer.quantity;
1134
+ const unitsNeeded = remainder === 0 ? 0 : offer.quantity - remainder;
1135
+ const applied = (cart?.applied_promotions ?? []).find(
1136
+ (p) => p && p.id === offer.promotionId
1137
+ );
1138
+ return {
1139
+ unitsInCart,
1140
+ unitsNeeded,
1141
+ groupsUnlocked,
1142
+ savingMajor: applied ? applied.amount || 0 : 0
1143
+ };
1144
+ }
1145
+ function offerBeatsRegularPrice(offer, unitPriceMajor) {
1146
+ if (!offer || typeof unitPriceMajor !== "number" || unitPriceMajor <= 0) {
1147
+ return false;
1148
+ }
1149
+ const unitCents = Math.round(unitPriceMajor * 100);
1150
+ return unitCents * offer.quantity > offer.groupPriceCents;
1151
+ }
958
1152
  function useProductSizeChart(productOverride) {
959
1153
  const ctxProduct = useProductOptional();
960
1154
  const product = productOverride ?? ctxProduct;
@@ -1428,11 +1622,27 @@ var EMPTY_CART = {
1428
1622
  };
1429
1623
  function normalizeCartFromServer(cart) {
1430
1624
  const toMajor = (n) => typeof n === "number" ? n / 100 : 0;
1625
+ const { automatic_discount_cents: wireAutomaticCents, ...rest } = cart;
1431
1626
  return {
1432
- ...cart,
1627
+ ...rest,
1433
1628
  subtotal: toMajor(cart.subtotal),
1434
1629
  total: toMajor(cart.total),
1435
1630
  ...cart.discount_amount != null ? { discount_amount: toMajor(cart.discount_amount) } : {},
1631
+ // Offers-v2 automatic promotions. These MUST be converted here too —
1632
+ // they arrive in cents next to already-major totals, so forwarding them
1633
+ // raw makes every theme render a saving 100x too large. This function is
1634
+ // the one and only cents→major boundary for the cart.
1635
+ //
1636
+ // The backend field is `automatic_discount_cents`; themes get
1637
+ // `automatic_discount` (major), because a `_cents` name holding pounds
1638
+ // invites exactly the double-divide this conversion exists to prevent.
1639
+ ...wireAutomaticCents != null ? { automatic_discount: toMajor(wireAutomaticCents) } : {},
1640
+ ...Array.isArray(cart.applied_promotions) ? {
1641
+ applied_promotions: cart.applied_promotions.map((p) => ({
1642
+ ...p,
1643
+ amount: toMajor(p.amount)
1644
+ }))
1645
+ } : {},
1436
1646
  items: Array.isArray(cart.items) ? cart.items.map((it) => {
1437
1647
  const raw = it;
1438
1648
  return {
@@ -2254,13 +2464,13 @@ function pickDemo(ctx, themeSettings) {
2254
2464
  const t = themeSettings.templates;
2255
2465
  return !t || Object.keys(t).length === 0;
2256
2466
  }
2257
- function wrapEntityProviders(app, pageData) {
2467
+ function wrapEntityProviders(app, pageData2) {
2258
2468
  let inner = app;
2259
- if (pageData.collection) {
2260
- inner = /* @__PURE__ */ jsx(CollectionProvider, { collection: pageData.collection, children: inner });
2469
+ if (pageData2.collection) {
2470
+ inner = /* @__PURE__ */ jsx(CollectionProvider, { collection: pageData2.collection, children: inner });
2261
2471
  }
2262
- if (pageData.product) {
2263
- inner = /* @__PURE__ */ jsx(ProductProvider, { product: pageData.product, children: inner });
2472
+ if (pageData2.product) {
2473
+ inner = /* @__PURE__ */ jsx(ProductProvider, { product: pageData2.product, children: inner });
2264
2474
  }
2265
2475
  return inner;
2266
2476
  }
@@ -2283,7 +2493,7 @@ var ThemeMountBridge = forwardRef(function ThemeMountBridge2({ ctx, mountEl, ren
2283
2493
  const store = pickStore(ctx);
2284
2494
  const template = pickTemplate(ctx);
2285
2495
  const demo = pickDemo(ctx, themeSettings);
2286
- const pageData = ctx.page?.data ?? {};
2496
+ const pageData2 = ctx.page?.data ?? {};
2287
2497
  const app = renderApp({
2288
2498
  currentTemplate: template,
2289
2499
  demo,
@@ -2301,11 +2511,11 @@ var ThemeMountBridge = forwardRef(function ThemeMountBridge2({ ctx, mountEl, ren
2301
2511
  locale: ctx.locale,
2302
2512
  translations: ctx.translations,
2303
2513
  navigation: ctx.navigation,
2304
- initialProducts: pageData.products,
2305
- initialCollections: pageData.collections,
2514
+ initialProducts: pageData2.products,
2515
+ initialCollections: pageData2.collections,
2306
2516
  currentTemplate: template,
2307
2517
  pageTemplate: ctx.page?.template,
2308
- children: wrapEntityProviders(app, pageData)
2518
+ children: wrapEntityProviders(app, pageData2)
2309
2519
  }
2310
2520
  );
2311
2521
  });
@@ -2348,7 +2558,7 @@ function Money({
2348
2558
  className,
2349
2559
  as = "span"
2350
2560
  }) {
2351
- const { formatMoney } = useLocalization();
2561
+ const { formatMoney: formatMoney2 } = useLocalization();
2352
2562
  const shop = useShop();
2353
2563
  const { selected, base, autoConvert, convert } = useCurrency();
2354
2564
  const shouldConvert = autoConvert && !currency && !!selected && selected !== base;
@@ -2356,12 +2566,12 @@ function Money({
2356
2566
  const toDisplay = (major) => shouldConvert ? convert(Math.round(major * 100), selected) / 100 : major;
2357
2567
  const showCompare = compareAt != null && compareAt > amount;
2358
2568
  const children = [
2359
- /* @__PURE__ */ jsx("span", { children: formatMoney(toDisplay(amount), ccy) }, "amt")
2569
+ /* @__PURE__ */ jsx("span", { children: formatMoney2(toDisplay(amount), ccy) }, "amt")
2360
2570
  ];
2361
2571
  if (showCompare) {
2362
2572
  children.push(" ");
2363
2573
  children.push(
2364
- /* @__PURE__ */ jsx("s", { style: { opacity: 0.6 }, children: formatMoney(toDisplay(compareAt), ccy) }, "cmp")
2574
+ /* @__PURE__ */ jsx("s", { style: { opacity: 0.6 }, children: formatMoney2(toDisplay(compareAt), ccy) }, "cmp")
2365
2575
  );
2366
2576
  }
2367
2577
  return createElement(
@@ -2381,7 +2591,7 @@ function asImageTransform(v) {
2381
2591
  return void 0;
2382
2592
  }
2383
2593
  function applyImageTransform(t, fit = "cover") {
2384
- if (!t) return { objectFit: fit };
2594
+ if (!t) return {};
2385
2595
  const fx = Math.round(_clampT(t.focal?.x ?? 0.5, 0, 1) * 1e4) / 100;
2386
2596
  const fy = Math.round(_clampT(t.focal?.y ?? 0.5, 0, 1) * 1e4) / 100;
2387
2597
  const zoom = _clampT(t.zoom ?? 1, 1, 4);
@@ -2584,7 +2794,10 @@ function HeroMedia({
2584
2794
  const activeBase = useMobile ? MOBILE_BASE_WIDTH : DESKTOP_BASE_WIDTH;
2585
2795
  const activeSrc = rawFallback ? activeUrl : focalSrc(activeUrl, { width: activeBase, ...activeCrop });
2586
2796
  const activeSrcSet = rawFallback ? void 0 : heroSrcSet(activeUrl, activeCrop);
2587
- const fitStyle = applyImageTransform(useMobile ? mobileTransform ?? transform : transform, fit);
2797
+ const fitStyle = {
2798
+ objectFit: fit,
2799
+ ...applyImageTransform(useMobile ? mobileTransform ?? transform : transform, fit)
2800
+ };
2588
2801
  return /* @__PURE__ */ jsx(
2589
2802
  "img",
2590
2803
  {
@@ -2925,6 +3138,20 @@ function Form({
2925
3138
  }
2926
3139
  );
2927
3140
  }
3141
+
3142
+ // src/utils/routes.ts
3143
+ function productHref(slugOrId) {
3144
+ if (!slugOrId) return "/products";
3145
+ return `/products/${slugOrId}`;
3146
+ }
3147
+ function collectionHref(category) {
3148
+ if (!category) return "/collections";
3149
+ if (typeof category === "string") {
3150
+ return category ? `/collections/${category}` : "/collections";
3151
+ }
3152
+ const key = category.slug || category.id;
3153
+ return key ? `/collections/${key}` : "/collections";
3154
+ }
2928
3155
  function joinClass(...names) {
2929
3156
  return names.filter(Boolean).join(" ");
2930
3157
  }
@@ -2935,7 +3162,7 @@ function ProductCard({
2935
3162
  slots,
2936
3163
  imageSizes
2937
3164
  }) {
2938
- const target = href ?? `/products/${product.slug}`;
3165
+ const target = href ?? productHref(product.slug);
2939
3166
  const firstImage = product.images?.[0];
2940
3167
  const inStock = product.in_stock;
2941
3168
  const badge = slots?.badge !== void 0 ? slots.badge : inStock ? null : /* @__PURE__ */ jsx("span", { className: "numu-product-card__badge", children: "Sold out" });
@@ -3548,7 +3775,19 @@ function resolveSourcePath(path, ctx) {
3548
3775
  return null;
3549
3776
  }
3550
3777
  }
3778
+ function resolveMetafield(metafields, field) {
3779
+ const address = field.slice("metafield:".length);
3780
+ const dot = address.indexOf(".");
3781
+ if (dot === -1) return null;
3782
+ const namespace = address.slice(0, dot);
3783
+ const key = address.slice(dot + 1);
3784
+ const hit = (metafields ?? []).find(
3785
+ (m) => m.namespace === namespace && m.key === key
3786
+ );
3787
+ return hit ? hit.value ?? null : null;
3788
+ }
3551
3789
  function resolveProductField(p, field) {
3790
+ if (field.startsWith("metafield:")) return resolveMetafield(p.metafields, field);
3552
3791
  switch (field) {
3553
3792
  case "title":
3554
3793
  case "name":
@@ -3571,6 +3810,7 @@ function resolveProductField(p, field) {
3571
3810
  }
3572
3811
  }
3573
3812
  function resolveCollectionField(c, field) {
3813
+ if (field.startsWith("metafield:")) return resolveMetafield(c.metafields, field);
3574
3814
  switch (field) {
3575
3815
  case "title":
3576
3816
  case "name":
@@ -3753,6 +3993,50 @@ function assetUrl(name) {
3753
3993
  return `${cleanBase}${filename}`;
3754
3994
  }
3755
3995
 
3996
+ // src/utils/templates.ts
3997
+ function resolveSections(group) {
3998
+ if (!group) return [];
3999
+ if (Array.isArray(group.sections)) {
4000
+ return group.sections.map((instance, idx) => ({
4001
+ id: `${instance.type}-${idx}`,
4002
+ instance
4003
+ }));
4004
+ }
4005
+ const map = group.sections ?? {};
4006
+ const order = group.order ?? Object.keys(map);
4007
+ const out = [];
4008
+ for (const id of order) {
4009
+ const instance = map[id];
4010
+ if (instance) out.push({ id, instance });
4011
+ }
4012
+ return out;
4013
+ }
4014
+ function selectTemplateSections(hostTemplate, builtinTemplate, isKnown) {
4015
+ const hostSections = resolveSections(hostTemplate);
4016
+ if (hostSections.length === 0) {
4017
+ return resolveSections(builtinTemplate);
4018
+ }
4019
+ const anyKnown = hostSections.some(({ instance }) => isKnown(instance.type));
4020
+ if (!anyKnown) return resolveSections(builtinTemplate);
4021
+ return hostSections.filter(({ instance }) => isKnown(instance.type));
4022
+ }
4023
+ function selectChromeSections(options) {
4024
+ const { hostGroup, presetGroup, inline, templates, isChrome, isKnown } = options;
4025
+ const known = (list) => list.filter(({ instance }) => isKnown(instance.type));
4026
+ const fromHost = known(resolveSections(hostGroup));
4027
+ if (fromHost.length > 0) return fromHost;
4028
+ if (inline && inline.length > 0) return known(inline);
4029
+ const fromPreset = known(resolveSections(presetGroup));
4030
+ if (fromPreset.length > 0) return fromPreset;
4031
+ for (const template of templates ?? []) {
4032
+ const borrowed = known(resolveSections(template)).filter(
4033
+ ({ instance }) => isChrome(instance.type)
4034
+ );
4035
+ if (borrowed.length > 0) return borrowed;
4036
+ }
4037
+ return [];
4038
+ }
4039
+
3756
4040
  // src/utils/locales.ts
3757
4041
  function flattenMessages(source, prefix = "") {
3758
4042
  const out = {};
@@ -3797,6 +4081,6 @@ function buildLocaleBundle(modules) {
3797
4081
  return bundle;
3798
4082
  }
3799
4083
 
3800
- export { AddToCartButton, Block, CollectionCard, CollectionProvider, CurrencySwitcher, EditableImage, EditableText, Form, HeroMedia, ICON_NAMES, Icon, IconMap, Image, LOGO_SHAPE_OPTIONS, LOGO_SIZE_OPTIONS, Link, LocaleSwitcher, Logo, MAX_BLOCK_DEPTH, Money, NAVIGATE_EVENT, NuMuProvider, ProductCard, ProductProvider, RichText, Section, SectionContext, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, buildThemeElement, clearSdkSingleton, collectBlocks, collectSections, computeGlobalStyleTokens, defaultVariant, defineBlock, defineSection, defineThemeEntry, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, logoImgStyle, logoStyleTokens, mountTheme, pickTranslations, publishVariantSelection, readVariantSelection, registerReactSingleton, registerSdkSingleton, requestNavigate, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSizeChart, resolveSourcePath, sanitizeHtml, useAnalytics, useApp, useCachedResource, useCart, useCheckout, useCollection, useCollectionOptional, useCurrency, useCurrentTemplate, useCustomerActions, useCustomerAddresses, useGiftCardBalance, useImage, useMoney, useNavigation, useOrder, useOrders, useProduct, useProductOptional, useProductSizeChart, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionGroup, useSectionOptional, useShippingRates, useVariantSelection, useWishlist };
4084
+ export { AddToCartButton, Block, CollectionCard, CollectionProvider, CurrencySwitcher, EditableImage, EditableText, Form, HeroMedia, ICON_NAMES, Icon, IconMap, Image, LOGO_SHAPE_OPTIONS, LOGO_SIZE_OPTIONS, Link, LocaleSwitcher, Logo, MAX_BLOCK_DEPTH, Money, NAVIGATE_EVENT, NuMuProvider, ProductCard, ProductProvider, RichText, Section, SectionContext, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, buildThemeElement, centsToMajor, clearSdkSingleton, collectBlocks, collectSections, collectionHref, computeGlobalStyleTokens, defaultVariant, defineBlock, defineSection, defineThemeEntry, dynamicSource, eligibleUnitsInCart, findVariantByOptions, flattenMessages, focalSrc, formatMoney, formatMoneyMajor, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, logoImgStyle, logoStyleTokens, majorToCents, mountTheme, multibuyOffers, offerBeatsRegularPrice, offerIncludesProduct, offerProgress, pickTranslations, productHref, publishVariantSelection, readVariantSelection, registerReactSingleton, registerSdkSingleton, requestNavigate, resolveDynamicValue, resolveFontStack, resolveSections, resolveSettingsMap, resolveSizeChart, resolveSourcePath, sanitizeHtml, selectChromeSections, selectTemplateSections, useActivePromotions, useAnalytics, useApp, useArticle, useArticles, useBlog, useBlogs, useCachedResource, useCart, useCheckout, useCollection, useCollectionOptional, useCurrency, useCurrentTemplate, useCustomerActions, useCustomerAddresses, useGiftCardBalance, useImage, useListingHeading, useMetafield, useMetafields, useMoney, useNavigation, useOrder, useOrders, useProduct, useProductOptional, useProductSizeChart, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionGroup, useSectionOptional, useShippingRates, useVariantSelection, useWishlist };
3801
4085
  //# sourceMappingURL=index.mjs.map
3802
4086
  //# sourceMappingURL=index.mjs.map