svelte-currency-input icon indicating copy to clipboard operation
svelte-currency-input copied to clipboard

Caret shifts to the last character when the "thousands" separator gets applied

Open fmaclen opened this issue 1 year ago • 2 comments

https://github.com/fmaclen/svelte-currency-input/assets/1434675/de131586-9c31-41c5-8a29-a0eae8556691

fmaclen avatar Oct 24 '23 16:10 fmaclen

After doing some research I think there's multiple issues at play here.

I was able to "fix" the caret shifting issue by implementing Svelte's await tick() to determine when the DOM has finished updating instead of retrying:

// Wait for Svelte DOM updates
await tick();

// Defer caret position update
const endCaretPosition =
	startCaretPosition + formattedValue.length - previousFormattedValueLength;

// Set the caret position after DOM updates
inputElement?.setSelectionRange(endCaretPosition, endCaretPosition);

This solution worked okay for Chrome and Firefox but it was causing an infinite loop in Safari (WebKit) where the on:blur event was getting triggered constantly until the browser crashes.

This is likely caused by calling setFormattedValue() from multiple places:

The fact that the data flows in so many different ways makes me think that our overall implementation needs to be re-thought from the ground up.

For example, I'm not sure we should listen to an on:blur event, looking at react-currency-field the formatting is always applied as the user types and not after clicking outside of the input, which feels like a nicer UX.

For reference, Bits-UI has WIP implementation of a NumberInput component written in Svelte 5 (which lacks a lot of our current features) and applies formatting after clicking outside of the input.

Maybe this is a good excuse to start re-writing the library with Svelte 5's new syntax 🤔

fmaclen avatar Sep 20 '24 16:09 fmaclen

Great progress! Personally, I think the formatting should occur everytime the user types a number or a punctuation sign, it feels more intuitive (even more if we wanted to use this input in a mobile environment).

GregoMac1 avatar Sep 23 '24 14:09 GregoMac1