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).