{"version":3,"file":"utils.mjs","sources":["../../../src/expressiveMoneyInput/amountInput/utils.ts"],"sourcesContent":["import { formatAmount } from '@transferwise/formatting';\nimport type { KeyboardEvent } from 'react';\n\nexport const getDecimalSeparator = (currency: string, locale: string): string | null => {\n  return formatAmount(1.1, currency, locale).replace(/\\p{Number}/gu, '');\n};\n\nexport const getGroupSeparator = (currency: string, locale: string): string | null => {\n  return formatAmount(10000000, currency, locale).replace(/\\p{Number}/gu, '')[0];\n};\n\nexport const getDecimalCount = (currency: string, locale: string): number => {\n  const decimalSeparator = getDecimalSeparator(currency, locale);\n  if (!decimalSeparator) {\n    return 0;\n  }\n  const parts = formatAmount(1.1, currency, locale).split(decimalSeparator);\n  return parts.length === 2 ? parts[1].length : 0;\n};\n\nexport const getEnteredDecimalsCount = (value: string, decimalSeparator: string) => {\n  return value.split(decimalSeparator)[1]?.length ?? 0;\n};\n\nexport const getUnformattedNumber = ({\n  value: formattedValue,\n  currency,\n  locale,\n}: {\n  value: string;\n  currency: string;\n  locale: string;\n}): number | null => {\n  const groupSeparator = getGroupSeparator(currency, locale);\n  const decimalSeparator = getDecimalSeparator(currency, locale);\n  if (!formattedValue) {\n    return null;\n  }\n\n  // parseFloat can't handle thousands separators\n  const withoutGroupSeparator = groupSeparator\n    ? formattedValue.replace(/ /gu, '').replace(new RegExp(`\\\\${groupSeparator}`, 'g'), '')\n    : formattedValue;\n\n  // parseFloat can only handle . as decimal separator\n  const withNormalisedDecimalSeparator = decimalSeparator\n    ? withoutGroupSeparator.replace(decimalSeparator, '.')\n    : withoutGroupSeparator;\n\n  const parsedValue = Number.parseFloat(withNormalisedDecimalSeparator);\n  return parsedValue;\n};\n\nexport const getFormattedString = ({\n  value: unformattedValue,\n  currency,\n  locale,\n  alwaysShowDecimals = false,\n}: {\n  value: number;\n  currency: string;\n  locale: string;\n  alwaysShowDecimals?: boolean;\n}): string => {\n  const decimalSeparator = getDecimalSeparator(currency, locale);\n  // formatAmount rounds extra decimals, so 1.999 will become 2. Instead we will manually strip extra decimals so that it becomes 1.99 after formatting\n  const decimalCount = getDecimalCount(currency, locale);\n  const unformattedString = unformattedValue.toString();\n\n  const [integerPart, decimalPart] = decimalSeparator\n    ? unformattedString.split(decimalSeparator)\n    : [unformattedString, undefined];\n\n  const formattedDecimalPart = decimalPart ? decimalPart.slice(0, decimalCount) : '';\n\n  const sanitisedUnformattedValue = Number.parseFloat(`${integerPart}.${formattedDecimalPart}`);\n\n  return formatAmount(sanitisedUnformattedValue, currency, locale, {\n    alwaysShowDecimals,\n  });\n};\n\nexport const isInputPossiblyOverflowing = ({\n  ref,\n  value,\n}: {\n  ref: React.RefObject<HTMLInputElement>;\n  value: string;\n}) => {\n  const textLength = value.length;\n  const inputWidth = ref.current?.clientWidth;\n  if (!inputWidth || !textLength) {\n    return;\n  }\n\n  const maxCharactersWithoutOverflow = Math.floor(inputWidth / 19);\n  return textLength > maxCharactersWithoutOverflow;\n};\n\nconst allowedInputKeys = new Set([\n  'Backspace',\n  'Delete',\n  ',',\n  '.',\n  'ArrowLeft',\n  'ArrowRight',\n  'Enter',\n  'Tab',\n]);\n\nexport const isAllowedInputKey = (e: KeyboardEvent<HTMLInputElement>) => {\n  const { metaKey, key, ctrlKey } = e;\n  const isNumberKey = !Number.isNaN(Number.parseInt(key, 10));\n\n  return isNumberKey || metaKey || ctrlKey || allowedInputKeys.has(key);\n};\n"],"names":["getDecimalSeparator","currency","locale","formatAmount","replace","getGroupSeparator","getDecimalCount","decimalSeparator","parts","split","length","getEnteredDecimalsCount","value","getUnformattedNumber","formattedValue","groupSeparator","withoutGroupSeparator","RegExp","withNormalisedDecimalSeparator","parsedValue","Number","parseFloat","getFormattedString","unformattedValue","alwaysShowDecimals","decimalCount","unformattedString","toString","integerPart","decimalPart","undefined","formattedDecimalPart","slice","sanitisedUnformattedValue","isInputPossiblyOverflowing","ref","textLength","inputWidth","current","clientWidth","maxCharactersWithoutOverflow","Math","floor","allowedInputKeys","Set","isAllowedInputKey","e","metaKey","key","ctrlKey","isNumberKey","isNaN","parseInt","has"],"mappings":"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"}