{"version":3,"file":"useMoney.mjs","sources":["../../src/useMoney.tsx"],"sourcesContent":["import {useMemo} from 'react';\nimport {useShop} from './ShopifyProvider.js';\nimport {CurrencyCode, MoneyV2} from './storefront-api-types.js';\n\nexport type UseMoneyValue = {\n  /**\n   * The currency code from the `MoneyV2` object.\n   */\n  currencyCode: CurrencyCode;\n  /**\n   * The name for the currency code, returned by `Intl.NumberFormat`.\n   */\n  currencyName?: string;\n  /**\n   * The currency symbol returned by `Intl.NumberFormat`.\n   */\n  currencySymbol?: string;\n  /**\n   * The currency narrow symbol returned by `Intl.NumberFormat`.\n   */\n  currencyNarrowSymbol?: string;\n  /**\n   * The localized amount, without any currency symbols or non-number types from the `Intl.NumberFormat.formatToParts` parts.\n   */\n  amount: string;\n  /**\n   * All parts returned by `Intl.NumberFormat.formatToParts`.\n   */\n  parts: Intl.NumberFormatPart[];\n  /**\n   * A string returned by `new Intl.NumberFormat` for the amount and currency code,\n   * using the `locale` value in the [`LocalizationProvider` component](https://shopify.dev/api/hydrogen/components/localization/localizationprovider).\n   */\n  localizedString: string;\n  /**\n   * The `MoneyV2` object provided as an argument to the hook.\n   */\n  original: MoneyV2;\n  /**\n   * A string with trailing zeros removed from the fractional part, if any exist. If there are no trailing zeros, then the fractional part remains.\n   * For example, `$640.00` turns into `$640`.\n   * `$640.42` remains `$640.42`.\n   */\n  withoutTrailingZeros: string;\n  /**\n   * A string without currency and without trailing zeros removed from the fractional part, if any exist. If there are no trailing zeros, then the fractional part remains.\n   * For example, `$640.00` turns into `640`.\n   * `$640.42` turns into `640.42`.\n   */\n  withoutTrailingZerosAndCurrency: string;\n};\n\n/**\n * The `useMoney` hook takes a [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2) and returns a\n * default-formatted string of the amount with the correct currency indicator, along with some of the parts provided by\n * [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat).\n * Uses `locale` from `ShopifyProvider`\n */\nexport function useMoney(money: MoneyV2): UseMoneyValue {\n  const {locale} = useShop();\n\n  if (!locale) {\n    throw new Error(\n      `useMoney(): Unable to get 'locale' from 'useShop()', which means that 'locale' was not passed to '<ShopifyProvider/>'. 'locale' is required for 'useMoney()' to work`\n    );\n  }\n\n  const amount = parseFloat(money.amount);\n\n  const options = useMemo(\n    () => ({\n      style: 'currency',\n      currency: money.currencyCode,\n    }),\n    [money.currencyCode]\n  );\n\n  const defaultFormatter = useLazyFormatter(locale, options);\n\n  const nameFormatter = useLazyFormatter(locale, {\n    ...options,\n    currencyDisplay: 'name',\n  });\n\n  const narrowSymbolFormatter = useLazyFormatter(locale, {\n    ...options,\n    currencyDisplay: 'narrowSymbol',\n  });\n\n  const withoutTrailingZerosFormatter = useLazyFormatter(locale, {\n    ...options,\n    minimumFractionDigits: 0,\n    maximumFractionDigits: 0,\n  });\n\n  const withoutCurrencyFormatter = useLazyFormatter(locale);\n\n  const withoutTrailingZerosOrCurrencyFormatter = useLazyFormatter(locale, {\n    minimumFractionDigits: 0,\n    maximumFractionDigits: 0,\n  });\n\n  const isPartCurrency = (part: Intl.NumberFormatPart) =>\n    part.type === 'currency';\n\n  // By wrapping these properties in functions, we only\n  // create formatters if they are going to be used.\n  const lazyFormatters = useMemo(\n    () => ({\n      original: () => money,\n      currencyCode: () => money.currencyCode,\n\n      localizedString: () => defaultFormatter().format(amount),\n\n      parts: () => defaultFormatter().formatToParts(amount),\n\n      withoutTrailingZeros: () =>\n        amount % 1 === 0\n          ? withoutTrailingZerosFormatter().format(amount)\n          : defaultFormatter().format(amount),\n\n      withoutTrailingZerosAndCurrency: () =>\n        amount % 1 === 0\n          ? withoutTrailingZerosOrCurrencyFormatter().format(amount)\n          : withoutCurrencyFormatter().format(amount),\n\n      currencyName: () =>\n        nameFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n        money.currencyCode, // e.g. \"US dollars\"\n\n      currencySymbol: () =>\n        defaultFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n        money.currencyCode, // e.g. \"USD\"\n\n      currencyNarrowSymbol: () =>\n        narrowSymbolFormatter().formatToParts(amount).find(isPartCurrency)\n          ?.value ?? '', // e.g. \"$\"\n\n      amount: () =>\n        defaultFormatter()\n          .formatToParts(amount)\n          .filter((part) =>\n            ['decimal', 'fraction', 'group', 'integer', 'literal'].includes(\n              part.type\n            )\n          )\n          .map((part) => part.value)\n          .join(''),\n    }),\n    [\n      money,\n      amount,\n      nameFormatter,\n      defaultFormatter,\n      narrowSymbolFormatter,\n      withoutCurrencyFormatter,\n      withoutTrailingZerosFormatter,\n      withoutTrailingZerosOrCurrencyFormatter,\n    ]\n  );\n\n  // Call functions automatically when the properties are accessed\n  // to keep these functions as an implementation detail.\n  return useMemo(\n    () =>\n      new Proxy(lazyFormatters as unknown as UseMoneyValue, {\n        get: (target, key) => Reflect.get(target, key)?.call(null),\n      }),\n    [lazyFormatters]\n  );\n}\n\nfunction useLazyFormatter(locale: string, options?: Intl.NumberFormatOptions) {\n  return useMemo(() => {\n    let memoized: Intl.NumberFormat;\n    return () => (memoized ??= new Intl.NumberFormat(locale, options));\n  }, [locale, options]);\n}\n"],"names":["useMoney","money","locale","useShop","Error","amount","parseFloat","options","useMemo","style","currency","currencyCode","defaultFormatter","useLazyFormatter","nameFormatter","currencyDisplay","narrowSymbolFormatter","withoutTrailingZerosFormatter","minimumFractionDigits","maximumFractionDigits","withoutCurrencyFormatter","withoutTrailingZerosOrCurrencyFormatter","isPartCurrency","part","type","lazyFormatters","original","localizedString","format","parts","formatToParts","withoutTrailingZeros","withoutTrailingZerosAndCurrency","currencyName","find","value","currencySymbol","currencyNarrowSymbol","filter","includes","map","join","Proxy","get","target","key","Reflect","call","memoized","Intl","NumberFormat"],"mappings":"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"}