UNPKG

@shopify/hydrogen-react

Version:

React components, hooks, and utilities for creating custom Shopify storefronts

160 lines (159 loc) 5.67 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const React = require("react"); const ShopifyProvider = require("./ShopifyProvider.js"); function useMoney(money) { const { countryIsoCode, languageIsoCode } = ShopifyProvider.useShop(); const locale = languageIsoCode.includes("_") ? languageIsoCode.replace("_", "-") : `${languageIsoCode}-${countryIsoCode}`; if (!locale) { throw new Error( `useMoney(): Unable to get 'locale' from 'useShop()', which means that 'locale' was not passed to '<ShopifyProvider/>'. 'locale' is required for 'useMoney()' to work` ); } const amount = parseFloat(money.amount); let isCurrencySupported = true; try { new Intl.NumberFormat(locale, { style: "currency", currency: money.currencyCode }); } catch (e) { if (e instanceof RangeError && e.message.includes("currency")) { isCurrencySupported = false; } } const { defaultFormatter, nameFormatter, narrowSymbolFormatter, withoutTrailingZerosFormatter, withoutCurrencyFormatter, withoutTrailingZerosOrCurrencyFormatter } = React.useMemo(() => { const options = isCurrencySupported ? { style: "currency", currency: money.currencyCode } : { style: "decimal", minimumFractionDigits: 2, maximumFractionDigits: 2 }; return { defaultFormatter: getLazyFormatter(locale, options), nameFormatter: getLazyFormatter(locale, { ...options, currencyDisplay: "name" }), narrowSymbolFormatter: getLazyFormatter(locale, { ...options, currencyDisplay: "narrowSymbol" }), withoutTrailingZerosFormatter: getLazyFormatter(locale, { ...options, minimumFractionDigits: 0, maximumFractionDigits: 0 }), withoutCurrencyFormatter: getLazyFormatter(locale, { minimumFractionDigits: 2, maximumFractionDigits: 2 }), withoutTrailingZerosOrCurrencyFormatter: getLazyFormatter(locale, { minimumFractionDigits: 0, maximumFractionDigits: 0 }) }; }, [money.currencyCode, locale, isCurrencySupported]); const isPartCurrency = (part) => part.type === "currency"; const lazyFormatters = React.useMemo( () => ({ original: () => money, currencyCode: () => money.currencyCode, localizedString: () => { const formatted = defaultFormatter().format(amount); return isCurrencySupported ? formatted : `${formatted} ${money.currencyCode}`; }, parts: () => { const parts = defaultFormatter().formatToParts(amount); if (!isCurrencySupported) { parts.push( { type: "literal", value: " " }, { type: "currency", value: money.currencyCode } ); } return parts; }, withoutTrailingZeros: () => { const formatted = amount % 1 === 0 ? withoutTrailingZerosFormatter().format(amount) : defaultFormatter().format(amount); return isCurrencySupported ? formatted : `${formatted} ${money.currencyCode}`; }, withoutTrailingZerosAndCurrency: () => amount % 1 === 0 ? withoutTrailingZerosOrCurrencyFormatter().format(amount) : withoutCurrencyFormatter().format(amount), currencyName: () => { var _a; return ((_a = nameFormatter().formatToParts(amount).find(isPartCurrency)) == null ? void 0 : _a.value) ?? money.currencyCode; }, // e.g. "US dollars" currencySymbol: () => { var _a; return ((_a = defaultFormatter().formatToParts(amount).find(isPartCurrency)) == null ? void 0 : _a.value) ?? money.currencyCode; }, // e.g. "USD" currencyNarrowSymbol: () => { var _a; return ((_a = narrowSymbolFormatter().formatToParts(amount).find(isPartCurrency)) == null ? void 0 : _a.value) ?? ""; }, // e.g. "$" amount: () => defaultFormatter().formatToParts(amount).filter( (part) => ["decimal", "fraction", "group", "integer", "literal"].includes( part.type ) ).map((part) => part.value).join("") }), [ money, amount, isCurrencySupported, nameFormatter, defaultFormatter, narrowSymbolFormatter, withoutCurrencyFormatter, withoutTrailingZerosFormatter, withoutTrailingZerosOrCurrencyFormatter ] ); return React.useMemo( () => new Proxy(lazyFormatters, { // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call get: (target, key) => { var _a; return (_a = Reflect.get(target, key)) == null ? void 0 : _a.call(null); } }), [lazyFormatters] ); } const formatterCache = /* @__PURE__ */ new Map(); function getLazyFormatter(locale, options) { const key = JSON.stringify([locale, options]); return function() { let formatter = formatterCache.get(key); if (!formatter) { try { formatter = new Intl.NumberFormat(locale, options); } catch (error) { if (error instanceof RangeError && error.message.includes("currency")) { const fallbackOptions = { ...options }; delete fallbackOptions.currency; delete fallbackOptions.currencyDisplay; delete fallbackOptions.currencySign; formatter = new Intl.NumberFormat(locale, fallbackOptions); } else { throw error; } } formatterCache.set(key, formatter); } return formatter; }; } exports.useMoney = useMoney; //# sourceMappingURL=useMoney.js.map