svelte-currency-input
svelte-currency-input copied to clipboard
Caret shifts to the last character when the "thousands" separator gets applied
https://github.com/fmaclen/svelte-currency-input/assets/1434675/de131586-9c31-41c5-8a29-a0eae8556691
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:
onMount()on:blur={setFormattedValue}$: value, setFormattedValue();- At te end of
setUnformattedValue() - And inside
setFormattedValue()we are also calling backsetUnformattedValue()
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 🤔
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).