-
Notifications
You must be signed in to change notification settings - Fork 10
/
NumberInput.svelte
77 lines (60 loc) · 2.12 KB
/
NumberInput.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<script>
import { createEventDispatcher } from 'svelte';
import MaskInput from './MaskInput.svelte';
export let value = undefined;
export let defaultValue = undefined;
let inputValue = value || defaultValue || '';
const dispatch = createEventDispatcher();
$: inputValue = value || defaultValue || '';
function reformat({ value, input = '', selection }) {
const newSelection = {
start: selection.start,
end: selection.end,
};
let data = removeSelectedRange(value.replace(/(\D)/g, text => (text === ' ' ? ' ' : '')), newSelection);
const inputValue = input.replace(/\D/g, '');
const oldLength = data.length;
data = data.slice(0, newSelection.start) + inputValue + data.slice(newSelection.start, data.length);
const spaces = data.match(/\s/g) || [];
let oldSpacesCount = spaces.length;
let newSpacesCount = 0;
data = data.replace(/\s/g, '').replace(/(\d)(?=(\d\d\d)+(?!\d))/g, text => {
newSpacesCount++;
return `${text} `;
});
let index = newSelection.start + Math.min(0, newSpacesCount - oldSpacesCount);
if (inputValue) {
index = Math.max(0, data.length - oldLength + index);
}
newSelection.end = newSelection.start = index;
return {
value: data,
maskedValue: data,
visibleValue: data,
selection: newSelection,
};
}
function removeSelectedRange(value, selection) {
if (selection.start === selection.end) {
return value;
}
if (selection.end < selection.start) {
const tmp = selection.end;
selection.end = selection.start;
selection.start = tmp;
}
if (value.length > selection.start) {
return value.slice(0, selection.start).concat(value.slice(selection.end, value.length));
}
return value;
}
function handleLeadingZeros(e) {
inputValue = inputValue.replace(/^[0 ]+$/, '0');
dispatch('blur', e.detail);
}
function handleChange(e) {
inputValue = e.detail.inputState.maskedValue;
dispatch('change', e.detail);
}
</script>
<MaskInput {...$$props} value={inputValue} {reformat} on:blur={handleLeadingZeros} on:change={handleChange} />