@tecsinapse/react-core 1.13.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/components/atoms/Input/InputElement/InputElement.d.ts +5 -3
- package/dist/components/atoms/Input/InputElement/InputElement.js +22 -8
- package/dist/components/atoms/Input/InputElement/InputElement.js.map +1 -1
- package/dist/components/atoms/Input/hooks/useNumberMask.d.ts +8 -0
- package/dist/components/atoms/Input/hooks/useNumberMask.js +98 -0
- package/dist/components/atoms/Input/hooks/useNumberMask.js.map +1 -0
- package/dist/components/atoms/Input/hooks/useStringMask.d.ts +8 -0
- package/dist/components/atoms/Input/hooks/useStringMask.js +109 -0
- package/dist/components/atoms/Input/hooks/useStringMask.js.map +1 -0
- package/dist/components/atoms/Input/index.d.ts +2 -3
- package/dist/components/atoms/Input/index.js +12 -26
- package/dist/components/atoms/Input/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -29
- package/dist/index.js.map +1 -1
- package/dist/utils/formatWithMask.d.ts +3 -0
- package/dist/utils/formatWithMask.js +31 -0
- package/dist/utils/formatWithMask.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +28 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/masks.d.ts +10 -0
- package/dist/utils/masks.js +18 -0
- package/dist/utils/masks.js.map +1 -0
- package/package.json +2 -2
- package/src/components/atoms/Input/InputElement/InputElement.tsx +37 -11
- package/src/components/atoms/Input/hooks/useNumberMask.ts +99 -0
- package/src/components/atoms/Input/hooks/useStringMask.ts +126 -0
- package/src/components/atoms/Input/index.ts +2 -3
- package/src/index.ts +3 -6
- package/src/utils/formatWithMask.ts +25 -0
- package/src/utils/index.ts +4 -2
- package/src/utils/masks.ts +13 -0
- package/dist/components/atoms/Input/hooks/useCurrencyMask.d.ts +0 -3
- package/dist/components/atoms/Input/hooks/useCurrencyMask.js +0 -69
- package/dist/components/atoms/Input/hooks/useCurrencyMask.js.map +0 -1
- package/dist/components/atoms/Input/hooks/useMask.d.ts +0 -9
- package/dist/components/atoms/Input/hooks/useMask.js +0 -61
- package/dist/components/atoms/Input/hooks/useMask.js.map +0 -1
- package/dist/components/atoms/Input/masks/index.d.ts +0 -10
- package/dist/components/atoms/Input/masks/index.js +0 -18
- package/dist/components/atoms/Input/masks/index.js.map +0 -1
- package/src/components/atoms/Input/hooks/useCurrencyMask.ts +0 -74
- package/src/components/atoms/Input/hooks/useMask.ts +0 -92
- package/src/components/atoms/Input/masks/index.ts +0 -12
package/dist/utils/index.js
CHANGED
|
@@ -58,4 +58,32 @@ Object.keys(_ResponsiveFontSize).forEach(function (key) {
|
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
var _masks = require("./masks");
|
|
63
|
+
|
|
64
|
+
Object.keys(_masks).forEach(function (key) {
|
|
65
|
+
if (key === "default" || key === "__esModule") return;
|
|
66
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
67
|
+
if (key in exports && exports[key] === _masks[key]) return;
|
|
68
|
+
Object.defineProperty(exports, key, {
|
|
69
|
+
enumerable: true,
|
|
70
|
+
get: function () {
|
|
71
|
+
return _masks[key];
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
var _formatWithMask = require("./formatWithMask");
|
|
77
|
+
|
|
78
|
+
Object.keys(_formatWithMask).forEach(function (key) {
|
|
79
|
+
if (key === "default" || key === "__esModule") return;
|
|
80
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
81
|
+
if (key in exports && exports[key] === _formatWithMask[key]) return;
|
|
82
|
+
Object.defineProperty(exports, key, {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
get: function () {
|
|
85
|
+
return _formatWithMask[key];
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
61
89
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AAIA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["export { lightenDarkenColor } from './lightenDarkenColor';\nexport {\n extractNumbersFromString,\n extractDigitsFromString,\n} from './extractNumbersFromString';\nexport * from './IPhoneXHelper'
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AAIA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["export { lightenDarkenColor } from './lightenDarkenColor';\nexport {\n extractNumbersFromString,\n extractDigitsFromString,\n} from './extractNumbersFromString';\nexport * from './IPhoneXHelper';\nexport * from './ResponsiveFontSize';\nexport * from './masks';\nexport * from './formatWithMask';\n"],"file":"index.js"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Masks = void 0;
|
|
7
|
+
const Masks = {
|
|
8
|
+
CPF: ['999.999.999-99'],
|
|
9
|
+
CNPJ: ['99.999.999/9999-99'],
|
|
10
|
+
DATE: ['99/99/9999'],
|
|
11
|
+
MONTH_YEAR: ['99/9999'],
|
|
12
|
+
CEP: ['99999-999'],
|
|
13
|
+
PHONE: ['(99) 9999-9999'],
|
|
14
|
+
PHONE_EXTENDED: ['(99) 99999-9999'],
|
|
15
|
+
COMBINED_PHONE: value => (value === null || value === void 0 ? void 0 : value.length) <= 14 ? Masks.PHONE : Masks.PHONE_EXTENDED
|
|
16
|
+
};
|
|
17
|
+
exports.Masks = Masks;
|
|
18
|
+
//# sourceMappingURL=masks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/masks.ts"],"names":["Masks","CPF","CNPJ","DATE","MONTH_YEAR","CEP","PHONE","PHONE_EXTENDED","COMBINED_PHONE","value","length"],"mappings":";;;;;;AACO,MAAMA,KAAK,GAAG;AACnBC,EAAAA,GAAG,EAAE,CAAC,gBAAD,CADc;AAEnBC,EAAAA,IAAI,EAAE,CAAC,oBAAD,CAFa;AAGnBC,EAAAA,IAAI,EAAE,CAAC,YAAD,CAHa;AAInBC,EAAAA,UAAU,EAAE,CAAC,SAAD,CAJO;AAKnBC,EAAAA,GAAG,EAAE,CAAC,WAAD,CALc;AAMnBC,EAAAA,KAAK,EAAE,CAAC,gBAAD,CANY;AAOnBC,EAAAA,cAAc,EAAE,CAAC,iBAAD,CAPG;AAQnBC,EAAAA,cAAc,EAAGC,KAAD,IAEd,CAAAA,KAAK,SAAL,IAAAA,KAAK,WAAL,YAAAA,KAAK,CAAEC,MAAP,KAAiB,EAAjB,GAAsBV,KAAK,CAACM,KAA5B,GAAoCN,KAAK,CAACO;AAVzB,CAAd","sourcesContent":["// NOTE: Add here all individually utils, then you can use it on input components everywhere.\nexport const Masks = {\n CPF: ['999.999.999-99'],\n CNPJ: ['99.999.999/9999-99'],\n DATE: ['99/99/9999'],\n MONTH_YEAR: ['99/9999'],\n CEP: ['99999-999'],\n PHONE: ['(99) 9999-9999'],\n PHONE_EXTENDED: ['(99) 99999-9999'],\n COMBINED_PHONE: (value: string) =>\n // Value in formatted mode\n value?.length <= 14 ? Masks.PHONE : Masks.PHONE_EXTENDED,\n};\n"],"file":"masks.js"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tecsinapse/react-core",
|
|
3
3
|
"description": "TecSinapse hybrid React components",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.14.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -31,5 +31,5 @@
|
|
|
31
31
|
"react-native": ">=0.64.0",
|
|
32
32
|
"react-native-vector-icons": ">=8.1.0"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "fb1d3b3bfa028174ef30ee2c9387a04c81699c3f"
|
|
35
35
|
}
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import { useTheme } from '@emotion/react';
|
|
2
2
|
import { ThemeProp } from '@tecsinapse/react-core';
|
|
3
|
-
import React, { FC } from 'react';
|
|
3
|
+
import React, { FC, useEffect, useState } from 'react';
|
|
4
4
|
import { StyleProp, TextInputProps, TextStyle } from 'react-native';
|
|
5
|
-
import { IMask } from '../hooks/useMask';
|
|
6
5
|
import { StyledInputElement } from '../styled';
|
|
6
|
+
import { MaskType, useStringMask } from '../hooks/useStringMask';
|
|
7
|
+
import { CurrencyOptions, useNumberMask } from '../hooks/useNumberMask';
|
|
7
8
|
|
|
8
9
|
export interface InputElementProps
|
|
9
10
|
extends Omit<TextInputProps, 'onChange' | 'value' | 'ref'> {
|
|
10
11
|
style?: StyleProp<TextStyle>;
|
|
11
|
-
|
|
12
|
-
* TODO:
|
|
13
|
-
*/
|
|
14
|
-
value?: string | IMask;
|
|
12
|
+
value: string | number;
|
|
15
13
|
placeholder?: string;
|
|
16
14
|
disabled?: boolean;
|
|
17
|
-
onChange?: (value:
|
|
15
|
+
onChange?: (value: any) => void;
|
|
16
|
+
/**
|
|
17
|
+
To use mask for strings you have to pass a MaskType[] or ((value: string) => MaskType[])
|
|
18
|
+
A MaskType can be a string, RegExp, or Array<RegExp>.
|
|
19
|
+
In case we have a string, '9' represents digits, 'a' represents alphabet characters, and any other character represents fixed characters in the mask.
|
|
20
|
+
For example a phone mask can be represented as ['(99) \\99999-9999'], or ['(99) ', '/[9]/', '9999-9999'], or ['(', /[0-9]/, /[0-9]/, ') ', '/[9]/', '9999-9999'] and many others.
|
|
21
|
+
To use mask for numbers you have to pass a CurrencyOptions object
|
|
22
|
+
A CurrencyOptions object contains symbol, separator, decimal, precision. For example {symbol: 'R$ ', separator: '.', decimal: ',', precision: 2,}.
|
|
23
|
+
**/
|
|
24
|
+
mask?: (MaskType[] | ((value: string) => MaskType[])) | CurrencyOptions;
|
|
18
25
|
onFocus?: () => void;
|
|
19
26
|
onBlur?: () => void;
|
|
20
27
|
ref?: React.Ref<any>;
|
|
@@ -28,21 +35,40 @@ const InputElement: FC<InputElementProps> = React.forwardRef(
|
|
|
28
35
|
value,
|
|
29
36
|
disabled = false,
|
|
30
37
|
placeholderTextColor,
|
|
38
|
+
mask,
|
|
31
39
|
...rest
|
|
32
40
|
},
|
|
33
41
|
ref: React.Ref<any>
|
|
34
42
|
): JSX.Element => {
|
|
35
43
|
const theme = useTheme() as ThemeProp;
|
|
36
|
-
const _value =
|
|
37
|
-
typeof value === 'string' ? value : value?.maskValue?.formatted;
|
|
38
44
|
const _placeholderColor = placeholderTextColor || theme.font.color.dark;
|
|
39
45
|
|
|
46
|
+
const [maskValue, setMaskValue] =
|
|
47
|
+
mask === undefined
|
|
48
|
+
? useState<string>(String(value))
|
|
49
|
+
: Array.isArray(mask) || typeof mask === 'function'
|
|
50
|
+
? useStringMask(mask, String(value))
|
|
51
|
+
: useNumberMask(mask, value);
|
|
52
|
+
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (onChange) {
|
|
55
|
+
if (typeof maskValue === 'string') onChange(maskValue);
|
|
56
|
+
else onChange(maskValue?.raw);
|
|
57
|
+
}
|
|
58
|
+
}, [maskValue]);
|
|
59
|
+
|
|
60
|
+
const onChangeValue = (value: string) => {
|
|
61
|
+
setMaskValue(value);
|
|
62
|
+
};
|
|
63
|
+
|
|
40
64
|
return (
|
|
41
65
|
<StyledInputElement
|
|
42
66
|
{...rest}
|
|
43
67
|
ref={ref}
|
|
44
|
-
onChangeText={
|
|
45
|
-
value={
|
|
68
|
+
onChangeText={onChangeValue}
|
|
69
|
+
value={
|
|
70
|
+
typeof maskValue === 'string' ? maskValue : maskValue?.formatted ?? ''
|
|
71
|
+
}
|
|
46
72
|
placeholder={placeholder}
|
|
47
73
|
placeholderTextColor={_placeholderColor}
|
|
48
74
|
disabled={disabled}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import currency from 'currency.js';
|
|
2
|
+
import { useCallback, useState } from 'react';
|
|
3
|
+
import { extractNumbersFromString } from '../../../../utils';
|
|
4
|
+
import { MaskValue } from './useStringMask';
|
|
5
|
+
|
|
6
|
+
export type CurrencyOptions = currency.Options;
|
|
7
|
+
|
|
8
|
+
const DEFAULT_OPTIONS: CurrencyOptions = {
|
|
9
|
+
symbol: 'R$ ',
|
|
10
|
+
separator: '.',
|
|
11
|
+
decimal: ',',
|
|
12
|
+
precision: 2,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const getRegex = (precision: number) =>
|
|
16
|
+
new RegExp(`\\B(?=(\\d{${precision}})(?!\\d))`, 'g');
|
|
17
|
+
|
|
18
|
+
export const getInternalNumberAndMask = (
|
|
19
|
+
value: string | number,
|
|
20
|
+
options?: CurrencyOptions
|
|
21
|
+
): { internalNumber: number; mergedOptions: CurrencyOptions } => {
|
|
22
|
+
const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
|
|
23
|
+
const { precision = -1 } = mergedOptions;
|
|
24
|
+
|
|
25
|
+
let internalNumber;
|
|
26
|
+
|
|
27
|
+
if (typeof value === 'number') {
|
|
28
|
+
if (precision) {
|
|
29
|
+
let stringValue = String(value);
|
|
30
|
+
const decimalIndex = stringValue.indexOf('.');
|
|
31
|
+
const currentPrecision = decimalIndex + precision;
|
|
32
|
+
if (decimalIndex !== -1 && currentPrecision <= stringValue.length) {
|
|
33
|
+
const zeros = stringValue.length + 1 - currentPrecision;
|
|
34
|
+
for (let i = 0; i < zeros; i++) stringValue = stringValue + `0`;
|
|
35
|
+
}
|
|
36
|
+
internalNumber = Number(stringValue);
|
|
37
|
+
} else {
|
|
38
|
+
internalNumber = value;
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
const onlyNumbers = String(extractNumbersFromString(value));
|
|
42
|
+
const padZeros = String(onlyNumbers).padStart(precision + 1, '0');
|
|
43
|
+
internalNumber = Number(padZeros.replace(getRegex(precision), '.'));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (internalNumber > Number.MAX_SAFE_INTEGER) {
|
|
47
|
+
internalNumber = Number.MAX_SAFE_INTEGER;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (internalNumber < Number.MIN_SAFE_INTEGER) {
|
|
51
|
+
internalNumber = Number.MIN_SAFE_INTEGER;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
internalNumber,
|
|
56
|
+
mergedOptions,
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* TODO:
|
|
62
|
+
* @param options
|
|
63
|
+
* @param defaultValue
|
|
64
|
+
* @returns
|
|
65
|
+
*/
|
|
66
|
+
export const useNumberMask = (
|
|
67
|
+
options?: CurrencyOptions,
|
|
68
|
+
defaultValue?: string | number
|
|
69
|
+
): [MaskValue, (value: string) => void] => {
|
|
70
|
+
const applyMask = useCallback(
|
|
71
|
+
(value: string | number = 0): MaskValue => {
|
|
72
|
+
const { internalNumber, mergedOptions } = getInternalNumberAndMask(
|
|
73
|
+
value,
|
|
74
|
+
options
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
raw: internalNumber,
|
|
79
|
+
formatted: currency(internalNumber).format(mergedOptions),
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
[options, getRegex]
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const [value, setValue] = useState<MaskValue>(applyMask(defaultValue));
|
|
86
|
+
|
|
87
|
+
const handleChangeValue = useCallback(
|
|
88
|
+
(formattedValue: string) => {
|
|
89
|
+
const { raw, formatted } = applyMask(formattedValue);
|
|
90
|
+
setValue({
|
|
91
|
+
raw,
|
|
92
|
+
formatted,
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
[applyMask, setValue]
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
return [value, handleChangeValue];
|
|
99
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface MaskValue {
|
|
4
|
+
formatted?: string;
|
|
5
|
+
raw?: any;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type MaskType = string | RegExp | Array<RegExp>;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* TODO:
|
|
12
|
+
* @param value
|
|
13
|
+
* @param mask
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
export const mergeMask = (value = '', mask: MaskType[]): MaskValue => {
|
|
17
|
+
let formatted = '';
|
|
18
|
+
let raw = '';
|
|
19
|
+
let iMask = 0;
|
|
20
|
+
let iChars = 0;
|
|
21
|
+
|
|
22
|
+
while (!(iMask === mask.length || iChars === value.length)) {
|
|
23
|
+
const maskChar = mask[iMask];
|
|
24
|
+
const valueChar = value[iChars];
|
|
25
|
+
|
|
26
|
+
if (maskChar === valueChar) {
|
|
27
|
+
formatted += maskChar;
|
|
28
|
+
iChars++;
|
|
29
|
+
iMask++;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const rawValueChar = value[iChars];
|
|
34
|
+
|
|
35
|
+
if (typeof maskChar === 'object') {
|
|
36
|
+
iChars++;
|
|
37
|
+
|
|
38
|
+
const maskCharRegex = Array.isArray(maskChar) ? maskChar[0] : maskChar;
|
|
39
|
+
const matchRegex = RegExp(maskCharRegex).test(valueChar);
|
|
40
|
+
|
|
41
|
+
if (matchRegex) {
|
|
42
|
+
formatted += valueChar;
|
|
43
|
+
raw += rawValueChar;
|
|
44
|
+
iMask++;
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
formatted += maskChar;
|
|
48
|
+
iMask++;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return { raw, formatted };
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const getMask = (
|
|
56
|
+
mask: MaskType[] | ((value: string) => MaskType[]),
|
|
57
|
+
newValue: string
|
|
58
|
+
): MaskType[] => {
|
|
59
|
+
let maskArray: MaskType[];
|
|
60
|
+
const regexArray: MaskType[] = [];
|
|
61
|
+
|
|
62
|
+
if (typeof mask === 'function') {
|
|
63
|
+
maskArray = mask(newValue);
|
|
64
|
+
} else {
|
|
65
|
+
maskArray = mask;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
maskArray.forEach(exp => {
|
|
69
|
+
if (typeof exp !== 'string') {
|
|
70
|
+
if (Array.isArray(exp)) regexArray.push(exp);
|
|
71
|
+
else regexArray.push(exp);
|
|
72
|
+
} else {
|
|
73
|
+
for (let i = 0; i < exp.length; i++) {
|
|
74
|
+
if (exp[i] === '\\') {
|
|
75
|
+
regexArray.push(exp[i + 1]);
|
|
76
|
+
i++;
|
|
77
|
+
} else {
|
|
78
|
+
if (exp[i] === '9') regexArray.push(/\d/);
|
|
79
|
+
else if (exp[i] === 'a') regexArray.push(/[a-zA-Z]/);
|
|
80
|
+
else regexArray.push(exp[i]);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return regexArray;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* TODO:
|
|
91
|
+
* @param mask
|
|
92
|
+
* @param defaultValue
|
|
93
|
+
* @returns
|
|
94
|
+
*/
|
|
95
|
+
export const useStringMask = (
|
|
96
|
+
mask: MaskType[] | ((value: string) => MaskType[]),
|
|
97
|
+
defaultValue?: string
|
|
98
|
+
): [MaskValue, (text: string) => void] => {
|
|
99
|
+
const applyMask = useCallback(
|
|
100
|
+
(value = ''): MaskValue => {
|
|
101
|
+
const selectedMask = getMask(mask, value);
|
|
102
|
+
const { formatted, raw } = mergeMask(value, selectedMask);
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
raw,
|
|
106
|
+
formatted,
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
[mask]
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const [value, setValue] = useState<MaskValue>(applyMask(defaultValue));
|
|
113
|
+
|
|
114
|
+
const handleChangeValue = useCallback(
|
|
115
|
+
(formattedValue: string) => {
|
|
116
|
+
const { raw, formatted } = applyMask(formattedValue);
|
|
117
|
+
setValue({
|
|
118
|
+
raw,
|
|
119
|
+
formatted,
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
[applyMask, setValue]
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return [value, handleChangeValue];
|
|
126
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { default as Hint } from './Hint';
|
|
2
|
-
export * from './hooks/useCurrencyMask';
|
|
3
2
|
export * from './hooks/useInputFocus';
|
|
4
|
-
export * from './hooks/
|
|
3
|
+
export * from './hooks/useNumberMask';
|
|
4
|
+
export * from './hooks/useStringMask';
|
|
5
5
|
export {
|
|
6
6
|
default as InputContainer,
|
|
7
7
|
InputContainerProps,
|
|
@@ -11,7 +11,6 @@ export {
|
|
|
11
11
|
default as InputElement,
|
|
12
12
|
InputElementProps,
|
|
13
13
|
} from './InputElement/InputElement';
|
|
14
|
-
export * from './masks';
|
|
15
14
|
export {
|
|
16
15
|
PressableInputContainer,
|
|
17
16
|
PressableInputContainerProps,
|
package/src/index.ts
CHANGED
|
@@ -31,16 +31,13 @@ export {
|
|
|
31
31
|
InputElement,
|
|
32
32
|
InputElementProps,
|
|
33
33
|
InputVariantType,
|
|
34
|
-
Masks,
|
|
35
34
|
PressableInputContainer,
|
|
36
35
|
PressableInputContainerProps,
|
|
37
36
|
StyledBorderKeeper,
|
|
38
|
-
useCurrencyMask,
|
|
39
37
|
useInputFocus,
|
|
40
|
-
|
|
38
|
+
useNumberMask,
|
|
39
|
+
useStringMask,
|
|
41
40
|
disabledInputStyles,
|
|
42
|
-
IMask,
|
|
43
|
-
IMaskValue,
|
|
44
41
|
} from './components/atoms/Input';
|
|
45
42
|
export { Paper, PaperProps } from './components/atoms/Paper';
|
|
46
43
|
export {
|
|
@@ -57,7 +54,7 @@ export {
|
|
|
57
54
|
CalendarProps,
|
|
58
55
|
DateRange,
|
|
59
56
|
SelectionType,
|
|
60
|
-
Value
|
|
57
|
+
Value,
|
|
61
58
|
} from './components/molecules/Calendar';
|
|
62
59
|
export { DatePicker, DatePickerProps } from './components/molecules/DatePicker';
|
|
63
60
|
export {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MaskType,
|
|
3
|
+
CurrencyOptions,
|
|
4
|
+
getMask,
|
|
5
|
+
mergeMask,
|
|
6
|
+
getInternalNumberAndMask,
|
|
7
|
+
} from '../components/atoms/Input';
|
|
8
|
+
import currency from 'currency.js';
|
|
9
|
+
|
|
10
|
+
export const formatWithMask = (
|
|
11
|
+
mask: (MaskType[] | ((value: string) => MaskType[])) | CurrencyOptions,
|
|
12
|
+
value: string | number
|
|
13
|
+
): string | number => {
|
|
14
|
+
if (Array.isArray(mask) || typeof mask === 'function') {
|
|
15
|
+
const selectedMask = getMask(mask, String(value));
|
|
16
|
+
const { formatted } = mergeMask(String(value), selectedMask);
|
|
17
|
+
return formatted || '';
|
|
18
|
+
} else {
|
|
19
|
+
const { internalNumber, mergedOptions } = getInternalNumberAndMask(
|
|
20
|
+
value,
|
|
21
|
+
mask
|
|
22
|
+
);
|
|
23
|
+
return currency(internalNumber).format(mergedOptions);
|
|
24
|
+
}
|
|
25
|
+
};
|
package/src/utils/index.ts
CHANGED
|
@@ -3,5 +3,7 @@ export {
|
|
|
3
3
|
extractNumbersFromString,
|
|
4
4
|
extractDigitsFromString,
|
|
5
5
|
} from './extractNumbersFromString';
|
|
6
|
-
export * from './IPhoneXHelper'
|
|
7
|
-
export * from './ResponsiveFontSize'
|
|
6
|
+
export * from './IPhoneXHelper';
|
|
7
|
+
export * from './ResponsiveFontSize';
|
|
8
|
+
export * from './masks';
|
|
9
|
+
export * from './formatWithMask';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// NOTE: Add here all individually utils, then you can use it on input components everywhere.
|
|
2
|
+
export const Masks = {
|
|
3
|
+
CPF: ['999.999.999-99'],
|
|
4
|
+
CNPJ: ['99.999.999/9999-99'],
|
|
5
|
+
DATE: ['99/99/9999'],
|
|
6
|
+
MONTH_YEAR: ['99/9999'],
|
|
7
|
+
CEP: ['99999-999'],
|
|
8
|
+
PHONE: ['(99) 9999-9999'],
|
|
9
|
+
PHONE_EXTENDED: ['(99) 99999-9999'],
|
|
10
|
+
COMBINED_PHONE: (value: string) =>
|
|
11
|
+
// Value in formatted mode
|
|
12
|
+
value?.length <= 14 ? Masks.PHONE : Masks.PHONE_EXTENDED,
|
|
13
|
+
};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.useCurrencyMask = void 0;
|
|
7
|
-
|
|
8
|
-
var _currency = _interopRequireDefault(require("currency.js"));
|
|
9
|
-
|
|
10
|
-
var _react = require("react");
|
|
11
|
-
|
|
12
|
-
var _utils = require("../../../../utils");
|
|
13
|
-
|
|
14
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
|
-
const DEFAULT_OPTIONS = {
|
|
17
|
-
symbol: 'R$ ',
|
|
18
|
-
separator: '.',
|
|
19
|
-
decimal: ',',
|
|
20
|
-
precision: 2
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const useCurrencyMask = (options, defaultValue) => {
|
|
24
|
-
const getRegex = (0, _react.useCallback)(precision => new RegExp(`\\B(?=(\\d{${precision}})(?!\\d))`, 'g'), [options]);
|
|
25
|
-
const applyMask = (0, _react.useCallback)((value = '') => {
|
|
26
|
-
const mergedOptions = { ...DEFAULT_OPTIONS,
|
|
27
|
-
...options
|
|
28
|
-
};
|
|
29
|
-
const {
|
|
30
|
-
precision = -1
|
|
31
|
-
} = mergedOptions;
|
|
32
|
-
const onlyNumbers = String((0, _utils.extractNumbersFromString)(value));
|
|
33
|
-
const padZeros = String(onlyNumbers).padStart(precision + 1, '0');
|
|
34
|
-
let internalNumber = Number(padZeros.replace(getRegex(precision), '.'));
|
|
35
|
-
|
|
36
|
-
if (internalNumber > Number.MAX_SAFE_INTEGER) {
|
|
37
|
-
internalNumber = Number.MAX_SAFE_INTEGER;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (internalNumber < Number.MIN_SAFE_INTEGER) {
|
|
41
|
-
internalNumber = Number.MIN_SAFE_INTEGER;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
raw: internalNumber,
|
|
46
|
-
formatted: (0, _currency.default)(internalNumber).format(mergedOptions)
|
|
47
|
-
};
|
|
48
|
-
}, [options, getRegex]);
|
|
49
|
-
const [value, setValue] = (0, _react.useState)({
|
|
50
|
-
converter: applyMask,
|
|
51
|
-
maskValue: applyMask(defaultValue)
|
|
52
|
-
});
|
|
53
|
-
const handleChangeValue = (0, _react.useCallback)(formattedValue => {
|
|
54
|
-
const {
|
|
55
|
-
raw,
|
|
56
|
-
formatted
|
|
57
|
-
} = applyMask(formattedValue);
|
|
58
|
-
setValue(oldValue => ({ ...oldValue,
|
|
59
|
-
maskValue: {
|
|
60
|
-
raw,
|
|
61
|
-
formatted
|
|
62
|
-
}
|
|
63
|
-
}));
|
|
64
|
-
}, [applyMask, setValue]);
|
|
65
|
-
return [value, handleChangeValue];
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
exports.useCurrencyMask = useCurrencyMask;
|
|
69
|
-
//# sourceMappingURL=useCurrencyMask.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/atoms/Input/hooks/useCurrencyMask.ts"],"names":["DEFAULT_OPTIONS","symbol","separator","decimal","precision","useCurrencyMask","options","defaultValue","getRegex","RegExp","applyMask","value","mergedOptions","onlyNumbers","String","padZeros","padStart","internalNumber","Number","replace","MAX_SAFE_INTEGER","MIN_SAFE_INTEGER","raw","formatted","format","setValue","converter","maskValue","handleChangeValue","formattedValue","oldValue"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;;;AAKA,MAAMA,eAAgC,GAAG;AACvCC,EAAAA,MAAM,EAAE,KAD+B;AAEvCC,EAAAA,SAAS,EAAE,GAF4B;AAGvCC,EAAAA,OAAO,EAAE,GAH8B;AAIvCC,EAAAA,SAAS,EAAE;AAJ4B,CAAzC;;AAaO,MAAMC,eAAe,GAAG,CAC7BC,OAD6B,EAE7BC,YAF6B,KAGQ;AACrC,QAAMC,QAAQ,GAAG,wBACdJ,SAAD,IAAuB,IAAIK,MAAJ,CAAY,cAAaL,SAAU,YAAnC,EAAgD,GAAhD,CADR,EAEf,CAACE,OAAD,CAFe,CAAjB;AAKA,QAAMI,SAAS,GAAG,wBAChB,CAACC,KAAK,GAAG,EAAT,KAA4B;AAC1B,UAAMC,aAAa,GAAG,EAAE,GAAGZ,eAAL;AAAsB,SAAGM;AAAzB,KAAtB;AACA,UAAM;AAAEF,MAAAA,SAAS,GAAG,CAAC;AAAf,QAAqBQ,aAA3B;AACA,UAAMC,WAAW,GAAGC,MAAM,CAAC,qCAAyBH,KAAzB,CAAD,CAA1B;AACA,UAAMI,QAAQ,GAAGD,MAAM,CAACD,WAAD,CAAN,CAAoBG,QAApB,CAA6BZ,SAAS,GAAG,CAAzC,EAA4C,GAA5C,CAAjB;AACA,QAAIa,cAAc,GAAGC,MAAM,CAACH,QAAQ,CAACI,OAAT,CAAiBX,QAAQ,CAACJ,SAAD,CAAzB,EAAsC,GAAtC,CAAD,CAA3B;;AAEA,QAAIa,cAAc,GAAGC,MAAM,CAACE,gBAA5B,EAA8C;AAC5CH,MAAAA,cAAc,GAAGC,MAAM,CAACE,gBAAxB;AACD;;AAED,QAAIH,cAAc,GAAGC,MAAM,CAACG,gBAA5B,EAA8C;AAC5CJ,MAAAA,cAAc,GAAGC,MAAM,CAACG,gBAAxB;AACD;;AAED,WAAO;AACLC,MAAAA,GAAG,EAAEL,cADA;AAELM,MAAAA,SAAS,EAAE,uBAASN,cAAT,EAAyBO,MAAzB,CAAgCZ,aAAhC;AAFN,KAAP;AAID,GApBe,EAqBhB,CAACN,OAAD,EAAUE,QAAV,CArBgB,CAAlB;AAwBA,QAAM,CAACG,KAAD,EAAQc,QAAR,IAAoB,qBAAgB;AACxCC,IAAAA,SAAS,EAAEhB,SAD6B;AAExCiB,IAAAA,SAAS,EAAEjB,SAAS,CAACH,YAAD;AAFoB,GAAhB,CAA1B;AAKA,QAAMqB,iBAAiB,GAAG,wBACvBC,cAAD,IAA4B;AAC1B,UAAM;AAAEP,MAAAA,GAAF;AAAOC,MAAAA;AAAP,QAAqBb,SAAS,CAACmB,cAAD,CAApC;AACAJ,IAAAA,QAAQ,CAACK,QAAQ,KAAK,EACpB,GAAGA,QADiB;AAEpBH,MAAAA,SAAS,EAAE;AACTL,QAAAA,GADS;AAETC,QAAAA;AAFS;AAFS,KAAL,CAAT,CAAR;AAOD,GAVuB,EAWxB,CAACb,SAAD,EAAYe,QAAZ,CAXwB,CAA1B;AAcA,SAAO,CAACd,KAAD,EAAQiB,iBAAR,CAAP;AACD,CArDM","sourcesContent":["import currency from 'currency.js';\nimport { useCallback, useState } from 'react';\nimport { extractNumbersFromString } from '../../../../utils';\nimport { IMask, IMaskValue } from './useMask';\n\ntype CurrencyOptions = currency.Options;\n\nconst DEFAULT_OPTIONS: CurrencyOptions = {\n symbol: 'R$ ',\n separator: '.',\n decimal: ',',\n precision: 2,\n};\n\n/**\n * TODO:\n * @param options\n * @param defaultValue\n * @returns\n */\nexport const useCurrencyMask = (\n options?: CurrencyOptions,\n defaultValue?: string\n): [IMask, (value: string) => void] => {\n const getRegex = useCallback(\n (precision: number) => new RegExp(`\\\\B(?=(\\\\d{${precision}})(?!\\\\d))`, 'g'),\n [options]\n );\n\n const applyMask = useCallback(\n (value = ''): IMaskValue => {\n const mergedOptions = { ...DEFAULT_OPTIONS, ...options };\n const { precision = -1 } = mergedOptions;\n const onlyNumbers = String(extractNumbersFromString(value));\n const padZeros = String(onlyNumbers).padStart(precision + 1, '0');\n let internalNumber = Number(padZeros.replace(getRegex(precision), '.'));\n\n if (internalNumber > Number.MAX_SAFE_INTEGER) {\n internalNumber = Number.MAX_SAFE_INTEGER;\n }\n\n if (internalNumber < Number.MIN_SAFE_INTEGER) {\n internalNumber = Number.MIN_SAFE_INTEGER;\n }\n\n return {\n raw: internalNumber,\n formatted: currency(internalNumber).format(mergedOptions),\n };\n },\n [options, getRegex]\n );\n\n const [value, setValue] = useState<IMask>({\n converter: applyMask,\n maskValue: applyMask(defaultValue),\n });\n\n const handleChangeValue = useCallback(\n (formattedValue: string) => {\n const { raw, formatted } = applyMask(formattedValue);\n setValue(oldValue => ({\n ...oldValue,\n maskValue: {\n raw,\n formatted,\n },\n }));\n },\n [applyMask, setValue]\n );\n\n return [value, handleChangeValue];\n};\n"],"file":"useCurrencyMask.js"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export interface IMaskValue {
|
|
2
|
-
formatted?: string;
|
|
3
|
-
raw?: any;
|
|
4
|
-
}
|
|
5
|
-
export interface IMask {
|
|
6
|
-
converter?: (raw?: string) => IMaskValue;
|
|
7
|
-
maskValue?: IMaskValue;
|
|
8
|
-
}
|
|
9
|
-
export declare const useMask: (mask: string | ((raw: any) => string), defaultValue?: string | undefined) => [IMask, (text: string) => void];
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.useMask = void 0;
|
|
7
|
-
|
|
8
|
-
var _react = require("react");
|
|
9
|
-
|
|
10
|
-
var _utils = require("../../../../utils");
|
|
11
|
-
|
|
12
|
-
const mergeMask = (value = '', mask) => {
|
|
13
|
-
const chars = '' + value;
|
|
14
|
-
let formattedValue = '';
|
|
15
|
-
|
|
16
|
-
for (let iMask = 0, iChars = 0; iMask < mask.length && iChars < chars.length; iMask++) {
|
|
17
|
-
formattedValue += mask.charAt(iMask) === '9' ? chars.charAt(iChars++) : mask.charAt(iMask);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return formattedValue;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const getMask = (value = '', mask) => {
|
|
24
|
-
if (typeof mask === 'function') {
|
|
25
|
-
return mask(value);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return mask;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const useMask = (mask, defaultValue) => {
|
|
32
|
-
const applyMask = (0, _react.useCallback)((value = '') => {
|
|
33
|
-
const onlyNumbers = value ? (0, _utils.extractDigitsFromString)(value) : value;
|
|
34
|
-
const selectedMask = getMask(onlyNumbers, mask);
|
|
35
|
-
const formattedValue = mergeMask(onlyNumbers, selectedMask);
|
|
36
|
-
return {
|
|
37
|
-
raw: onlyNumbers,
|
|
38
|
-
formatted: formattedValue
|
|
39
|
-
};
|
|
40
|
-
}, [mask]);
|
|
41
|
-
const [value, setValue] = (0, _react.useState)({
|
|
42
|
-
converter: applyMask,
|
|
43
|
-
maskValue: applyMask(defaultValue)
|
|
44
|
-
});
|
|
45
|
-
const handleChangeValue = (0, _react.useCallback)(value => {
|
|
46
|
-
const {
|
|
47
|
-
raw,
|
|
48
|
-
formatted
|
|
49
|
-
} = applyMask(value);
|
|
50
|
-
setValue(oldValue => ({ ...oldValue,
|
|
51
|
-
maskValue: {
|
|
52
|
-
raw,
|
|
53
|
-
formatted
|
|
54
|
-
}
|
|
55
|
-
}));
|
|
56
|
-
}, [applyMask, setValue]);
|
|
57
|
-
return [value, handleChangeValue];
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
exports.useMask = useMask;
|
|
61
|
-
//# sourceMappingURL=useMask.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/atoms/Input/hooks/useMask.ts"],"names":["mergeMask","value","mask","chars","formattedValue","iMask","iChars","length","charAt","getMask","useMask","defaultValue","applyMask","onlyNumbers","selectedMask","raw","formatted","setValue","converter","maskValue","handleChangeValue","oldValue"],"mappings":";;;;;;;AAAA;;AACA;;AAkBA,MAAMA,SAAS,GAAG,CAACC,KAAK,GAAG,EAAT,EAAaC,IAAb,KAA8B;AAC9C,QAAMC,KAAK,GAAG,KAAKF,KAAnB;AACA,MAAIG,cAAc,GAAG,EAArB;;AAEA,OACE,IAAIC,KAAK,GAAG,CAAZ,EAAeC,MAAM,GAAG,CAD1B,EAEED,KAAK,GAAGH,IAAI,CAACK,MAAb,IAAuBD,MAAM,GAAGH,KAAK,CAACI,MAFxC,EAGEF,KAAK,EAHP,EAIE;AACAD,IAAAA,cAAc,IACZF,IAAI,CAACM,MAAL,CAAYH,KAAZ,MAAuB,GAAvB,GAA6BF,KAAK,CAACK,MAAN,CAAaF,MAAM,EAAnB,CAA7B,GAAsDJ,IAAI,CAACM,MAAL,CAAYH,KAAZ,CADxD;AAED;;AACD,SAAOD,cAAP;AACD,CAbD;;AAqBA,MAAMK,OAAO,GAAG,CAACR,KAAK,GAAG,EAAT,EAAaC,IAAb,KAA+D;AAC7E,MAAI,OAAOA,IAAP,KAAgB,UAApB,EAAgC;AAC9B,WAAOA,IAAI,CAACD,KAAD,CAAX;AACD;;AACD,SAAOC,IAAP;AACD,CALD;;AAaO,MAAMQ,OAAO,GAAG,CACrBR,IADqB,EAErBS,YAFqB,KAGe;AACpC,QAAMC,SAAS,GAAG,wBAChB,CAACX,KAAK,GAAG,EAAT,KAA4B;AAC1B,UAAMY,WAAW,GAAGZ,KAAK,GAAG,oCAAwBA,KAAxB,CAAH,GAAoCA,KAA7D;AACA,UAAMa,YAAY,GAAGL,OAAO,CAACI,WAAD,EAAcX,IAAd,CAA5B;AACA,UAAME,cAAc,GAAGJ,SAAS,CAACa,WAAD,EAAcC,YAAd,CAAhC;AAEA,WAAO;AACLC,MAAAA,GAAG,EAAEF,WADA;AAELG,MAAAA,SAAS,EAAEZ;AAFN,KAAP;AAID,GAVe,EAWhB,CAACF,IAAD,CAXgB,CAAlB;AAcA,QAAM,CAACD,KAAD,EAAQgB,QAAR,IAAoB,qBAAgB;AACxCC,IAAAA,SAAS,EAAEN,SAD6B;AAExCO,IAAAA,SAAS,EAAEP,SAAS,CAACD,YAAD;AAFoB,GAAhB,CAA1B;AAKA,QAAMS,iBAAiB,GAAG,wBACvBnB,KAAD,IAAmB;AACjB,UAAM;AAAEc,MAAAA,GAAF;AAAOC,MAAAA;AAAP,QAAqBJ,SAAS,CAACX,KAAD,CAApC;AACAgB,IAAAA,QAAQ,CAACI,QAAQ,KAAK,EACpB,GAAGA,QADiB;AAEpBF,MAAAA,SAAS,EAAE;AACTJ,QAAAA,GADS;AAETC,QAAAA;AAFS;AAFS,KAAL,CAAT,CAAR;AAOD,GAVuB,EAWxB,CAACJ,SAAD,EAAYK,QAAZ,CAXwB,CAA1B;AAcA,SAAO,CAAChB,KAAD,EAAQmB,iBAAR,CAAP;AACD,CAtCM","sourcesContent":["import { useCallback, useState } from 'react';\nimport { extractDigitsFromString } from '../../../../utils';\n\nexport interface IMaskValue {\n formatted?: string;\n raw?: any;\n}\n\nexport interface IMask {\n converter?: (raw?: string) => IMaskValue;\n maskValue?: IMaskValue;\n}\n\n/**\n * TODO:\n * @param value\n * @param mask\n * @returns\n */\nconst mergeMask = (value = '', mask: string) => {\n const chars = '' + value;\n let formattedValue = '';\n\n for (\n let iMask = 0, iChars = 0;\n iMask < mask.length && iChars < chars.length;\n iMask++\n ) {\n formattedValue +=\n mask.charAt(iMask) === '9' ? chars.charAt(iChars++) : mask.charAt(iMask);\n }\n return formattedValue;\n};\n\n/**\n * TODO:\n * @param value\n * @param mask\n * @returns\n */\nconst getMask = (value = '', mask: ((raw: any) => string) | string): string => {\n if (typeof mask === 'function') {\n return mask(value);\n }\n return mask;\n};\n\n/**\n * TODO:\n * @param mask\n * @param defaultValue\n * @returns\n */\nexport const useMask = (\n mask: ((raw: any) => string) | string,\n defaultValue?: string\n): [IMask, (text: string) => void] => {\n const applyMask = useCallback(\n (value = ''): IMaskValue => {\n const onlyNumbers = value ? extractDigitsFromString(value) : value;\n const selectedMask = getMask(onlyNumbers, mask);\n const formattedValue = mergeMask(onlyNumbers, selectedMask);\n\n return {\n raw: onlyNumbers,\n formatted: formattedValue,\n };\n },\n [mask]\n );\n\n const [value, setValue] = useState<IMask>({\n converter: applyMask,\n maskValue: applyMask(defaultValue),\n });\n\n const handleChangeValue = useCallback(\n (value: string) => {\n const { raw, formatted } = applyMask(value);\n setValue(oldValue => ({\n ...oldValue,\n maskValue: {\n raw,\n formatted,\n },\n }));\n },\n [applyMask, setValue]\n );\n\n return [value, handleChangeValue];\n};\n"],"file":"useMask.js"}
|