Skip to content

Commit e2da5b5

Browse files
author
Hector Arce De Las Heras
committed
Fixed inputCurrency with maxDecimals set to 0
Resolved an issue with the inputCurrency component when maxDecimals was set to 0. The component now correctly handles this case, ensuring accurate and expected behavior.
1 parent 4a8846f commit e2da5b5

File tree

4 files changed

+43
-19
lines changed

4 files changed

+43
-19
lines changed

src/hooks/useInput/__tests__/useInput.test.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { act, renderHook } from '@testing-library/react-hooks';
2-
import { ChangeEvent } from 'react';
2+
import React, { ChangeEvent } from 'react';
33

44
import * as validationsProvider from '@/provider/validations/validationsProvider';
55

@@ -9,7 +9,12 @@ describe('useInput Hook', () => {
99
it('useInput - on internal change should call parent onChange', () => {
1010
const onChange = jest.fn();
1111
const formatNumber = { style: 'decimal' };
12-
const { result } = renderHook(() => useInput({ onChange, formatNumber }));
12+
const ref = React.createRef<HTMLInputElement | undefined>();
13+
const currentValue = '123234';
14+
const regex = new RegExp('^[0-9]*$');
15+
const { result } = renderHook(() =>
16+
useInput({ onChange, formatNumber, ref, currentValue, regex })
17+
);
1318

1419
act(() => {
1520
result.current.handleChangeInternal({
@@ -38,17 +43,19 @@ describe('useInput Hook', () => {
3843
});
3944
it('useInput - on internal blur should call parent onBlur', () => {
4045
const onBlur = jest.fn();
41-
const { result } = renderHook(() => useInput({ onBlur }));
46+
const formatNumber = { style: 'decimal' };
47+
const { result } = renderHook(() => useInput({ onBlur, formatNumber }));
4248

4349
act(() => {
4450
result.current.handleBlurInternal({
4551
target: {
46-
value: 'value',
52+
value: '12323',
4753
},
4854
} as React.FocusEvent<HTMLInputElement>);
4955
});
5056

5157
expect(onBlur).toHaveBeenCalled();
58+
expect(result.current.value).toBe('12,323');
5259
});
5360
it('useInput - on internal blur, if onError, errorExecution === onBlur and keyValidation should call parent onError', () => {
5461
jest.spyOn(validationsProvider, 'useValidations').mockImplementation(() => ({

src/hooks/useInput/types/inputHook.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export type ParamsTypeInputHook = {
2929
informationAssociated?: string;
3030
ignoreKeys?: string[];
3131
formatNumber?: FormatNumber;
32+
locale?: string;
3233
onBlur?: FocusEventHandler<HTMLInputElement>;
3334
onChange?: ChangeEventHandler<HTMLInputElement>;
3435
onFocus?: FocusEventHandler<HTMLInputElement>;

src/hooks/useInput/useInput.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ import { ERROR_EXECUTION, FormatNumber } from '@/components/input/types/input';
1414
import { InputTypeType } from '@/components/input/types/inputType';
1515
import {
1616
checkValidFormattedNumber,
17+
convertDecimalSeparator,
1718
formatNumber,
19+
getDecimalSeparator,
1820
getState,
1921
removeThousandSeparator,
2022
} from '@/components/input/utils';
@@ -28,7 +30,6 @@ import {
2830
getPosition,
2931
isArrowDownPressed,
3032
isArrowUpPressed,
31-
isKeyEnterPressed,
3233
maxCountBetweenChars,
3334
} from '@/utils';
3435
import { matchInputValue } from '@/utils/maskUtility/mask.utility';
@@ -82,7 +83,7 @@ export const useInput = (props: ParamsTypeInputHook): ReturnTypeInputHook => {
8283
if (props.currentValue !== undefined) {
8384
let newValue = props.currentValue;
8485
// format with formatNumber configuration
85-
if (firstRender.current && props.formatNumber) {
86+
if (firstRender.current && props.formatNumber && !focus) {
8687
// add thousand separator to the value
8788
newValue = addThousandSeparator(String(props.currentValue), props.formatNumber);
8889
}
@@ -118,7 +119,7 @@ export const useInput = (props: ParamsTypeInputHook): ReturnTypeInputHook => {
118119

119120
// truncate the value with maximun of decimals
120121
const truncateValue =
121-
props.truncate && props.maxDecimals
122+
props.truncate && props.maxDecimals !== null && props.maxDecimals !== undefined
122123
? truncatedValue(String(limitedValue), props.maxDecimals)
123124
: limitedValue;
124125
handleSetValue(truncateValue);
@@ -127,9 +128,9 @@ export const useInput = (props: ParamsTypeInputHook): ReturnTypeInputHook => {
127128

128129
// add thousand separator to the value
129130
const addThousandSeparator = (value: string, format: FormatNumber) => {
130-
if (checkValidFormattedNumber(value, format.locale)) {
131+
if (checkValidFormattedNumber(value, props.locale || format.locale)) {
131132
// remove existing thousand separator
132-
const newValue = removeThousandSeparator(value, format.locale);
133+
const newValue = removeThousandSeparator(value, props.locale || format.locale);
133134
// format value
134135
const formattedValue = formatNumber(Number(newValue), format);
135136
return formattedValue;
@@ -149,8 +150,12 @@ export const useInput = (props: ParamsTypeInputHook): ReturnTypeInputHook => {
149150
const newMaskedValue = matchInputValue(String(value), event.target.value, props.regex);
150151
event.target.value = newMaskedValue;
151152
}
152-
if (props.truncate && props.maxDecimals) {
153-
event.target.value = truncatedValue(String(event.target.value), props.maxDecimals);
153+
if (props.truncate && props.maxDecimals !== null && props.maxDecimals !== undefined) {
154+
event.target.value = truncatedValue(
155+
String(event.target.value),
156+
props.maxDecimals,
157+
props.locale || props.formatNumber?.locale
158+
);
154159
}
155160

156161
// key validation
@@ -186,6 +191,20 @@ export const useInput = (props: ParamsTypeInputHook): ReturnTypeInputHook => {
186191
};
187192

188193
const handleFocusInternal: FocusEventHandler<HTMLInputElement> = event => {
194+
if (props.formatNumber) {
195+
// remove thousand separator to the value
196+
event.target.value = removeThousandSeparator(
197+
event.target.value,
198+
props.locale || props.formatNumber?.locale,
199+
false
200+
);
201+
handleSetValue(event.target.value);
202+
}
203+
// transform the string value to a number format with dot as decimal separator to avoid errors
204+
event.target.value = convertDecimalSeparator(
205+
event.target.value,
206+
getDecimalSeparator(props.locale || props.formatNumber?.locale)
207+
);
189208
props.onFocus?.(event);
190209
};
191210

@@ -207,12 +226,6 @@ export const useInput = (props: ParamsTypeInputHook): ReturnTypeInputHook => {
207226
) {
208227
event.preventDefault();
209228
}
210-
// Check if the input has a formatNumber ans press the enter key
211-
if (props.formatNumber && isKeyEnterPressed(event.key) && inputRef.current) {
212-
// add thousand separator to the value
213-
const newValue = addThousandSeparator(String(value), props.formatNumber);
214-
handleSetValue(newValue);
215-
}
216229

217230
const {
218231
key,

src/utils/cursorUtility/cursor.utility.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BACKSPACE } from '@/constants';
1+
import { BACKSPACE, DELETE } from '@/constants';
22
import { CursorType } from '@/types/type';
33

44
import { getPosition } from './cursor.utility';
@@ -11,7 +11,10 @@ describe('Cursor', () => {
1111
const position = getPosition(BACKSPACE.key, VALUE, CURSOR);
1212
expect(position).toBe(-1);
1313
});
14-
14+
it('getPosition - should return 0', () => {
15+
const position = getPosition(DELETE.key, VALUE, CURSOR);
16+
expect(position).toBe(0);
17+
});
1518
it('getPosition - should return 1', () => {
1619
const position = getPosition('t', VALUE, CURSOR);
1720
expect(position).toBe(1);

0 commit comments

Comments
 (0)