@canutin/svelte-currency-input 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,8 +26,9 @@ const handleKeyDown = (event) => {
26
26
  const isDeletion = event.key === 'Backspace' || event.key === 'Delete';
27
27
  const isModifier = event.metaKey || event.altKey || event.ctrlKey;
28
28
  const isArrowKey = event.key === 'ArrowLeft' || event.key === 'ArrowRight';
29
+ const isTab = event.key === 'Tab';
29
30
  const isInvalidCharacter = !/^\d|,|\.|-$/g.test(event.key); // Keys that are not a digit, comma, period or minus sign
30
- if (!isDeletion && !isModifier && !isArrowKey && isInvalidCharacter)
31
+ if (!isDeletion && !isModifier && !isArrowKey && isInvalidCharacter && !isTab)
31
32
  event.preventDefault();
32
33
  };
33
34
  let inputTarget;
@@ -38,28 +39,31 @@ const currencySymbol = formatCurrency(0, 0)
38
39
  .replace(/\u00A0/, ''); // e.g '0 €' > '€'
39
40
  // Updates `value` by stripping away the currency formatting
40
41
  const setUnformattedValue = (event) => {
41
- // Don't format if the user is typing a `currencyDecimal` point
42
- if (event.key === currencyDecimal)
43
- return;
44
- // Always convert _the opposite_ decimal key press to the `currencyDecimal` point
45
- if (isDecimalComma && event.key === '.')
46
- formattedValue = formattedValue.replace('.', currencyDecimal);
47
- if (!isDecimalComma && event.key === ',')
48
- formattedValue = formattedValue.replace(',', currencyDecimal);
49
- // Don't format if `formattedValue` is ['$', '-$', "-"]
50
- const ignoreSymbols = [currencySymbol, `-${currencySymbol}`, '-'];
51
- const strippedUnformattedValue = formattedValue.replace(' ', '');
52
- if (ignoreSymbols.includes(strippedUnformattedValue))
53
- return;
54
- // Set the starting caret positions
55
- inputTarget = event.target;
42
+ if (event) {
43
+ // Don't format if the user is typing a `currencyDecimal` point
44
+ if (event.key === currencyDecimal)
45
+ return;
46
+ // Pressing `.` when the decimal point is `,` gets replaced with `,`
47
+ if (isDecimalComma && event.key === '.')
48
+ formattedValue = formattedValue.replace(/\.([^.]*)$/, currencyDecimal + '$1'); // Only replace the last occurence
49
+ // Pressing `,` when the decimal point is `.` gets replaced with `.`
50
+ if (!isDecimalComma && event.key === ',')
51
+ formattedValue = formattedValue.replace(/\,([^,]*)$/, currencyDecimal + '$1'); // Only replace the last occurence
52
+ // Don't format if `formattedValue` is ['$', '-$', "-"]
53
+ const ignoreSymbols = [currencySymbol, `-${currencySymbol}`, '-'];
54
+ const strippedUnformattedValue = formattedValue.replace(' ', '');
55
+ if (ignoreSymbols.includes(strippedUnformattedValue))
56
+ return;
57
+ // Set the starting caret positions
58
+ inputTarget = event.target;
59
+ // Reverse the value when minus is pressed
60
+ if (isNegativeAllowed && event.key === '-')
61
+ value = value * -1;
62
+ }
56
63
  // Remove all characters that arent: numbers, commas, periods (or minus signs if `isNegativeAllowed`)
57
64
  let unformattedValue = isNegativeAllowed
58
65
  ? formattedValue.replace(/[^0-9,.-]/g, '')
59
66
  : formattedValue.replace(/[^0-9,.]/g, '');
60
- // Reverse the value when minus is pressed
61
- if (isNegativeAllowed && event.key === '-')
62
- value = value * -1;
63
67
  // Finally set the value
64
68
  if (Number.isNaN(parseFloat(unformattedValue))) {
65
69
  value = 0;
@@ -69,7 +73,18 @@ const setUnformattedValue = (event) => {
69
73
  unformattedValue = unformattedValue.replace(isDecimalComma ? /\./g : /\,/g, ''); // Remove all group symbols
70
74
  if (isDecimalComma)
71
75
  unformattedValue = unformattedValue.replace(',', '.'); // If the decimal point is a comma, replace it with a period
76
+ // If the zero-key has been pressed
77
+ // and if the current `value` is the same as the `value` before the key-press
78
+ // formatting may need to be done (Issue #30)
79
+ const previousValue = value;
72
80
  value = parseFloat(unformattedValue);
81
+ if (event && previousValue === value) {
82
+ // Do the formatting if the number of digits after the decimal point exceeds `fractionDigits`
83
+ if (unformattedValue.includes('.') &&
84
+ unformattedValue.split('.')[1].length > fractionDigits) {
85
+ setFormattedValue();
86
+ }
87
+ }
73
88
  }
74
89
  };
75
90
  const setFormattedValue = () => {
@@ -78,6 +93,8 @@ const setFormattedValue = () => {
78
93
  const previousFormattedValueLength = formattedValue.length;
79
94
  // Apply formatting to input
80
95
  formattedValue = isZero ? '' : formatCurrency(value, fractionDigits, 0);
96
+ // Update `value` after formatting
97
+ setUnformattedValue();
81
98
  // New caret position
82
99
  const endCaretPosition = startCaretPosition + formattedValue.length - previousFormattedValueLength;
83
100
  // HACK:
@@ -111,6 +128,7 @@ $: value, setFormattedValue();
111
128
  bind:value={formattedValue}
112
129
  on:keydown={handleKeyDown}
113
130
  on:keyup={setUnformattedValue}
131
+ on:blur={setFormattedValue}
114
132
  />
115
133
  </div>
116
134
 
package/README.md CHANGED
@@ -118,3 +118,20 @@ npm run dev
118
118
  # or start the server and open the app in a new browser tab
119
119
  npm run dev -- --open
120
120
  ```
121
+
122
+ #### Integration tests
123
+
124
+ The component is tested using [Playwright](https://playwright.dev/).
125
+ You can find the tests in [`tests/svelte-currency-input.test.ts`](https://github.com/Canutin/svelte-currency-input/blob/main/tests/svelte-currency-input.test.ts)
126
+
127
+ To run all tests on **Chromium**, **Firefox** and **Webkit**:
128
+ ```bash
129
+ npm run test
130
+ ```
131
+
132
+ To run all tests on a specific browser (e.g. **Webkit**):
133
+ ```bash
134
+ npx playwright test --project=webkit
135
+ ```
136
+
137
+ Additional debug commands can be found on [Playwright's documentation](https://playwright.dev/docs/test-cli).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canutin/svelte-currency-input",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "exports": {
5
5
  "./package.json": "./package.json",
6
6
  ".": "./index.js",