@arkyn/components 1.3.63 → 1.3.64
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/bundle.js +898 -892
- package/dist/bundle.umd.cjs +12 -12
- package/dist/components/Input/CurrencyInput/getConfig.d.ts +6 -5
- package/dist/components/Input/CurrencyInput/getConfig.d.ts.map +1 -1
- package/dist/components/Input/CurrencyInput/getConfig.js +6 -3
- package/dist/components/Input/CurrencyInput/index.d.ts.map +1 -1
- package/dist/components/Input/CurrencyInput/index.js +27 -12
- package/dist/constants/decimals.d.ts +3 -0
- package/dist/constants/decimals.d.ts.map +1 -0
- package/dist/constants/decimals.js +2 -0
- package/dist/services/clearNumber.d.ts +3 -0
- package/dist/services/clearNumber.d.ts.map +1 -0
- package/dist/services/clearNumber.js +6 -0
- package/dist/services/format.d.ts +3 -0
- package/dist/services/format.d.ts.map +1 -0
- package/dist/services/format.js +13 -0
- package/dist/services/maskValues.d.ts +3 -0
- package/dist/services/maskValues.d.ts.map +1 -0
- package/dist/services/maskValues.js +10 -0
- package/dist/services/normalizeValue.d.ts +3 -0
- package/dist/services/normalizeValue.d.ts.map +1 -0
- package/dist/services/normalizeValue.js +18 -0
- package/package.json +1 -1
- package/src/components/Input/CurrencyInput/getConfig.tsx +6 -4
- package/src/components/Input/CurrencyInput/index.tsx +51 -22
- package/src/constants/decimals.ts +3 -0
- package/src/services/clearNumber.ts +6 -0
- package/src/services/format.ts +21 -0
- package/src/services/maskValues.ts +17 -0
- package/src/services/normalizeValue.ts +21 -0
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/services/format.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,cAAc,WACV,MAAM,SACP,MAAM,wDAcd,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
const SYMBOL_LENGTH = 3;
|
2
|
+
const formatCurrency = (locale = "pt-BR", value, currencyType = "BRL", hideSymbol = true) => {
|
3
|
+
const formatter = new Intl.NumberFormat(locale, {
|
4
|
+
style: "currency",
|
5
|
+
currency: currencyType,
|
6
|
+
currencyDisplay: "symbol",
|
7
|
+
minimumFractionDigits: 2,
|
8
|
+
maximumFractionDigits: 2,
|
9
|
+
});
|
10
|
+
const formattedValue = formatter.format(value);
|
11
|
+
return formattedValue.slice(hideSymbol ? SYMBOL_LENGTH : 0);
|
12
|
+
};
|
13
|
+
export { formatCurrency };
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"maskValues.d.ts","sourceRoot":"","sources":["../../src/services/maskValues.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,UAAU,WACN,MAAM,mBACG,MAAM,GAAG,MAAM,GAAG,SAAS,YAClC,MAAM,KACf,CAAC,MAAM,EAAE,MAAM,CAOjB,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { formatCurrency } from "./format";
|
2
|
+
import { normalizeValue } from "./normalizeValue";
|
3
|
+
const maskValues = (locale, inputFieldValue, currency) => {
|
4
|
+
if (!inputFieldValue)
|
5
|
+
return [0, ""];
|
6
|
+
const value = normalizeValue(inputFieldValue);
|
7
|
+
const maskedValue = formatCurrency(locale, value, currency);
|
8
|
+
return [value, maskedValue];
|
9
|
+
};
|
10
|
+
export { maskValues };
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"normalizeValue.d.ts","sourceRoot":"","sources":["../../src/services/normalizeValue.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,cAAc,WAAY,MAAM,GAAG,MAAM,WAe9C,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { MAXIMUM_FRACTION_DIGITS } from "../constants/decimals";
|
2
|
+
import { clearNumber } from "./clearNumber";
|
3
|
+
const normalizeValue = (number) => {
|
4
|
+
let safeNumber = number;
|
5
|
+
if (typeof number === "string") {
|
6
|
+
safeNumber = clearNumber(number);
|
7
|
+
if (safeNumber % 1 !== 0) {
|
8
|
+
safeNumber = safeNumber.toFixed(MAXIMUM_FRACTION_DIGITS);
|
9
|
+
}
|
10
|
+
}
|
11
|
+
else {
|
12
|
+
safeNumber = Number.isInteger(number)
|
13
|
+
? Number(number) * 10 ** MAXIMUM_FRACTION_DIGITS
|
14
|
+
: number.toFixed(MAXIMUM_FRACTION_DIGITS);
|
15
|
+
}
|
16
|
+
return clearNumber(safeNumber) / 10 ** MAXIMUM_FRACTION_DIGITS;
|
17
|
+
};
|
18
|
+
export { normalizeValue };
|
package/package.json
CHANGED
@@ -20,9 +20,10 @@ function getConfig(props: CurrencyInputProps, isFocused: boolean) {
|
|
20
20
|
onBlur,
|
21
21
|
title,
|
22
22
|
style,
|
23
|
-
showCents = false,
|
23
|
+
// showCents = false,
|
24
24
|
max = 1000000000,
|
25
|
-
|
25
|
+
locale = "pt-BR",
|
26
|
+
currency = "BRL",
|
26
27
|
...rest
|
27
28
|
} = props;
|
28
29
|
|
@@ -46,14 +47,15 @@ function getConfig(props: CurrencyInputProps, isFocused: boolean) {
|
|
46
47
|
LeftIcon,
|
47
48
|
RightIcon,
|
48
49
|
disabled,
|
50
|
+
locale,
|
51
|
+
currency,
|
49
52
|
readOnly,
|
50
53
|
onFocus,
|
51
54
|
onBlur,
|
52
55
|
title,
|
53
56
|
style,
|
54
57
|
max,
|
55
|
-
|
56
|
-
showCents,
|
58
|
+
// showCents,
|
57
59
|
loadingPosition,
|
58
60
|
iconSize: iconSize,
|
59
61
|
Spinner: <Loader2 className="spinner" size={iconSize} strokeWidth={2.5} />,
|
@@ -1,14 +1,16 @@
|
|
1
1
|
import type { CurrencyInputProps } from "@arkyn/types";
|
2
|
-
import type { FocusEvent, KeyboardEvent } from "react";
|
3
|
-
|
4
|
-
import { useRef, useState } from "react";
|
2
|
+
import type { ChangeEvent, FocusEvent, KeyboardEvent } from "react";
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
5
4
|
|
6
5
|
import { useFormController } from "../../../components/Form/FormController";
|
6
|
+
import { maskValues } from "../../../services/maskValues";
|
7
|
+
import { normalizeValue } from "../../../services/normalizeValue";
|
8
|
+
|
7
9
|
import { getConfig } from "./getConfig";
|
8
|
-
import { currencyInputKeyDown, valueDisplay } from "./utils";
|
9
10
|
|
10
11
|
function CurrencyInput(props: CurrencyInputProps) {
|
11
12
|
const [isFocused, setIsFocused] = useState(false);
|
13
|
+
const [maskedValue, setMaskedValue] = useState("");
|
12
14
|
|
13
15
|
const baseRef = useRef<HTMLInputElement>(null);
|
14
16
|
|
@@ -35,15 +37,15 @@ function CurrencyInput(props: CurrencyInputProps) {
|
|
35
37
|
Spinner,
|
36
38
|
value,
|
37
39
|
max,
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
onChangeValue,
|
41
|
+
onKeyPress,
|
42
|
+
currency,
|
43
|
+
locale,
|
44
|
+
name,
|
41
45
|
defaultValue,
|
42
46
|
...rest
|
43
47
|
} = getConfig({ ...props, id, isError }, isFocused);
|
44
48
|
|
45
|
-
const [currencyValue, setCurrencyValue] = useState(defaultValue * 100 || 0);
|
46
|
-
|
47
49
|
const showLeftIcon = LeftIcon && !isLoading;
|
48
50
|
const showRightIcon = RightIcon && !isLoading;
|
49
51
|
|
@@ -56,15 +58,9 @@ function CurrencyInput(props: CurrencyInputProps) {
|
|
56
58
|
ref.current.focus();
|
57
59
|
}
|
58
60
|
|
59
|
-
function
|
60
|
-
currencyInputKeyDown({ currencyValue, event, max, setCurrencyValue });
|
61
|
-
onChange && onChange(currencyValue / 100);
|
62
|
-
onKeyDown && onKeyDown(event);
|
63
|
-
}
|
64
|
-
|
65
|
-
function handleFocus(e: FocusEvent<HTMLInputElement>) {
|
61
|
+
function handleFocus(event: FocusEvent<HTMLInputElement>) {
|
66
62
|
setIsFocused(true);
|
67
|
-
if (onFocus) onFocus(
|
63
|
+
if (onFocus) onFocus(event);
|
68
64
|
}
|
69
65
|
|
70
66
|
function handleBlur(e: FocusEvent<HTMLInputElement>) {
|
@@ -72,6 +68,37 @@ function CurrencyInput(props: CurrencyInputProps) {
|
|
72
68
|
if (onBlur) onBlur(e);
|
73
69
|
}
|
74
70
|
|
71
|
+
const updateValues = (originalValue: string | number) => {
|
72
|
+
const [calculatedValue, calculatedMaskedValue] = maskValues(
|
73
|
+
locale,
|
74
|
+
originalValue,
|
75
|
+
currency
|
76
|
+
);
|
77
|
+
|
78
|
+
if (!max || calculatedValue <= max) {
|
79
|
+
setMaskedValue(calculatedMaskedValue);
|
80
|
+
return [calculatedValue, calculatedMaskedValue];
|
81
|
+
}
|
82
|
+
|
83
|
+
return [normalizeValue(maskedValue), maskedValue];
|
84
|
+
};
|
85
|
+
|
86
|
+
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
87
|
+
event.preventDefault();
|
88
|
+
const [originalValue, maskedValue] = updateValues(event.target.value);
|
89
|
+
onChangeValue(event, String(originalValue), String(maskedValue));
|
90
|
+
};
|
91
|
+
|
92
|
+
const handleKeyUp = (event: KeyboardEvent<HTMLInputElement>) =>
|
93
|
+
onKeyPress && onKeyPress(event, event.key, event.key);
|
94
|
+
|
95
|
+
useEffect(() => {
|
96
|
+
const currentValue = value || defaultValue || undefined;
|
97
|
+
const [, maskedValue] = maskValues(locale, currentValue, currency);
|
98
|
+
|
99
|
+
setMaskedValue(maskedValue);
|
100
|
+
}, [currency, defaultValue, value]);
|
101
|
+
|
75
102
|
return (
|
76
103
|
<section
|
77
104
|
title={title}
|
@@ -84,17 +111,19 @@ function CurrencyInput(props: CurrencyInputProps) {
|
|
84
111
|
{showLeftIcon && <LeftIcon size={iconSize} strokeWidth={2.5} />}
|
85
112
|
|
86
113
|
<input
|
87
|
-
value={
|
88
|
-
|
114
|
+
value={maskedValue}
|
115
|
+
onChange={handleChange}
|
116
|
+
onBlur={handleBlur}
|
117
|
+
onFocus={handleFocus}
|
118
|
+
onKeyUp={handleKeyUp}
|
89
119
|
disabled={disabled || isLoading}
|
90
120
|
readOnly={readOnly}
|
91
121
|
ref={ref}
|
92
|
-
onFocus={handleFocus}
|
93
|
-
onBlur={handleBlur}
|
94
|
-
onChange={() => {}}
|
95
122
|
{...rest}
|
96
123
|
/>
|
97
124
|
|
125
|
+
<input type="hidden" name={name} value={normalizeValue(maskedValue)} />
|
126
|
+
|
98
127
|
{showRightSpinner && Spinner}
|
99
128
|
{showRightIcon && <RightIcon size={iconSize} strokeWidth={2.5} />}
|
100
129
|
{sufix}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
const SYMBOL_LENGTH = 3;
|
2
|
+
|
3
|
+
const formatCurrency = (
|
4
|
+
locale: string = "pt-BR",
|
5
|
+
value: number,
|
6
|
+
currencyType = "BRL",
|
7
|
+
hideSymbol = true
|
8
|
+
) => {
|
9
|
+
const formatter = new Intl.NumberFormat(locale, {
|
10
|
+
style: "currency",
|
11
|
+
currency: currencyType,
|
12
|
+
currencyDisplay: "symbol",
|
13
|
+
minimumFractionDigits: 2,
|
14
|
+
maximumFractionDigits: 2,
|
15
|
+
});
|
16
|
+
const formattedValue = formatter.format(value);
|
17
|
+
|
18
|
+
return formattedValue.slice(hideSymbol ? SYMBOL_LENGTH : 0);
|
19
|
+
};
|
20
|
+
|
21
|
+
export { formatCurrency };
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { formatCurrency } from "./format";
|
2
|
+
import { normalizeValue } from "./normalizeValue";
|
3
|
+
|
4
|
+
const maskValues = (
|
5
|
+
locale: string,
|
6
|
+
inputFieldValue: string | number | undefined,
|
7
|
+
currency: string
|
8
|
+
): [number, string] => {
|
9
|
+
if (!inputFieldValue) return [0, ""];
|
10
|
+
|
11
|
+
const value = normalizeValue(inputFieldValue);
|
12
|
+
const maskedValue = formatCurrency(locale, value, currency);
|
13
|
+
|
14
|
+
return [value, maskedValue];
|
15
|
+
};
|
16
|
+
|
17
|
+
export { maskValues };
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { MAXIMUM_FRACTION_DIGITS } from "../constants/decimals";
|
2
|
+
import { clearNumber } from "./clearNumber";
|
3
|
+
|
4
|
+
const normalizeValue = (number: string | number) => {
|
5
|
+
let safeNumber = number;
|
6
|
+
|
7
|
+
if (typeof number === "string") {
|
8
|
+
safeNumber = clearNumber(number);
|
9
|
+
if (safeNumber % 1 !== 0) {
|
10
|
+
safeNumber = safeNumber.toFixed(MAXIMUM_FRACTION_DIGITS);
|
11
|
+
}
|
12
|
+
} else {
|
13
|
+
safeNumber = Number.isInteger(number)
|
14
|
+
? Number(number) * 10 ** MAXIMUM_FRACTION_DIGITS
|
15
|
+
: number.toFixed(MAXIMUM_FRACTION_DIGITS);
|
16
|
+
}
|
17
|
+
|
18
|
+
return clearNumber(safeNumber) / 10 ** MAXIMUM_FRACTION_DIGITS;
|
19
|
+
};
|
20
|
+
|
21
|
+
export { normalizeValue };
|