@numueg/theme-sdk 0.2.3 → 0.3.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/CHANGELOG.md +29 -1
- package/dist/{entities-C8B2U-V0.d.mts → entities-6MGANln7.d.mts} +45 -1
- package/dist/{entities-C8B2U-V0.d.ts → entities-6MGANln7.d.ts} +45 -1
- package/dist/index.cjs +123 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +138 -5
- package/dist/index.d.ts +138 -5
- package/dist/index.mjs +120 -46
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/v2-compat.cjs.map +1 -1
- package/dist/v2-compat.d.mts +1 -1
- package/dist/v2-compat.d.ts +1 -1
- package/dist/v2-compat.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, forwardRef, useState, useImperativeHandle, useEffect, useCallback, useMemo, useRef, useContext, StrictMode, createElement, Component } from 'react';
|
|
2
|
-
import { createRoot } from 'react-dom/client';
|
|
2
|
+
import { hydrateRoot, createRoot } from 'react-dom/client';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
// src/types/theme.ts
|
|
@@ -526,9 +526,8 @@ function toNavigationItem(raw, locale) {
|
|
|
526
526
|
url: raw.url || "/",
|
|
527
527
|
resource_type: mapResourceType(raw.type),
|
|
528
528
|
resource_handle: raw.resource_id ?? null,
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
)
|
|
529
|
+
target_visible: raw.target_visible !== false,
|
|
530
|
+
children: (raw.children ?? []).map((child) => toNavigationItem(child, locale)).filter((child) => child.target_visible)
|
|
532
531
|
};
|
|
533
532
|
}
|
|
534
533
|
function useNavigation(handle, options) {
|
|
@@ -538,7 +537,8 @@ function useNavigation(handle, options) {
|
|
|
538
537
|
const hostProvidedAny = !!navMap && Object.keys(navMap).length > 0;
|
|
539
538
|
const rawItems = handle ? navMap?.[handle] : void 0;
|
|
540
539
|
const hostItems = useMemo(() => {
|
|
541
|
-
if (rawItems)
|
|
540
|
+
if (rawItems)
|
|
541
|
+
return rawItems.map((it) => toNavigationItem(it, locale)).filter((it) => it.target_visible);
|
|
542
542
|
if (hostProvidedAny) return [];
|
|
543
543
|
return null;
|
|
544
544
|
}, [rawItems, hostProvidedAny, locale]);
|
|
@@ -940,6 +940,29 @@ function useRelatedProducts(productId, options = {}) {
|
|
|
940
940
|
}, [productId, limit]);
|
|
941
941
|
return { items, loading, error };
|
|
942
942
|
}
|
|
943
|
+
function useProductSizeChart(productOverride) {
|
|
944
|
+
const ctxProduct = useProductOptional();
|
|
945
|
+
const product = productOverride ?? ctxProduct;
|
|
946
|
+
const shop = useShop();
|
|
947
|
+
const storeSettings = shop?.settings;
|
|
948
|
+
return useMemo(
|
|
949
|
+
() => resolveSizeChart(product?.attributes, storeSettings),
|
|
950
|
+
[product?.attributes, storeSettings]
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
function hasRows(c) {
|
|
954
|
+
return !!c && typeof c === "object" && Array.isArray(c.rows) && c.rows.length > 0;
|
|
955
|
+
}
|
|
956
|
+
function resolveSizeChart(productAttributes, storeSettings) {
|
|
957
|
+
const product = productAttributes?.size_chart;
|
|
958
|
+
const storeDefault = storeSettings?.size_chart;
|
|
959
|
+
if (product?.mode === "off") return null;
|
|
960
|
+
if (product?.mode === "custom") return hasRows(product) ? product : null;
|
|
961
|
+
if (product?.mode === "default") return hasRows(storeDefault) ? storeDefault : null;
|
|
962
|
+
if (hasRows(product)) return product;
|
|
963
|
+
if (hasRows(storeDefault)) return storeDefault;
|
|
964
|
+
return null;
|
|
965
|
+
}
|
|
943
966
|
var COOKIE_NAME = "numu_currency";
|
|
944
967
|
var COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
|
|
945
968
|
function readCookie(name) {
|
|
@@ -1452,7 +1475,15 @@ function normalizeCartFromServer(cart) {
|
|
|
1452
1475
|
subtotal: toMajor(cart.subtotal),
|
|
1453
1476
|
total: toMajor(cart.total),
|
|
1454
1477
|
...cart.discount_amount != null ? { discount_amount: toMajor(cart.discount_amount) } : {},
|
|
1455
|
-
items: Array.isArray(cart.items) ? cart.items.map((it) =>
|
|
1478
|
+
items: Array.isArray(cart.items) ? cart.items.map((it) => {
|
|
1479
|
+
const raw = it;
|
|
1480
|
+
return {
|
|
1481
|
+
...it,
|
|
1482
|
+
name: raw.name || raw.product_name || "",
|
|
1483
|
+
price: toMajor(raw.price ?? raw.unit_price),
|
|
1484
|
+
variant_name: raw.variant_name ?? void 0
|
|
1485
|
+
};
|
|
1486
|
+
}) : []
|
|
1456
1487
|
};
|
|
1457
1488
|
}
|
|
1458
1489
|
function unwrapCart(json) {
|
|
@@ -1989,6 +2020,9 @@ function injectFontLink(href) {
|
|
|
1989
2020
|
link.setAttribute("data-numu-font", "");
|
|
1990
2021
|
document.head.appendChild(link);
|
|
1991
2022
|
}
|
|
2023
|
+
function lookupFontStack(value) {
|
|
2024
|
+
return FONT_REGISTRY[value]?.stack ?? value;
|
|
2025
|
+
}
|
|
1992
2026
|
function resolveFontStack(value) {
|
|
1993
2027
|
const entry = FONT_REGISTRY[value];
|
|
1994
2028
|
if (entry) {
|
|
@@ -1997,39 +2031,69 @@ function resolveFontStack(value) {
|
|
|
1997
2031
|
}
|
|
1998
2032
|
return value;
|
|
1999
2033
|
}
|
|
2000
|
-
function
|
|
2001
|
-
|
|
2002
|
-
const
|
|
2034
|
+
function computeGlobalStyleTokens(globalSettings) {
|
|
2035
|
+
const cssVars = {};
|
|
2036
|
+
const fontHrefs = [];
|
|
2037
|
+
if (!globalSettings || typeof globalSettings !== "object") {
|
|
2038
|
+
return { cssVars, fontHrefs };
|
|
2039
|
+
}
|
|
2040
|
+
const pushHref = (href) => {
|
|
2041
|
+
if (href && !fontHrefs.includes(href)) fontHrefs.push(href);
|
|
2042
|
+
};
|
|
2003
2043
|
for (const [key, value] of Object.entries(globalSettings)) {
|
|
2004
2044
|
if (!key || key.startsWith("__")) continue;
|
|
2005
2045
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
2006
2046
|
for (const [role, c] of Object.entries(value)) {
|
|
2007
|
-
if (isColorValue(c))
|
|
2047
|
+
if (isColorValue(c)) cssVars[`--scheme-${key}-${role}`] = c;
|
|
2008
2048
|
}
|
|
2009
2049
|
continue;
|
|
2010
2050
|
}
|
|
2011
2051
|
if (isColorValue(value)) {
|
|
2012
|
-
|
|
2052
|
+
cssVars[`--theme-${key}`] = value.trim();
|
|
2013
2053
|
const role = COLOR_ROLE_ALIASES[key];
|
|
2014
|
-
if (role)
|
|
2054
|
+
if (role) cssVars[`--theme-color-${role}`] = value.trim();
|
|
2015
2055
|
continue;
|
|
2016
2056
|
}
|
|
2017
2057
|
if (isFontToken(value)) {
|
|
2018
|
-
const
|
|
2019
|
-
|
|
2058
|
+
const entry = FONT_REGISTRY[value];
|
|
2059
|
+
cssVars[`--theme-${key}`] = entry.stack;
|
|
2020
2060
|
const role = FONT_ROLE_ALIASES[key];
|
|
2021
|
-
if (role)
|
|
2061
|
+
if (role) cssVars[`--theme-font-${role}`] = entry.stack;
|
|
2062
|
+
pushHref(entry.href);
|
|
2022
2063
|
continue;
|
|
2023
2064
|
}
|
|
2024
2065
|
if (typeof value === "string" || typeof value === "number") {
|
|
2025
2066
|
const v = String(value).trim();
|
|
2026
|
-
if (v)
|
|
2067
|
+
if (v) cssVars[`--theme-${key}`] = v;
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
for (const id of ["heading_font", "body_font"]) {
|
|
2071
|
+
const value = globalSettings[id];
|
|
2072
|
+
if (typeof value === "string" && value.trim()) {
|
|
2073
|
+
cssVars[`--theme-${id}`] = lookupFontStack(value);
|
|
2074
|
+
pushHref(FONT_REGISTRY[value]?.href);
|
|
2027
2075
|
}
|
|
2028
2076
|
}
|
|
2077
|
+
return { cssVars, fontHrefs };
|
|
2078
|
+
}
|
|
2079
|
+
function applyGlobalStyleTokens(globalSettings, el) {
|
|
2080
|
+
if (!el || !globalSettings || typeof globalSettings !== "object") return;
|
|
2081
|
+
const { cssVars, fontHrefs } = computeGlobalStyleTokens(globalSettings);
|
|
2082
|
+
const style = el.style;
|
|
2083
|
+
for (const [prop, value] of Object.entries(cssVars)) {
|
|
2084
|
+
style.setProperty(prop, value);
|
|
2085
|
+
}
|
|
2086
|
+
for (const href of fontHrefs) injectFontLink(href);
|
|
2029
2087
|
}
|
|
2030
2088
|
function pickStore(ctx) {
|
|
2031
2089
|
const s = ctx.storeData ?? ctx.store;
|
|
2032
|
-
if (s)
|
|
2090
|
+
if (s) {
|
|
2091
|
+
const raw = s;
|
|
2092
|
+
if (!raw.currency && raw.default_currency) {
|
|
2093
|
+
return { ...raw, currency: raw.default_currency };
|
|
2094
|
+
}
|
|
2095
|
+
return s;
|
|
2096
|
+
}
|
|
2033
2097
|
return {
|
|
2034
2098
|
id: "unknown",
|
|
2035
2099
|
name: "Store",
|
|
@@ -2064,19 +2128,9 @@ var ThemeMountBridge = forwardRef(function ThemeMountBridge2({ ctx, mountEl, ren
|
|
|
2064
2128
|
[]
|
|
2065
2129
|
);
|
|
2066
2130
|
useEffect(() => {
|
|
2131
|
+
if (!mountEl) return;
|
|
2067
2132
|
const gs = themeSettings.global_settings ?? {};
|
|
2068
2133
|
applyGlobalStyleTokens(gs, mountEl);
|
|
2069
|
-
const headingFont = gs.heading_font;
|
|
2070
|
-
if (typeof headingFont === "string" && headingFont.trim()) {
|
|
2071
|
-
mountEl.style.setProperty(
|
|
2072
|
-
"--theme-heading_font",
|
|
2073
|
-
resolveFontStack(headingFont)
|
|
2074
|
-
);
|
|
2075
|
-
}
|
|
2076
|
-
const bodyFont = gs.body_font;
|
|
2077
|
-
if (typeof bodyFont === "string" && bodyFont.trim()) {
|
|
2078
|
-
mountEl.style.setProperty("--theme-body_font", resolveFontStack(bodyFont));
|
|
2079
|
-
}
|
|
2080
2134
|
}, [themeSettings, mountEl]);
|
|
2081
2135
|
const store = pickStore(ctx);
|
|
2082
2136
|
const template = pickTemplate(ctx);
|
|
@@ -2106,22 +2160,22 @@ var ThemeMountBridge = forwardRef(function ThemeMountBridge2({ ctx, mountEl, ren
|
|
|
2106
2160
|
}
|
|
2107
2161
|
);
|
|
2108
2162
|
});
|
|
2163
|
+
function buildThemeElement(ctx, mountEl, renderApp, ref) {
|
|
2164
|
+
return /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(ThemeMountBridge, { ctx, mountEl, renderApp, ref }) });
|
|
2165
|
+
}
|
|
2109
2166
|
function mountTheme(el, ctx, renderApp) {
|
|
2110
|
-
const root = createRoot(el);
|
|
2111
2167
|
const handleRef = { current: null };
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
) })
|
|
2124
|
-
);
|
|
2168
|
+
const element = buildThemeElement(ctx, el, renderApp, (h) => {
|
|
2169
|
+
handleRef.current = h;
|
|
2170
|
+
});
|
|
2171
|
+
const shouldHydrate = ctx.hydrate === true && el.firstElementChild !== null;
|
|
2172
|
+
let root;
|
|
2173
|
+
if (shouldHydrate) {
|
|
2174
|
+
root = hydrateRoot(el, element);
|
|
2175
|
+
} else {
|
|
2176
|
+
root = createRoot(el);
|
|
2177
|
+
root.render(element);
|
|
2178
|
+
}
|
|
2125
2179
|
return {
|
|
2126
2180
|
applyDraft: (next) => handleRef.current?.applyDraft(next),
|
|
2127
2181
|
cleanup: () => {
|
|
@@ -2130,6 +2184,14 @@ function mountTheme(el, ctx, renderApp) {
|
|
|
2130
2184
|
}
|
|
2131
2185
|
};
|
|
2132
2186
|
}
|
|
2187
|
+
|
|
2188
|
+
// src/entry.tsx
|
|
2189
|
+
function defineThemeEntry(renderApp) {
|
|
2190
|
+
return {
|
|
2191
|
+
mount: (el, ctx) => mountTheme(el, ctx, renderApp),
|
|
2192
|
+
createApp: (ctx) => buildThemeElement(ctx, null, renderApp)
|
|
2193
|
+
};
|
|
2194
|
+
}
|
|
2133
2195
|
function CollectionProvider({ collection, children }) {
|
|
2134
2196
|
return /* @__PURE__ */ jsx(CollectionContext.Provider, { value: collection, children });
|
|
2135
2197
|
}
|
|
@@ -2753,7 +2815,14 @@ function sanitizeHtmlServer(input) {
|
|
|
2753
2815
|
return s;
|
|
2754
2816
|
}
|
|
2755
2817
|
function RichText({ html, className, as = "div" }) {
|
|
2756
|
-
const
|
|
2818
|
+
const [domReady, setDomReady] = useState(false);
|
|
2819
|
+
useEffect(() => {
|
|
2820
|
+
setDomReady(true);
|
|
2821
|
+
}, []);
|
|
2822
|
+
const safe = useMemo(
|
|
2823
|
+
() => domReady ? sanitizeHtml(html || "") : sanitizeHtmlServer(html || ""),
|
|
2824
|
+
[html, domReady]
|
|
2825
|
+
);
|
|
2757
2826
|
if (!safe) return null;
|
|
2758
2827
|
const Tag = as;
|
|
2759
2828
|
return /* @__PURE__ */ jsx(
|
|
@@ -3419,8 +3488,13 @@ function collectBlocks(modules) {
|
|
|
3419
3488
|
|
|
3420
3489
|
// src/utils/assetUrl.ts
|
|
3421
3490
|
function getRuntime() {
|
|
3422
|
-
if (typeof window
|
|
3423
|
-
|
|
3491
|
+
if (typeof window !== "undefined") {
|
|
3492
|
+
return window;
|
|
3493
|
+
}
|
|
3494
|
+
if (typeof globalThis !== "undefined") {
|
|
3495
|
+
return globalThis;
|
|
3496
|
+
}
|
|
3497
|
+
return {};
|
|
3424
3498
|
}
|
|
3425
3499
|
function assetUrl(name) {
|
|
3426
3500
|
if (!name) return "";
|
|
@@ -3481,6 +3555,6 @@ function buildLocaleBundle(modules) {
|
|
|
3481
3555
|
return bundle;
|
|
3482
3556
|
}
|
|
3483
3557
|
|
|
3484
|
-
export { AddToCartButton, Block, CartContext, CollectionCard, CollectionContext, CollectionProvider, CurrencySwitcher, CustomerContext, EditableImage, EditableText, Form, ICON_NAMES, Icon, IconMap, Image, Link, LocaleSwitcher, LocalizationContext, MAX_BLOCK_DEPTH, Money, NavigationContext, NuMuProvider, PageContext, ProductCard, ProductContext, ProductProvider, RichText, Section, SectionContext, ShopContext, ThemeSettingsContext, applyGlobalStyleTokens, applyImageTransform, asImageTransform, assetUrl, availableValues, buildLocaleBundle, clearSdkSingleton, collectBlocks, collectSections, defaultVariant, defineBlock, defineSection, dynamicSource, findVariantByOptions, flattenMessages, focalSrc, getReactSingleton, getSdkSingleton, isDefinedBlock, isDefinedSection, isDynamicSource, isSdkAvailable, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSourcePath, resolveThemeSettings, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
|
|
3558
|
+
export { AddToCartButton, Block, CartContext, CollectionCard, CollectionContext, CollectionProvider, CurrencySwitcher, CustomerContext, EditableImage, EditableText, Form, ICON_NAMES, Icon, IconMap, Image, Link, LocaleSwitcher, LocalizationContext, MAX_BLOCK_DEPTH, Money, NavigationContext, NuMuProvider, PageContext, ProductCard, ProductContext, ProductProvider, RichText, Section, SectionContext, ShopContext, ThemeSettingsContext, 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, mountTheme, pickTranslations, registerReactSingleton, registerSdkSingleton, resolveDynamicValue, resolveFontStack, resolveSettingsMap, resolveSizeChart, resolveSourcePath, resolveThemeSettings, sanitizeHtml, useAnalytics, useApp, useCart, useCheckout, useCollection, useCollectionOptional, useCollections, useCurrency, useCurrentTemplate, useCustomer, useCustomerActions, useCustomerAddresses, useDirection, useFieldTranslation, useGiftCardBalance, useImage, useLocale, useLocalization, useMoney, useNavigation, useNumberFormat, useOrder, useOrders, usePage, useProduct, useProductOptional, useProductSizeChart, useProducts, useRelatedProducts, useReorder, useResolvedSettings, useSearch, useSection, useSectionOptional, useShippingRates, useShop, useThemeSettings, useTranslation, useVariantSelection, useWishlist };
|
|
3485
3559
|
//# sourceMappingURL=index.mjs.map
|
|
3486
3560
|
//# sourceMappingURL=index.mjs.map
|