Skip to content

Commit 82c994d

Browse files
author
cnilton
committed
changed currency mask back to old form
1 parent be199b3 commit 82c994d

File tree

4 files changed

+57
-32
lines changed

4 files changed

+57
-32
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ yarn add [email protected]
7171
| `staticLabel` | boolean | false | Set this to true if you want the label to be always at a set position. Commonly used with hint for displaying both label and hint for your input. For changing the position of the label with this prop as true, use the **customLabelStyles** _topFocused_ and _leftFocused_ to adjust the wanted position. |
7272
| `hint` | string | undefined | Hint displayed when label is focused or `staticLabel` prop is being used |
7373
| `hintTextColor` | string | '#ccc' | Set hint text color |
74+
| `currency` | string | undefined | Set currency on input |
7475
| `currencyDivider` | ','<br/>'.' | ',' | Set currency thousands divider |
7576
| `maxDecimalPlaces` | number | 2 | Set maximum decimal places |
7677
| `isFocused` | boolean | undefined | If you override the onFocus/onBlur props, you must handle this prop as an state variable |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-native-floating-label-input",
33
"description": "A simple and customizable React Native TextInput with it's placeholder always shown.",
4-
"version": "1.3.13",
4+
"version": "1.3.14",
55
"author": "Caio Nilton <cnilton>",
66
"main": "index.tsx",
77
"private": false,

src/index.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ export interface Props extends Omit<TextInputProps, 'secureTextEntry'> {
7878
currencyDivider?: ',' | '.';
7979
/** Maxinum number of decimal places allowed for currency mask. */
8080
maxDecimalPlaces?: number;
81+
/** Set currency on input value */
82+
currency?: string;
8183
/** Changes the input from single line input to multiline input */
8284
multiline?: true | false;
8385
/** Maxinum number of characters allowed. Overriden by mask if present */
@@ -181,6 +183,7 @@ const FloatingLabelInput: React.ForwardRefRenderFunction<InputRef, Props> = (
181183
darkTheme,
182184
countdownLabel,
183185
currencyDivider,
186+
currency,
184187
maskType,
185188
onChangeText,
186189
customHidePasswordComponent,
@@ -596,15 +599,31 @@ const FloatingLabelInput: React.ForwardRefRenderFunction<InputRef, Props> = (
596599
}
597600

598601
if (maskType === 'currency') {
602+
if (
603+
currency !== undefined &&
604+
!/^[0-9]+$/g.test(val.replace(/[.,]/g, '').replace(currency, '')) &&
605+
val.replace(/[.,]/g, '').replace(currency, '') !== ''
606+
) {
607+
return undefined;
608+
} else if (
609+
currency === undefined &&
610+
!/^[0-9]+$/g.test(val.replace(/[.,]/g, '')) &&
611+
val.replace(/[.,]/g, '') !== ''
612+
) {
613+
return undefined;
614+
}
615+
599616
newValue = getValueWithCurrencyMask({
600-
value,
601-
newValue: val,
617+
value: currency !== undefined ? value.replace(currency, '') : value,
618+
newValue: currency !== undefined ? val.replace(currency, '') : val,
602619
currencyDivider,
603620
maxDecimalPlaces,
604621
});
605622
}
606623

607-
if (newValue !== undefined) return onChangeText(newValue);
624+
if (newValue !== undefined) {
625+
return onChangeText((currency !== undefined ? currency : '') + newValue);
626+
}
608627
}
609628

610629
function onLayout(event: LayoutChangeEvent) {

src/utils.tsx

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,41 +56,46 @@ function getCurrencyDividerAndDecimal(divider: CurrencyDivider | undefined) {
5656
};
5757
}
5858

59-
function convertToNumber(
60-
value: string,
61-
divider: CurrencyDivider,
62-
decimal: CurrencyDivider,
63-
): number {
64-
// Replace decimal with a dot to allow parsing with Number default constructor
65-
return Number(
66-
value.replace(`/${divider}/g`, '').replace(`/${decimal}/`, '.'),
67-
);
68-
}
69-
7059
export function getValueWithCurrencyMask({
7160
value,
7261
newValue,
7362
currencyDivider,
74-
maxDecimalPlaces,
7563
}: CurrencyMaskTypeArgs): ResultType {
7664
const { divider, decimal } = getCurrencyDividerAndDecimal(currencyDivider);
7765

78-
if (value.length >= newValue.length) return undefined;
79-
80-
const newValueAsNumber = convertToNumber(newValue, divider, decimal);
81-
82-
const decimalPlaces: number =
83-
maxDecimalPlaces !== undefined ? maxDecimalPlaces : 2;
66+
if (value !== undefined) {
67+
if (!newValue.includes(decimal)) {
68+
if (newValue?.replace(/[,.]/g, '')?.length > 3) {
69+
let arr: string[] = [];
70+
let unmasked = newValue.replace(/[,.]/g, '');
71+
for (let i = 0; i < unmasked.length; i += 3) {
72+
arr.push(
73+
unmasked
74+
.split('')
75+
.splice(unmasked.length - i, 3)
76+
.join(''),
77+
);
78+
}
8479

85-
if (divider === ',') {
86-
// en-US uses dot as decimal separator and comma for thousands
87-
return newValueAsNumber.toLocaleString('en-US', {
88-
maximumFractionDigits: decimalPlaces,
89-
});
90-
} else {
91-
// German uses comma as decimal separator and period for thousands
92-
return newValueAsNumber.toLocaleString('de-DE', {
93-
maximumFractionDigits: decimalPlaces,
94-
});
80+
arr = arr.reverse();
81+
arr.pop();
82+
const initial = arr.join('');
83+
if (unmasked.includes(initial)) {
84+
unmasked = unmasked.replace(initial, '');
85+
}
86+
newValue = unmasked + divider + arr.join(divider);
87+
} else {
88+
newValue = newValue?.replace(/[,.]/g, '');
89+
}
90+
} else {
91+
if (
92+
newValue?.split(decimal).length > 2 ||
93+
newValue?.split(decimal)[1].includes(divider)
94+
) {
95+
return value;
96+
}
97+
}
9598
}
99+
100+
return newValue;
96101
}

0 commit comments

Comments
 (0)