@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.
@@ -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,3 @@
1
+ declare const maskValues: (locale: string, inputFieldValue: string | number | undefined, currency: string) => [number, string];
2
+ export { maskValues };
3
+ //# sourceMappingURL=maskValues.d.ts.map
@@ -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,3 @@
1
+ declare const normalizeValue: (number: string | number) => number;
2
+ export { normalizeValue };
3
+ //# sourceMappingURL=normalizeValue.d.ts.map
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkyn/components",
3
- "version": "1.3.63",
3
+ "version": "1.3.64",
4
4
  "main": "./dist/bundle.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Lucas Gonçalves",
@@ -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
- onChange,
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
- onChange,
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
- onKeyDown,
39
- onChange,
40
- showCents,
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 handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {
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(e);
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={valueDisplay(value || currencyValue, showCents)}
88
- onKeyDown={handleKeyDown}
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,3 @@
1
+ const MAXIMUM_FRACTION_DIGITS = 2;
2
+
3
+ export { MAXIMUM_FRACTION_DIGITS };
@@ -0,0 +1,6 @@
1
+ const clearNumber = (number: any) => {
2
+ if (typeof number === "number") return number;
3
+ return Number(number.toString().replace(/[^0-9-]/g, ""));
4
+ };
5
+
6
+ export { clearNumber };
@@ -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 };