numora 1.0.4 → 2.0.1

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.
Files changed (34) hide show
  1. package/README.md +233 -23
  2. package/dist/NumoraInput.d.ts +72 -0
  3. package/dist/config.d.ts +11 -0
  4. package/dist/features/compact-notation.d.ts +17 -0
  5. package/dist/features/decimals.d.ts +52 -0
  6. package/dist/features/formatting/caret-position-utils.d.ts +54 -0
  7. package/dist/features/formatting/change-detection.d.ts +40 -0
  8. package/dist/features/formatting/character-equivalence.d.ts +9 -0
  9. package/dist/features/formatting/constants.d.ts +29 -0
  10. package/dist/features/formatting/cursor-boundary.d.ts +39 -0
  11. package/dist/features/formatting/cursor-position.d.ts +50 -0
  12. package/dist/features/formatting/digit-counting.d.ts +61 -0
  13. package/dist/features/formatting/index.d.ts +19 -0
  14. package/dist/features/formatting/large-number.d.ts +39 -0
  15. package/dist/features/formatting/percent.d.ts +45 -0
  16. package/dist/features/formatting/subscript-notation.d.ts +20 -0
  17. package/dist/features/formatting/thousand-grouping.d.ts +34 -0
  18. package/dist/features/leading-zeros.d.ts +18 -0
  19. package/dist/features/mobile-keyboard-filtering.d.ts +18 -0
  20. package/dist/features/non-numeric-characters.d.ts +9 -0
  21. package/dist/features/sanitization.d.ts +41 -0
  22. package/dist/features/scientific-notation.d.ts +9 -0
  23. package/dist/index.d.ts +4 -4
  24. package/dist/index.js +1 -1
  25. package/dist/index.mjs +1136 -59
  26. package/dist/types.d.ts +34 -0
  27. package/dist/utils/escape-reg-exp.d.ts +16 -0
  28. package/dist/utils/event-handlers.d.ts +15 -14
  29. package/dist/utils/input-pattern.d.ts +5 -0
  30. package/dist/validation.d.ts +20 -0
  31. package/package.json +9 -9
  32. package/dist/NumericInput.d.ts +0 -21
  33. package/dist/utils/decimals.d.ts +0 -13
  34. package/dist/utils/sanitization.d.ts +0 -1
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Advanced cursor position calculation for formatted numeric inputs.
3
+ * Handles cursor preservation during formatting changes, insertion, and deletion operations.
4
+ */
5
+ import type { ChangeRange } from './constants';
6
+ import { ThousandStyle } from '@/types';
7
+ /**
8
+ * Type for character equivalence checking.
9
+ * Returns true if two characters should be considered equivalent for cursor mapping.
10
+ */
11
+ export type IsCharacterEquivalent = (char1: string, char2: string, context: {
12
+ oldValue: string;
13
+ newValue: string;
14
+ typedRange?: ChangeRange;
15
+ oldIndex: number;
16
+ newIndex: number;
17
+ }) => boolean;
18
+ /**
19
+ * Options for cursor position calculation.
20
+ */
21
+ export interface CursorPositionOptions {
22
+ thousandSeparator?: string;
23
+ decimalSeparator?: string;
24
+ isCharacterEquivalent?: IsCharacterEquivalent;
25
+ boundary?: boolean[];
26
+ }
27
+ /**
28
+ * Calculates the new cursor position after formatting is applied.
29
+ * Uses digit index mapping to preserve cursor position relative to actual digits,
30
+ * handling insertion and deletion differently.
31
+ *
32
+ * Supports character equivalence for cases where characters are transformed
33
+ * (e.g., allowed decimal separators normalized to canonical separator).
34
+ *
35
+ * @param oldFormattedValue - The formatted value before the change
36
+ * @param newFormattedValue - The formatted value after formatting
37
+ * @param oldCursorPosition - The cursor position in the old formatted value
38
+ * @param separator - The thousand separator character used in formatting
39
+ * @param _groupStyle - The grouping style used (unused but kept for API compatibility)
40
+ * @param changeRange - Optional change range info to distinguish Delete vs Backspace
41
+ * @param decimalSeparator - The decimal separator character (default: '.')
42
+ * @param options - Additional options for cursor calculation
43
+ * @returns The new cursor position in the new formatted value
44
+ *
45
+ * @example
46
+ * // Typing that adds a comma
47
+ * calculateCursorPositionAfterFormatting("100", "1,000", 3, ",")
48
+ * // Returns: 5 (cursor after last zero)
49
+ */
50
+ export declare function calculateCursorPositionAfterFormatting(oldFormattedValue: string, newFormattedValue: string, oldCursorPosition: number, separator: string, _groupStyle: ThousandStyle, changeRange?: ChangeRange, decimalSeparator?: string, options?: CursorPositionOptions): number;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Utilities for counting and locating meaningful digits in formatted numbers.
3
+ * "Meaningful digits" are actual numeric digits, excluding separators and decimal points.
4
+ */
5
+ /**
6
+ * Counts meaningful digits (non-separator, non-decimal) before a position.
7
+ * This is the core digit counting logic used throughout cursor positioning.
8
+ *
9
+ * @param value - The formatted string value
10
+ * @param position - The position to count up to
11
+ * @param separator - The thousand separator character
12
+ * @param decimalSeparator - The decimal separator character (default: '.')
13
+ * @returns The count of meaningful digits before the position
14
+ *
15
+ * @example
16
+ * countMeaningfulDigitsBeforePosition("1,234", 3, ",") // Returns: 2 (digits "1" and "2")
17
+ * countMeaningfulDigitsBeforePosition("1,234.56", 8, ",") // Returns: 6
18
+ * countMeaningfulDigitsBeforePosition("1.234,56", 8, ".", ",") // Returns: 6
19
+ */
20
+ export declare function countMeaningfulDigitsBeforePosition(value: string, position: number, separator: string, decimalSeparator?: string): number;
21
+ /**
22
+ * Finds the position in the string for a specific digit index.
23
+ * Returns the position AFTER the digit at targetDigitIndex.
24
+ *
25
+ * @param value - The formatted string value
26
+ * @param targetDigitIndex - The zero-based index of the target digit
27
+ * @param separator - The thousand separator character
28
+ * @param decimalSeparator - The decimal separator character (default: '.')
29
+ * @returns The position after the target digit
30
+ *
31
+ * @example
32
+ * findPositionForDigitIndex("1,234", 2, ",") // Returns: 4 (after digit "3")
33
+ */
34
+ export declare function findPositionForDigitIndex(value: string, targetDigitIndex: number, separator: string, decimalSeparator?: string): number;
35
+ /**
36
+ * Finds the position in the string where the digit count equals targetDigitCount.
37
+ * Returns the position after reaching the target count.
38
+ *
39
+ * @param value - The formatted string value
40
+ * @param targetDigitCount - The target number of digits
41
+ * @param separator - The thousand separator character
42
+ * @param decimalSeparator - The decimal separator character (default: '.')
43
+ * @returns The position where digit count equals target
44
+ *
45
+ * @example
46
+ * findPositionWithMeaningfulDigitCount("1,234", 3, ",") // Returns: 5 (after "2,3")
47
+ */
48
+ export declare function findPositionWithMeaningfulDigitCount(value: string, targetDigitCount: number, separator: string, decimalSeparator?: string): number;
49
+ /**
50
+ * Checks if a position in the string is on a separator character.
51
+ *
52
+ * @param value - The formatted string value
53
+ * @param position - The position to check
54
+ * @param separator - The thousand separator character
55
+ * @returns True if the position is on a separator character
56
+ *
57
+ * @example
58
+ * isPositionOnSeparator("1,234", 1, ",") // Returns: true
59
+ * isPositionOnSeparator("1,234", 2, ",") // Returns: false
60
+ */
61
+ export declare function isPositionOnSeparator(value: string, position: number, separator: string): boolean;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Numora Formatting Module
3
+ *
4
+ * Provides comprehensive number formatting with thousand separators and
5
+ * sophisticated cursor position preservation for numeric input fields.
6
+ *
7
+ * @module formatting
8
+ */
9
+ export type { ChangeRange } from './constants';
10
+ export { GROUPING_CONFIG } from './constants';
11
+ export { formatWithSeparators, formatNumoraInput } from './thousand-grouping';
12
+ export { calculateCursorPositionAfterFormatting, type CursorPositionOptions, type IsCharacterEquivalent, } from './cursor-position';
13
+ export { findChangedRangeFromCaretPositions, findChangeRange } from './change-detection';
14
+ export { getCaretBoundary, getCaretPosInBoundary } from './cursor-boundary';
15
+ export { setCaretPosition, setCaretPositionWithRetry, getInputCaretPosition, updateCursorPosition, skipOverThousandSeparatorOnDelete } from './caret-position-utils';
16
+ export { countMeaningfulDigitsBeforePosition, findPositionForDigitIndex, findPositionWithMeaningfulDigitCount, isPositionOnSeparator, } from './digit-counting';
17
+ export { formatPercent, formatLargePercent } from './percent';
18
+ export { condenseDecimalZeros } from './subscript-notation';
19
+ export { formatLargeNumber, type FormatLargeNumberOptions } from './large-number';
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Large number formatting utilities for displaying numbers with scale notation (k, M, T, etc.).
3
+ * These are display-only utilities, not for input formatting.
4
+ */
5
+ import { ThousandStyle } from '@/types';
6
+ export interface FormatLargeNumberOptions {
7
+ /** Minimum scale threshold - only apply scale notation above this (default: 0, meaning always apply if applicable) */
8
+ minScale?: number;
9
+ /** Under what value should decimals be shown (default: 1000) */
10
+ decimalsUnder?: number;
11
+ /** Maximum decimal places to show (default: 2) */
12
+ decimals?: number;
13
+ /** Minimum decimal places to show (default: 0) */
14
+ decimalsMin?: number;
15
+ /** Show minimum decimals even when value is 0 (default: false) */
16
+ decimalsMinAppliesToZero?: boolean;
17
+ /** Placeholder for very large numbers that exceed our scale notation (default: '🔥') */
18
+ veryLargePlaceholder?: string;
19
+ /** Decimal separator (default: '.') */
20
+ decimalSeparator?: string;
21
+ /** Thousand separator for formatting (optional) */
22
+ thousandSeparator?: string;
23
+ /** Thousand grouping style (default: None) */
24
+ thousandStyle?: ThousandStyle;
25
+ }
26
+ /**
27
+ * Formats a large number with scale notation (k, M, T, etc.) for display.
28
+ *
29
+ * @param value - The numeric string value to format
30
+ * @param options - Optional formatting options
31
+ * @returns The formatted string with scale suffix if applicable
32
+ *
33
+ * @example
34
+ * formatLargeNumber("123") // "123"
35
+ * formatLargeNumber("1234") // "1.23k"
36
+ * formatLargeNumber("1234567") // "1.23M"
37
+ * formatLargeNumber("0") // "0"
38
+ */
39
+ export declare function formatLargeNumber(value: string, options?: FormatLargeNumberOptions): string;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Percent formatting utilities for displaying numeric values as percentages.
3
+ * All functions use string arithmetic to avoid precision loss.
4
+ */
5
+ import { ThousandStyle } from '@/types';
6
+ /**
7
+ * Formats a decimal value as a percentage string.
8
+ * Input is expected as a decimal (e.g., 0.01 represents 1%).
9
+ *
10
+ * @param value - The numeric string value (as decimal, e.g., "0.01" for 1%)
11
+ * @param decimals - Number of decimal places to show (default: 2)
12
+ * @param decimalSeparator - The decimal separator character (default: '.')
13
+ * @param thousandSeparator - Optional thousand separator for large percentages
14
+ * @param thousandStyle - Optional thousand grouping style
15
+ * @returns The formatted percentage string (e.g., "1.00%")
16
+ *
17
+ * @example
18
+ * formatPercent("0.01", 2) // "1.00%"
19
+ * formatPercent("0.1234", 2) // "12.34%"
20
+ * formatPercent("1", 0) // "100%"
21
+ * formatPercent("0", 2) // "0%"
22
+ */
23
+ export declare function formatPercent(value: string, decimals?: number, decimalSeparator?: string, thousandSeparator?: string, thousandStyle?: ThousandStyle): string;
24
+ /**
25
+ * Formats a large percentage value with scale notation (k, M, T, etc.) for very large percentages.
26
+ * Input is expected as a decimal (e.g., 0.01 represents 1%).
27
+ *
28
+ * @param value - The numeric string value (as decimal, e.g., "0.01" for 1%)
29
+ * @param decimals - Number of decimal places to show for values under threshold (default: 2)
30
+ * @param options - Optional formatting options
31
+ * @returns The formatted percentage string with scale suffix if needed (e.g., "1.23M%")
32
+ *
33
+ * @example
34
+ * formatLargePercent("0.01", 2) // "1.00%"
35
+ * formatLargePercent("1000", 2) // "100000%"
36
+ * formatLargePercent("1000000", 2) // "100M%"
37
+ */
38
+ export declare function formatLargePercent(value: string | null | undefined, decimals?: number, options?: {
39
+ missingPlaceholder?: string;
40
+ veryLargePlaceholder?: string;
41
+ decimalsUnder?: number;
42
+ decimalSeparator?: string;
43
+ thousandSeparator?: string;
44
+ thousandStyle?: ThousandStyle;
45
+ }): string;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Subscript notation utilities for condensing leading decimal zeros.
3
+ * Converts very small numbers like 0.000001 to 0₆1 for better readability.
4
+ */
5
+ /**
6
+ * Condenses leading decimal zeros in a numeric string to subscript notation.
7
+ * For example: 0.000001 → 0₆1 (meaning 6 leading zeros)
8
+ *
9
+ * @param value - The numeric string value to condense
10
+ * @param maxDecimalDigits - Maximum number of decimal digits to show after condensation
11
+ * @param decimalSeparator - The decimal separator character (default: '.')
12
+ * @returns The condensed string with subscript notation for leading zeros
13
+ *
14
+ * @example
15
+ * condenseDecimalZeros("0.000001", 8) // "0₆1"
16
+ * condenseDecimalZeros("0.000123", 8) // "0₃123"
17
+ * condenseDecimalZeros("1.000001", 8) // "1.000001" (no leading zeros to condense)
18
+ * condenseDecimalZeros("0.123", 8) // "0.123" (not enough zeros to condense)
19
+ */
20
+ export declare function condenseDecimalZeros(value: string, maxDecimalDigits?: number, decimalSeparator?: string): string;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Number formatting utilities with thousand separators.
3
+ * Supports multiple grouping styles: thousand (Western), lakh (Indian), wan (Chinese)
4
+ */
5
+ import type { FormattingOptions, Separators } from '@/types';
6
+ import { ThousandStyle } from '@/types';
7
+ /**
8
+ * Formats a numeric string with thousand separators based on the specified group style.
9
+ *
10
+ * @param value - The numeric string to format (e.g., "1234567")
11
+ * @param separator - The separator character to use (e.g., ",")
12
+ * @param groupStyle - The grouping style: 'none' (no separators), 'thousand' (1,234,567), 'lakh' (12,34,567), or 'wan' (123,4567)
13
+ * @param enableLeadingZeros - Whether to preserve leading zeros
14
+ * @param decimalSeparator - The decimal separator character (default: '.')
15
+ * @returns The formatted string with separators
16
+ *
17
+ * @example
18
+ * formatWithSeparators("1234567", ",", "thousand") // "1,234,567"
19
+ * formatWithSeparators("1234567", ",", "lakh") // "12,34,567"
20
+ * formatWithSeparators("1234567", ",", "wan") // "123,4567"
21
+ * formatWithSeparators("1234.56", ",", "thousand", false, '.') // "1,234.56"
22
+ * formatWithSeparators("1234,56", ",", "thousand", false, ',') // "1,234,56"
23
+ */
24
+ export declare function formatWithSeparators(value: string, separator: string, groupStyle: ThousandStyle, enableLeadingZeros?: boolean, decimalSeparator?: string): string;
25
+ /**
26
+ * Applies formatting to the input element if formatting is enabled.
27
+ *
28
+ * @param target - The input element
29
+ * @param sanitizedAndTrimmedValue - The sanitized value to format
30
+ * @param formattingOptions - Optional formatting options
31
+ * @param separators - Optional separator configuration
32
+ * @returns The formatted value, or the original value if formatting is not needed
33
+ */
34
+ export declare function formatNumoraInput(sanitizedAndTrimmedValue: string, formattingOptions?: FormattingOptions, separators?: Separators): string;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Removes leading zeros from a numeric string while preserving the value "0" itself.
3
+ * Only removes leading zeros from the integer part, not from decimal values like "0.5".
4
+ *
5
+ * @param value - The numeric string to process
6
+ * @returns The string with leading zeros removed
7
+ *
8
+ * @example
9
+ * removeLeadingZeros("007") // "7"
10
+ * removeLeadingZeros("0001") // "1"
11
+ * removeLeadingZeros("0") // "0"
12
+ * removeLeadingZeros("0.5") // "0.5"
13
+ * removeLeadingZeros("-007") // "-7"
14
+ * removeLeadingZeros("123") // "123"
15
+ * removeLeadingZeros("00.5") // "0.5"
16
+ * removeLeadingZeros("-00.5") // "-0.5"
17
+ */
18
+ export declare function removeLeadingZeros(value: string): string;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Mobile keyboard artifact filtering utilities.
3
+ * Handles filtering of unwanted characters that mobile keyboards insert,
4
+ * such as non-breaking spaces, Unicode whitespace variants, and IME formatting characters.
5
+ */
6
+ /**
7
+ * Filters mobile keyboard artifacts from input value.
8
+ * Removes non-breaking spaces, zero-width spaces, and other Unicode whitespace variants
9
+ * that mobile keyboards may insert.
10
+ *
11
+ * @param value - Input value to filter
12
+ * @returns Filtered value with mobile keyboard artifacts removed
13
+ *
14
+ * @example
15
+ * filterMobileKeyboardArtifacts("1\u00A0234") // Returns: "1234" (removes non-breaking space)
16
+ * filterMobileKeyboardArtifacts("1 234") // Returns: "1234" (removes regular space)
17
+ */
18
+ export declare function filterMobileKeyboardArtifacts(value: string): string;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Removes non-numeric characters from a string, preserving the decimal separator.
3
+ *
4
+ * @param value - The string to sanitize
5
+ * @param enableNegative - Whether to allow negative sign
6
+ * @param decimalSeparator - The decimal separator character (default: '.')
7
+ * @returns The sanitized string with only numbers and the decimal separator
8
+ */
9
+ export declare const removeNonNumericCharacters: (value: string, enableNegative?: boolean, decimalSeparator?: string) => string;
@@ -0,0 +1,41 @@
1
+ import type { FormattingOptions, Separators } from '@/types';
2
+ /**
3
+ * Removes all occurrences of thousand separator from a string.
4
+ * Escapes special regex characters in the separator to ensure safe pattern matching.
5
+ *
6
+ * @param value - The string to remove separators from
7
+ * @param thousandSeparator - The thousand separator character to remove
8
+ * @returns The string with all thousand separators removed
9
+ */
10
+ export declare function removeThousandSeparators(value: string, thousandSeparator: string): string;
11
+ export interface SanitizationOptions {
12
+ enableCompactNotation?: boolean;
13
+ enableNegative?: boolean;
14
+ enableLeadingZeros?: boolean;
15
+ decimalSeparator?: string;
16
+ thousandSeparator?: string;
17
+ }
18
+ /**
19
+ * Sanitizes numeric input by:
20
+ * 0. Filter mobile keyboard artifacts (non-breaking spaces, Unicode whitespace)
21
+ * 1. Remove thousand separators (formatting, not data)
22
+ * 2. (Optional) Expanding compact notation (e.g., 1k → 1000)
23
+ * 3. Expanding scientific notation (e.g., 1.5e-5 → 0.000015)
24
+ * 4. Removing non-numeric characters
25
+ * 5. Removing extra decimal points
26
+ * 6. (Optional) Removing leading zeros
27
+ *
28
+ * @param value - The string value to sanitize
29
+ * @param options - Optional sanitization configuration
30
+ * @returns The sanitized numeric string
31
+ */
32
+ export declare const sanitizeNumoraInput: (value: string, options?: SanitizationOptions) => string;
33
+ /**
34
+ * Builds sanitization options from formatting options and separators.
35
+ *
36
+ * @param formattingOptions - Optional formatting options
37
+ * @param separators - Separator configuration
38
+ * @param shouldRemoveThousandSeparators - Whether to remove thousand separators
39
+ * @returns Sanitization options
40
+ */
41
+ export declare function buildSanitizationOptions(formattingOptions: FormattingOptions | undefined, separators: Separators, shouldRemoveThousandSeparators: boolean): SanitizationOptions;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Expands scientific notation to decimal notation using string manipulation only.
3
+ * Handles formats like: 1.5e-7, 2e+5, 1.23e-4, etc.
4
+ * Finds and expands scientific notation anywhere in the string.
5
+ *
6
+ * @param value - The string value that may contain scientific notation
7
+ * @returns The expanded decimal string, or original value if not scientific notation
8
+ */
9
+ export declare function expandScientificNotation(value: string): string;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './NumericInput';
2
- export * from './utils/event-handlers';
3
- export * from './utils/sanitization';
4
- export * from './utils/decimals';
1
+ export * from './NumoraInput';
2
+ export { ThousandStyle, FormatOn } from './types';
3
+ export { handleOnChangeNumoraInput, handleOnPasteNumoraInput, handleOnKeyDownNumoraInput, } from './utils/event-handlers';
4
+ export type { FormattingOptions, CaretPositionInfo } from './types';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var N=Object.defineProperty;var f=(t,e,n)=>e in t?N(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var r=(t,e,n)=>f(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=t=>t.replace(/[^0-9.]/g,""),L=t=>t.replace(/(\..*?)\./g,"$1"),o=t=>L(y(t)),g=t=>t.replace(/,/g,"."),v=t=>[".",","].some(n=>t.key===n&&t.target&&t.target.value.includes(".")),a=(t,e)=>{const[n,i]=t.split(".");return i?`${n}.${i.slice(0,e)}`:t};function D(t,e){const n=t.target;n.value=g(n.value),n.value=o(n.value),n.value=a(n.value,e)}function b(t){v(t)&&t.preventDefault()}function C(t,e){var d;const n=t.target,{value:i,selectionStart:s,selectionEnd:E}=n,c=o(((d=t.clipboardData)==null?void 0:d.getData("text/plain"))||""),u=i.slice(0,s||0)+c+i.slice(E||0),[I,...h]=u.split("."),l=I+(h.length>0?"."+h.join(""):"");t.preventDefault(),n.value=a(l,e);const m=(s||0)+c.length-(u.length-l.length);return n.setSelectionRange(m,m),a(l,e)}const p=2;class A{constructor(e,{maxDecimals:n=p,onChange:i,...s}){r(this,"element");r(this,"options");this.options={maxDecimals:n,onChange:i,...s},this.createInputElement(e),this.setupEventListeners()}createInputElement(e){this.element=document.createElement("input"),this.element.setAttribute("minlength","1"),this.element.setAttribute("pattern","^[0-9]*[.,]?[0-9]*$"),this.element.setAttribute("spellcheck","false"),this.element.setAttribute("type","text"),this.element.setAttribute("inputmode","decimal");const{maxDecimals:n,onChange:i,...s}=this.options;Object.assign(this.element,s),e.appendChild(this.element)}setupEventListeners(){this.element.addEventListener("input",this.handleChange.bind(this)),this.element.addEventListener("keydown",this.handleKeyDown.bind(this)),this.element.addEventListener("paste",this.handlePaste.bind(this))}handleChange(e){D(e,this.options.maxDecimals||p),this.options.onChange&&this.options.onChange(e.target.value)}handleKeyDown(e){b(e)}handlePaste(e){C(e,this.options.maxDecimals),this.options.onChange&&this.options.onChange(e.target.value)}getValue(){return this.element.value}setValue(e){this.element.value=e}disable(){this.element.disabled=!0}enable(){this.element.disabled=!1}addEventListener(e,n){this.element.addEventListener(e,n)}removeEventListener(e,n){this.element.removeEventListener(e,n)}}exports.NumericInput=A;exports.alreadyHasDecimal=v;exports.handleOnChangeNumericInput=D;exports.handleOnKeyDownNumericInput=b;exports.handleOnPasteNumericInput=C;exports.replaceCommasWithDots=g;exports.sanitizeNumericInput=o;exports.trimToMaxDecimals=a;
1
+ "use strict";var V=Object.defineProperty;var F=(e,t,n)=>t in e?V(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var w=(e,t,n)=>F(e,typeof t!="symbol"?t+"":t,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var v=(e=>(e.Blur="blur",e.Change="change",e))(v||{}),b=(e=>(e.None="none",e.Thousand="thousand",e.Lakh="lakh",e.Wan="wan",e))(b||{});const I=2,x=0,O=v.Blur,R=",",_=b.None,E=".",P=!1,B=!1,W=!1,k=!1;function m(e){return e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&")}function C(e){return{decimalSeparator:(e==null?void 0:e.decimalSeparator)??E,thousandSeparator:e==null?void 0:e.thousandSeparator}}function ee(e,t){if(e.key!==t)return!1;const n=e.target;return n?n.value.includes(t):!1}function te(e,t,n,r){const{selectionStart:i,selectionEnd:a,value:s}=t,{key:o}=e,c=n==null?void 0:n.ThousandStyle;if(c!==b.None&&c!==void 0||o!==","&&o!==".")return!1;if(ee(e,r))return!0;if(o!==r){const l=i??0,h=a??l,d=s.slice(0,l)+r+s.slice(h);t.value=d;const u=l+1;return t.setSelectionRange(u,u),!0}return!1}const ne=(e,t,n=E)=>{const[r,i]=e.split(n);return i?`${r}${n}${i.slice(0,t)}`:e},re=(e,t=E)=>{const n=m(t),r=new RegExp(`(${n}.*?)${n}`,"g");return e.replace(r,`$1${t}`)},se=(e,t=0,n=E)=>{if(t===0)return e;if(!e||e==="0"||e===n||e==="-"||e===`-${n}`)return e==="-"||e===`-${n}`?`-${n}${"0".repeat(t)}`:e===n?`${n}${"0".repeat(t)}`:`${e}${n}${"0".repeat(t)}`;const r=e.includes(n),i=e.startsWith("-"),a=i?e.slice(1):e,[s,o=""]=a.split(n);if(!r){const c="0".repeat(t);return i?`-${s}${n}${c}`:`${s}${n}${c}`}if(o.length<t){const c=t-o.length,l=o+"0".repeat(c);return i?`-${s}${n}${l}`:`${s}${n}${l}`}return e},ie=(e,t=!1,n=".")=>{const r=m(n),i=new RegExp(`[^0-9${r}]`,"g");if(!t)return e.replace(i,"");const a=e.startsWith("-"),s=e.replace(i,"");if(a){if(s.length>0)return"-"+s;if(e==="-")return"-"}return s};function ae(e){const t=/([+-]?\d+\.?\d*)[eE]([+-]?\d+)/g;let n=e,r;const i=[];for(;(r=t.exec(e))!==null;){const a=r[0],s=r[1],o=parseInt(r[2],10);let c;if(o===0)c=s;else{const l=s.startsWith("-"),h=l?s.slice(1):s,[d,u=""]=h.split(".");o>0?c=oe(d,u,o):c=ce(d,u,Math.abs(o)),l&&(c="-"+c)}i.push({full:a,expanded:c})}for(const{full:a,expanded:s}of i)n=n.replace(a,s);return n}function oe(e,t,n){const r=e+t;if(r==="0"||r.match(/^0+$/))return"0";const i=t.length;if(n<=i){const s=r.slice(0,e.length+n),o=r.slice(e.length+n);return o?`${s}.${o}`:s}const a=n-i;return r+"0".repeat(a)}function ce(e,t,n){const r=e+t;if(r==="0"||r.match(/^0+$/))return"0";const s=e.length-n;if(s<=0){const o=Math.abs(s),c=`0.${"0".repeat(o)}${r}`;return y(c)}if(s<e.length){const o=r.slice(0,s),c=r.slice(s),l=`${o}.${c}`;return y(l)}return y(r)}function y(e){if(!e.includes("."))return e;if(e==="0"||e==="0.")return"0";if(e.startsWith("0.")){const t=e.replace(/\.?0+$/,"");return t==="0"?"0":t||"0"}if(e.startsWith("-0.")){const t=e.replace(/\.?0+$/,"");return t==="-0"||t==="0"?"0":t||"0"}return e.replace(/\.?0+$/,"")||e}function le(e){const t=/(\d+\.?\d*)\s*(Qa|Qi|Sx|Sp|[kmbMTO]|N)/gi;return e.replace(t,(n,r,i)=>{const a={k:3,m:6,M:6,b:9,T:12,Qa:15,Qi:18,Sx:21,Sp:24,O:27,N:30};let s;if(i.length>1)s=a[i]||a[i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()];else{const f=i.toLowerCase();s=a[i]||a[f]}if(!s)return n;const o=r.startsWith("-"),c=o?r.slice(1):r,[l,h=""]=c.split("."),d=l.replace(/^0+/,"")||"0";let u;if(h.length===0)u=d+"0".repeat(s);else if(h.length<=s){const f=s-h.length;u=d+h+"0".repeat(f)}else{const f=h.slice(0,s),g=h.slice(s);u=d+f+"."+g}return u=u.replace(/^(-?)0+([1-9])/,"$1$2"),u.match(/^-?0+$/)&&(u=o?"-0":"0"),u=u.replace(/\.?0+$/,""),o&&!u.startsWith("-")?"-"+u:u})}function he(e){if(!e||e==="0"||e==="-0"||e==="-"||e===".")return e;const t=e.startsWith("-"),n=t?e.slice(1):e;if(!n||n==="0"||n===".")return e;if(n.includes(".")){const[i,a]=n.split(".");if(i&&i.length>0){const o=(i.replace(/^0+/,"")||"0")+"."+a;return t?"-"+o:o}return e}if(n.startsWith("0")&&n.length>1){const i=n.replace(/^0+/,"")||"0";return t?"-"+i:i}return e}function ue(e){return e.replace(/[\u00A0\u2000-\u200B\u202F\u205F\u3000]/g," ").replace(/\s/g,"")}function L(e,t){const n=m(t);return e.replace(new RegExp(n,"g"),"")}const de=(e,t)=>{let n=ue(e);return t!=null&&t.thousandSeparator&&(n=L(n,t.thousandSeparator)),t!=null&&t.enableCompactNotation&&(n=le(n)),n=ae(n),n=ie(n,t==null?void 0:t.enableNegative,t==null?void 0:t.decimalSeparator),n=re(n,(t==null?void 0:t.decimalSeparator)||E),t!=null&&t.enableLeadingZeros||(n=he(n)),n};function fe(e,t,n){return{enableCompactNotation:e==null?void 0:e.enableCompactNotation,enableNegative:e==null?void 0:e.enableNegative,enableLeadingZeros:e==null?void 0:e.enableLeadingZeros,decimalSeparator:t.decimalSeparator,thousandSeparator:n?t.thousandSeparator:void 0}}const N={thousand:{size:3},lakh:{firstGroup:3,restGroup:2},wan:{size:4}};function U(e,t,n,r=!1,i="."){if(!e||e==="0"||e===i||e==="-"||e===`-${i}`)return e;const a=e.includes(i),s=e.startsWith("-"),o=s?e.slice(1):e,[c,l]=o.split(i);if(!c){const u=l?`${i}${l}`:o;return s?`-${u}`:u}if(r&&c.startsWith("0")&&c.length>1){const u=c.match(/^(0+)/);if(u){const f=u[1],g=c.slice(f.length);if(g){const p=Z(g,t,n),$=f+p,D=s?"-":"";return a?l?`${D}${$}${i}${l}`:`${D}${$}${i}`:`${D}${$}`}}}const h=Z(c,t,n),d=s?"-":"";return a?l?`${d}${h}${i}${l}`:`${d}${h}${i}`:`${d}${h}`}function Z(e,t,n){if(e==="0"||e==="")return e;switch(n){case b.None:return e;case b.Thousand:return ge(e,t);case b.Lakh:return pe(e,t);case b.Wan:return be(e,t);default:return e}}function ge(e,t){return z(e,t,N.thousand.size)}function pe(e,t){if(e.length<=N.lakh.firstGroup)return e;const n=e.split("").reverse(),r=[],i=n.slice(0,N.lakh.firstGroup).reverse().join("");r.push(i);for(let a=N.lakh.firstGroup;a<n.length;a+=N.lakh.restGroup)r.push(n.slice(a,a+N.lakh.restGroup).reverse().join(""));return r.reverse().join(t)}function be(e,t){return z(e,t,N.wan.size)}function z(e,t,n){const r=e.split("").reverse(),i=[];for(let a=0;a<r.length;a+=n)i.push(r.slice(a,a+n).reverse().join(""));return i.reverse().join(t)}function Se(e,t,n){return(t==null?void 0:t.formatOn)==="change"&&t.thousandSeparator?U(e,t.thousandSeparator,t.ThousandStyle??b.None,t.enableLeadingZeros,(n==null?void 0:n.decimalSeparator)??E):e}function S(e,t,n,r="."){let i=0;for(let a=0;a<t&&a<e.length;a++){const s=e[a];s!==n&&s!==r&&i++}return i}function ve(e,t,n,r="."){if(t===0)return 0;let i=0;for(let a=0;a<e.length;a++){const s=e[a];if(s!==n&&s!==r){if(i===t-1)return a+1;i++}}return e.length}function A(e,t,n,r="."){if(t===0)return 0;let i=0;for(let a=0;a<e.length;a++){const s=e[a];if(s!==n&&s!==r){if(i++,i===t)return a+1;if(i>t)return a}}return e.length}function j(e,t,n){return t<0||t>=e.length?!1:e[t]===n}function $e(e,t={}){const{thousandSeparator:n,decimalSeparator:r=".",prefix:i="",suffix:a=""}=t,s=Array.from({length:e.length+1}).map(()=>!0);if(i&&s.fill(!1,0,i.length),a){const o=e.length-a.length;s.fill(!1,o+1,e.length+1)}for(let o=0;o<e.length;o++){const c=e[o];(n&&c===n||c===r)&&(s[o]=!1,o+1<e.length&&!/\d/.test(e[o+1])&&(s[o+1]=!1))}return s.some(o=>o)||s.fill(!0),s}function T(e,t,n,r){const i=e.length;if(t=Math.max(0,Math.min(t,i)),!n[t]){let a=t;for(;a<=i&&!n[a];)a++;let s=t;for(;s>=0&&!n[s];)s--;a<=i&&s>=0?t=t-s<a-t?s:a:a<=i?t=a:s>=0&&(t=s)}return(t===-1||t>i)&&(t=i),t}const J=(e,t)=>e===t;function Ee(e,t,n,r,i,a,s=".",o={}){if(n<0)return 0;if(n>e.length||e===""||t==="")return t.length;const c=t.length<e.length,l=j(e,n,r),h=e.indexOf(s),d=t.indexOf(s);if(o.isCharacterEquivalent&&e!==t){const g=Ne(e,t,n,o.isCharacterEquivalent||J,a,o);if(g!==void 0)return g}if(c)return we(e,t,n,r,l,h,d,a,s,o);const f=Me(e,t,n,r,l,s);return o.boundary?T(t,f,o.boundary):f}function Ne(e,t,n,r,i,a){const s=e.length,o=t.length,c={},l=new Array(s);for(let g=0;g<s;g++){l[g]=-1;for(let p=0;p<o;p++){if(c[p])continue;if(r(e[g],t[p],{oldValue:e,newValue:t,typedRange:i,oldIndex:g,newIndex:p})){l[g]=p,c[p]=!0;break}}}let h=n;for(;h<s&&(l[h]===-1||!/\d/.test(e[h]));)h++;const d=h===s||l[h]===-1?o:l[h];for(h=n-1;h>=0&&l[h]===-1;)h--;const u=h===-1||l[h]===-1?0:l[h]+1;if(u>d)return d;const f=n-u<d-n?u:d;return a.boundary?T(t,f,a.boundary):f}function we(e,t,n,r,i,a,s,o,c,l={}){if(i)return Le(e,t,n,r,s,c);const h=S(e,n,r,c),d=S(e,e.length,r,c),u=S(t,t.length,r,c),f=d-u,g=me(e,n,r,h,f,a,o,c),p=a===-1||n<=a,$=De(t,g,r,f,o,c,p,s);return l.boundary?T(t,$,l.boundary):$}function Le(e,t,n,r,i,a){const s=n+1;if(s<e.length){const o=S(e,s,r,a),c=ve(t,o,r,a);return c<t.length&&t[c]!==r?c+1:c}return n}function me(e,t,n,r,i,a,s,o){if(s){const{start:l,isDelete:h}=s;return h?S(e,l,n,o):Math.max(0,S(e,l,n,o))}return t>0&&e[t-1]===n&&i>0?r+1:r}function De(e,t,n,r,i,a,s,o){if(s&&o!==-1){const l=e.substring(0,o),h=S(l,l.length,n,a);if(t<=h){const d=A(l,t,n,a);if(d>0&&d<l.length&&S(l,d,n,a)===t){if(l[d]===n&&i&&r>0&&d<l.length-1)return d+1;if(!i&&r>0&&d<l.length-1)return Math.min(d+1,l.length)}return d}}const c=A(e,t,n,a);if(c>0&&c<e.length&&S(e,c,n,a)===t){if(e[c]===n&&i&&r>0&&c<e.length-1)return c+1;if(!i&&r>0&&c<e.length-1)return Math.min(c+1,e.length)}return c}function Me(e,t,n,r,i,a){const s=n>=e.length,o=S(e,n,r,a),c=S(e,e.length,r,a),l=S(t,t.length,r,a);if(s||o===c)return t.length;const h=l-c;let d=o;h>0&&!s&&o<c&&(d=o+1);const u=A(t,d,r,a);return i&&!j(t,u,r)?Math.max(0,u-1):u}function ye(e,t,n){const{selectionStart:r,selectionEnd:i,endOffset:a=0}=e;if(r!==i){const h=i-r;return{start:r,end:i,deletedLength:h,isDelete:!1}}if(a>0){const h=a;return{start:r,end:r+h,deletedLength:h,isDelete:!0}}const o=t.length,c=n.length,l=o-c;if(!(l<=0))return{start:r,end:r+l,deletedLength:l,isDelete:!1}}function Ae(e,t){if(e===t)return;let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n++;let r=e.length-1,i=t.length-1;for(;r>=n&&i>=n&&e[r]===t[i];)r--,i--;const a=r-n+1,s=i-n+1;if(!(a===0&&s===0))return{start:n,end:r+1,deletedLength:a,isDelete:a>s}}function G(e,t){if(e.value=e.value,e===null)return!1;if(e.createTextRange){const n=e.createTextRange();return n.move("character",t),n.select(),!0}return e.selectionStart!==null||e.selectionStart===0?(e.focus(),e.setSelectionRange(t,t),!0):(e.focus(),!1)}function Ce(e,t,n){return e.selectionStart===0&&e.selectionEnd===e.value.length?null:(G(e,t),setTimeout(()=>{e.value===n&&e.selectionStart!==t&&G(e,t)},0))}function Te(e){return Math.max(e.selectionStart,e.selectionEnd)}function Ie(e,t,n){if((n==null?void 0:n.formatOn)!==v.Change||!n.thousandSeparator)return;const{selectionStart:r,selectionEnd:i,value:a}=t;if(r===null||i===null||r!==i)return;const{key:s}=e,o=n.thousandSeparator;s==="Backspace"&&r>0&&a[r-1]===o&&t.setSelectionRange(r-1,r-1),s==="Delete"&&a[r]===o&&t.setSelectionRange(r+1,r+1)}function xe(e,t,n,r,i,a,s){if(!i)return;const{selectionStart:o=0,selectionEnd:c=0,endOffset:l=0}=i;let h=ye({selectionStart:o,selectionEnd:c,endOffset:l},t,n);if(h||(h=Ae(t,n)),!h)return;const d=$e(n,{thousandSeparator:(s==null?void 0:s.thousandSeparator)??a.thousandSeparator,decimalSeparator:a.decimalSeparator}),u={thousandSeparator:(s==null?void 0:s.thousandSeparator)??a.thousandSeparator,isCharacterEquivalent:J,boundary:d},f=(s==null?void 0:s.thousandSeparator)??a.thousandSeparator??",",g=(s==null?void 0:s.ThousandStyle)??b.None,p=Ee(t,n,r,f,g,h,a.decimalSeparator,u);Ce(e,p,n)}function H(e,t,n,r,i){const a=de(e,fe(r,i,n)),s=ne(a,t,i.decimalSeparator),o=(r==null?void 0:r.decimalMinLength)??0,c=se(s,o,i.decimalSeparator),l=c;return{formatted:Se(c,r,i),raw:l}}function Oe(e,t,n){if(e==="Backspace"||e==="Delete")return e==="Delete"&&t===n?{endOffset:1}:{endOffset:0}}function K(e,t){const{decimalSeparator:n}=C(t),r=e.target;if(te(e,r,t,n)){e.preventDefault();return}return Ie(e,r,t),Oe(e.key,r.selectionStart,r.selectionEnd)}function q(e,t,n,r){const i=e.target,a=i.value,s=Te(i),o=C(r),c=(r==null?void 0:r.formatOn)===v.Change,{formatted:l,raw:h}=H(a,t,c,r,o);i.value=l,r!=null&&r.rawValueMode&&i.setAttribute("data-raw-value",h),a!==l&&xe(i,a,l,s,n,o,r)}function Re(e,t,n,r){const i=r-n;return e+t+i}function Q(e,t,n){var f;e.preventDefault();const r=e.target,{value:i,selectionStart:a,selectionEnd:s}=r,o=C(n),c=((f=e.clipboardData)==null?void 0:f.getData("text/plain"))||"",l=i.slice(0,a||0)+c+i.slice(s||0),{formatted:h,raw:d}=H(l,t,!0,n,o);r.value=h,n!=null&&n.rawValueMode&&r.setAttribute("data-raw-value",d);const u=Re(a||0,c.length,l.length,h.length);return r.setSelectionRange(u,u),r.value}function _e(e,t){const n=m(e);return t?`^-?[0-9]*[${n}]?[0-9]*$`:`^[0-9]*[${n}]?[0-9]*$`}function Pe(e){Be(e.decimalMaxLength),We(e.decimalMinLength),ke(e.decimalMinLength,e.decimalMaxLength),Ze(e.formatOn),Ge(e.thousandSeparator),Ue(e.thousandStyle),ze(e.decimalSeparator),je(e.thousandSeparator,e.decimalSeparator),M("enableCompactNotation",e.enableCompactNotation),M("enableNegative",e.enableNegative),M("enableLeadingZeros",e.enableLeadingZeros),M("rawValueMode",e.rawValueMode),Je(e.onChange)}function Be(e){if(e!==void 0){if(typeof e!="number")throw new Error(`decimalMaxLength must be a number. Received: ${typeof e} (${JSON.stringify(e)})`);if(!Number.isInteger(e))throw new Error(`decimalMaxLength must be an integer. Received: ${e}`);if(e<0)throw new Error(`decimalMaxLength must be non-negative. Received: ${e}`)}}function We(e){if(e!==void 0){if(typeof e!="number")throw new Error(`decimalMinLength must be a number. Received: ${typeof e} (${JSON.stringify(e)})`);if(!Number.isInteger(e))throw new Error(`decimalMinLength must be an integer. Received: ${e}`);if(e<0)throw new Error(`decimalMinLength must be non-negative. Received: ${e}`)}}function ke(e,t){if(!(e===void 0||t===void 0)&&e>t)throw new Error(`decimalMinLength (${e}) cannot be greater than decimalMaxLength (${t}).`)}function Ze(e){if(e!==void 0&&e!==v.Blur&&e!==v.Change)throw new Error(`formatOn must be either ${v.Blur} or ${v.Change}. Received: ${JSON.stringify(e)}`)}function Ge(e){if(e!==void 0){if(typeof e!="string")throw new Error(`thousandSeparator must be a string. Received: ${typeof e} (${JSON.stringify(e)})`);if(e.length===0)throw new Error(`thousandSeparator cannot be empty. Received: ${JSON.stringify(e)}`);if(e.length>1)throw new Error(`thousandSeparator must be a single character. Received: "${e}" (length: ${e.length})`)}}function Ue(e){if(e!==void 0&&!Object.values(b).includes(e))throw new Error(`ThousandStyle must be one of: ${Object.values(b).map(t=>`'${t}'`).join(", ")}. Received: ${JSON.stringify(e)}`)}function ze(e){if(e!==void 0){if(typeof e!="string")throw new Error(`decimalSeparator must be a string. Received: ${typeof e} (${JSON.stringify(e)})`);if(e.length===0)throw new Error(`decimalSeparator cannot be empty. Received: ${JSON.stringify(e)}`);if(e.length>1)throw new Error(`decimalSeparator must be a single character. Received: "${e}" (length: ${e.length})`)}}function je(e,t){if(!(e===void 0||t===void 0)&&e===t)throw new Error(`Decimal separator can't be same as thousand separator. thousandSeparator: ${e}, decimalSeparator: ${t}`)}function M(e,t){if(t!==void 0&&typeof t!="boolean")throw new Error(`${e} must be a boolean. Received: ${typeof t} (${JSON.stringify(t)})`)}function Je(e){if(e!==void 0&&typeof e!="function")throw new Error(`onChange must be a function or undefined. Received: ${typeof e} (${JSON.stringify(e)})`)}class He{constructor(t,{decimalMaxLength:n=I,decimalMinLength:r=x,formatOn:i=O,thousandSeparator:a=R,thousandStyle:s=_,decimalSeparator:o=E,enableCompactNotation:c=P,enableNegative:l=B,enableLeadingZeros:h=W,rawValueMode:d=k,onChange:u,...f}){w(this,"element");w(this,"options");w(this,"resolvedOptions");w(this,"rawValue","");w(this,"caretPositionBeforeChange");if(Pe({decimalMaxLength:n,decimalMinLength:r,formatOn:i,thousandSeparator:a,thousandStyle:s,decimalSeparator:o,enableCompactNotation:c,enableNegative:l,enableLeadingZeros:h,rawValueMode:d,onChange:u}),this.options={decimalMaxLength:n,decimalMinLength:r,onChange:u,formatOn:i,thousandSeparator:a,thousandStyle:s,decimalSeparator:o,enableCompactNotation:c,enableNegative:l,enableLeadingZeros:h,rawValueMode:d,...f},this.resolvedOptions=this.getResolvedOptions(),this.createInputElement(t),this.setupEventListeners(),this.resolvedOptions.rawValueMode&&this.element.value){const g=this.element.value,p=this.resolvedOptions.thousandSeparator?L(g,this.resolvedOptions.thousandSeparator):g;this.rawValue=p,this.element.value=this.formatValueForDisplay(p)}else if(this.element.value&&!this.resolvedOptions.rawValueMode){const g=this.element.value;this.element.value=this.formatValueForDisplay(g)}}createInputElement(t){if(this.element=document.createElement("input"),this.element.setAttribute("type","text"),this.element.setAttribute("inputmode","decimal"),this.element.setAttribute("spellcheck","false"),this.element.setAttribute("autocomplete","off"),this.resolvedOptions.decimalSeparator!==void 0&&this.resolvedOptions.enableNegative!==void 0){const Y=_e(this.resolvedOptions.decimalSeparator,this.resolvedOptions.enableNegative);this.element.setAttribute("pattern",Y)}const{decimalMaxLength:n,decimalMinLength:r,formatOn:i,thousandSeparator:a,thousandStyle:s,decimalSeparator:o,enableCompactNotation:c,enableNegative:l,enableLeadingZeros:h,rawValueMode:d,onChange:u,value:f,defaultValue:g,type:p,inputMode:$,spellcheck:D,autocomplete:Ke,...X}=this.options;Object.assign(this.element,X),f!==void 0?this.element.value=f:g!==void 0&&(this.element.defaultValue=g,this.element.value=g),t.appendChild(this.element)}setupEventListeners(){this.element.addEventListener("input",this.handleChange.bind(this)),this.element.addEventListener("keydown",this.handleKeyDown.bind(this)),this.element.addEventListener("paste",this.handlePaste.bind(this)),this.resolvedOptions.formatOn===v.Blur&&this.resolvedOptions.thousandSeparator&&(this.element.addEventListener("focus",this.handleFocus.bind(this)),this.element.addEventListener("blur",this.handleBlur.bind(this)))}getResolvedOptions(){return{decimalMaxLength:this.options.decimalMaxLength??I,decimalMinLength:this.options.decimalMinLength??x,formatOn:this.options.formatOn??O,thousandSeparator:this.options.thousandSeparator??R,thousandStyle:this.options.thousandStyle??_,decimalSeparator:this.options.decimalSeparator??E,enableCompactNotation:this.options.enableCompactNotation??P,enableNegative:this.options.enableNegative??B,enableLeadingZeros:this.options.enableLeadingZeros??W,rawValueMode:this.options.rawValueMode??k,onChange:this.options.onChange}}buildFormattingOptions(){return{formatOn:this.resolvedOptions.formatOn,thousandSeparator:this.resolvedOptions.thousandSeparator,ThousandStyle:this.resolvedOptions.thousandStyle,enableCompactNotation:this.resolvedOptions.enableCompactNotation,enableNegative:this.resolvedOptions.enableNegative,enableLeadingZeros:this.resolvedOptions.enableLeadingZeros,decimalSeparator:this.resolvedOptions.decimalSeparator,decimalMinLength:this.resolvedOptions.decimalMinLength,rawValueMode:this.resolvedOptions.rawValueMode}}handleValueChange(t,n){const r=n??t;if(this.resolvedOptions.rawValueMode&&this.updateRawValue(r),this.resolvedOptions.onChange){const i=this.resolvedOptions.rawValueMode?this.rawValue:t;this.resolvedOptions.onChange(i)}}formatValueForDisplay(t){if(!t)return t;const{thousandSeparator:n,thousandStyle:r,enableLeadingZeros:i,decimalSeparator:a}=this.resolvedOptions;return n&&r!==b.None?U(t,n,r,i,a):t}handleChange(t){const n=t.target;q(t,this.resolvedOptions.decimalMaxLength,this.caretPositionBeforeChange,this.buildFormattingOptions()),this.caretPositionBeforeChange=void 0,this.handleValueChange(n.value)}handleKeyDown(t){const n=t.target,{selectionStart:r,selectionEnd:i}=n,a=this.buildFormattingOptions(),s=K(t,{formatOn:a.formatOn,thousandSeparator:a.thousandSeparator,ThousandStyle:a.ThousandStyle,decimalSeparator:a.decimalSeparator});s?this.caretPositionBeforeChange={selectionStart:r??0,selectionEnd:i??0,endOffset:s.endOffset}:this.caretPositionBeforeChange={selectionStart:r??0,selectionEnd:i??0}}handlePaste(t){const n=Q(t,this.resolvedOptions.decimalMaxLength,this.buildFormattingOptions());this.handleValueChange(n);const r=new Event("input",{bubbles:!0,cancelable:!0});this.element.dispatchEvent(r)}handleFocus(t){if(this.resolvedOptions.formatOn===v.Blur&&this.resolvedOptions.thousandSeparator){const n=t.target;n.value=L(n.value,this.resolvedOptions.thousandSeparator)}}handleBlur(t){const n=t.target,{thousandSeparator:r,thousandStyle:i}=this.resolvedOptions;if(r&&i!==b.None&&n.value){const a=n.value,s=this.formatValueForDisplay(n.value);if(n.value=s,this.handleValueChange(s),a!==s){const o=new Event("input",{bubbles:!0,cancelable:!0});this.element.dispatchEvent(o);const c=new Event("change",{bubbles:!0,cancelable:!0});this.element.dispatchEvent(c)}}}updateRawValue(t){const n=this.element.getAttribute("data-raw-value");if(n!==null){this.rawValue=n,this.element.removeAttribute("data-raw-value");return}if(!this.resolvedOptions.thousandSeparator){this.rawValue=t;return}this.rawValue=L(t,this.resolvedOptions.thousandSeparator)}getValue(){return this.resolvedOptions.rawValueMode?this.rawValue:this.element.value}setValue(t){if(this.resolvedOptions.rawValueMode){const n=this.resolvedOptions.thousandSeparator?L(t,this.resolvedOptions.thousandSeparator):t;this.rawValue=n,this.element.value=this.formatValueForDisplay(n)}else this.element.value=t}disable(){this.element.disabled=!0}enable(){this.element.disabled=!1}addEventListener(t,n){this.element.addEventListener(t,n)}removeEventListener(t,n){this.element.removeEventListener(t,n)}getElement(){return this.element}get value(){return this.getValue()}set value(t){this.setValue(t)}get valueAsNumber(){const t=this.getValue();if(!t)return NaN;const n=this.resolvedOptions.thousandSeparator?L(t,this.resolvedOptions.thousandSeparator):t,r=this.resolvedOptions.decimalSeparator&&this.resolvedOptions.decimalSeparator!=="."?n.replace(new RegExp(m(this.resolvedOptions.decimalSeparator),"g"),"."):n;return parseFloat(r)}set valueAsNumber(t){if(isNaN(t)){this.setValue("");return}const n=t.toString();this.setValue(n)}}exports.FormatOn=v;exports.NumoraInput=He;exports.ThousandStyle=b;exports.handleOnChangeNumoraInput=q;exports.handleOnKeyDownNumoraInput=K;exports.handleOnPasteNumoraInput=Q;