How to make a currency mask
-
I'm submitting a ... [ ] bug report [ ] feature request [ ] question about the decisions made in the repository [ x ] question about how to use this project
-
Summary I'm trying to make a simple number mask to currency values.
<Space direction="vertical">
<label>Entrada</label>
<MaskedInput
autoComplete="off"
placeholder = "Entrada"
mask={
React.useMemo<MaskType>(() => [
{
mask: 'R$ num',
lazy: true,
blocks: {
num: {
mask: Number,
thousandsSeparator: '.',
padFractionalZeros: true
}
}
}
], [])
}
/>
</Space>

But that way only one digit appears and throws this warning on the console. What am I doing wrong?
- Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)
I am following this documentation: https://imask.js.org/

Thanks!
@lpepinelli did you find any solution?
Not with this library, not yet. But I found an alternative with typescript, regex and antd input component.
export const currencyMask = (value: string) => {
let valueFormatted = value
valueFormatted = valueFormatted.replace(/\D/g, '')
valueFormatted = valueFormatted.replace(/(\d)(\d{2})$/, '$1,$2')
valueFormatted = valueFormatted.replace(/(?=(\d{3})+(\D))\B/g, '.')
return {
maskedValue: valueFormatted,
unmaskedValue: Number(valueFormatted.replace('.', '').replace(',', '.'))
}
}
<Input
prefix='R$'
placeholder="Entrada"
autoComplete='off'
value={entradaInput}
onChange={({ target }) => handleEntradaChange(target.value)} />
const handleEntradaChange = (value: string) => {
setEntradaInput(currencyMask(value).maskedValue)
const unmaskedValue = currencyMask(value).unmaskedValue
console.log(unmaskedValue)
}

You must use useMeme in the component body
@antoniopresto how to use the example that working of @lpepinelli with useMemo?
@lpepinelli How would this function look like when I type 1, it starts formatting from right to left, that is, it would look like this: 0.01. When I typed 15 it would format to 0.15?
Hi @renerlemes
If you add a "padStart" to the function you will have the behavior that you want.
export const currencyMask = (value: string) => {
let valueFormatted = value
valueFormatted = valueFormatted.replace(/\D/g, '')
// Add a leading zero for numbers with one or two digits
valueFormatted = valueFormatted.padStart(3, '0')
valueFormatted = valueFormatted.replace(/(\d{1})(\d{2})$/, '$1,$2')
valueFormatted = valueFormatted.replace(/(?=(\d{3})+(\D))\B/g, '.')
return {
maskedValue: valueFormatted,
unmaskedValue: Number(valueFormatted.replace('.', '').replace(',', '.'))
}
}
I don't have my project working here to test, but I think it will work.

@lpepinelli the code you suggested did not work. See the image below. But I made a small change and it worked.
export const currencyMask = (value: string) => {
let valueFormatted = value;
valueFormatted = valueFormatted.replace(/\D/g, "");
valueFormatted = valueFormatted.padStart(3, "0");
valueFormatted = valueFormatted.replace(/(\d{1})(\d{2})$/, "$1,$2");
valueFormatted = valueFormatted.replace(/(?=(\d{3})+(\D))\B/g, ".");
let beforeComma = valueFormatted.split(",")[0];
if (beforeComma === "00" || (beforeComma.length === 2 && beforeComma[0] === "0" && beforeComma[1] !== "0")) {
valueFormatted = valueFormatted.slice(1);
}
return {
maskedValue: valueFormatted,
unmaskedValue: Number(valueFormatted.replace('.', '').replace(',', '.'))
}
