rifm icon indicating copy to clipboard operation
rifm copied to clipboard

help with currency mask and rifm props

Open sibelius opened this issue 4 years ago • 11 comments

I'm trying to apply this mask 0.000.000,00 for Brazilian currency

I'd like to have the following behavior:

1 cents -> 0,01 (when user types 1, it gets 0,01) 10 cents -> 0,10 100 cents -> 1,00 100000 cents -> 1.000,00

I'm not sure if I need to use format, replace, mask true or false, or append to achieve this behavior

any thoughts on this?

sibelius avatar Jan 18 '21 17:01 sibelius

would it be a stupid suggestion if I said to divide the field entrance by 100? so, if the user types "1", in the text field it would appear "0.01"

igorlourenco avatar Jan 18 '21 17:01 igorlourenco

I don't know if it's the better solution, but: https://codesandbox.io/s/damp-resonance-xcz6d?file=/src/App.js

The tricky is that format receive a str value (formatted one, like "R$ 0,01"). You need to get the number from it (regex + parseInt), then back it to string (formatting back to "R$ 0,01"). The cents parts, as @igorlrnc said, is just divide it by 100 with toFixed(2)

renatorib avatar Jan 18 '21 17:01 renatorib

it is looking great, tks

the only problem is the delete keycode that is jumping the cursor to the beginning of the input

is there a way to fix it?

sibelius avatar Jan 18 '21 17:01 sibelius

I think you should use accept prop (not sure). But I couldn't make it work here

renatorib avatar Jan 18 '21 18:01 renatorib

image

R$ 1,23|

press delete

image

|R$ 0,12

sibelius avatar Jan 18 '21 18:01 sibelius

I figured out that it only happens when you delete the last char when it's only three digits (4+ works)

cursor-bug-rifm

renatorib avatar Jan 18 '21 18:01 renatorib

what is the best way to add a failing test case for this behavior?

sibelius avatar Jan 18 '21 19:01 sibelius

what about an advanced prop where the user could return the cursor position?

sibelius avatar Jan 18 '21 19:01 sibelius

this line is breaking the backspace behavior

https://github.com/realadvisor/rifm/blob/master/src/Rifm.js#L211

// Visually improves working with masked values, // like cursor jumping over refused symbols // as an example date mask: was "5|1-24-3" then user pressed "6" // it becomes "56-|12-43" with this code, and "56|-12-43" without

sibelius avatar Jan 26 '21 14:01 sibelius

working version without that line


const numberFormat = (str: string) => {
    if (str === '') str = '0';
    const value = (parseInt(str.replace(/[^\d]+/gi, ''), 10) / 100).toFixed(2);

    const getCurrencyFormat = () => {
      if (!value) {
        return '';
      }

      return new Intl.NumberFormat('pt-br', {
        style: 'currency',
        currency: 'BRL',
      })
        .format(value)
        .replace('R$ ', '');
    };

    return getCurrencyFormat();
  };

  const rifm = useMask({
    value,
    onChange: (value) => {
      const e = { target: { value } };
      onChange(e);
    },
    format: numberFormat,
  });

sibelius avatar Jan 26 '21 14:01 sibelius

do you see a bug where the second inserted number after an erase goes to the decimals?

https://user-images.githubusercontent.com/14146176/160015674-e497c02e-c96e-4e53-8c20-da53ec590cd3.mp4

added a new if to the numberFormat above to fix it:

const numberFormat = (str: string) => {
    if (str === '') str = '0';
	if (str.includes('R$') && !isNaN(parseInt(str.charAt(0)))) {
		str = str.replace('R$', '')
		str = str.slice(1, str.length) + str.charAt(0)
	}
    const value = (parseInt(str.replace(/[^\d]+/gi, ''), 10) / 100).toFixed(2);

    const getCurrencyFormat = () => {
      if (!value) {
        return '';
      }

      return new Intl.NumberFormat('pt-br', {
        style: 'currency',
        currency: 'BRL',
      })
        .format(value)
        .replace('R$ ', '');
    };

    return getCurrencyFormat();
  };


luizcieslak avatar Mar 24 '22 21:03 luizcieslak