@elliemae/ds-form-helpers-mask-hooks 3.16.0-next.8 → 3.16.0-next.9

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.
@@ -37,10 +37,17 @@ var import_utils = require("../utils");
37
37
  var import_react_desc_prop_types = require("../react-desc-prop-types");
38
38
  const addThousandsSeparator = (n, separator) => n.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
39
39
  const conformValue = (rawValue, cursorPos, lastKeyCode, opts) => {
40
- const { includeThousandsSeparator, allowNegative, prefix, suffix, decimalPlaces, decimalRequired } = opts;
40
+ const {
41
+ includeThousandsSeparator = true,
42
+ allowNegative = false,
43
+ prefix = "",
44
+ suffix = "",
45
+ decimalPlaces = 2,
46
+ decimalRequired = false
47
+ } = opts;
41
48
  const THOUSANDSSEPARATOR = ",";
42
49
  let dotIdx = -1;
43
- let finalPrefix = [prefix.length, 0].includes(rawValue.indexOf("-")) && allowNegative ? "-" : "";
50
+ let finalPrefix = [prefix?.length, 0].includes(rawValue.indexOf("-")) && allowNegative ? "-" : "";
44
51
  let maskedValue = String(rawValue).split("").filter((char, idx) => {
45
52
  const validChar = char >= "0" && char <= "9" || char === "." && dotIdx === -1 && decimalPlaces;
46
53
  if (char === "." && validChar)
@@ -102,7 +109,7 @@ const useNumberMask = (props) => {
102
109
  const maskedValue = e.target.value;
103
110
  const dotIdx = maskedValue.indexOf(".");
104
111
  const minusIndex = maskedValue.indexOf("-");
105
- const { decimalRequired, decimalPlaces, suffix } = opts;
112
+ const { decimalRequired = true, decimalPlaces = 2, suffix = "" } = opts;
106
113
  const suffixIndex = suffix.length ? maskedValue.indexOf(suffix) : -1;
107
114
  if (decimalRequired) {
108
115
  if (dotIdx > -1) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/useNumberMask.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-params */\n/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskNumberHookDefaultProps, DSMaskNumberHookPropsTypes } from '../react-desc-prop-types';\n\nconst addThousandsSeparator = (n: string, separator: string) => n.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n opts: DSMaskT.NumberHookArgs,\n): [string, number] => {\n const { includeThousandsSeparator, allowNegative, prefix, suffix, decimalPlaces, decimalRequired } = opts;\n const THOUSANDSSEPARATOR = ',';\n\n let dotIdx = -1;\n // allow minus sign before and after the preffix\n let finalPrefix = [prefix.length, 0].includes(rawValue.indexOf('-')) && allowNegative ? '-' : '';\n\n let maskedValue = String(rawValue)\n .split('')\n .filter((char, idx) => {\n // we take only the first dot\n const validChar = (char >= '0' && char <= '9') || (char === '.' && dotIdx === -1 && decimalPlaces);\n if (char === '.' && validChar) dotIdx = idx;\n return validChar;\n });\n\n if (prefix && maskedValue.length) finalPrefix += prefix;\n\n // REMOVE FOLLOWING ZEROS IN INTEGER PART AFTER LEADER ZERO NUMBER\n while (maskedValue.length >= 2 && maskedValue[0] === '0' && maskedValue[1] !== '.') {\n maskedValue = maskedValue.splice(1);\n }\n dotIdx = maskedValue.findIndex((char) => char === '.');\n\n let integer = maskedValue.slice(0, dotIdx !== -1 ? dotIdx : maskedValue.length);\n const decimal = maskedValue.slice(dotIdx, dotIdx + decimalPlaces + 1);\n // ADDING THOUSANDS SEPARATOR\n if (includeThousandsSeparator) {\n integer = addThousandsSeparator(integer.join(''), THOUSANDSSEPARATOR).split('');\n }\n\n // MERGIN INT AND DECIMAL IF NECCESSARY\n if (dotIdx !== -1 && !(lastKeyCode === 'Backspace' && decimal.length === 1)) {\n if (integer.length) {\n maskedValue = [...integer, ...decimal];\n } else {\n // if theres no integer add a zero to the left of the dot to cover .23 => 0.23 case\n maskedValue = ['0', ...decimal];\n }\n } else {\n // If decimal is required we add a dot after integer if exists\n maskedValue = decimalRequired && integer.length ? [...integer, '.'] : integer;\n }\n\n // remove orphans prefix for example \"-$\"\n if (lastKeyCode === 'Backspace' && maskedValue.length === 0) {\n finalPrefix = '';\n }\n\n // SET REAL CURSOR POSITION AFTER ADDING DOT and COMMAS SEPARATORS\n let maskedPos = 0;\n\n // 0 leading case we move the cursor to continue typing\n if (maskedValue[maskedPos] === '0' && cursorPos === 1 + prefix.length) maskedPos += 1;\n\n for (let i = 0; i < cursorPos; i += 1) {\n if (maskedValue[maskedPos] === THOUSANDSSEPARATOR) maskedPos += 1;\n if (maskedValue[maskedPos] === rawValue[i]) maskedPos += 1;\n }\n\n maskedPos += finalPrefix.length;\n\n const finalSuffix = maskedValue.length ? suffix : '';\n\n const maskedValueString = finalPrefix + maskedValue.join('') + finalSuffix;\n return [maskedValueString, maskedPos];\n};\n\nexport const useNumberMask: DSMaskT.NumberHook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskNumberHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskNumberHookPropsTypes, 'useNumberMask');\n\n const {\n valueSetter,\n onChange: userOnChange,\n onKeyDown: userOnKeyDown,\n onBlur: userOnBlur,\n ...opts\n } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onBlur: React.FocusEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const maskedValue = e.target.value;\n const dotIdx = maskedValue.indexOf('.');\n const minusIndex = maskedValue.indexOf('-');\n\n const { decimalRequired, decimalPlaces, suffix } = opts;\n\n const suffixIndex = suffix.length ? maskedValue.indexOf(suffix) : -1;\n\n if (decimalRequired) {\n if (dotIdx > -1) {\n const decimal = maskedValue.slice(dotIdx + 1, suffix.length ? -suffix.length : maskedValue.length);\n\n let zerosRest = '';\n while (decimal.length + zerosRest.length !== decimalPlaces) {\n zerosRest += '0';\n }\n\n valueSetter((suffix.length ? maskedValue.slice(0, suffixIndex) : maskedValue) + zerosRest + suffix);\n }\n } else if (maskedValue.length - suffix.length - 1 === dotIdx) {\n // removing orphans dots\n valueSetter(maskedValue.replace('.', ''));\n } else if (maskedValue.length - 1 === minusIndex) {\n // removing orphans minus\n valueSetter(maskedValue.replace('-', ''));\n }\n if (userOnBlur) userOnBlur(e);\n },\n [userOnBlur, valueSetter, opts],\n );\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(\n e.target.value,\n e.target.selectionEnd ?? 0,\n lastKeyCode.current,\n opts as DSMaskT.NumberHookArgs,\n );\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n\n return mask;\n });\n if (userOnChange) userOnChange(e, mask);\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange, opts],\n );\n\n return {\n onKeyDown,\n onChange,\n onBlur,\n };\n};\n\nexport const getNumberMaskedValue = (value: string, opts: DSMaskT.NumberHookArgs) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', opts);\n return maskedValue;\n};\n\nuseNumberMask.displayName = 'useNumberMask';\nexport const UseNumberMaskWithSchema = describe(useNumberMask);\nUseNumberMaskWithSchema.propTypes = DSMaskNumberHookPropsTypes;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable max-params */\n/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskNumberHookDefaultProps, DSMaskNumberHookPropsTypes } from '../react-desc-prop-types';\n\nconst addThousandsSeparator = (n: string, separator: string) => n.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n opts: Partial<DSMaskT.NumberHookArgs>,\n): [string, number] => {\n const {\n includeThousandsSeparator = true,\n allowNegative = false,\n prefix = '',\n suffix = '',\n decimalPlaces = 2,\n decimalRequired = false,\n } = opts;\n const THOUSANDSSEPARATOR = ',';\n\n let dotIdx = -1;\n // allow minus sign before and after the preffix\n let finalPrefix = [prefix?.length, 0].includes(rawValue.indexOf('-')) && allowNegative ? '-' : '';\n\n let maskedValue = String(rawValue)\n .split('')\n .filter((char, idx) => {\n // we take only the first dot\n const validChar = (char >= '0' && char <= '9') || (char === '.' && dotIdx === -1 && decimalPlaces);\n if (char === '.' && validChar) dotIdx = idx;\n return validChar;\n });\n\n if (prefix && maskedValue.length) finalPrefix += prefix;\n\n // REMOVE FOLLOWING ZEROS IN INTEGER PART AFTER LEADER ZERO NUMBER\n while (maskedValue.length >= 2 && maskedValue[0] === '0' && maskedValue[1] !== '.') {\n maskedValue = maskedValue.splice(1);\n }\n dotIdx = maskedValue.findIndex((char) => char === '.');\n\n let integer = maskedValue.slice(0, dotIdx !== -1 ? dotIdx : maskedValue.length);\n const decimal = maskedValue.slice(dotIdx, dotIdx + decimalPlaces + 1);\n // ADDING THOUSANDS SEPARATOR\n if (includeThousandsSeparator) {\n integer = addThousandsSeparator(integer.join(''), THOUSANDSSEPARATOR).split('');\n }\n\n // MERGIN INT AND DECIMAL IF NECCESSARY\n if (dotIdx !== -1 && !(lastKeyCode === 'Backspace' && decimal.length === 1)) {\n if (integer.length) {\n maskedValue = [...integer, ...decimal];\n } else {\n // if theres no integer add a zero to the left of the dot to cover .23 => 0.23 case\n maskedValue = ['0', ...decimal];\n }\n } else {\n // If decimal is required we add a dot after integer if exists\n maskedValue = decimalRequired && integer.length ? [...integer, '.'] : integer;\n }\n\n // remove orphans prefix for example \"-$\"\n if (lastKeyCode === 'Backspace' && maskedValue.length === 0) {\n finalPrefix = '';\n }\n\n // SET REAL CURSOR POSITION AFTER ADDING DOT and COMMAS SEPARATORS\n let maskedPos = 0;\n\n // 0 leading case we move the cursor to continue typing\n if (maskedValue[maskedPos] === '0' && cursorPos === 1 + prefix.length) maskedPos += 1;\n\n for (let i = 0; i < cursorPos; i += 1) {\n if (maskedValue[maskedPos] === THOUSANDSSEPARATOR) maskedPos += 1;\n if (maskedValue[maskedPos] === rawValue[i]) maskedPos += 1;\n }\n\n maskedPos += finalPrefix.length;\n\n const finalSuffix = maskedValue.length ? suffix : '';\n\n const maskedValueString = finalPrefix + maskedValue.join('') + finalSuffix;\n return [maskedValueString, maskedPos];\n};\n\nexport const useNumberMask: DSMaskT.NumberHook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskNumberHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskNumberHookPropsTypes, 'useNumberMask');\n\n const {\n valueSetter,\n onChange: userOnChange,\n onKeyDown: userOnKeyDown,\n onBlur: userOnBlur,\n ...opts\n } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onBlur: React.FocusEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const maskedValue = e.target.value;\n const dotIdx = maskedValue.indexOf('.');\n const minusIndex = maskedValue.indexOf('-');\n\n const { decimalRequired = true, decimalPlaces = 2, suffix = '' } = opts;\n\n const suffixIndex = suffix.length ? maskedValue.indexOf(suffix) : -1;\n\n if (decimalRequired) {\n if (dotIdx > -1) {\n const decimal = maskedValue.slice(dotIdx + 1, suffix.length ? -suffix.length : maskedValue.length);\n\n let zerosRest = '';\n while (decimal.length + zerosRest.length !== decimalPlaces) {\n zerosRest += '0';\n }\n\n valueSetter((suffix.length ? maskedValue.slice(0, suffixIndex) : maskedValue) + zerosRest + suffix);\n }\n } else if (maskedValue.length - suffix.length - 1 === dotIdx) {\n // removing orphans dots\n valueSetter(maskedValue.replace('.', ''));\n } else if (maskedValue.length - 1 === minusIndex) {\n // removing orphans minus\n valueSetter(maskedValue.replace('-', ''));\n }\n if (userOnBlur) userOnBlur(e);\n },\n [userOnBlur, valueSetter, opts],\n );\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(\n e.target.value,\n e.target.selectionEnd ?? 0,\n lastKeyCode.current,\n opts as DSMaskT.NumberHookArgs,\n );\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n\n return mask;\n });\n if (userOnChange) userOnChange(e, mask);\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange, opts],\n );\n\n return {\n onKeyDown,\n onChange,\n onBlur,\n };\n};\n\nexport const getNumberMaskedValue = (value: string, opts: DSMaskT.NumberHookArgs) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', opts);\n return maskedValue;\n};\n\nuseNumberMask.displayName = 'useNumberMask';\nexport const UseNumberMaskWithSchema = describe(useNumberMask);\nUseNumberMaskWithSchema.propTypes = DSMaskNumberHookPropsTypes;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -47,7 +47,7 @@ const internationalPhoneSpecialChars = [
47
47
  ];
48
48
  const conformValue = (rawValue, cursorPos, lastKeyCode, opts) => {
49
49
  const characters = String(rawValue).split("");
50
- const { isInternational } = opts;
50
+ const { isInternational = false } = opts;
51
51
  let maskedValue = characters.filter((char, idx, array) => {
52
52
  if (isInternational && idx === 1 && char === "1" && array[0] === "+") {
53
53
  return false;
@@ -68,7 +68,7 @@ const conformValue = (rawValue, cursorPos, lastKeyCode, opts) => {
68
68
  const usePhoneMask = (props) => {
69
69
  const propsWithDefault = (0, import_ds_props_helpers.useMemoMergePropsWithDefault)(props, import_react_desc_prop_types.DSMaskPhoneHookDefaultProps);
70
70
  (0, import_ds_props_helpers.useValidateTypescriptPropTypes)(propsWithDefault, import_react_desc_prop_types.DSMaskPhoneHookPropsTypes, "usePhoneMask");
71
- const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown, onBlur, ...opts } = propsWithDefault;
71
+ const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown, ...opts } = propsWithDefault;
72
72
  const lastKeyCode = (0, import_react.useRef)("Unidentified");
73
73
  const scheduleAfterRender = (0, import_ds_utilities.useCallbackAfterRender)(true);
74
74
  const [, setKey] = (0, import_react.useState)(0);
@@ -99,7 +99,7 @@ const usePhoneMask = (props) => {
99
99
  onChange
100
100
  };
101
101
  };
102
- const getPhoneMaskedValue = (value, opts) => {
102
+ const getPhoneMaskedValue = (value, opts = {}) => {
103
103
  const [maskedValue] = conformValue(value, value.length - 1, "", opts);
104
104
  return maskedValue;
105
105
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/usePhoneMask.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-params */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskPhoneHookPropsTypes, DSMaskPhoneHookDefaultProps } from '../react-desc-prop-types';\n\nconst phoneSpecialChars: [string, number][] = [\n ['(', 0],\n [') ', 4],\n [' - ', 9],\n];\n\nconst internationalPhoneSpecialChars: [string, number][] = [\n ['+1 (', 0],\n [') ', 7],\n [' - ', 12],\n];\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n opts: Partial<DSMaskT.PhoneHookArgs>,\n) => {\n const characters = String(rawValue).split('');\n // Work with digits only\n const { isInternational } = opts;\n let maskedValue = characters.filter((char, idx, array) => {\n if (isInternational && idx === 1 && char === '1' && array[0] === '+') {\n return false;\n }\n return char >= '0' && char <= '9';\n });\n // We can't have zeros at the start of the array\n while (maskedValue.length && maskedValue[0] === '0') maskedValue.splice(0, 1);\n\n // We only consider first 10 digits\n maskedValue = maskedValue.slice(0, 10);\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n\n return addSpecialCharacters(\n maskedValue,\n isInternational ? internationalPhoneSpecialChars : phoneSpecialChars,\n maskedPos,\n lastKeyCode,\n );\n};\n\nexport const usePhoneMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskPhoneHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskPhoneHookPropsTypes, 'usePhoneMask');\n const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown, onBlur, ...opts } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(e.target.value, e.target.selectionEnd ?? 0, lastKeyCode.current, opts);\n\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n return mask;\n });\n\n if (userOnChange) userOnChange(e, mask);\n\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, opts, userOnChange],\n );\n\n return {\n onKeyDown,\n onChange,\n };\n};\n\nexport const getPhoneMaskedValue = (value: string, opts: Partial<DSMaskT.PhoneHookArgs>) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', opts);\n return maskedValue;\n};\n\nusePhoneMask.displayName = 'usePhoneMask';\nexport const UsePhoneMaskWithSchema = describe(usePhoneMask);\nUsePhoneMaskWithSchema.propTypes = DSMaskPhoneHookPropsTypes;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,mBAA8C;AAC9C,8BAAuF;AACvF,0BAAuC;AACvC,mBAA6E;AAE7E,mCAAuE;AAEvE,MAAM,oBAAwC;AAAA,EAC5C,CAAC,KAAK,CAAC;AAAA,EACP,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,OAAO,CAAC;AACX;AAEA,MAAM,iCAAqD;AAAA,EACzD,CAAC,QAAQ,CAAC;AAAA,EACV,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,OAAO,EAAE;AACZ;AAEA,MAAM,eAAe,CACnB,UACA,WACA,aACA,SACG;AACH,QAAM,aAAa,OAAO,QAAQ,EAAE,MAAM,EAAE;AAE5C,QAAM,EAAE,gBAAgB,IAAI;AAC5B,MAAI,cAAc,WAAW,OAAO,CAAC,MAAM,KAAK,UAAU;AACxD,QAAI,mBAAmB,QAAQ,KAAK,SAAS,OAAO,MAAM,OAAO,KAAK;AACpE,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,OAAO,QAAQ;AAAA,EAChC,CAAC;AAED,SAAO,YAAY,UAAU,YAAY,OAAO;AAAK,gBAAY,OAAO,GAAG,CAAC;AAG5E,gBAAc,YAAY,MAAM,GAAG,EAAE;AAErC,QAAM,gBAAY,kCAAoB,UAAU,aAAa,SAAS;AAEtE,aAAO;AAAA,IACL;AAAA,IACA,kBAAkB,iCAAiC;AAAA,IACnD;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,eAA6B,CAAC,UAAU;AACnD,QAAM,uBAAmB,sDAA6B,OAAO,wDAA2B;AACxF,8DAA+B,kBAAkB,wDAA2B,cAAc;AAC1F,QAAM,EAAE,aAAa,UAAU,cAAc,WAAW,eAAe,WAAW,KAAK,IAAI;AAE3F,QAAM,kBAAc,qBAAO,cAAc;AAEzC,QAAM,0BAAsB,4CAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,QAAI,uBAAS,CAAC;AAE7B,QAAM,gBAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,eAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI,aAAa,EAAE,OAAO,OAAO,EAAE,OAAO,gBAAgB,GAAG,YAAY,SAAS,IAAI;AAE5G,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAC9C,eAAO;AAAA,MACT,CAAC;AAED,UAAI;AAAc,qBAAa,GAAG,IAAI;AAEtC,0BAAoB,UAAM,gCAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,MAAM,YAAY;AAAA,EACvD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,CAAC,OAAe,SAAyC;AAC1F,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,IAAI,IAAI;AACpE,SAAO;AACT;AAEA,aAAa,cAAc;AACpB,MAAM,6BAAyB,kCAAS,YAAY;AAC3D,uBAAuB,YAAY;",
4
+ "sourcesContent": ["/* eslint-disable max-params */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskPhoneHookPropsTypes, DSMaskPhoneHookDefaultProps } from '../react-desc-prop-types';\n\nconst phoneSpecialChars: [string, number][] = [\n ['(', 0],\n [') ', 4],\n [' - ', 9],\n];\n\nconst internationalPhoneSpecialChars: [string, number][] = [\n ['+1 (', 0],\n [') ', 7],\n [' - ', 12],\n];\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n opts: Partial<DSMaskT.PhoneHookArgs>,\n) => {\n const characters = String(rawValue).split('');\n // Work with digits only\n const { isInternational = false } = opts;\n let maskedValue = characters.filter((char, idx, array) => {\n if (isInternational && idx === 1 && char === '1' && array[0] === '+') {\n return false;\n }\n return char >= '0' && char <= '9';\n });\n // We can't have zeros at the start of the array\n while (maskedValue.length && maskedValue[0] === '0') maskedValue.splice(0, 1);\n\n // We only consider first 10 digits\n maskedValue = maskedValue.slice(0, 10);\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n\n return addSpecialCharacters(\n maskedValue,\n isInternational ? internationalPhoneSpecialChars : phoneSpecialChars,\n maskedPos,\n lastKeyCode,\n );\n};\n\nexport const usePhoneMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskPhoneHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskPhoneHookPropsTypes, 'usePhoneMask');\n const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown, ...opts } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(e.target.value, e.target.selectionEnd ?? 0, lastKeyCode.current, opts);\n\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n return mask;\n });\n\n if (userOnChange) userOnChange(e, mask);\n\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, opts, userOnChange],\n );\n\n return {\n onKeyDown,\n onChange,\n };\n};\n\nexport const getPhoneMaskedValue = (value: string, opts: Partial<DSMaskT.PhoneHookArgs> = {}) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', opts);\n return maskedValue;\n};\n\nusePhoneMask.displayName = 'usePhoneMask';\nexport const UsePhoneMaskWithSchema = describe(usePhoneMask);\nUsePhoneMaskWithSchema.propTypes = DSMaskPhoneHookPropsTypes;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,mBAA8C;AAC9C,8BAAuF;AACvF,0BAAuC;AACvC,mBAA6E;AAE7E,mCAAuE;AAEvE,MAAM,oBAAwC;AAAA,EAC5C,CAAC,KAAK,CAAC;AAAA,EACP,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,OAAO,CAAC;AACX;AAEA,MAAM,iCAAqD;AAAA,EACzD,CAAC,QAAQ,CAAC;AAAA,EACV,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,OAAO,EAAE;AACZ;AAEA,MAAM,eAAe,CACnB,UACA,WACA,aACA,SACG;AACH,QAAM,aAAa,OAAO,QAAQ,EAAE,MAAM,EAAE;AAE5C,QAAM,EAAE,kBAAkB,MAAM,IAAI;AACpC,MAAI,cAAc,WAAW,OAAO,CAAC,MAAM,KAAK,UAAU;AACxD,QAAI,mBAAmB,QAAQ,KAAK,SAAS,OAAO,MAAM,OAAO,KAAK;AACpE,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,OAAO,QAAQ;AAAA,EAChC,CAAC;AAED,SAAO,YAAY,UAAU,YAAY,OAAO;AAAK,gBAAY,OAAO,GAAG,CAAC;AAG5E,gBAAc,YAAY,MAAM,GAAG,EAAE;AAErC,QAAM,gBAAY,kCAAoB,UAAU,aAAa,SAAS;AAEtE,aAAO;AAAA,IACL;AAAA,IACA,kBAAkB,iCAAiC;AAAA,IACnD;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,eAA6B,CAAC,UAAU;AACnD,QAAM,uBAAmB,sDAA6B,OAAO,wDAA2B;AACxF,8DAA+B,kBAAkB,wDAA2B,cAAc;AAC1F,QAAM,EAAE,aAAa,UAAU,cAAc,WAAW,kBAAkB,KAAK,IAAI;AAEnF,QAAM,kBAAc,qBAAO,cAAc;AAEzC,QAAM,0BAAsB,4CAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,QAAI,uBAAS,CAAC;AAE7B,QAAM,gBAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,eAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI,aAAa,EAAE,OAAO,OAAO,EAAE,OAAO,gBAAgB,GAAG,YAAY,SAAS,IAAI;AAE5G,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAC9C,eAAO;AAAA,MACT,CAAC;AAED,UAAI;AAAc,qBAAa,GAAG,IAAI;AAEtC,0BAAoB,UAAM,gCAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,MAAM,YAAY;AAAA,EACvD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,CAAC,OAAe,OAAuC,CAAC,MAAM;AAC/F,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,IAAI,IAAI;AACpE,SAAO;AACT;AAEA,aAAa,cAAc;AACpB,MAAM,6BAAyB,kCAAS,YAAY;AAC3D,uBAAuB,YAAY;",
6
6
  "names": []
7
7
  }
@@ -25,6 +25,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
25
25
  var useRegExpMask_exports = {};
26
26
  __export(useRegExpMask_exports, {
27
27
  UseRegExpMaskWithSchema: () => UseRegExpMaskWithSchema,
28
+ getRegExpMaskedValue: () => getRegExpMaskedValue,
28
29
  useRegExpMask: () => useRegExpMask
29
30
  });
30
31
  module.exports = __toCommonJS(useRegExpMask_exports);
@@ -78,7 +79,8 @@ const conformValue = (rawValue, cursorPos, lastKeyCode, regExp, filledMask) => {
78
79
  maskedPos,
79
80
  lastKeyCode
80
81
  );
81
- return [maskWithSpecialsChars + specialCharsLeft, finalMaskedPos];
82
+ const maskReturn = maskWithSpecialsChars + specialCharsLeft;
83
+ return [maskReturn, finalMaskedPos];
82
84
  };
83
85
  const useRegExpMask = (props) => {
84
86
  const propsWithDefault = (0, import_ds_props_helpers.useMemoMergePropsWithDefault)(props, import_react_desc_prop_types.DSMaskRegExpHookDefaultProps);
@@ -120,7 +122,7 @@ const useRegExpMask = (props) => {
120
122
  userOnChange(e, mask);
121
123
  scheduleAfterRender(() => (0, import_utils.setCursorPosition)(e.target, cursorPos));
122
124
  },
123
- [valueSetter, scheduleAfterRender, userOnChange]
125
+ [regExp, filledMask, valueSetter, userOnChange, scheduleAfterRender]
124
126
  );
125
127
  const onBlur = (0, import_react.useCallback)(
126
128
  (e) => {
@@ -134,7 +136,7 @@ const useRegExpMask = (props) => {
134
136
  if (userOnBlur)
135
137
  userOnBlur(e);
136
138
  },
137
- [valueSetter, userOnBlur]
139
+ [filledMask, userOnBlur, regExp, valueSetter]
138
140
  );
139
141
  return {
140
142
  onKeyDown,
@@ -142,6 +144,10 @@ const useRegExpMask = (props) => {
142
144
  onBlur
143
145
  };
144
146
  };
147
+ const getRegExpMaskedValue = (value, regExp) => {
148
+ const [maskedValue] = conformValue(value, value.length - 1, "", regExp, false);
149
+ return maskedValue;
150
+ };
145
151
  useRegExpMask.displayName = "useRegExpMask";
146
152
  const UseRegExpMaskWithSchema = (0, import_ds_props_helpers.describe)(useRegExpMask);
147
153
  UseRegExpMaskWithSchema.propTypes = import_react_desc_prop_types.DSMaskRegExpHookPropsTypes;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/useRegExpMask.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-depth */\n/* eslint-disable max-statements */\n/* eslint-disable max-params */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition, flatStringArray } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskRegExpHookPropsTypes, DSMaskRegExpHookDefaultProps } from '../react-desc-prop-types';\n\nconst isRegExp = (item: RegExp | string): item is RegExp => typeof item === 'object';\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n regExp: string[],\n filledMask: boolean,\n) => {\n const specialChars: [string, number][] = [];\n const flatRegExp = flatStringArray(regExp);\n const rawValueArray = String(rawValue).split('');\n let offSet = 0;\n let charsFound = 0;\n let specialCharsLeft = '';\n let fullRegExpMatched = false;\n const maskedValue: string[] = [];\n for (let i = 0; i < flatRegExp.length; i += 1) {\n if (isRegExp(flatRegExp[i])) {\n specialCharsLeft = '';\n fullRegExpMatched = false;\n for (let j = charsFound + offSet; j < rawValueArray.length; j += 1) {\n const match = rawValueArray[j]?.match(flatRegExp[i]);\n if (match) {\n maskedValue.push(match[0]);\n charsFound += 1;\n fullRegExpMatched = true;\n break;\n } else {\n offSet += 1;\n }\n }\n if (filledMask && !fullRegExpMatched) {\n maskedValue.push('_');\n }\n } else {\n specialChars.push([flatRegExp[i], i]);\n if (rawValueArray[i + offSet] === flatRegExp[i]) charsFound += 1;\n specialCharsLeft += flatRegExp[i];\n }\n }\n if (!fullRegExpMatched) specialCharsLeft = '';\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n const [maskWithSpecialsChars, finalMaskedPos] = addSpecialCharacters(\n maskedValue,\n specialChars,\n maskedPos,\n lastKeyCode,\n );\n\n return [maskWithSpecialsChars + specialCharsLeft, finalMaskedPos];\n};\n\nexport const useRegExpMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskRegExpHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskRegExpHookPropsTypes, 'useRegExpMask');\n const {\n valueSetter,\n onChange: userOnChange,\n onKeyDown: userOnKeyDown,\n onBlur: userOnBlur,\n regExp,\n filledMask,\n } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(\n e.target.value,\n e.target.selectionEnd ?? 0,\n lastKeyCode.current,\n regExp,\n filledMask,\n );\n\n valueSetter((prevMask) => {\n // Here we need to update the key\n\n if (mask === prevMask) setKey((key) => key + 1);\n return mask;\n });\n\n if (userOnChange) userOnChange(e, mask);\n\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange],\n );\n const onBlur: React.FocusEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n if (filledMask) {\n const maskedValue = e.target.value.split('');\n\n const flatRegExp = flatStringArray(regExp);\n const firstUnderscoreIdx = maskedValue.findIndex((char, idx) => char === '_' && flatRegExp[idx] !== '_');\n if (firstUnderscoreIdx > -1) valueSetter(maskedValue.slice(0, firstUnderscoreIdx).join(''));\n }\n\n if (userOnBlur) userOnBlur(e);\n },\n [valueSetter, userOnBlur],\n );\n\n return {\n onKeyDown,\n onChange,\n onBlur,\n };\n};\n\nuseRegExpMask.displayName = 'useRegExpMask';\nexport const UseRegExpMaskWithSchema = describe(useRegExpMask);\nUseRegExpMaskWithSchema.propTypes = DSMaskRegExpHookPropsTypes;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable max-depth */\n/* eslint-disable max-statements */\n/* eslint-disable max-params */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition, flatStringArray } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskRegExpHookPropsTypes, DSMaskRegExpHookDefaultProps } from '../react-desc-prop-types';\n\nconst isRegExp = (item: RegExp | string): item is RegExp => typeof item === 'object';\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n regExp: string[],\n filledMask: boolean,\n) => {\n const specialChars: [string, number][] = [];\n const flatRegExp = flatStringArray(regExp);\n const rawValueArray = String(rawValue).split('');\n let offSet = 0;\n let charsFound = 0;\n let specialCharsLeft = '';\n let fullRegExpMatched = false;\n const maskedValue: string[] = [];\n for (let i = 0; i < flatRegExp.length; i += 1) {\n if (isRegExp(flatRegExp[i])) {\n specialCharsLeft = '';\n fullRegExpMatched = false;\n for (let j = charsFound + offSet; j < rawValueArray.length; j += 1) {\n const match = rawValueArray[j]?.match(flatRegExp[i]);\n if (match) {\n maskedValue.push(match[0]);\n charsFound += 1;\n fullRegExpMatched = true;\n break;\n } else {\n offSet += 1;\n }\n }\n if (filledMask && !fullRegExpMatched) {\n maskedValue.push('_');\n }\n } else {\n specialChars.push([flatRegExp[i], i]);\n if (rawValueArray[i + offSet] === flatRegExp[i]) charsFound += 1;\n specialCharsLeft += flatRegExp[i];\n }\n }\n if (!fullRegExpMatched) specialCharsLeft = '';\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n const [maskWithSpecialsChars, finalMaskedPos] = addSpecialCharacters(\n maskedValue,\n specialChars,\n maskedPos,\n lastKeyCode,\n );\n const maskReturn = maskWithSpecialsChars + specialCharsLeft;\n return [maskReturn, finalMaskedPos];\n};\n\nexport const useRegExpMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskRegExpHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskRegExpHookPropsTypes, 'useRegExpMask');\n const {\n valueSetter,\n onChange: userOnChange,\n onKeyDown: userOnKeyDown,\n onBlur: userOnBlur,\n regExp,\n filledMask,\n } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(\n e.target.value,\n e.target.selectionEnd ?? 0,\n lastKeyCode.current,\n regExp,\n filledMask,\n );\n\n valueSetter((prevMask) => {\n // Here we need to update the key\n\n if (mask === prevMask) setKey((key) => key + 1);\n return mask as string;\n });\n\n if (userOnChange) userOnChange(e, mask as string);\n\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos as number));\n },\n [regExp, filledMask, valueSetter, userOnChange, scheduleAfterRender],\n );\n const onBlur: React.FocusEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n if (filledMask) {\n const maskedValue = e.target.value.split('');\n\n const flatRegExp = flatStringArray(regExp);\n const firstUnderscoreIdx = maskedValue.findIndex((char, idx) => char === '_' && flatRegExp[idx] !== '_');\n if (firstUnderscoreIdx > -1) valueSetter(maskedValue.slice(0, firstUnderscoreIdx).join(''));\n }\n\n if (userOnBlur) userOnBlur(e);\n },\n [filledMask, userOnBlur, regExp, valueSetter],\n );\n\n return {\n onKeyDown,\n onChange,\n onBlur,\n };\n};\n\nexport const getRegExpMaskedValue = (value: string, regExp: string[]) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', regExp, false);\n return maskedValue;\n};\n\nuseRegExpMask.displayName = 'useRegExpMask';\nexport const UseRegExpMaskWithSchema = describe(useRegExpMask);\nUseRegExpMaskWithSchema.propTypes = DSMaskRegExpHookPropsTypes;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -25,7 +25,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
25
25
  var useZipCodeMask_exports = {};
26
26
  __export(useZipCodeMask_exports, {
27
27
  UseZipCodeMaskWithSchema: () => UseZipCodeMaskWithSchema,
28
- getUseZipMaskedValue: () => getUseZipMaskedValue,
28
+ getZipCodeMaskedValue: () => getZipCodeMaskedValue,
29
29
  useZipCodeMask: () => useZipCodeMask
30
30
  });
31
31
  module.exports = __toCommonJS(useZipCodeMask_exports);
@@ -76,7 +76,7 @@ const useZipCodeMask = (props) => {
76
76
  onChange
77
77
  };
78
78
  };
79
- const getUseZipMaskedValue = (value) => {
79
+ const getZipCodeMaskedValue = (value) => {
80
80
  const [maskedValue] = conformValue(value, value.length - 1, "");
81
81
  return maskedValue;
82
82
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/useZipCodeMask.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskHookDefaultProps, DSMaskHookPropsTypes } from '../react-desc-prop-types';\n\nconst zipCodeSpecialChars: [string, number][] = [['-', 5]];\n\nconst conformValue = (rawValue: string, cursorPos: number, lastKeyCode: string) => {\n // Work with digits only\n let maskedValue = String(rawValue)\n .split('')\n .filter((char) => char >= '0' && char <= '9');\n\n // We only consider first 9 digits\n maskedValue = maskedValue.slice(0, 9);\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n\n return addSpecialCharacters(maskedValue, zipCodeSpecialChars, maskedPos, lastKeyCode);\n};\n\nexport const useZipCodeMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskHookPropsTypes, 'useZipCodeMask');\n const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(e.target.value, e.target.selectionEnd ?? 0, lastKeyCode.current);\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n\n return mask;\n });\n if (userOnChange) userOnChange(e, mask);\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange],\n );\n\n return {\n onKeyDown,\n onChange,\n };\n};\n\nexport const getUseZipMaskedValue = (value: string) => {\n const [maskedValue] = conformValue(value, value.length - 1, '');\n return maskedValue;\n};\n\nuseZipCodeMask.displayName = 'useZipCodeMask';\nexport const UseZipCodeMaskWithSchema = describe(useZipCodeMask);\nUseZipCodeMaskWithSchema.propTypes = DSMaskHookPropsTypes;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,mBAA8C;AAC9C,8BAAuF;AACvF,0BAAuC;AACvC,mBAA6E;AAE7E,mCAA6D;AAE7D,MAAM,sBAA0C,CAAC,CAAC,KAAK,CAAC,CAAC;AAEzD,MAAM,eAAe,CAAC,UAAkB,WAAmB,gBAAwB;AAEjF,MAAI,cAAc,OAAO,QAAQ,EAC9B,MAAM,EAAE,EACR,OAAO,CAAC,SAAS,QAAQ,OAAO,QAAQ,GAAG;AAG9C,gBAAc,YAAY,MAAM,GAAG,CAAC;AAEpC,QAAM,gBAAY,kCAAoB,UAAU,aAAa,SAAS;AAEtE,aAAO,mCAAqB,aAAa,qBAAqB,WAAW,WAAW;AACtF;AAEO,MAAM,iBAA+B,CAAC,UAAU;AACrD,QAAM,uBAAmB,sDAA6B,OAAO,mDAAsB;AACnF,8DAA+B,kBAAkB,mDAAsB,gBAAgB;AACvF,QAAM,EAAE,aAAa,UAAU,cAAc,WAAW,cAAc,IAAI;AAE1E,QAAM,kBAAc,qBAAO,cAAc;AACzC,QAAM,0BAAsB,4CAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,QAAI,uBAAS,CAAC;AAE7B,QAAM,gBAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,eAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI,aAAa,EAAE,OAAO,OAAO,EAAE,OAAO,gBAAgB,GAAG,YAAY,OAAO;AACtG,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAE9C,eAAO;AAAA,MACT,CAAC;AACD,UAAI;AAAc,qBAAa,GAAG,IAAI;AACtC,0BAAoB,UAAM,gCAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,YAAY;AAAA,EACjD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,uBAAuB,CAAC,UAAkB;AACrD,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,EAAE;AAC9D,SAAO;AACT;AAEA,eAAe,cAAc;AACtB,MAAM,+BAA2B,kCAAS,cAAc;AAC/D,yBAAyB,YAAY;",
4
+ "sourcesContent": ["import type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskHookDefaultProps, DSMaskHookPropsTypes } from '../react-desc-prop-types';\n\nconst zipCodeSpecialChars: [string, number][] = [['-', 5]];\n\nconst conformValue = (rawValue: string, cursorPos: number, lastKeyCode: string) => {\n // Work with digits only\n let maskedValue = String(rawValue)\n .split('')\n .filter((char) => char >= '0' && char <= '9');\n\n // We only consider first 9 digits\n maskedValue = maskedValue.slice(0, 9);\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n\n return addSpecialCharacters(maskedValue, zipCodeSpecialChars, maskedPos, lastKeyCode);\n};\n\nexport const useZipCodeMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskHookPropsTypes, 'useZipCodeMask');\n const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(e.target.value, e.target.selectionEnd ?? 0, lastKeyCode.current);\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n\n return mask;\n });\n if (userOnChange) userOnChange(e, mask);\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange],\n );\n\n return {\n onKeyDown,\n onChange,\n };\n};\n\nexport const getZipCodeMaskedValue = (value: string) => {\n const [maskedValue] = conformValue(value, value.length - 1, '');\n return maskedValue;\n};\n\nuseZipCodeMask.displayName = 'useZipCodeMask';\nexport const UseZipCodeMaskWithSchema = describe(useZipCodeMask);\nUseZipCodeMaskWithSchema.propTypes = DSMaskHookPropsTypes;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,mBAA8C;AAC9C,8BAAuF;AACvF,0BAAuC;AACvC,mBAA6E;AAE7E,mCAA6D;AAE7D,MAAM,sBAA0C,CAAC,CAAC,KAAK,CAAC,CAAC;AAEzD,MAAM,eAAe,CAAC,UAAkB,WAAmB,gBAAwB;AAEjF,MAAI,cAAc,OAAO,QAAQ,EAC9B,MAAM,EAAE,EACR,OAAO,CAAC,SAAS,QAAQ,OAAO,QAAQ,GAAG;AAG9C,gBAAc,YAAY,MAAM,GAAG,CAAC;AAEpC,QAAM,gBAAY,kCAAoB,UAAU,aAAa,SAAS;AAEtE,aAAO,mCAAqB,aAAa,qBAAqB,WAAW,WAAW;AACtF;AAEO,MAAM,iBAA+B,CAAC,UAAU;AACrD,QAAM,uBAAmB,sDAA6B,OAAO,mDAAsB;AACnF,8DAA+B,kBAAkB,mDAAsB,gBAAgB;AACvF,QAAM,EAAE,aAAa,UAAU,cAAc,WAAW,cAAc,IAAI;AAE1E,QAAM,kBAAc,qBAAO,cAAc;AACzC,QAAM,0BAAsB,4CAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,QAAI,uBAAS,CAAC;AAE7B,QAAM,gBAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,eAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI,aAAa,EAAE,OAAO,OAAO,EAAE,OAAO,gBAAgB,GAAG,YAAY,OAAO;AACtG,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAE9C,eAAO;AAAA,MACT,CAAC;AACD,UAAI;AAAc,qBAAa,GAAG,IAAI;AACtC,0BAAoB,UAAM,gCAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,YAAY;AAAA,EACjD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,wBAAwB,CAAC,UAAkB;AACtD,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,EAAE;AAC9D,SAAO;AACT;AAEA,eAAe,cAAc;AACtB,MAAM,+BAA2B,kCAAS,cAAc;AAC/D,yBAAyB,YAAY;",
6
6
  "names": []
7
7
  }
@@ -31,7 +31,8 @@ __export(react_desc_prop_types_exports, {
31
31
  DSMaskPhoneHookDefaultProps: () => DSMaskPhoneHookDefaultProps,
32
32
  DSMaskPhoneHookPropsTypes: () => DSMaskPhoneHookPropsTypes,
33
33
  DSMaskRegExpHookDefaultProps: () => DSMaskRegExpHookDefaultProps,
34
- DSMaskRegExpHookPropsTypes: () => DSMaskRegExpHookPropsTypes
34
+ DSMaskRegExpHookPropsTypes: () => DSMaskRegExpHookPropsTypes,
35
+ DSMaskSSNDefaultProps: () => DSMaskSSNDefaultProps
35
36
  });
36
37
  module.exports = __toCommonJS(react_desc_prop_types_exports);
37
38
  var React = __toESM(require("react"));
@@ -47,7 +48,11 @@ const DSMaskPhoneHookDefaultProps = {
47
48
  };
48
49
  const DSMaskRegExpHookDefaultProps = {
49
50
  ...DSMaskHookDefaultProps,
50
- filledMask: false
51
+ filledMask: false,
52
+ regExp: []
53
+ };
54
+ const DSMaskSSNDefaultProps = {
55
+ ...DSMaskHookDefaultProps
51
56
  };
52
57
  const DSMaskNumberHookDefaultProps = {
53
58
  ...DSMaskHookDefaultProps,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/react-desc-prop-types.ts", "../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import { PropTypes } from '@elliemae/ds-props-helpers';\nimport type { WeakValidationMap } from 'react';\nimport type React from 'react';\n\nexport declare namespace DSMaskT {\n interface HookArgs {\n valueSetter: React.Dispatch<React.SetStateAction<string>>;\n onChange?: (e: React.ChangeEvent<HTMLInputElement>, mask?: string) => void;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n }\n\n interface HookReturn {\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n }\n\n export interface NumberHookArgs extends HookArgs {\n suffix: string;\n prefix: string;\n decimalPlaces: number;\n allowNegative: boolean;\n includeThousandsSeparator: boolean;\n decimalRequired: boolean;\n }\n\n export interface PhoneHookArgs extends HookArgs {\n isInternational: boolean;\n }\n\n export interface RegExpHookArgs extends HookArgs {\n filledMask: boolean;\n }\n\n export type Hook = ((args: HookArgs) => HookReturn) & { displayName: string };\n export type PhoneHook = ((args: PhoneHookArgs) => HookReturn) & { displayName: string };\n export type NumberHook = ((args: NumberHookArgs) => HookReturn) & { displayName: string };\n}\n\nexport const DSMaskHookDefaultProps: Partial<DSMaskT.HookReturn> = {\n onChange: () => null,\n onKeyDown: () => null,\n onBlur: () => null,\n};\n\nexport const DSMaskPhoneHookDefaultProps: Partial<DSMaskT.PhoneHookArgs> = {\n ...DSMaskHookDefaultProps,\n isInternational: false,\n};\nexport const DSMaskRegExpHookDefaultProps: Partial<DSMaskT.RegExpHookArgs> = {\n ...DSMaskHookDefaultProps,\n filledMask: false,\n};\n\nexport const DSMaskNumberHookDefaultProps: Partial<DSMaskT.NumberHookArgs> = {\n ...DSMaskHookDefaultProps,\n suffix: '',\n prefix: '',\n decimalPlaces: 2,\n allowNegative: false,\n includeThousandsSeparator: true,\n decimalRequired: false,\n};\n\nexport const DSMaskHookPropsTypes = {\n valueSetter: PropTypes.func.description('React set state function for the value').isRequired,\n onChange: PropTypes.func.description('Callback for onChange'),\n onKeyDown: PropTypes.func.description('Callback for onKeyDown'),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskRegExpHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n regExp: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(RegExp)])).description(\n 'Array with regexp or special chars per character',\n ).isRequired,\n filledMask: PropTypes.bool.description('Show blank chars positions').defaultValue(false),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskPhoneHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n isInternational: PropTypes.bool.description('Use or not internaltional phone mask number').defaultValue(false),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskNumberHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n suffix: PropTypes.string.description('String will be added at the end of the input value').defaultValue(''),\n prefix: PropTypes.string.description('String will be added at the start of the input value').defaultValue(''),\n decimalPlaces: PropTypes.number.description('Number of decimals allowed').defaultValue(2),\n allowNegative: PropTypes.bool.description('Wether the input allows negative number').defaultValue(false),\n includeThousandsSeparator: PropTypes.bool\n .description('Wether the integer part will be separated by thousands')\n .defaultValue(true),\n decimalRequired: PropTypes.bool.description('Wether decimal part is mandatory').defaultValue(false),\n} as WeakValidationMap<unknown>;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,8BAA0B;AAwCnB,MAAM,yBAAsD;AAAA,EACjE,UAAU,MAAM;AAAA,EAChB,WAAW,MAAM;AAAA,EACjB,QAAQ,MAAM;AAChB;AAEO,MAAM,8BAA8D;AAAA,EACzE,GAAG;AAAA,EACH,iBAAiB;AACnB;AACO,MAAM,+BAAgE;AAAA,EAC3E,GAAG;AAAA,EACH,YAAY;AACd;AAEO,MAAM,+BAAgE;AAAA,EAC3E,GAAG;AAAA,EACH,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,eAAe;AAAA,EACf,2BAA2B;AAAA,EAC3B,iBAAiB;AACnB;AAEO,MAAM,uBAAuB;AAAA,EAClC,aAAa,kCAAU,KAAK,YAAY,wCAAwC,EAAE;AAAA,EAClF,UAAU,kCAAU,KAAK,YAAY,uBAAuB;AAAA,EAC5D,WAAW,kCAAU,KAAK,YAAY,wBAAwB;AAChE;AAEO,MAAM,6BAA6B;AAAA,EACxC,GAAG;AAAA,EACH,QAAQ,kCAAU,QAAQ,kCAAU,UAAU,CAAC,kCAAU,QAAQ,kCAAU,WAAW,MAAM,CAAC,CAAC,CAAC,EAAE;AAAA,IAC/F;AAAA,EACF,EAAE;AAAA,EACF,YAAY,kCAAU,KAAK,YAAY,4BAA4B,EAAE,aAAa,KAAK;AACzF;AAEO,MAAM,4BAA4B;AAAA,EACvC,GAAG;AAAA,EACH,iBAAiB,kCAAU,KAAK,YAAY,6CAA6C,EAAE,aAAa,KAAK;AAC/G;AAEO,MAAM,6BAA6B;AAAA,EACxC,GAAG;AAAA,EACH,QAAQ,kCAAU,OAAO,YAAY,oDAAoD,EAAE,aAAa,EAAE;AAAA,EAC1G,QAAQ,kCAAU,OAAO,YAAY,sDAAsD,EAAE,aAAa,EAAE;AAAA,EAC5G,eAAe,kCAAU,OAAO,YAAY,4BAA4B,EAAE,aAAa,CAAC;AAAA,EACxF,eAAe,kCAAU,KAAK,YAAY,yCAAyC,EAAE,aAAa,KAAK;AAAA,EACvG,2BAA2B,kCAAU,KAClC,YAAY,wDAAwD,EACpE,aAAa,IAAI;AAAA,EACpB,iBAAiB,kCAAU,KAAK,YAAY,kCAAkC,EAAE,aAAa,KAAK;AACpG;",
4
+ "sourcesContent": ["import { PropTypes } from '@elliemae/ds-props-helpers';\nimport type { WeakValidationMap } from 'react';\nimport type React from 'react';\n\nexport declare namespace DSMaskT {\n interface HookArgs {\n valueSetter: React.Dispatch<React.SetStateAction<string>>;\n onChange?: (e: React.ChangeEvent<HTMLInputElement>, mask?: string) => void;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n }\n\n interface HookReturn {\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n }\n\n export interface NumberHookArgs extends HookArgs {\n suffix?: string;\n prefix?: string;\n decimalPlaces?: number;\n allowNegative?: boolean;\n includeThousandsSeparator?: boolean;\n decimalRequired?: boolean;\n }\n\n export interface PhoneHookArgs extends HookArgs {\n isInternational?: boolean;\n }\n\n export interface RegExpHookArgs extends HookArgs {\n filledMask: boolean;\n regExp: string[];\n }\n\n export type Hook = ((args: HookArgs) => HookReturn) & { displayName: string };\n export type PhoneHook = ((args: PhoneHookArgs) => HookReturn) & { displayName: string };\n export type NumberHook = ((args: NumberHookArgs) => HookReturn) & { displayName: string };\n}\n\nexport const DSMaskHookDefaultProps: Partial<DSMaskT.HookArgs> = {\n onChange: () => null,\n onKeyDown: () => null,\n onBlur: () => null,\n};\n\nexport const DSMaskPhoneHookDefaultProps: Partial<DSMaskT.PhoneHookArgs> = {\n ...DSMaskHookDefaultProps,\n isInternational: false,\n};\nexport const DSMaskRegExpHookDefaultProps: Partial<DSMaskT.RegExpHookArgs> = {\n ...DSMaskHookDefaultProps,\n filledMask: false,\n regExp: [],\n};\n\nexport const DSMaskSSNDefaultProps: Partial<DSMaskT.PhoneHookArgs> = {\n ...DSMaskHookDefaultProps,\n};\n\nexport const DSMaskNumberHookDefaultProps: Partial<DSMaskT.NumberHookArgs> = {\n ...DSMaskHookDefaultProps,\n suffix: '',\n prefix: '',\n decimalPlaces: 2,\n allowNegative: false,\n includeThousandsSeparator: true,\n decimalRequired: false,\n};\n\nexport const DSMaskHookPropsTypes = {\n valueSetter: PropTypes.func.description('React set state function for the value').isRequired,\n onChange: PropTypes.func.description('Callback for onChange'),\n onKeyDown: PropTypes.func.description('Callback for onKeyDown'),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskRegExpHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n regExp: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(RegExp)])).description(\n 'Array with regexp or special chars per character',\n ).isRequired,\n filledMask: PropTypes.bool.description('Show blank chars positions').defaultValue(false),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskPhoneHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n isInternational: PropTypes.bool.description('Use or not internaltional phone mask number').defaultValue(false),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskNumberHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n suffix: PropTypes.string.description('String will be added at the end of the input value').defaultValue(''),\n prefix: PropTypes.string.description('String will be added at the start of the input value').defaultValue(''),\n decimalPlaces: PropTypes.number.description('Number of decimals allowed').defaultValue(2),\n allowNegative: PropTypes.bool.description('Wether the input allows negative number').defaultValue(false),\n includeThousandsSeparator: PropTypes.bool\n .description('Wether the integer part will be separated by thousands')\n .defaultValue(true),\n decimalRequired: PropTypes.bool.description('Wether decimal part is mandatory').defaultValue(false),\n} as WeakValidationMap<unknown>;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,8BAA0B;AAyCnB,MAAM,yBAAoD;AAAA,EAC/D,UAAU,MAAM;AAAA,EAChB,WAAW,MAAM;AAAA,EACjB,QAAQ,MAAM;AAChB;AAEO,MAAM,8BAA8D;AAAA,EACzE,GAAG;AAAA,EACH,iBAAiB;AACnB;AACO,MAAM,+BAAgE;AAAA,EAC3E,GAAG;AAAA,EACH,YAAY;AAAA,EACZ,QAAQ,CAAC;AACX;AAEO,MAAM,wBAAwD;AAAA,EACnE,GAAG;AACL;AAEO,MAAM,+BAAgE;AAAA,EAC3E,GAAG;AAAA,EACH,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,eAAe;AAAA,EACf,2BAA2B;AAAA,EAC3B,iBAAiB;AACnB;AAEO,MAAM,uBAAuB;AAAA,EAClC,aAAa,kCAAU,KAAK,YAAY,wCAAwC,EAAE;AAAA,EAClF,UAAU,kCAAU,KAAK,YAAY,uBAAuB;AAAA,EAC5D,WAAW,kCAAU,KAAK,YAAY,wBAAwB;AAChE;AAEO,MAAM,6BAA6B;AAAA,EACxC,GAAG;AAAA,EACH,QAAQ,kCAAU,QAAQ,kCAAU,UAAU,CAAC,kCAAU,QAAQ,kCAAU,WAAW,MAAM,CAAC,CAAC,CAAC,EAAE;AAAA,IAC/F;AAAA,EACF,EAAE;AAAA,EACF,YAAY,kCAAU,KAAK,YAAY,4BAA4B,EAAE,aAAa,KAAK;AACzF;AAEO,MAAM,4BAA4B;AAAA,EACvC,GAAG;AAAA,EACH,iBAAiB,kCAAU,KAAK,YAAY,6CAA6C,EAAE,aAAa,KAAK;AAC/G;AAEO,MAAM,6BAA6B;AAAA,EACxC,GAAG;AAAA,EACH,QAAQ,kCAAU,OAAO,YAAY,oDAAoD,EAAE,aAAa,EAAE;AAAA,EAC1G,QAAQ,kCAAU,OAAO,YAAY,sDAAsD,EAAE,aAAa,EAAE;AAAA,EAC5G,eAAe,kCAAU,OAAO,YAAY,4BAA4B,EAAE,aAAa,CAAC;AAAA,EACxF,eAAe,kCAAU,KAAK,YAAY,yCAAyC,EAAE,aAAa,KAAK;AAAA,EACvG,2BAA2B,kCAAU,KAClC,YAAY,wDAAwD,EACpE,aAAa,IAAI;AAAA,EACpB,iBAAiB,kCAAU,KAAK,YAAY,kCAAkC,EAAE,aAAa,KAAK;AACpG;",
6
6
  "names": []
7
7
  }
@@ -6,10 +6,17 @@ import { setCursorPosition } from "../utils";
6
6
  import { DSMaskNumberHookDefaultProps, DSMaskNumberHookPropsTypes } from "../react-desc-prop-types";
7
7
  const addThousandsSeparator = (n, separator) => n.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
8
8
  const conformValue = (rawValue, cursorPos, lastKeyCode, opts) => {
9
- const { includeThousandsSeparator, allowNegative, prefix, suffix, decimalPlaces, decimalRequired } = opts;
9
+ const {
10
+ includeThousandsSeparator = true,
11
+ allowNegative = false,
12
+ prefix = "",
13
+ suffix = "",
14
+ decimalPlaces = 2,
15
+ decimalRequired = false
16
+ } = opts;
10
17
  const THOUSANDSSEPARATOR = ",";
11
18
  let dotIdx = -1;
12
- let finalPrefix = [prefix.length, 0].includes(rawValue.indexOf("-")) && allowNegative ? "-" : "";
19
+ let finalPrefix = [prefix?.length, 0].includes(rawValue.indexOf("-")) && allowNegative ? "-" : "";
13
20
  let maskedValue = String(rawValue).split("").filter((char, idx) => {
14
21
  const validChar = char >= "0" && char <= "9" || char === "." && dotIdx === -1 && decimalPlaces;
15
22
  if (char === "." && validChar)
@@ -71,7 +78,7 @@ const useNumberMask = (props) => {
71
78
  const maskedValue = e.target.value;
72
79
  const dotIdx = maskedValue.indexOf(".");
73
80
  const minusIndex = maskedValue.indexOf("-");
74
- const { decimalRequired, decimalPlaces, suffix } = opts;
81
+ const { decimalRequired = true, decimalPlaces = 2, suffix = "" } = opts;
75
82
  const suffixIndex = suffix.length ? maskedValue.indexOf(suffix) : -1;
76
83
  if (decimalRequired) {
77
84
  if (dotIdx > -1) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../../src/hooks/useNumberMask.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-params */\n/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskNumberHookDefaultProps, DSMaskNumberHookPropsTypes } from '../react-desc-prop-types';\n\nconst addThousandsSeparator = (n: string, separator: string) => n.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n opts: DSMaskT.NumberHookArgs,\n): [string, number] => {\n const { includeThousandsSeparator, allowNegative, prefix, suffix, decimalPlaces, decimalRequired } = opts;\n const THOUSANDSSEPARATOR = ',';\n\n let dotIdx = -1;\n // allow minus sign before and after the preffix\n let finalPrefix = [prefix.length, 0].includes(rawValue.indexOf('-')) && allowNegative ? '-' : '';\n\n let maskedValue = String(rawValue)\n .split('')\n .filter((char, idx) => {\n // we take only the first dot\n const validChar = (char >= '0' && char <= '9') || (char === '.' && dotIdx === -1 && decimalPlaces);\n if (char === '.' && validChar) dotIdx = idx;\n return validChar;\n });\n\n if (prefix && maskedValue.length) finalPrefix += prefix;\n\n // REMOVE FOLLOWING ZEROS IN INTEGER PART AFTER LEADER ZERO NUMBER\n while (maskedValue.length >= 2 && maskedValue[0] === '0' && maskedValue[1] !== '.') {\n maskedValue = maskedValue.splice(1);\n }\n dotIdx = maskedValue.findIndex((char) => char === '.');\n\n let integer = maskedValue.slice(0, dotIdx !== -1 ? dotIdx : maskedValue.length);\n const decimal = maskedValue.slice(dotIdx, dotIdx + decimalPlaces + 1);\n // ADDING THOUSANDS SEPARATOR\n if (includeThousandsSeparator) {\n integer = addThousandsSeparator(integer.join(''), THOUSANDSSEPARATOR).split('');\n }\n\n // MERGIN INT AND DECIMAL IF NECCESSARY\n if (dotIdx !== -1 && !(lastKeyCode === 'Backspace' && decimal.length === 1)) {\n if (integer.length) {\n maskedValue = [...integer, ...decimal];\n } else {\n // if theres no integer add a zero to the left of the dot to cover .23 => 0.23 case\n maskedValue = ['0', ...decimal];\n }\n } else {\n // If decimal is required we add a dot after integer if exists\n maskedValue = decimalRequired && integer.length ? [...integer, '.'] : integer;\n }\n\n // remove orphans prefix for example \"-$\"\n if (lastKeyCode === 'Backspace' && maskedValue.length === 0) {\n finalPrefix = '';\n }\n\n // SET REAL CURSOR POSITION AFTER ADDING DOT and COMMAS SEPARATORS\n let maskedPos = 0;\n\n // 0 leading case we move the cursor to continue typing\n if (maskedValue[maskedPos] === '0' && cursorPos === 1 + prefix.length) maskedPos += 1;\n\n for (let i = 0; i < cursorPos; i += 1) {\n if (maskedValue[maskedPos] === THOUSANDSSEPARATOR) maskedPos += 1;\n if (maskedValue[maskedPos] === rawValue[i]) maskedPos += 1;\n }\n\n maskedPos += finalPrefix.length;\n\n const finalSuffix = maskedValue.length ? suffix : '';\n\n const maskedValueString = finalPrefix + maskedValue.join('') + finalSuffix;\n return [maskedValueString, maskedPos];\n};\n\nexport const useNumberMask: DSMaskT.NumberHook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskNumberHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskNumberHookPropsTypes, 'useNumberMask');\n\n const {\n valueSetter,\n onChange: userOnChange,\n onKeyDown: userOnKeyDown,\n onBlur: userOnBlur,\n ...opts\n } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onBlur: React.FocusEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const maskedValue = e.target.value;\n const dotIdx = maskedValue.indexOf('.');\n const minusIndex = maskedValue.indexOf('-');\n\n const { decimalRequired, decimalPlaces, suffix } = opts;\n\n const suffixIndex = suffix.length ? maskedValue.indexOf(suffix) : -1;\n\n if (decimalRequired) {\n if (dotIdx > -1) {\n const decimal = maskedValue.slice(dotIdx + 1, suffix.length ? -suffix.length : maskedValue.length);\n\n let zerosRest = '';\n while (decimal.length + zerosRest.length !== decimalPlaces) {\n zerosRest += '0';\n }\n\n valueSetter((suffix.length ? maskedValue.slice(0, suffixIndex) : maskedValue) + zerosRest + suffix);\n }\n } else if (maskedValue.length - suffix.length - 1 === dotIdx) {\n // removing orphans dots\n valueSetter(maskedValue.replace('.', ''));\n } else if (maskedValue.length - 1 === minusIndex) {\n // removing orphans minus\n valueSetter(maskedValue.replace('-', ''));\n }\n if (userOnBlur) userOnBlur(e);\n },\n [userOnBlur, valueSetter, opts],\n );\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(\n e.target.value,\n e.target.selectionEnd ?? 0,\n lastKeyCode.current,\n opts as DSMaskT.NumberHookArgs,\n );\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n\n return mask;\n });\n if (userOnChange) userOnChange(e, mask);\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange, opts],\n );\n\n return {\n onKeyDown,\n onChange,\n onBlur,\n };\n};\n\nexport const getNumberMaskedValue = (value: string, opts: DSMaskT.NumberHookArgs) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', opts);\n return maskedValue;\n};\n\nuseNumberMask.displayName = 'useNumberMask';\nexport const UseNumberMaskWithSchema = describe(useNumberMask);\nUseNumberMaskWithSchema.propTypes = DSMaskNumberHookPropsTypes;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-params */\n/* eslint-disable max-statements */\n/* eslint-disable complexity */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskNumberHookDefaultProps, DSMaskNumberHookPropsTypes } from '../react-desc-prop-types';\n\nconst addThousandsSeparator = (n: string, separator: string) => n.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n opts: Partial<DSMaskT.NumberHookArgs>,\n): [string, number] => {\n const {\n includeThousandsSeparator = true,\n allowNegative = false,\n prefix = '',\n suffix = '',\n decimalPlaces = 2,\n decimalRequired = false,\n } = opts;\n const THOUSANDSSEPARATOR = ',';\n\n let dotIdx = -1;\n // allow minus sign before and after the preffix\n let finalPrefix = [prefix?.length, 0].includes(rawValue.indexOf('-')) && allowNegative ? '-' : '';\n\n let maskedValue = String(rawValue)\n .split('')\n .filter((char, idx) => {\n // we take only the first dot\n const validChar = (char >= '0' && char <= '9') || (char === '.' && dotIdx === -1 && decimalPlaces);\n if (char === '.' && validChar) dotIdx = idx;\n return validChar;\n });\n\n if (prefix && maskedValue.length) finalPrefix += prefix;\n\n // REMOVE FOLLOWING ZEROS IN INTEGER PART AFTER LEADER ZERO NUMBER\n while (maskedValue.length >= 2 && maskedValue[0] === '0' && maskedValue[1] !== '.') {\n maskedValue = maskedValue.splice(1);\n }\n dotIdx = maskedValue.findIndex((char) => char === '.');\n\n let integer = maskedValue.slice(0, dotIdx !== -1 ? dotIdx : maskedValue.length);\n const decimal = maskedValue.slice(dotIdx, dotIdx + decimalPlaces + 1);\n // ADDING THOUSANDS SEPARATOR\n if (includeThousandsSeparator) {\n integer = addThousandsSeparator(integer.join(''), THOUSANDSSEPARATOR).split('');\n }\n\n // MERGIN INT AND DECIMAL IF NECCESSARY\n if (dotIdx !== -1 && !(lastKeyCode === 'Backspace' && decimal.length === 1)) {\n if (integer.length) {\n maskedValue = [...integer, ...decimal];\n } else {\n // if theres no integer add a zero to the left of the dot to cover .23 => 0.23 case\n maskedValue = ['0', ...decimal];\n }\n } else {\n // If decimal is required we add a dot after integer if exists\n maskedValue = decimalRequired && integer.length ? [...integer, '.'] : integer;\n }\n\n // remove orphans prefix for example \"-$\"\n if (lastKeyCode === 'Backspace' && maskedValue.length === 0) {\n finalPrefix = '';\n }\n\n // SET REAL CURSOR POSITION AFTER ADDING DOT and COMMAS SEPARATORS\n let maskedPos = 0;\n\n // 0 leading case we move the cursor to continue typing\n if (maskedValue[maskedPos] === '0' && cursorPos === 1 + prefix.length) maskedPos += 1;\n\n for (let i = 0; i < cursorPos; i += 1) {\n if (maskedValue[maskedPos] === THOUSANDSSEPARATOR) maskedPos += 1;\n if (maskedValue[maskedPos] === rawValue[i]) maskedPos += 1;\n }\n\n maskedPos += finalPrefix.length;\n\n const finalSuffix = maskedValue.length ? suffix : '';\n\n const maskedValueString = finalPrefix + maskedValue.join('') + finalSuffix;\n return [maskedValueString, maskedPos];\n};\n\nexport const useNumberMask: DSMaskT.NumberHook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskNumberHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskNumberHookPropsTypes, 'useNumberMask');\n\n const {\n valueSetter,\n onChange: userOnChange,\n onKeyDown: userOnKeyDown,\n onBlur: userOnBlur,\n ...opts\n } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onBlur: React.FocusEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const maskedValue = e.target.value;\n const dotIdx = maskedValue.indexOf('.');\n const minusIndex = maskedValue.indexOf('-');\n\n const { decimalRequired = true, decimalPlaces = 2, suffix = '' } = opts;\n\n const suffixIndex = suffix.length ? maskedValue.indexOf(suffix) : -1;\n\n if (decimalRequired) {\n if (dotIdx > -1) {\n const decimal = maskedValue.slice(dotIdx + 1, suffix.length ? -suffix.length : maskedValue.length);\n\n let zerosRest = '';\n while (decimal.length + zerosRest.length !== decimalPlaces) {\n zerosRest += '0';\n }\n\n valueSetter((suffix.length ? maskedValue.slice(0, suffixIndex) : maskedValue) + zerosRest + suffix);\n }\n } else if (maskedValue.length - suffix.length - 1 === dotIdx) {\n // removing orphans dots\n valueSetter(maskedValue.replace('.', ''));\n } else if (maskedValue.length - 1 === minusIndex) {\n // removing orphans minus\n valueSetter(maskedValue.replace('-', ''));\n }\n if (userOnBlur) userOnBlur(e);\n },\n [userOnBlur, valueSetter, opts],\n );\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(\n e.target.value,\n e.target.selectionEnd ?? 0,\n lastKeyCode.current,\n opts as DSMaskT.NumberHookArgs,\n );\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n\n return mask;\n });\n if (userOnChange) userOnChange(e, mask);\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange, opts],\n );\n\n return {\n onKeyDown,\n onChange,\n onBlur,\n };\n};\n\nexport const getNumberMaskedValue = (value: string, opts: DSMaskT.NumberHookArgs) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', opts);\n return maskedValue;\n};\n\nuseNumberMask.displayName = 'useNumberMask';\nexport const UseNumberMaskWithSchema = describe(useNumberMask);\nUseNumberMaskWithSchema.propTypes = DSMaskNumberHookPropsTypes;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACIvB,SAAS,aAAa,QAAQ,gBAAgB;AAC9C,SAAS,UAAU,8BAA8B,sCAAsC;AACvF,SAAS,8BAA8B;AACvC,SAAS,yBAAyB;AAElC,SAAS,8BAA8B,kCAAkC;AAEzE,MAAM,wBAAwB,CAAC,GAAW,cAAsB,EAAE,QAAQ,yBAAyB,SAAS;AAE5G,MAAM,eAAe,CACnB,UACA,WACA,aACA,SACqB;AACrB,QAAM;AAAA,IACJ,4BAA4B;AAAA,IAC5B,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,EACpB,IAAI;AACJ,QAAM,qBAAqB;AAE3B,MAAI,SAAS;AAEb,MAAI,cAAc,CAAC,QAAQ,QAAQ,CAAC,EAAE,SAAS,SAAS,QAAQ,GAAG,CAAC,KAAK,gBAAgB,MAAM;AAE/F,MAAI,cAAc,OAAO,QAAQ,EAC9B,MAAM,EAAE,EACR,OAAO,CAAC,MAAM,QAAQ;AAErB,UAAM,YAAa,QAAQ,OAAO,QAAQ,OAAS,SAAS,OAAO,WAAW,MAAM;AACpF,QAAI,SAAS,OAAO;AAAW,eAAS;AACxC,WAAO;AAAA,EACT,CAAC;AAEH,MAAI,UAAU,YAAY;AAAQ,mBAAe;AAGjD,SAAO,YAAY,UAAU,KAAK,YAAY,OAAO,OAAO,YAAY,OAAO,KAAK;AAClF,kBAAc,YAAY,OAAO,CAAC;AAAA,EACpC;AACA,WAAS,YAAY,UAAU,CAAC,SAAS,SAAS,GAAG;AAErD,MAAI,UAAU,YAAY,MAAM,GAAG,WAAW,KAAK,SAAS,YAAY,MAAM;AAC9E,QAAM,UAAU,YAAY,MAAM,QAAQ,SAAS,gBAAgB,CAAC;AAEpE,MAAI,2BAA2B;AAC7B,cAAU,sBAAsB,QAAQ,KAAK,EAAE,GAAG,kBAAkB,EAAE,MAAM,EAAE;AAAA,EAChF;AAGA,MAAI,WAAW,MAAM,EAAE,gBAAgB,eAAe,QAAQ,WAAW,IAAI;AAC3E,QAAI,QAAQ,QAAQ;AAClB,oBAAc,CAAC,GAAG,SAAS,GAAG,OAAO;AAAA,IACvC,OAAO;AAEL,oBAAc,CAAC,KAAK,GAAG,OAAO;AAAA,IAChC;AAAA,EACF,OAAO;AAEL,kBAAc,mBAAmB,QAAQ,SAAS,CAAC,GAAG,SAAS,GAAG,IAAI;AAAA,EACxE;AAGA,MAAI,gBAAgB,eAAe,YAAY,WAAW,GAAG;AAC3D,kBAAc;AAAA,EAChB;AAGA,MAAI,YAAY;AAGhB,MAAI,YAAY,eAAe,OAAO,cAAc,IAAI,OAAO;AAAQ,iBAAa;AAEpF,WAAS,IAAI,GAAG,IAAI,WAAW,KAAK,GAAG;AACrC,QAAI,YAAY,eAAe;AAAoB,mBAAa;AAChE,QAAI,YAAY,eAAe,SAAS;AAAI,mBAAa;AAAA,EAC3D;AAEA,eAAa,YAAY;AAEzB,QAAM,cAAc,YAAY,SAAS,SAAS;AAElD,QAAM,oBAAoB,cAAc,YAAY,KAAK,EAAE,IAAI;AAC/D,SAAO,CAAC,mBAAmB,SAAS;AACtC;AAEO,MAAM,gBAAoC,CAAC,UAAU;AAC1D,QAAM,mBAAmB,6BAA6B,OAAO,4BAA4B;AACzF,iCAA+B,kBAAkB,4BAA4B,eAAe;AAE5F,QAAM;AAAA,IACJ;AAAA,IACA,UAAU;AAAA,IACV,WAAW;AAAA,IACX,QAAQ;AAAA,OACL;AAAA,EACL,IAAI;AAEJ,QAAM,cAAc,OAAO,cAAc;AAEzC,QAAM,sBAAsB,uBAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC;AAE7B,QAAM,SAAoD;AAAA,IACxD,CAAC,MAAM;AACL,YAAM,cAAc,EAAE,OAAO;AAC7B,YAAM,SAAS,YAAY,QAAQ,GAAG;AACtC,YAAM,aAAa,YAAY,QAAQ,GAAG;AAE1C,YAAM,EAAE,kBAAkB,MAAM,gBAAgB,GAAG,SAAS,GAAG,IAAI;AAEnE,YAAM,cAAc,OAAO,SAAS,YAAY,QAAQ,MAAM,IAAI;AAElE,UAAI,iBAAiB;AACnB,YAAI,SAAS,IAAI;AACf,gBAAM,UAAU,YAAY,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,OAAO,SAAS,YAAY,MAAM;AAEjG,cAAI,YAAY;AAChB,iBAAO,QAAQ,SAAS,UAAU,WAAW,eAAe;AAC1D,yBAAa;AAAA,UACf;AAEA,uBAAa,OAAO,SAAS,YAAY,MAAM,GAAG,WAAW,IAAI,eAAe,YAAY,MAAM;AAAA,QACpG;AAAA,MACF,WAAW,YAAY,SAAS,OAAO,SAAS,MAAM,QAAQ;AAE5D,oBAAY,YAAY,QAAQ,KAAK,EAAE,CAAC;AAAA,MAC1C,WAAW,YAAY,SAAS,MAAM,YAAY;AAEhD,oBAAY,YAAY,QAAQ,KAAK,EAAE,CAAC;AAAA,MAC1C;AACA,UAAI;AAAY,mBAAW,CAAC;AAAA,IAC9B;AAAA,IACA,CAAC,YAAY,aAAa,IAAI;AAAA,EAChC;AAEA,QAAM,YAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,WAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI;AAAA,QACxB,EAAE,OAAO;AAAA,QACT,EAAE,OAAO,gBAAgB;AAAA,QACzB,YAAY;AAAA,QACZ;AAAA,MACF;AACA,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAE9C,eAAO;AAAA,MACT,CAAC;AACD,UAAI;AAAc,qBAAa,GAAG,IAAI;AACtC,0BAAoB,MAAM,kBAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,cAAc,IAAI;AAAA,EACvD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,uBAAuB,CAAC,OAAe,SAAiC;AACnF,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,IAAI,IAAI;AACpE,SAAO;AACT;AAEA,cAAc,cAAc;AACrB,MAAM,0BAA0B,SAAS,aAAa;AAC7D,wBAAwB,YAAY;",
6
6
  "names": []
7
7
  }
@@ -16,7 +16,7 @@ const internationalPhoneSpecialChars = [
16
16
  ];
17
17
  const conformValue = (rawValue, cursorPos, lastKeyCode, opts) => {
18
18
  const characters = String(rawValue).split("");
19
- const { isInternational } = opts;
19
+ const { isInternational = false } = opts;
20
20
  let maskedValue = characters.filter((char, idx, array) => {
21
21
  if (isInternational && idx === 1 && char === "1" && array[0] === "+") {
22
22
  return false;
@@ -37,7 +37,7 @@ const conformValue = (rawValue, cursorPos, lastKeyCode, opts) => {
37
37
  const usePhoneMask = (props) => {
38
38
  const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskPhoneHookDefaultProps);
39
39
  useValidateTypescriptPropTypes(propsWithDefault, DSMaskPhoneHookPropsTypes, "usePhoneMask");
40
- const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown, onBlur, ...opts } = propsWithDefault;
40
+ const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown, ...opts } = propsWithDefault;
41
41
  const lastKeyCode = useRef("Unidentified");
42
42
  const scheduleAfterRender = useCallbackAfterRender(true);
43
43
  const [, setKey] = useState(0);
@@ -68,7 +68,7 @@ const usePhoneMask = (props) => {
68
68
  onChange
69
69
  };
70
70
  };
71
- const getPhoneMaskedValue = (value, opts) => {
71
+ const getPhoneMaskedValue = (value, opts = {}) => {
72
72
  const [maskedValue] = conformValue(value, value.length - 1, "", opts);
73
73
  return maskedValue;
74
74
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../../src/hooks/usePhoneMask.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-params */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskPhoneHookPropsTypes, DSMaskPhoneHookDefaultProps } from '../react-desc-prop-types';\n\nconst phoneSpecialChars: [string, number][] = [\n ['(', 0],\n [') ', 4],\n [' - ', 9],\n];\n\nconst internationalPhoneSpecialChars: [string, number][] = [\n ['+1 (', 0],\n [') ', 7],\n [' - ', 12],\n];\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n opts: Partial<DSMaskT.PhoneHookArgs>,\n) => {\n const characters = String(rawValue).split('');\n // Work with digits only\n const { isInternational } = opts;\n let maskedValue = characters.filter((char, idx, array) => {\n if (isInternational && idx === 1 && char === '1' && array[0] === '+') {\n return false;\n }\n return char >= '0' && char <= '9';\n });\n // We can't have zeros at the start of the array\n while (maskedValue.length && maskedValue[0] === '0') maskedValue.splice(0, 1);\n\n // We only consider first 10 digits\n maskedValue = maskedValue.slice(0, 10);\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n\n return addSpecialCharacters(\n maskedValue,\n isInternational ? internationalPhoneSpecialChars : phoneSpecialChars,\n maskedPos,\n lastKeyCode,\n );\n};\n\nexport const usePhoneMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskPhoneHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskPhoneHookPropsTypes, 'usePhoneMask');\n const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown, onBlur, ...opts } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(e.target.value, e.target.selectionEnd ?? 0, lastKeyCode.current, opts);\n\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n return mask;\n });\n\n if (userOnChange) userOnChange(e, mask);\n\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, opts, userOnChange],\n );\n\n return {\n onKeyDown,\n onChange,\n };\n};\n\nexport const getPhoneMaskedValue = (value: string, opts: Partial<DSMaskT.PhoneHookArgs>) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', opts);\n return maskedValue;\n};\n\nusePhoneMask.displayName = 'usePhoneMask';\nexport const UsePhoneMaskWithSchema = describe(usePhoneMask);\nUsePhoneMaskWithSchema.propTypes = DSMaskPhoneHookPropsTypes;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,aAAa,QAAQ,gBAAgB;AAC9C,SAAS,UAAU,8BAA8B,sCAAsC;AACvF,SAAS,8BAA8B;AACvC,SAAS,sBAAsB,qBAAqB,yBAAyB;AAE7E,SAAS,2BAA2B,mCAAmC;AAEvE,MAAM,oBAAwC;AAAA,EAC5C,CAAC,KAAK,CAAC;AAAA,EACP,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,OAAO,CAAC;AACX;AAEA,MAAM,iCAAqD;AAAA,EACzD,CAAC,QAAQ,CAAC;AAAA,EACV,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,OAAO,EAAE;AACZ;AAEA,MAAM,eAAe,CACnB,UACA,WACA,aACA,SACG;AACH,QAAM,aAAa,OAAO,QAAQ,EAAE,MAAM,EAAE;AAE5C,QAAM,EAAE,gBAAgB,IAAI;AAC5B,MAAI,cAAc,WAAW,OAAO,CAAC,MAAM,KAAK,UAAU;AACxD,QAAI,mBAAmB,QAAQ,KAAK,SAAS,OAAO,MAAM,OAAO,KAAK;AACpE,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,OAAO,QAAQ;AAAA,EAChC,CAAC;AAED,SAAO,YAAY,UAAU,YAAY,OAAO;AAAK,gBAAY,OAAO,GAAG,CAAC;AAG5E,gBAAc,YAAY,MAAM,GAAG,EAAE;AAErC,QAAM,YAAY,oBAAoB,UAAU,aAAa,SAAS;AAEtE,SAAO;AAAA,IACL;AAAA,IACA,kBAAkB,iCAAiC;AAAA,IACnD;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,eAA6B,CAAC,UAAU;AACnD,QAAM,mBAAmB,6BAA6B,OAAO,2BAA2B;AACxF,iCAA+B,kBAAkB,2BAA2B,cAAc;AAC1F,QAAM,EAAE,aAAa,UAAU,cAAc,WAAW,eAAe,WAAW,KAAK,IAAI;AAE3F,QAAM,cAAc,OAAO,cAAc;AAEzC,QAAM,sBAAsB,uBAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC;AAE7B,QAAM,YAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,WAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI,aAAa,EAAE,OAAO,OAAO,EAAE,OAAO,gBAAgB,GAAG,YAAY,SAAS,IAAI;AAE5G,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAC9C,eAAO;AAAA,MACT,CAAC;AAED,UAAI;AAAc,qBAAa,GAAG,IAAI;AAEtC,0BAAoB,MAAM,kBAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,MAAM,YAAY;AAAA,EACvD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,CAAC,OAAe,SAAyC;AAC1F,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,IAAI,IAAI;AACpE,SAAO;AACT;AAEA,aAAa,cAAc;AACpB,MAAM,yBAAyB,SAAS,YAAY;AAC3D,uBAAuB,YAAY;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-params */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskPhoneHookPropsTypes, DSMaskPhoneHookDefaultProps } from '../react-desc-prop-types';\n\nconst phoneSpecialChars: [string, number][] = [\n ['(', 0],\n [') ', 4],\n [' - ', 9],\n];\n\nconst internationalPhoneSpecialChars: [string, number][] = [\n ['+1 (', 0],\n [') ', 7],\n [' - ', 12],\n];\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n opts: Partial<DSMaskT.PhoneHookArgs>,\n) => {\n const characters = String(rawValue).split('');\n // Work with digits only\n const { isInternational = false } = opts;\n let maskedValue = characters.filter((char, idx, array) => {\n if (isInternational && idx === 1 && char === '1' && array[0] === '+') {\n return false;\n }\n return char >= '0' && char <= '9';\n });\n // We can't have zeros at the start of the array\n while (maskedValue.length && maskedValue[0] === '0') maskedValue.splice(0, 1);\n\n // We only consider first 10 digits\n maskedValue = maskedValue.slice(0, 10);\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n\n return addSpecialCharacters(\n maskedValue,\n isInternational ? internationalPhoneSpecialChars : phoneSpecialChars,\n maskedPos,\n lastKeyCode,\n );\n};\n\nexport const usePhoneMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskPhoneHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskPhoneHookPropsTypes, 'usePhoneMask');\n const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown, ...opts } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(e.target.value, e.target.selectionEnd ?? 0, lastKeyCode.current, opts);\n\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n return mask;\n });\n\n if (userOnChange) userOnChange(e, mask);\n\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, opts, userOnChange],\n );\n\n return {\n onKeyDown,\n onChange,\n };\n};\n\nexport const getPhoneMaskedValue = (value: string, opts: Partial<DSMaskT.PhoneHookArgs> = {}) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', opts);\n return maskedValue;\n};\n\nusePhoneMask.displayName = 'usePhoneMask';\nexport const UsePhoneMaskWithSchema = describe(usePhoneMask);\nUsePhoneMaskWithSchema.propTypes = DSMaskPhoneHookPropsTypes;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB,SAAS,aAAa,QAAQ,gBAAgB;AAC9C,SAAS,UAAU,8BAA8B,sCAAsC;AACvF,SAAS,8BAA8B;AACvC,SAAS,sBAAsB,qBAAqB,yBAAyB;AAE7E,SAAS,2BAA2B,mCAAmC;AAEvE,MAAM,oBAAwC;AAAA,EAC5C,CAAC,KAAK,CAAC;AAAA,EACP,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,OAAO,CAAC;AACX;AAEA,MAAM,iCAAqD;AAAA,EACzD,CAAC,QAAQ,CAAC;AAAA,EACV,CAAC,MAAM,CAAC;AAAA,EACR,CAAC,OAAO,EAAE;AACZ;AAEA,MAAM,eAAe,CACnB,UACA,WACA,aACA,SACG;AACH,QAAM,aAAa,OAAO,QAAQ,EAAE,MAAM,EAAE;AAE5C,QAAM,EAAE,kBAAkB,MAAM,IAAI;AACpC,MAAI,cAAc,WAAW,OAAO,CAAC,MAAM,KAAK,UAAU;AACxD,QAAI,mBAAmB,QAAQ,KAAK,SAAS,OAAO,MAAM,OAAO,KAAK;AACpE,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,OAAO,QAAQ;AAAA,EAChC,CAAC;AAED,SAAO,YAAY,UAAU,YAAY,OAAO;AAAK,gBAAY,OAAO,GAAG,CAAC;AAG5E,gBAAc,YAAY,MAAM,GAAG,EAAE;AAErC,QAAM,YAAY,oBAAoB,UAAU,aAAa,SAAS;AAEtE,SAAO;AAAA,IACL;AAAA,IACA,kBAAkB,iCAAiC;AAAA,IACnD;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,eAA6B,CAAC,UAAU;AACnD,QAAM,mBAAmB,6BAA6B,OAAO,2BAA2B;AACxF,iCAA+B,kBAAkB,2BAA2B,cAAc;AAC1F,QAAM,EAAE,aAAa,UAAU,cAAc,WAAW,kBAAkB,KAAK,IAAI;AAEnF,QAAM,cAAc,OAAO,cAAc;AAEzC,QAAM,sBAAsB,uBAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC;AAE7B,QAAM,YAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,WAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI,aAAa,EAAE,OAAO,OAAO,EAAE,OAAO,gBAAgB,GAAG,YAAY,SAAS,IAAI;AAE5G,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAC9C,eAAO;AAAA,MACT,CAAC;AAED,UAAI;AAAc,qBAAa,GAAG,IAAI;AAEtC,0BAAoB,MAAM,kBAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,MAAM,YAAY;AAAA,EACvD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,CAAC,OAAe,OAAuC,CAAC,MAAM;AAC/F,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,IAAI,IAAI;AACpE,SAAO;AACT;AAEA,aAAa,cAAc;AACpB,MAAM,yBAAyB,SAAS,YAAY;AAC3D,uBAAuB,YAAY;",
6
6
  "names": []
7
7
  }
@@ -48,7 +48,8 @@ const conformValue = (rawValue, cursorPos, lastKeyCode, regExp, filledMask) => {
48
48
  maskedPos,
49
49
  lastKeyCode
50
50
  );
51
- return [maskWithSpecialsChars + specialCharsLeft, finalMaskedPos];
51
+ const maskReturn = maskWithSpecialsChars + specialCharsLeft;
52
+ return [maskReturn, finalMaskedPos];
52
53
  };
53
54
  const useRegExpMask = (props) => {
54
55
  const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskRegExpHookDefaultProps);
@@ -90,7 +91,7 @@ const useRegExpMask = (props) => {
90
91
  userOnChange(e, mask);
91
92
  scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));
92
93
  },
93
- [valueSetter, scheduleAfterRender, userOnChange]
94
+ [regExp, filledMask, valueSetter, userOnChange, scheduleAfterRender]
94
95
  );
95
96
  const onBlur = useCallback(
96
97
  (e) => {
@@ -104,7 +105,7 @@ const useRegExpMask = (props) => {
104
105
  if (userOnBlur)
105
106
  userOnBlur(e);
106
107
  },
107
- [valueSetter, userOnBlur]
108
+ [filledMask, userOnBlur, regExp, valueSetter]
108
109
  );
109
110
  return {
110
111
  onKeyDown,
@@ -112,11 +113,16 @@ const useRegExpMask = (props) => {
112
113
  onBlur
113
114
  };
114
115
  };
116
+ const getRegExpMaskedValue = (value, regExp) => {
117
+ const [maskedValue] = conformValue(value, value.length - 1, "", regExp, false);
118
+ return maskedValue;
119
+ };
115
120
  useRegExpMask.displayName = "useRegExpMask";
116
121
  const UseRegExpMaskWithSchema = describe(useRegExpMask);
117
122
  UseRegExpMaskWithSchema.propTypes = DSMaskRegExpHookPropsTypes;
118
123
  export {
119
124
  UseRegExpMaskWithSchema,
125
+ getRegExpMaskedValue,
120
126
  useRegExpMask
121
127
  };
122
128
  //# sourceMappingURL=useRegExpMask.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../../src/hooks/useRegExpMask.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-depth */\n/* eslint-disable max-statements */\n/* eslint-disable max-params */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition, flatStringArray } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskRegExpHookPropsTypes, DSMaskRegExpHookDefaultProps } from '../react-desc-prop-types';\n\nconst isRegExp = (item: RegExp | string): item is RegExp => typeof item === 'object';\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n regExp: string[],\n filledMask: boolean,\n) => {\n const specialChars: [string, number][] = [];\n const flatRegExp = flatStringArray(regExp);\n const rawValueArray = String(rawValue).split('');\n let offSet = 0;\n let charsFound = 0;\n let specialCharsLeft = '';\n let fullRegExpMatched = false;\n const maskedValue: string[] = [];\n for (let i = 0; i < flatRegExp.length; i += 1) {\n if (isRegExp(flatRegExp[i])) {\n specialCharsLeft = '';\n fullRegExpMatched = false;\n for (let j = charsFound + offSet; j < rawValueArray.length; j += 1) {\n const match = rawValueArray[j]?.match(flatRegExp[i]);\n if (match) {\n maskedValue.push(match[0]);\n charsFound += 1;\n fullRegExpMatched = true;\n break;\n } else {\n offSet += 1;\n }\n }\n if (filledMask && !fullRegExpMatched) {\n maskedValue.push('_');\n }\n } else {\n specialChars.push([flatRegExp[i], i]);\n if (rawValueArray[i + offSet] === flatRegExp[i]) charsFound += 1;\n specialCharsLeft += flatRegExp[i];\n }\n }\n if (!fullRegExpMatched) specialCharsLeft = '';\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n const [maskWithSpecialsChars, finalMaskedPos] = addSpecialCharacters(\n maskedValue,\n specialChars,\n maskedPos,\n lastKeyCode,\n );\n\n return [maskWithSpecialsChars + specialCharsLeft, finalMaskedPos];\n};\n\nexport const useRegExpMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskRegExpHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskRegExpHookPropsTypes, 'useRegExpMask');\n const {\n valueSetter,\n onChange: userOnChange,\n onKeyDown: userOnKeyDown,\n onBlur: userOnBlur,\n regExp,\n filledMask,\n } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(\n e.target.value,\n e.target.selectionEnd ?? 0,\n lastKeyCode.current,\n regExp,\n filledMask,\n );\n\n valueSetter((prevMask) => {\n // Here we need to update the key\n\n if (mask === prevMask) setKey((key) => key + 1);\n return mask;\n });\n\n if (userOnChange) userOnChange(e, mask);\n\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange],\n );\n const onBlur: React.FocusEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n if (filledMask) {\n const maskedValue = e.target.value.split('');\n\n const flatRegExp = flatStringArray(regExp);\n const firstUnderscoreIdx = maskedValue.findIndex((char, idx) => char === '_' && flatRegExp[idx] !== '_');\n if (firstUnderscoreIdx > -1) valueSetter(maskedValue.slice(0, firstUnderscoreIdx).join(''));\n }\n\n if (userOnBlur) userOnBlur(e);\n },\n [valueSetter, userOnBlur],\n );\n\n return {\n onKeyDown,\n onChange,\n onBlur,\n };\n};\n\nuseRegExpMask.displayName = 'useRegExpMask';\nexport const UseRegExpMaskWithSchema = describe(useRegExpMask);\nUseRegExpMaskWithSchema.propTypes = DSMaskRegExpHookPropsTypes;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-depth */\n/* eslint-disable max-statements */\n/* eslint-disable max-params */\nimport type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition, flatStringArray } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskRegExpHookPropsTypes, DSMaskRegExpHookDefaultProps } from '../react-desc-prop-types';\n\nconst isRegExp = (item: RegExp | string): item is RegExp => typeof item === 'object';\n\nconst conformValue = (\n rawValue: string,\n cursorPos: number,\n lastKeyCode: string,\n regExp: string[],\n filledMask: boolean,\n) => {\n const specialChars: [string, number][] = [];\n const flatRegExp = flatStringArray(regExp);\n const rawValueArray = String(rawValue).split('');\n let offSet = 0;\n let charsFound = 0;\n let specialCharsLeft = '';\n let fullRegExpMatched = false;\n const maskedValue: string[] = [];\n for (let i = 0; i < flatRegExp.length; i += 1) {\n if (isRegExp(flatRegExp[i])) {\n specialCharsLeft = '';\n fullRegExpMatched = false;\n for (let j = charsFound + offSet; j < rawValueArray.length; j += 1) {\n const match = rawValueArray[j]?.match(flatRegExp[i]);\n if (match) {\n maskedValue.push(match[0]);\n charsFound += 1;\n fullRegExpMatched = true;\n break;\n } else {\n offSet += 1;\n }\n }\n if (filledMask && !fullRegExpMatched) {\n maskedValue.push('_');\n }\n } else {\n specialChars.push([flatRegExp[i], i]);\n if (rawValueArray[i + offSet] === flatRegExp[i]) charsFound += 1;\n specialCharsLeft += flatRegExp[i];\n }\n }\n if (!fullRegExpMatched) specialCharsLeft = '';\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n const [maskWithSpecialsChars, finalMaskedPos] = addSpecialCharacters(\n maskedValue,\n specialChars,\n maskedPos,\n lastKeyCode,\n );\n const maskReturn = maskWithSpecialsChars + specialCharsLeft;\n return [maskReturn, finalMaskedPos];\n};\n\nexport const useRegExpMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskRegExpHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskRegExpHookPropsTypes, 'useRegExpMask');\n const {\n valueSetter,\n onChange: userOnChange,\n onKeyDown: userOnKeyDown,\n onBlur: userOnBlur,\n regExp,\n filledMask,\n } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(\n e.target.value,\n e.target.selectionEnd ?? 0,\n lastKeyCode.current,\n regExp,\n filledMask,\n );\n\n valueSetter((prevMask) => {\n // Here we need to update the key\n\n if (mask === prevMask) setKey((key) => key + 1);\n return mask as string;\n });\n\n if (userOnChange) userOnChange(e, mask as string);\n\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos as number));\n },\n [regExp, filledMask, valueSetter, userOnChange, scheduleAfterRender],\n );\n const onBlur: React.FocusEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n if (filledMask) {\n const maskedValue = e.target.value.split('');\n\n const flatRegExp = flatStringArray(regExp);\n const firstUnderscoreIdx = maskedValue.findIndex((char, idx) => char === '_' && flatRegExp[idx] !== '_');\n if (firstUnderscoreIdx > -1) valueSetter(maskedValue.slice(0, firstUnderscoreIdx).join(''));\n }\n\n if (userOnBlur) userOnBlur(e);\n },\n [filledMask, userOnBlur, regExp, valueSetter],\n );\n\n return {\n onKeyDown,\n onChange,\n onBlur,\n };\n};\n\nexport const getRegExpMaskedValue = (value: string, regExp: string[]) => {\n const [maskedValue] = conformValue(value, value.length - 1, '', regExp, false);\n return maskedValue;\n};\n\nuseRegExpMask.displayName = 'useRegExpMask';\nexport const UseRegExpMaskWithSchema = describe(useRegExpMask);\nUseRegExpMaskWithSchema.propTypes = DSMaskRegExpHookPropsTypes;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -45,7 +45,7 @@ const useZipCodeMask = (props) => {
45
45
  onChange
46
46
  };
47
47
  };
48
- const getUseZipMaskedValue = (value) => {
48
+ const getZipCodeMaskedValue = (value) => {
49
49
  const [maskedValue] = conformValue(value, value.length - 1, "");
50
50
  return maskedValue;
51
51
  };
@@ -54,7 +54,7 @@ const UseZipCodeMaskWithSchema = describe(useZipCodeMask);
54
54
  UseZipCodeMaskWithSchema.propTypes = DSMaskHookPropsTypes;
55
55
  export {
56
56
  UseZipCodeMaskWithSchema,
57
- getUseZipMaskedValue,
57
+ getZipCodeMaskedValue,
58
58
  useZipCodeMask
59
59
  };
60
60
  //# sourceMappingURL=useZipCodeMask.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../../src/hooks/useZipCodeMask.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskHookDefaultProps, DSMaskHookPropsTypes } from '../react-desc-prop-types';\n\nconst zipCodeSpecialChars: [string, number][] = [['-', 5]];\n\nconst conformValue = (rawValue: string, cursorPos: number, lastKeyCode: string) => {\n // Work with digits only\n let maskedValue = String(rawValue)\n .split('')\n .filter((char) => char >= '0' && char <= '9');\n\n // We only consider first 9 digits\n maskedValue = maskedValue.slice(0, 9);\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n\n return addSpecialCharacters(maskedValue, zipCodeSpecialChars, maskedPos, lastKeyCode);\n};\n\nexport const useZipCodeMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskHookPropsTypes, 'useZipCodeMask');\n const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(e.target.value, e.target.selectionEnd ?? 0, lastKeyCode.current);\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n\n return mask;\n });\n if (userOnChange) userOnChange(e, mask);\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange],\n );\n\n return {\n onKeyDown,\n onChange,\n };\n};\n\nexport const getUseZipMaskedValue = (value: string) => {\n const [maskedValue] = conformValue(value, value.length - 1, '');\n return maskedValue;\n};\n\nuseZipCodeMask.displayName = 'useZipCodeMask';\nexport const UseZipCodeMaskWithSchema = describe(useZipCodeMask);\nUseZipCodeMaskWithSchema.propTypes = DSMaskHookPropsTypes;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACCvB,SAAS,aAAa,QAAQ,gBAAgB;AAC9C,SAAS,UAAU,8BAA8B,sCAAsC;AACvF,SAAS,8BAA8B;AACvC,SAAS,sBAAsB,qBAAqB,yBAAyB;AAE7E,SAAS,wBAAwB,4BAA4B;AAE7D,MAAM,sBAA0C,CAAC,CAAC,KAAK,CAAC,CAAC;AAEzD,MAAM,eAAe,CAAC,UAAkB,WAAmB,gBAAwB;AAEjF,MAAI,cAAc,OAAO,QAAQ,EAC9B,MAAM,EAAE,EACR,OAAO,CAAC,SAAS,QAAQ,OAAO,QAAQ,GAAG;AAG9C,gBAAc,YAAY,MAAM,GAAG,CAAC;AAEpC,QAAM,YAAY,oBAAoB,UAAU,aAAa,SAAS;AAEtE,SAAO,qBAAqB,aAAa,qBAAqB,WAAW,WAAW;AACtF;AAEO,MAAM,iBAA+B,CAAC,UAAU;AACrD,QAAM,mBAAmB,6BAA6B,OAAO,sBAAsB;AACnF,iCAA+B,kBAAkB,sBAAsB,gBAAgB;AACvF,QAAM,EAAE,aAAa,UAAU,cAAc,WAAW,cAAc,IAAI;AAE1E,QAAM,cAAc,OAAO,cAAc;AACzC,QAAM,sBAAsB,uBAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC;AAE7B,QAAM,YAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,WAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI,aAAa,EAAE,OAAO,OAAO,EAAE,OAAO,gBAAgB,GAAG,YAAY,OAAO;AACtG,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAE9C,eAAO;AAAA,MACT,CAAC;AACD,UAAI;AAAc,qBAAa,GAAG,IAAI;AACtC,0BAAoB,MAAM,kBAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,YAAY;AAAA,EACjD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,uBAAuB,CAAC,UAAkB;AACrD,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,EAAE;AAC9D,SAAO;AACT;AAEA,eAAe,cAAc;AACtB,MAAM,2BAA2B,SAAS,cAAc;AAC/D,yBAAyB,YAAY;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';\nimport { useCallbackAfterRender } from '@elliemae/ds-utilities';\nimport { addSpecialCharacters, getPartialMaskedPos, setCursorPosition } from '../utils';\nimport type { DSMaskT } from '../react-desc-prop-types';\nimport { DSMaskHookDefaultProps, DSMaskHookPropsTypes } from '../react-desc-prop-types';\n\nconst zipCodeSpecialChars: [string, number][] = [['-', 5]];\n\nconst conformValue = (rawValue: string, cursorPos: number, lastKeyCode: string) => {\n // Work with digits only\n let maskedValue = String(rawValue)\n .split('')\n .filter((char) => char >= '0' && char <= '9');\n\n // We only consider first 9 digits\n maskedValue = maskedValue.slice(0, 9);\n\n const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);\n\n return addSpecialCharacters(maskedValue, zipCodeSpecialChars, maskedPos, lastKeyCode);\n};\n\nexport const useZipCodeMask: DSMaskT.Hook = (props) => {\n const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskHookDefaultProps);\n useValidateTypescriptPropTypes(propsWithDefault, DSMaskHookPropsTypes, 'useZipCodeMask');\n const { valueSetter, onChange: userOnChange, onKeyDown: userOnKeyDown } = propsWithDefault;\n\n const lastKeyCode = useRef('Unidentified');\n const scheduleAfterRender = useCallbackAfterRender(true);\n\n // Some times, the value of the mask is not gonna change (user types invalid char for example)\n // This makes the input to go from \"correct\" -> \"incorrect\" -> \"correct\"\n // But since the input is controlled, the input does not re-render\n // This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async\n // Solution for this is to trigger a re-render, we do this with a set state call in the on change event\n const [, setKey] = useState(0);\n\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n lastKeyCode.current = e.code;\n if (userOnKeyDown) userOnKeyDown(e);\n },\n [userOnKeyDown],\n );\n\n const onChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n const [mask, cursorPos] = conformValue(e.target.value, e.target.selectionEnd ?? 0, lastKeyCode.current);\n valueSetter((prevMask) => {\n // Here we need to update the key\n if (mask === prevMask) setKey((key) => key + 1);\n\n return mask;\n });\n if (userOnChange) userOnChange(e, mask);\n scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));\n },\n [valueSetter, scheduleAfterRender, userOnChange],\n );\n\n return {\n onKeyDown,\n onChange,\n };\n};\n\nexport const getZipCodeMaskedValue = (value: string) => {\n const [maskedValue] = conformValue(value, value.length - 1, '');\n return maskedValue;\n};\n\nuseZipCodeMask.displayName = 'useZipCodeMask';\nexport const UseZipCodeMaskWithSchema = describe(useZipCodeMask);\nUseZipCodeMaskWithSchema.propTypes = DSMaskHookPropsTypes;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACCvB,SAAS,aAAa,QAAQ,gBAAgB;AAC9C,SAAS,UAAU,8BAA8B,sCAAsC;AACvF,SAAS,8BAA8B;AACvC,SAAS,sBAAsB,qBAAqB,yBAAyB;AAE7E,SAAS,wBAAwB,4BAA4B;AAE7D,MAAM,sBAA0C,CAAC,CAAC,KAAK,CAAC,CAAC;AAEzD,MAAM,eAAe,CAAC,UAAkB,WAAmB,gBAAwB;AAEjF,MAAI,cAAc,OAAO,QAAQ,EAC9B,MAAM,EAAE,EACR,OAAO,CAAC,SAAS,QAAQ,OAAO,QAAQ,GAAG;AAG9C,gBAAc,YAAY,MAAM,GAAG,CAAC;AAEpC,QAAM,YAAY,oBAAoB,UAAU,aAAa,SAAS;AAEtE,SAAO,qBAAqB,aAAa,qBAAqB,WAAW,WAAW;AACtF;AAEO,MAAM,iBAA+B,CAAC,UAAU;AACrD,QAAM,mBAAmB,6BAA6B,OAAO,sBAAsB;AACnF,iCAA+B,kBAAkB,sBAAsB,gBAAgB;AACvF,QAAM,EAAE,aAAa,UAAU,cAAc,WAAW,cAAc,IAAI;AAE1E,QAAM,cAAc,OAAO,cAAc;AACzC,QAAM,sBAAsB,uBAAuB,IAAI;AAOvD,QAAM,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC;AAE7B,QAAM,YAA0D;AAAA,IAC9D,CAAC,MAAM;AACL,kBAAY,UAAU,EAAE;AACxB,UAAI;AAAe,sBAAc,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,WAAuD;AAAA,IAC3D,CAAC,MAAM;AACL,YAAM,CAAC,MAAM,SAAS,IAAI,aAAa,EAAE,OAAO,OAAO,EAAE,OAAO,gBAAgB,GAAG,YAAY,OAAO;AACtG,kBAAY,CAAC,aAAa;AAExB,YAAI,SAAS;AAAU,iBAAO,CAAC,QAAQ,MAAM,CAAC;AAE9C,eAAO;AAAA,MACT,CAAC;AACD,UAAI;AAAc,qBAAa,GAAG,IAAI;AACtC,0BAAoB,MAAM,kBAAkB,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa,qBAAqB,YAAY;AAAA,EACjD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,wBAAwB,CAAC,UAAkB;AACtD,QAAM,CAAC,WAAW,IAAI,aAAa,OAAO,MAAM,SAAS,GAAG,EAAE;AAC9D,SAAO;AACT;AAEA,eAAe,cAAc;AACtB,MAAM,2BAA2B,SAAS,cAAc;AAC/D,yBAAyB,YAAY;",
6
6
  "names": []
7
7
  }
@@ -11,7 +11,11 @@ const DSMaskPhoneHookDefaultProps = {
11
11
  };
12
12
  const DSMaskRegExpHookDefaultProps = {
13
13
  ...DSMaskHookDefaultProps,
14
- filledMask: false
14
+ filledMask: false,
15
+ regExp: []
16
+ };
17
+ const DSMaskSSNDefaultProps = {
18
+ ...DSMaskHookDefaultProps
15
19
  };
16
20
  const DSMaskNumberHookDefaultProps = {
17
21
  ...DSMaskHookDefaultProps,
@@ -55,6 +59,7 @@ export {
55
59
  DSMaskPhoneHookDefaultProps,
56
60
  DSMaskPhoneHookPropsTypes,
57
61
  DSMaskRegExpHookDefaultProps,
58
- DSMaskRegExpHookPropsTypes
62
+ DSMaskRegExpHookPropsTypes,
63
+ DSMaskSSNDefaultProps
59
64
  };
60
65
  //# sourceMappingURL=react-desc-prop-types.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../scripts/build/transpile/react-shim.js", "../../src/react-desc-prop-types.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { PropTypes } from '@elliemae/ds-props-helpers';\nimport type { WeakValidationMap } from 'react';\nimport type React from 'react';\n\nexport declare namespace DSMaskT {\n interface HookArgs {\n valueSetter: React.Dispatch<React.SetStateAction<string>>;\n onChange?: (e: React.ChangeEvent<HTMLInputElement>, mask?: string) => void;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n }\n\n interface HookReturn {\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n }\n\n export interface NumberHookArgs extends HookArgs {\n suffix: string;\n prefix: string;\n decimalPlaces: number;\n allowNegative: boolean;\n includeThousandsSeparator: boolean;\n decimalRequired: boolean;\n }\n\n export interface PhoneHookArgs extends HookArgs {\n isInternational: boolean;\n }\n\n export interface RegExpHookArgs extends HookArgs {\n filledMask: boolean;\n }\n\n export type Hook = ((args: HookArgs) => HookReturn) & { displayName: string };\n export type PhoneHook = ((args: PhoneHookArgs) => HookReturn) & { displayName: string };\n export type NumberHook = ((args: NumberHookArgs) => HookReturn) & { displayName: string };\n}\n\nexport const DSMaskHookDefaultProps: Partial<DSMaskT.HookReturn> = {\n onChange: () => null,\n onKeyDown: () => null,\n onBlur: () => null,\n};\n\nexport const DSMaskPhoneHookDefaultProps: Partial<DSMaskT.PhoneHookArgs> = {\n ...DSMaskHookDefaultProps,\n isInternational: false,\n};\nexport const DSMaskRegExpHookDefaultProps: Partial<DSMaskT.RegExpHookArgs> = {\n ...DSMaskHookDefaultProps,\n filledMask: false,\n};\n\nexport const DSMaskNumberHookDefaultProps: Partial<DSMaskT.NumberHookArgs> = {\n ...DSMaskHookDefaultProps,\n suffix: '',\n prefix: '',\n decimalPlaces: 2,\n allowNegative: false,\n includeThousandsSeparator: true,\n decimalRequired: false,\n};\n\nexport const DSMaskHookPropsTypes = {\n valueSetter: PropTypes.func.description('React set state function for the value').isRequired,\n onChange: PropTypes.func.description('Callback for onChange'),\n onKeyDown: PropTypes.func.description('Callback for onKeyDown'),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskRegExpHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n regExp: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(RegExp)])).description(\n 'Array with regexp or special chars per character',\n ).isRequired,\n filledMask: PropTypes.bool.description('Show blank chars positions').defaultValue(false),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskPhoneHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n isInternational: PropTypes.bool.description('Use or not internaltional phone mask number').defaultValue(false),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskNumberHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n suffix: PropTypes.string.description('String will be added at the end of the input value').defaultValue(''),\n prefix: PropTypes.string.description('String will be added at the start of the input value').defaultValue(''),\n decimalPlaces: PropTypes.number.description('Number of decimals allowed').defaultValue(2),\n allowNegative: PropTypes.bool.description('Wether the input allows negative number').defaultValue(false),\n includeThousandsSeparator: PropTypes.bool\n .description('Wether the integer part will be separated by thousands')\n .defaultValue(true),\n decimalRequired: PropTypes.bool.description('Wether decimal part is mandatory').defaultValue(false),\n} as WeakValidationMap<unknown>;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,iBAAiB;AAwCnB,MAAM,yBAAsD;AAAA,EACjE,UAAU,MAAM;AAAA,EAChB,WAAW,MAAM;AAAA,EACjB,QAAQ,MAAM;AAChB;AAEO,MAAM,8BAA8D;AAAA,EACzE,GAAG;AAAA,EACH,iBAAiB;AACnB;AACO,MAAM,+BAAgE;AAAA,EAC3E,GAAG;AAAA,EACH,YAAY;AACd;AAEO,MAAM,+BAAgE;AAAA,EAC3E,GAAG;AAAA,EACH,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,eAAe;AAAA,EACf,2BAA2B;AAAA,EAC3B,iBAAiB;AACnB;AAEO,MAAM,uBAAuB;AAAA,EAClC,aAAa,UAAU,KAAK,YAAY,wCAAwC,EAAE;AAAA,EAClF,UAAU,UAAU,KAAK,YAAY,uBAAuB;AAAA,EAC5D,WAAW,UAAU,KAAK,YAAY,wBAAwB;AAChE;AAEO,MAAM,6BAA6B;AAAA,EACxC,GAAG;AAAA,EACH,QAAQ,UAAU,QAAQ,UAAU,UAAU,CAAC,UAAU,QAAQ,UAAU,WAAW,MAAM,CAAC,CAAC,CAAC,EAAE;AAAA,IAC/F;AAAA,EACF,EAAE;AAAA,EACF,YAAY,UAAU,KAAK,YAAY,4BAA4B,EAAE,aAAa,KAAK;AACzF;AAEO,MAAM,4BAA4B;AAAA,EACvC,GAAG;AAAA,EACH,iBAAiB,UAAU,KAAK,YAAY,6CAA6C,EAAE,aAAa,KAAK;AAC/G;AAEO,MAAM,6BAA6B;AAAA,EACxC,GAAG;AAAA,EACH,QAAQ,UAAU,OAAO,YAAY,oDAAoD,EAAE,aAAa,EAAE;AAAA,EAC1G,QAAQ,UAAU,OAAO,YAAY,sDAAsD,EAAE,aAAa,EAAE;AAAA,EAC5G,eAAe,UAAU,OAAO,YAAY,4BAA4B,EAAE,aAAa,CAAC;AAAA,EACxF,eAAe,UAAU,KAAK,YAAY,yCAAyC,EAAE,aAAa,KAAK;AAAA,EACvG,2BAA2B,UAAU,KAClC,YAAY,wDAAwD,EACpE,aAAa,IAAI;AAAA,EACpB,iBAAiB,UAAU,KAAK,YAAY,kCAAkC,EAAE,aAAa,KAAK;AACpG;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { PropTypes } from '@elliemae/ds-props-helpers';\nimport type { WeakValidationMap } from 'react';\nimport type React from 'react';\n\nexport declare namespace DSMaskT {\n interface HookArgs {\n valueSetter: React.Dispatch<React.SetStateAction<string>>;\n onChange?: (e: React.ChangeEvent<HTMLInputElement>, mask?: string) => void;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n }\n\n interface HookReturn {\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n }\n\n export interface NumberHookArgs extends HookArgs {\n suffix?: string;\n prefix?: string;\n decimalPlaces?: number;\n allowNegative?: boolean;\n includeThousandsSeparator?: boolean;\n decimalRequired?: boolean;\n }\n\n export interface PhoneHookArgs extends HookArgs {\n isInternational?: boolean;\n }\n\n export interface RegExpHookArgs extends HookArgs {\n filledMask: boolean;\n regExp: string[];\n }\n\n export type Hook = ((args: HookArgs) => HookReturn) & { displayName: string };\n export type PhoneHook = ((args: PhoneHookArgs) => HookReturn) & { displayName: string };\n export type NumberHook = ((args: NumberHookArgs) => HookReturn) & { displayName: string };\n}\n\nexport const DSMaskHookDefaultProps: Partial<DSMaskT.HookArgs> = {\n onChange: () => null,\n onKeyDown: () => null,\n onBlur: () => null,\n};\n\nexport const DSMaskPhoneHookDefaultProps: Partial<DSMaskT.PhoneHookArgs> = {\n ...DSMaskHookDefaultProps,\n isInternational: false,\n};\nexport const DSMaskRegExpHookDefaultProps: Partial<DSMaskT.RegExpHookArgs> = {\n ...DSMaskHookDefaultProps,\n filledMask: false,\n regExp: [],\n};\n\nexport const DSMaskSSNDefaultProps: Partial<DSMaskT.PhoneHookArgs> = {\n ...DSMaskHookDefaultProps,\n};\n\nexport const DSMaskNumberHookDefaultProps: Partial<DSMaskT.NumberHookArgs> = {\n ...DSMaskHookDefaultProps,\n suffix: '',\n prefix: '',\n decimalPlaces: 2,\n allowNegative: false,\n includeThousandsSeparator: true,\n decimalRequired: false,\n};\n\nexport const DSMaskHookPropsTypes = {\n valueSetter: PropTypes.func.description('React set state function for the value').isRequired,\n onChange: PropTypes.func.description('Callback for onChange'),\n onKeyDown: PropTypes.func.description('Callback for onKeyDown'),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskRegExpHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n regExp: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(RegExp)])).description(\n 'Array with regexp or special chars per character',\n ).isRequired,\n filledMask: PropTypes.bool.description('Show blank chars positions').defaultValue(false),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskPhoneHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n isInternational: PropTypes.bool.description('Use or not internaltional phone mask number').defaultValue(false),\n} as WeakValidationMap<unknown>;\n\nexport const DSMaskNumberHookPropsTypes = {\n ...DSMaskHookPropsTypes,\n suffix: PropTypes.string.description('String will be added at the end of the input value').defaultValue(''),\n prefix: PropTypes.string.description('String will be added at the start of the input value').defaultValue(''),\n decimalPlaces: PropTypes.number.description('Number of decimals allowed').defaultValue(2),\n allowNegative: PropTypes.bool.description('Wether the input allows negative number').defaultValue(false),\n includeThousandsSeparator: PropTypes.bool\n .description('Wether the integer part will be separated by thousands')\n .defaultValue(true),\n decimalRequired: PropTypes.bool.description('Wether decimal part is mandatory').defaultValue(false),\n} as WeakValidationMap<unknown>;\n"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,iBAAiB;AAyCnB,MAAM,yBAAoD;AAAA,EAC/D,UAAU,MAAM;AAAA,EAChB,WAAW,MAAM;AAAA,EACjB,QAAQ,MAAM;AAChB;AAEO,MAAM,8BAA8D;AAAA,EACzE,GAAG;AAAA,EACH,iBAAiB;AACnB;AACO,MAAM,+BAAgE;AAAA,EAC3E,GAAG;AAAA,EACH,YAAY;AAAA,EACZ,QAAQ,CAAC;AACX;AAEO,MAAM,wBAAwD;AAAA,EACnE,GAAG;AACL;AAEO,MAAM,+BAAgE;AAAA,EAC3E,GAAG;AAAA,EACH,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,eAAe;AAAA,EACf,2BAA2B;AAAA,EAC3B,iBAAiB;AACnB;AAEO,MAAM,uBAAuB;AAAA,EAClC,aAAa,UAAU,KAAK,YAAY,wCAAwC,EAAE;AAAA,EAClF,UAAU,UAAU,KAAK,YAAY,uBAAuB;AAAA,EAC5D,WAAW,UAAU,KAAK,YAAY,wBAAwB;AAChE;AAEO,MAAM,6BAA6B;AAAA,EACxC,GAAG;AAAA,EACH,QAAQ,UAAU,QAAQ,UAAU,UAAU,CAAC,UAAU,QAAQ,UAAU,WAAW,MAAM,CAAC,CAAC,CAAC,EAAE;AAAA,IAC/F;AAAA,EACF,EAAE;AAAA,EACF,YAAY,UAAU,KAAK,YAAY,4BAA4B,EAAE,aAAa,KAAK;AACzF;AAEO,MAAM,4BAA4B;AAAA,EACvC,GAAG;AAAA,EACH,iBAAiB,UAAU,KAAK,YAAY,6CAA6C,EAAE,aAAa,KAAK;AAC/G;AAEO,MAAM,6BAA6B;AAAA,EACxC,GAAG;AAAA,EACH,QAAQ,UAAU,OAAO,YAAY,oDAAoD,EAAE,aAAa,EAAE;AAAA,EAC1G,QAAQ,UAAU,OAAO,YAAY,sDAAsD,EAAE,aAAa,EAAE;AAAA,EAC5G,eAAe,UAAU,OAAO,YAAY,4BAA4B,EAAE,aAAa,CAAC;AAAA,EACxF,eAAe,UAAU,KAAK,YAAY,yCAAyC,EAAE,aAAa,KAAK;AAAA,EACvG,2BAA2B,UAAU,KAClC,YAAY,wDAAwD,EACpE,aAAa,IAAI;AAAA,EACpB,iBAAiB,UAAU,KAAK,YAAY,kCAAkC,EAAE,aAAa,KAAK;AACpG;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
1
  import type { DSMaskT } from '../react-desc-prop-types';
2
2
  export declare const usePhoneMask: DSMaskT.Hook;
3
- export declare const getPhoneMaskedValue: (value: string, opts: Partial<DSMaskT.PhoneHookArgs>) => string;
3
+ export declare const getPhoneMaskedValue: (value: string, opts?: Partial<DSMaskT.PhoneHookArgs>) => string;
4
4
  export declare const UsePhoneMaskWithSchema: import("@elliemae/ds-props-helpers/dist/types/propTypes/types").DocumentedReactComponent<DSMaskT.HookArgs>;
@@ -1,3 +1,4 @@
1
1
  import type { DSMaskT } from '../react-desc-prop-types';
2
2
  export declare const useRegExpMask: DSMaskT.Hook;
3
+ export declare const getRegExpMaskedValue: (value: string, regExp: string[]) => string | number;
3
4
  export declare const UseRegExpMaskWithSchema: import("@elliemae/ds-props-helpers/dist/types/propTypes/types").DocumentedReactComponent<DSMaskT.HookArgs>;
@@ -1,4 +1,4 @@
1
1
  import type { DSMaskT } from '../react-desc-prop-types';
2
2
  export declare const useZipCodeMask: DSMaskT.Hook;
3
- export declare const getUseZipMaskedValue: (value: string) => string;
3
+ export declare const getZipCodeMaskedValue: (value: string) => string;
4
4
  export declare const UseZipCodeMaskWithSchema: import("@elliemae/ds-props-helpers/dist/types/propTypes/types").DocumentedReactComponent<DSMaskT.HookArgs>;
@@ -13,18 +13,19 @@ export declare namespace DSMaskT {
13
13
  onBlur?: React.FocusEventHandler<HTMLInputElement>;
14
14
  }
15
15
  interface NumberHookArgs extends HookArgs {
16
- suffix: string;
17
- prefix: string;
18
- decimalPlaces: number;
19
- allowNegative: boolean;
20
- includeThousandsSeparator: boolean;
21
- decimalRequired: boolean;
16
+ suffix?: string;
17
+ prefix?: string;
18
+ decimalPlaces?: number;
19
+ allowNegative?: boolean;
20
+ includeThousandsSeparator?: boolean;
21
+ decimalRequired?: boolean;
22
22
  }
23
23
  interface PhoneHookArgs extends HookArgs {
24
- isInternational: boolean;
24
+ isInternational?: boolean;
25
25
  }
26
26
  interface RegExpHookArgs extends HookArgs {
27
27
  filledMask: boolean;
28
+ regExp: string[];
28
29
  }
29
30
  type Hook = ((args: HookArgs) => HookReturn) & {
30
31
  displayName: string;
@@ -36,9 +37,10 @@ export declare namespace DSMaskT {
36
37
  displayName: string;
37
38
  };
38
39
  }
39
- export declare const DSMaskHookDefaultProps: Partial<DSMaskT.HookReturn>;
40
+ export declare const DSMaskHookDefaultProps: Partial<DSMaskT.HookArgs>;
40
41
  export declare const DSMaskPhoneHookDefaultProps: Partial<DSMaskT.PhoneHookArgs>;
41
42
  export declare const DSMaskRegExpHookDefaultProps: Partial<DSMaskT.RegExpHookArgs>;
43
+ export declare const DSMaskSSNDefaultProps: Partial<DSMaskT.PhoneHookArgs>;
42
44
  export declare const DSMaskNumberHookDefaultProps: Partial<DSMaskT.NumberHookArgs>;
43
45
  export declare const DSMaskHookPropsTypes: WeakValidationMap<unknown>;
44
46
  export declare const DSMaskRegExpHookPropsTypes: WeakValidationMap<unknown>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-form-helpers-mask-hooks",
3
- "version": "3.16.0-next.8",
3
+ "version": "3.16.0-next.9",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Controlled Form Helpers - Text Masks Hooks",
6
6
  "files": [
@@ -35,9 +35,9 @@
35
35
  "indent": 4
36
36
  },
37
37
  "dependencies": {
38
- "@elliemae/ds-props-helpers": "3.16.0-next.8",
39
- "@elliemae/ds-system": "3.16.0-next.8",
40
- "@elliemae/ds-utilities": "3.16.0-next.8"
38
+ "@elliemae/ds-props-helpers": "3.16.0-next.9",
39
+ "@elliemae/ds-system": "3.16.0-next.9",
40
+ "@elliemae/ds-utilities": "3.16.0-next.9"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@elliemae/pui-theme": "~2.6.0",
@@ -46,7 +46,7 @@
46
46
  "@testing-library/user-event": "~13.5.0",
47
47
  "styled-components": "~5.3.6",
48
48
  "styled-system": "~5.1.5",
49
- "@elliemae/ds-form-input-text": "3.16.0-next.8"
49
+ "@elliemae/ds-form-input-text": "3.16.0-next.9"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "@elliemae/pui-theme": "~2.6.0",