@canutin/svelte-currency-input 0.12.0 → 1.0.0-next.7
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.
- package/README.md +231 -110
- package/dist/currency-input.svelte +361 -0
- package/dist/currency-input.svelte.d.ts +29 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4 -2
- package/dist/types.d.ts +36 -9
- package/dist/utils/addSeparators.d.ts +1 -0
- package/dist/utils/addSeparators.js +3 -0
- package/dist/utils/cleanValue.d.ts +2 -0
- package/dist/utils/cleanValue.js +43 -0
- package/dist/utils/escapeRegExp.d.ts +1 -0
- package/dist/utils/escapeRegExp.js +3 -0
- package/dist/utils/fixedDecimalValue.d.ts +1 -0
- package/dist/utils/fixedDecimalValue.js +25 -0
- package/dist/utils/formatValue.d.ts +2 -0
- package/dist/utils/formatValue.js +101 -0
- package/dist/utils/getLocaleConfig.d.ts +2 -0
- package/dist/utils/getLocaleConfig.js +33 -0
- package/dist/utils/getSuffix.d.ts +6 -0
- package/dist/utils/getSuffix.js +6 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.js +13 -0
- package/dist/utils/isNumber.d.ts +1 -0
- package/dist/utils/isNumber.js +1 -0
- package/dist/utils/padTrimValue.d.ts +1 -0
- package/dist/utils/padTrimValue.js +26 -0
- package/dist/utils/parseAbbrValue.d.ts +2 -0
- package/dist/utils/parseAbbrValue.js +23 -0
- package/dist/utils/removeInvalidChars.d.ts +1 -0
- package/dist/utils/removeInvalidChars.js +6 -0
- package/dist/utils/removeSeparators.d.ts +1 -0
- package/dist/utils/removeSeparators.js +5 -0
- package/dist/utils/repositionCursor.d.ts +12 -0
- package/dist/utils/repositionCursor.js +18 -0
- package/package.json +77 -58
- package/dist/CurrencyInput.svelte +0 -180
- package/dist/CurrencyInput.svelte.d.ts +0 -30
- package/dist/constants.d.ts +0 -11
- package/dist/constants.js +0 -11
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { escapeRegExp } from './escapeRegExp';
|
|
2
|
+
export const getSuffix = (value, { groupSeparator = ',', decimalSeparator = '.' }) => {
|
|
3
|
+
const suffixReg = new RegExp(`\\d([^${escapeRegExp(groupSeparator)}${escapeRegExp(decimalSeparator)}0-9]+)`);
|
|
4
|
+
const suffixMatch = value.match(suffixReg);
|
|
5
|
+
return suffixMatch ? suffixMatch[1] : undefined;
|
|
6
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { addSeparators } from './addSeparators';
|
|
2
|
+
export { cleanValue } from './cleanValue';
|
|
3
|
+
export { escapeRegExp } from './escapeRegExp';
|
|
4
|
+
export { fixedDecimalValue } from './fixedDecimalValue';
|
|
5
|
+
export { formatValue } from './formatValue';
|
|
6
|
+
export { getLocaleConfig } from './getLocaleConfig';
|
|
7
|
+
export { getSuffix } from './getSuffix';
|
|
8
|
+
export { isNumber } from './isNumber';
|
|
9
|
+
export { padTrimValue } from './padTrimValue';
|
|
10
|
+
export { parseAbbrValue, abbrValue } from './parseAbbrValue';
|
|
11
|
+
export { removeInvalidChars } from './removeInvalidChars';
|
|
12
|
+
export { removeSeparators } from './removeSeparators';
|
|
13
|
+
export { repositionCursor } from './repositionCursor';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { addSeparators } from './addSeparators';
|
|
2
|
+
export { cleanValue } from './cleanValue';
|
|
3
|
+
export { escapeRegExp } from './escapeRegExp';
|
|
4
|
+
export { fixedDecimalValue } from './fixedDecimalValue';
|
|
5
|
+
export { formatValue } from './formatValue';
|
|
6
|
+
export { getLocaleConfig } from './getLocaleConfig';
|
|
7
|
+
export { getSuffix } from './getSuffix';
|
|
8
|
+
export { isNumber } from './isNumber';
|
|
9
|
+
export { padTrimValue } from './padTrimValue';
|
|
10
|
+
export { parseAbbrValue, abbrValue } from './parseAbbrValue';
|
|
11
|
+
export { removeInvalidChars } from './removeInvalidChars';
|
|
12
|
+
export { removeSeparators } from './removeSeparators';
|
|
13
|
+
export { repositionCursor } from './repositionCursor';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isNumber: (input: string) => boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const isNumber = (input) => RegExp(/\d/, 'gi').test(input);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const padTrimValue: (value: string, decimalSeparator?: string, decimalScale?: number) => string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const padTrimValue = (value, decimalSeparator, decimalScale) => {
|
|
2
|
+
if (decimalScale === undefined ||
|
|
3
|
+
decimalSeparator === '' ||
|
|
4
|
+
decimalSeparator === undefined ||
|
|
5
|
+
value === '' ||
|
|
6
|
+
value === undefined) {
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
if (!value.match(/\d/g)) {
|
|
10
|
+
return '';
|
|
11
|
+
}
|
|
12
|
+
const [int, decimals] = value.split(decimalSeparator);
|
|
13
|
+
if (decimalScale === 0) {
|
|
14
|
+
return int;
|
|
15
|
+
}
|
|
16
|
+
let newValue = decimals || '';
|
|
17
|
+
if (newValue.length < decimalScale) {
|
|
18
|
+
while (newValue.length < decimalScale) {
|
|
19
|
+
newValue += '0';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
newValue = newValue.slice(0, decimalScale);
|
|
24
|
+
}
|
|
25
|
+
return `${int}${decimalSeparator}${newValue}`;
|
|
26
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { escapeRegExp } from './escapeRegExp';
|
|
2
|
+
export const abbrValue = (value, decimalSeparator = '.', _decimalPlaces = 10) => {
|
|
3
|
+
if (value > 999) {
|
|
4
|
+
let valueLength = ('' + value).length;
|
|
5
|
+
const p = Math.pow;
|
|
6
|
+
const d = p(10, _decimalPlaces);
|
|
7
|
+
valueLength -= valueLength % 3;
|
|
8
|
+
const abbrValue = Math.round((value * d) / p(10, valueLength)) / d + ' kMGTPE'[valueLength / 3];
|
|
9
|
+
return abbrValue.replace('.', decimalSeparator);
|
|
10
|
+
}
|
|
11
|
+
return String(value);
|
|
12
|
+
};
|
|
13
|
+
const abbrMap = { k: 1000, m: 1000000, b: 1000000000 };
|
|
14
|
+
export const parseAbbrValue = (value, decimalSeparator = '.') => {
|
|
15
|
+
const reg = new RegExp(`(\\d+(${escapeRegExp(decimalSeparator)}\\d*)?)([kmb])$`, 'i');
|
|
16
|
+
const match = value.match(reg);
|
|
17
|
+
if (match) {
|
|
18
|
+
const [, digits, , abbr] = match;
|
|
19
|
+
const multiplier = abbrMap[abbr.toLowerCase()];
|
|
20
|
+
return Number(digits.replace(decimalSeparator, '.')) * multiplier;
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const removeInvalidChars: (value: string, validChars: ReadonlyArray<string>) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const removeSeparators: (value: string, separator?: string) => string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type RepositionCursorProps = {
|
|
2
|
+
selectionStart?: number | null;
|
|
3
|
+
value: string;
|
|
4
|
+
lastKeyStroke: string | null;
|
|
5
|
+
stateValue?: string;
|
|
6
|
+
groupSeparator?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const repositionCursor: ({ selectionStart, value, lastKeyStroke, stateValue, groupSeparator }: RepositionCursorProps) => {
|
|
9
|
+
modifiedValue: string;
|
|
10
|
+
cursorPosition: number | null | undefined;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const repositionCursor = ({ selectionStart, value, lastKeyStroke, stateValue, groupSeparator }) => {
|
|
2
|
+
let cursorPosition = selectionStart;
|
|
3
|
+
let modifiedValue = value;
|
|
4
|
+
if (stateValue && cursorPosition) {
|
|
5
|
+
const splitValue = value.split('');
|
|
6
|
+
if (lastKeyStroke === 'Backspace' && stateValue[cursorPosition] === groupSeparator) {
|
|
7
|
+
splitValue.splice(cursorPosition - 1, 1);
|
|
8
|
+
cursorPosition -= 1;
|
|
9
|
+
}
|
|
10
|
+
if (lastKeyStroke === 'Delete' && stateValue[cursorPosition] === groupSeparator) {
|
|
11
|
+
splitValue.splice(cursorPosition, 1);
|
|
12
|
+
cursorPosition += 1;
|
|
13
|
+
}
|
|
14
|
+
modifiedValue = splitValue.join('');
|
|
15
|
+
return { modifiedValue, cursorPosition };
|
|
16
|
+
}
|
|
17
|
+
return { modifiedValue, cursorPosition: selectionStart };
|
|
18
|
+
};
|
package/package.json
CHANGED
|
@@ -1,69 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canutin/svelte-currency-input",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"build": "vite build",
|
|
7
|
-
"preview": "vite preview",
|
|
8
|
-
"package": "svelte-kit sync && svelte-package && publint",
|
|
9
|
-
"test": "playwright test",
|
|
10
|
-
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
11
|
-
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
12
|
-
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
|
13
|
-
"format": "prettier --plugin-search-dir . --write ."
|
|
14
|
-
},
|
|
15
|
-
"exports": {
|
|
16
|
-
".": {
|
|
17
|
-
"types": "./dist/index.d.ts",
|
|
18
|
-
"svelte": "./dist/index.js"
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"files": [
|
|
22
|
-
"dist",
|
|
23
|
-
"!dist/**/*.test.*",
|
|
24
|
-
"!dist/**/*.spec.*"
|
|
25
|
-
],
|
|
26
|
-
"devDependencies": {
|
|
27
|
-
"@playwright/test": "^1.39.0",
|
|
28
|
-
"@sveltejs/adapter-auto": "^3.2.5",
|
|
29
|
-
"@sveltejs/adapter-cloudflare": "^4.7.3",
|
|
30
|
-
"@sveltejs/kit": "^2.7.1",
|
|
31
|
-
"@sveltejs/package": "^2.2.2",
|
|
32
|
-
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
|
33
|
-
"@types/node": "^20.8.7",
|
|
34
|
-
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
35
|
-
"@typescript-eslint/parser": "^6.0.0",
|
|
36
|
-
"date-fns": "^2.30.0",
|
|
37
|
-
"eslint": "^8.28.0",
|
|
38
|
-
"eslint-config-prettier": "^8.5.0",
|
|
39
|
-
"eslint-plugin-svelte": "^2.30.0",
|
|
40
|
-
"prettier": "^2.8.0",
|
|
41
|
-
"prettier-plugin-svelte": "^2.10.1",
|
|
42
|
-
"publint": "^0.2.5",
|
|
43
|
-
"sass": "^1.69.0",
|
|
44
|
-
"semantic-release": "^24.1.1",
|
|
45
|
-
"svelte": "^4.2.19",
|
|
46
|
-
"svelte-check": "^3.4.3",
|
|
47
|
-
"tslib": "^2.4.1",
|
|
48
|
-
"typescript": "^5.0.0",
|
|
49
|
-
"vite": "^5.0.0"
|
|
3
|
+
"version": "1.0.0-next.7",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": ">=22"
|
|
50
6
|
},
|
|
51
|
-
"
|
|
52
|
-
"@cloudflare/workerd-linux-64": "^1.20240909.0",
|
|
53
|
-
"@rollup/rollup-linux-x64-gnu": "^4.21.3"
|
|
54
|
-
},
|
|
55
|
-
"svelte": "./dist/index.js",
|
|
56
|
-
"types": "./dist/index.d.ts",
|
|
57
|
-
"type": "module",
|
|
58
|
-
"description": "A form input that converts numbers to currencies as you type in localized formats",
|
|
7
|
+
"description": "A fully-featured currency input component for Svelte 5 that handles formatting, localization, and validation",
|
|
59
8
|
"keywords": [
|
|
60
9
|
"svelte",
|
|
10
|
+
"svelte5",
|
|
61
11
|
"currency",
|
|
62
12
|
"money",
|
|
63
13
|
"input",
|
|
64
14
|
"i18n",
|
|
65
|
-
"
|
|
66
|
-
"
|
|
15
|
+
"formatting",
|
|
16
|
+
"localization"
|
|
67
17
|
],
|
|
68
18
|
"repository": {
|
|
69
19
|
"type": "git",
|
|
@@ -74,5 +24,74 @@
|
|
|
74
24
|
"bugs": {
|
|
75
25
|
"url": "https://github.com/fmaclen/svelte-currency-input/issues"
|
|
76
26
|
},
|
|
77
|
-
"homepage": "https://svelte-currency-input.fernando.is"
|
|
27
|
+
"homepage": "https://svelte-currency-input.fernando.is",
|
|
28
|
+
"scripts": {
|
|
29
|
+
"dev": "vite dev",
|
|
30
|
+
"build": "vite build && npm run prepack",
|
|
31
|
+
"preview": "vite preview",
|
|
32
|
+
"prepare": "svelte-kit sync || echo ''",
|
|
33
|
+
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
34
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
35
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
36
|
+
"format": "prettier --write .",
|
|
37
|
+
"lint": "prettier --check . && eslint .",
|
|
38
|
+
"quality": "bun run format && bun run eslint . && bun run check",
|
|
39
|
+
"test:unit": "vitest",
|
|
40
|
+
"test": "npm run test:unit -- --run && npm run test:e2e",
|
|
41
|
+
"test:e2e": "playwright test"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist"
|
|
45
|
+
],
|
|
46
|
+
"sideEffects": [
|
|
47
|
+
"**/*.css"
|
|
48
|
+
],
|
|
49
|
+
"svelte": "./dist/index.js",
|
|
50
|
+
"types": "./dist/index.d.ts",
|
|
51
|
+
"type": "module",
|
|
52
|
+
"exports": {
|
|
53
|
+
".": {
|
|
54
|
+
"types": "./dist/index.d.ts",
|
|
55
|
+
"svelte": "./dist/index.js"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"svelte": "^5.0.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@eslint/compat": "^1.4.0",
|
|
63
|
+
"@eslint/js": "^9.39.1",
|
|
64
|
+
"@playwright/test": "^1.57.0",
|
|
65
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
66
|
+
"@semantic-release/git": "^10.0.1",
|
|
67
|
+
"@semantic-release/github": "^12.0.2",
|
|
68
|
+
"@semantic-release/npm": "^13.1.3",
|
|
69
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
70
|
+
"@sveltejs/adapter-cloudflare": "^7.2.4",
|
|
71
|
+
"@sveltejs/kit": "^2.49.1",
|
|
72
|
+
"@sveltejs/package": "^2.5.7",
|
|
73
|
+
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
74
|
+
"@tailwindcss/vite": "^4.1.17",
|
|
75
|
+
"@testing-library/user-event": "^14.5.2",
|
|
76
|
+
"@types/node": "^22",
|
|
77
|
+
"@vitest/browser-playwright": "^4.0.15",
|
|
78
|
+
"eslint": "^9.39.1",
|
|
79
|
+
"eslint-config-prettier": "^10.1.8",
|
|
80
|
+
"eslint-plugin-svelte": "^3.13.1",
|
|
81
|
+
"globals": "^16.5.0",
|
|
82
|
+
"playwright": "^1.57.0",
|
|
83
|
+
"prettier": "^3.7.4",
|
|
84
|
+
"prettier-plugin-svelte": "^3.4.0",
|
|
85
|
+
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
86
|
+
"publint": "^0.3.15",
|
|
87
|
+
"semantic-release": "^25.0.2",
|
|
88
|
+
"svelte": "^5.45.6",
|
|
89
|
+
"svelte-check": "^4.3.4",
|
|
90
|
+
"tailwindcss": "^4.1.17",
|
|
91
|
+
"typescript": "^5.9.3",
|
|
92
|
+
"typescript-eslint": "^8.48.1",
|
|
93
|
+
"vite": "^7.2.6",
|
|
94
|
+
"vitest": "^4.0.15",
|
|
95
|
+
"vitest-browser-svelte": "^2.0.1"
|
|
96
|
+
}
|
|
78
97
|
}
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
<script>import {
|
|
2
|
-
DEFAULT_LOCALE,
|
|
3
|
-
DEFAULT_CURRENCY,
|
|
4
|
-
DEFAULT_NAME,
|
|
5
|
-
DEFAULT_VALUE,
|
|
6
|
-
DEFAULT_FRACTION_DIGITS,
|
|
7
|
-
DEFAULT_CLASS_WRAPPER,
|
|
8
|
-
DEFAULT_CLASS_UNFORMATTED,
|
|
9
|
-
DEFAULT_CLASS_FORMATTED,
|
|
10
|
-
DEFAULT_CLASS_FORMATTED_POSITIVE,
|
|
11
|
-
DEFAULT_CLASS_FORMATTED_NEGATIVE,
|
|
12
|
-
DEFAULT_CLASS_FORMATTED_ZERO
|
|
13
|
-
} from "./constants";
|
|
14
|
-
import { onMount } from "svelte";
|
|
15
|
-
export let value = DEFAULT_VALUE;
|
|
16
|
-
export let locale = DEFAULT_LOCALE;
|
|
17
|
-
export let currency = DEFAULT_CURRENCY;
|
|
18
|
-
export let fractionDigits = DEFAULT_FRACTION_DIGITS;
|
|
19
|
-
export let name = DEFAULT_NAME;
|
|
20
|
-
export let id = void 0;
|
|
21
|
-
export let required = false;
|
|
22
|
-
export let disabled = false;
|
|
23
|
-
export let placeholder = DEFAULT_VALUE;
|
|
24
|
-
export let autocomplete = void 0;
|
|
25
|
-
export let isNegativeAllowed = true;
|
|
26
|
-
export let isZeroNullish = false;
|
|
27
|
-
export let inputClasses = null;
|
|
28
|
-
export let onValueChange = () => {
|
|
29
|
-
};
|
|
30
|
-
let inputElement;
|
|
31
|
-
let inputTarget;
|
|
32
|
-
let formattedValue = "";
|
|
33
|
-
$: isNegative = value < 0;
|
|
34
|
-
$: isPositive = value > 0;
|
|
35
|
-
$: isZero = !isNegative && !isPositive;
|
|
36
|
-
$: value, setFormattedValue();
|
|
37
|
-
onMount(() => {
|
|
38
|
-
setFormattedValue();
|
|
39
|
-
});
|
|
40
|
-
function formatCurrency(value2, maximumFractionDigits, minimumFractionDigits) {
|
|
41
|
-
return new Intl.NumberFormat(locale, {
|
|
42
|
-
currency,
|
|
43
|
-
style: "currency",
|
|
44
|
-
maximumFractionDigits: maximumFractionDigits || 0,
|
|
45
|
-
minimumFractionDigits: minimumFractionDigits || 0
|
|
46
|
-
}).format(value2);
|
|
47
|
-
}
|
|
48
|
-
function handleKeyDown(event) {
|
|
49
|
-
const isDeletion = event.key === "Backspace" || event.key === "Delete";
|
|
50
|
-
const isModifier = event.metaKey || event.altKey || event.ctrlKey;
|
|
51
|
-
const isArrowKey = event.key === "ArrowLeft" || event.key === "ArrowRight";
|
|
52
|
-
const isTab = event.key === "Tab";
|
|
53
|
-
const isInvalidCharacter = !/^\d|,|\.|-$/g.test(event.key);
|
|
54
|
-
function isPunctuationDuplicated() {
|
|
55
|
-
if (event.key !== "," && event.key !== ".") return false;
|
|
56
|
-
if (isDecimalComma) return formattedValue.split(",").length >= 2;
|
|
57
|
-
if (!isDecimalComma) return formattedValue.split(".").length >= 2;
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
if (isPunctuationDuplicated() || !isDeletion && !isModifier && !isArrowKey && isInvalidCharacter && !isTab)
|
|
61
|
-
event.preventDefault();
|
|
62
|
-
}
|
|
63
|
-
function handlePlaceholder(placeholder2) {
|
|
64
|
-
if (typeof placeholder2 === "number")
|
|
65
|
-
return formatCurrency(placeholder2, fractionDigits, fractionDigits);
|
|
66
|
-
if (placeholder2 === null) return "";
|
|
67
|
-
return placeholder2;
|
|
68
|
-
}
|
|
69
|
-
const currencyDecimal = new Intl.NumberFormat(locale).format(1.1).charAt(1);
|
|
70
|
-
const isDecimalComma = currencyDecimal === ",";
|
|
71
|
-
const currencySymbol = formatCurrency(0, 0).replace("0", "").replace(/\u00A0/, "");
|
|
72
|
-
function setUnformattedValue(event) {
|
|
73
|
-
if (event) {
|
|
74
|
-
if (event.key === currencyDecimal) return;
|
|
75
|
-
if (isDecimalComma && event.key === ".")
|
|
76
|
-
formattedValue = formattedValue.replace(/\.([^.]*)$/, currencyDecimal + "$1");
|
|
77
|
-
if (!isDecimalComma && event.key === ",")
|
|
78
|
-
formattedValue = formattedValue.replace(/\,([^,]*)$/, currencyDecimal + "$1");
|
|
79
|
-
const ignoreSymbols = [currencySymbol, `-${currencySymbol}`, "-"];
|
|
80
|
-
const strippedUnformattedValue = formattedValue.replace(" ", "");
|
|
81
|
-
if (ignoreSymbols.includes(strippedUnformattedValue)) return;
|
|
82
|
-
inputTarget = event.target;
|
|
83
|
-
if (isNegativeAllowed && event.key === "-") value = value * -1;
|
|
84
|
-
}
|
|
85
|
-
let unformattedValue = isNegativeAllowed ? formattedValue.replace(/[^0-9,.-]/g, "") : formattedValue.replace(/[^0-9,.]/g, "");
|
|
86
|
-
if (Number.isNaN(parseFloat(unformattedValue))) {
|
|
87
|
-
value = 0;
|
|
88
|
-
} else {
|
|
89
|
-
unformattedValue = unformattedValue.replace(isDecimalComma ? /\./g : /\,/g, "");
|
|
90
|
-
if (isDecimalComma) unformattedValue = unformattedValue.replace(",", ".");
|
|
91
|
-
const previousValue = value;
|
|
92
|
-
value = parseFloat(unformattedValue);
|
|
93
|
-
if (event && previousValue === value) {
|
|
94
|
-
if (unformattedValue.includes(".") && unformattedValue.split(".")[1].length > fractionDigits) {
|
|
95
|
-
setFormattedValue();
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function setFormattedValue() {
|
|
101
|
-
if (!inputElement) return;
|
|
102
|
-
const startCaretPosition = inputElement.selectionStart || 0;
|
|
103
|
-
const previousFormattedValueLength = formattedValue.length;
|
|
104
|
-
formattedValue = isZero && !isZeroNullish ? "" : formatCurrency(
|
|
105
|
-
value,
|
|
106
|
-
fractionDigits,
|
|
107
|
-
document.activeElement === inputElement ? 0 : fractionDigits
|
|
108
|
-
);
|
|
109
|
-
setUnformattedValue();
|
|
110
|
-
let retries = 0;
|
|
111
|
-
while (previousFormattedValueLength === formattedValue.length && retries < 10) retries++;
|
|
112
|
-
if (previousFormattedValueLength !== formattedValue.length) {
|
|
113
|
-
const endCaretPosition = startCaretPosition + formattedValue.length - previousFormattedValueLength;
|
|
114
|
-
inputElement?.setSelectionRange(endCaretPosition, endCaretPosition);
|
|
115
|
-
}
|
|
116
|
-
onValueChange(value);
|
|
117
|
-
}
|
|
118
|
-
</script>
|
|
119
|
-
|
|
120
|
-
<div class={inputClasses?.wrapper ?? DEFAULT_CLASS_WRAPPER}>
|
|
121
|
-
<input
|
|
122
|
-
class={inputClasses?.unformatted ?? DEFAULT_CLASS_UNFORMATTED}
|
|
123
|
-
type="hidden"
|
|
124
|
-
{name}
|
|
125
|
-
{disabled}
|
|
126
|
-
bind:value
|
|
127
|
-
/>
|
|
128
|
-
<input
|
|
129
|
-
class="
|
|
130
|
-
{inputClasses?.formatted ?? DEFAULT_CLASS_FORMATTED}
|
|
131
|
-
{isNegativeAllowed && !isZero && !isNegative
|
|
132
|
-
? inputClasses?.formattedPositive ?? DEFAULT_CLASS_FORMATTED_POSITIVE
|
|
133
|
-
: ''}
|
|
134
|
-
{isZero ? inputClasses?.formattedZero ?? DEFAULT_CLASS_FORMATTED_ZERO : ''}
|
|
135
|
-
{isNegativeAllowed && isNegative
|
|
136
|
-
? inputClasses?.formattedNegative ?? DEFAULT_CLASS_FORMATTED_NEGATIVE
|
|
137
|
-
: ''}
|
|
138
|
-
"
|
|
139
|
-
type="text"
|
|
140
|
-
inputmode={fractionDigits > 0 ? 'decimal' : 'numeric'}
|
|
141
|
-
name={`formatted-${name}`}
|
|
142
|
-
required={required && !isZero}
|
|
143
|
-
placeholder={handlePlaceholder(placeholder)}
|
|
144
|
-
{autocomplete}
|
|
145
|
-
{disabled}
|
|
146
|
-
{id}
|
|
147
|
-
bind:this={inputElement}
|
|
148
|
-
bind:value={formattedValue}
|
|
149
|
-
on:keydown={handleKeyDown}
|
|
150
|
-
on:keyup={setUnformattedValue}
|
|
151
|
-
on:blur={setFormattedValue}
|
|
152
|
-
/>
|
|
153
|
-
</div>
|
|
154
|
-
|
|
155
|
-
<style>
|
|
156
|
-
input.currencyInput__formatted {
|
|
157
|
-
border: 1px solid #e2e2e2;
|
|
158
|
-
padding: 10px;
|
|
159
|
-
box-sizing: border-box;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
input.currencyInput__formatted--zero {
|
|
163
|
-
color: #333;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
input.currencyInput__formatted--positive {
|
|
167
|
-
color: #00a36f;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
input.currencyInput__formatted--negative {
|
|
171
|
-
color: #e75258;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
input.currencyInput__formatted:disabled {
|
|
175
|
-
color: #999;
|
|
176
|
-
background-color: #e2e2e2;
|
|
177
|
-
pointer-events: none;
|
|
178
|
-
cursor: default;
|
|
179
|
-
}
|
|
180
|
-
</style>
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
import type { InputClasses, Callback } from './types';
|
|
3
|
-
declare const __propDef: {
|
|
4
|
-
props: {
|
|
5
|
-
value?: number | undefined;
|
|
6
|
-
locale?: string | undefined;
|
|
7
|
-
currency?: string | undefined;
|
|
8
|
-
fractionDigits?: number | undefined;
|
|
9
|
-
name?: string | undefined;
|
|
10
|
-
id?: string | undefined;
|
|
11
|
-
required?: boolean | undefined;
|
|
12
|
-
disabled?: boolean | undefined;
|
|
13
|
-
placeholder?: string | number | null | undefined;
|
|
14
|
-
autocomplete?: string | null | undefined;
|
|
15
|
-
isNegativeAllowed?: boolean | undefined;
|
|
16
|
-
isZeroNullish?: boolean | undefined;
|
|
17
|
-
inputClasses?: InputClasses | null | undefined;
|
|
18
|
-
onValueChange?: Callback | undefined;
|
|
19
|
-
};
|
|
20
|
-
events: {
|
|
21
|
-
[evt: string]: CustomEvent<any>;
|
|
22
|
-
};
|
|
23
|
-
slots: {};
|
|
24
|
-
};
|
|
25
|
-
export type CurrencyInputProps = typeof __propDef.props;
|
|
26
|
-
export type CurrencyInputEvents = typeof __propDef.events;
|
|
27
|
-
export type CurrencyInputSlots = typeof __propDef.slots;
|
|
28
|
-
export default class CurrencyInput extends SvelteComponentTyped<CurrencyInputProps, CurrencyInputEvents, CurrencyInputSlots> {
|
|
29
|
-
}
|
|
30
|
-
export {};
|
package/dist/constants.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare const DEFAULT_LOCALE = "en-US";
|
|
2
|
-
export declare const DEFAULT_CURRENCY = "USD";
|
|
3
|
-
export declare const DEFAULT_NAME = "total";
|
|
4
|
-
export declare const DEFAULT_VALUE = 0;
|
|
5
|
-
export declare const DEFAULT_FRACTION_DIGITS = 2;
|
|
6
|
-
export declare const DEFAULT_CLASS_WRAPPER = "currencyInput";
|
|
7
|
-
export declare const DEFAULT_CLASS_UNFORMATTED = "currencyInput__unformatted";
|
|
8
|
-
export declare const DEFAULT_CLASS_FORMATTED = "currencyInput__formatted";
|
|
9
|
-
export declare const DEFAULT_CLASS_FORMATTED_POSITIVE = "currencyInput__formatted--positive";
|
|
10
|
-
export declare const DEFAULT_CLASS_FORMATTED_NEGATIVE = "currencyInput__formatted--negative";
|
|
11
|
-
export declare const DEFAULT_CLASS_FORMATTED_ZERO = "currencyInput__formatted--zero";
|
package/dist/constants.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_LOCALE = 'en-US';
|
|
2
|
-
export const DEFAULT_CURRENCY = 'USD';
|
|
3
|
-
export const DEFAULT_NAME = 'total';
|
|
4
|
-
export const DEFAULT_VALUE = 0;
|
|
5
|
-
export const DEFAULT_FRACTION_DIGITS = 2;
|
|
6
|
-
export const DEFAULT_CLASS_WRAPPER = 'currencyInput';
|
|
7
|
-
export const DEFAULT_CLASS_UNFORMATTED = 'currencyInput__unformatted';
|
|
8
|
-
export const DEFAULT_CLASS_FORMATTED = 'currencyInput__formatted';
|
|
9
|
-
export const DEFAULT_CLASS_FORMATTED_POSITIVE = 'currencyInput__formatted--positive';
|
|
10
|
-
export const DEFAULT_CLASS_FORMATTED_NEGATIVE = 'currencyInput__formatted--negative';
|
|
11
|
-
export const DEFAULT_CLASS_FORMATTED_ZERO = 'currencyInput__formatted--zero';
|