numora 2.0.4 → 2.0.5
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/dist/NumoraInput.d.ts +67 -0
- package/dist/config.d.ts +11 -0
- package/dist/features/compact-notation.d.ts +17 -0
- package/dist/features/decimals.d.ts +52 -0
- package/dist/features/formatting/caret-position-utils.d.ts +54 -0
- package/dist/features/formatting/change-detection.d.ts +40 -0
- package/dist/features/formatting/character-equivalence.d.ts +9 -0
- package/dist/features/formatting/constants.d.ts +29 -0
- package/dist/features/formatting/cursor-boundary.d.ts +39 -0
- package/dist/features/formatting/cursor-position.d.ts +50 -0
- package/dist/features/formatting/digit-counting.d.ts +61 -0
- package/dist/features/formatting/index.d.ts +19 -0
- package/dist/features/formatting/large-number.d.ts +39 -0
- package/dist/features/formatting/percent.d.ts +45 -0
- package/dist/features/formatting/subscript-notation.d.ts +20 -0
- package/dist/features/formatting/thousand-grouping.d.ts +34 -0
- package/dist/features/leading-zeros.d.ts +18 -0
- package/dist/features/mobile-keyboard-filtering.d.ts +18 -0
- package/dist/features/non-numeric-characters.d.ts +9 -0
- package/dist/features/sanitization.d.ts +41 -0
- package/dist/features/scientific-notation.d.ts +9 -0
- package/dist/index.d.ts +5 -0
- package/dist/types.d.ts +34 -0
- package/dist/utils/escape-reg-exp.d.ts +16 -0
- package/dist/utils/event-handlers.d.ts +31 -0
- package/dist/utils/format-utils.d.ts +28 -0
- package/dist/utils/input-pattern.d.ts +5 -0
- package/dist/validation.d.ts +20 -0
- package/package.json +2 -2
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { FormatOn, ThousandStyle } from './types';
|
|
2
|
+
export interface NumoraInputOptions extends Partial<Omit<HTMLInputElement, 'value' | 'defaultValue' | 'onchange'>> {
|
|
3
|
+
formatOn?: FormatOn;
|
|
4
|
+
thousandSeparator?: string;
|
|
5
|
+
thousandStyle?: ThousandStyle;
|
|
6
|
+
decimalSeparator?: string;
|
|
7
|
+
decimalMaxLength?: number;
|
|
8
|
+
decimalMinLength?: number;
|
|
9
|
+
enableCompactNotation?: boolean;
|
|
10
|
+
enableNegative?: boolean;
|
|
11
|
+
enableLeadingZeros?: boolean;
|
|
12
|
+
rawValueMode?: boolean;
|
|
13
|
+
onChange?: (value: string) => void;
|
|
14
|
+
value?: string;
|
|
15
|
+
defaultValue?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class NumoraInput {
|
|
18
|
+
private element;
|
|
19
|
+
private options;
|
|
20
|
+
private resolvedOptions;
|
|
21
|
+
private rawValue;
|
|
22
|
+
private caretPositionBeforeChange?;
|
|
23
|
+
constructor(container: HTMLElement, { decimalMaxLength, decimalMinLength, formatOn, thousandSeparator, thousandStyle, decimalSeparator, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode, onChange, ...rest }: NumoraInputOptions);
|
|
24
|
+
private createInputElement;
|
|
25
|
+
private setupEventListeners;
|
|
26
|
+
private getResolvedOptions;
|
|
27
|
+
private buildFormattingOptions;
|
|
28
|
+
private handleValueChange;
|
|
29
|
+
private formatValueForDisplay;
|
|
30
|
+
private handleChange;
|
|
31
|
+
private handleKeyDown;
|
|
32
|
+
private handlePaste;
|
|
33
|
+
private handleFocus;
|
|
34
|
+
private handleBlur;
|
|
35
|
+
getValue(): string;
|
|
36
|
+
setValue(value: string): void;
|
|
37
|
+
disable(): void;
|
|
38
|
+
enable(): void;
|
|
39
|
+
addEventListener(event: string, callback: EventListenerOrEventListenerObject): void;
|
|
40
|
+
removeEventListener(event: string, callback: EventListenerOrEventListenerObject): void;
|
|
41
|
+
/**
|
|
42
|
+
* Returns the underlying HTMLInputElement for direct access.
|
|
43
|
+
* This allows users to interact with the input as a normal HTMLInputElement.
|
|
44
|
+
*/
|
|
45
|
+
getElement(): HTMLInputElement;
|
|
46
|
+
/**
|
|
47
|
+
* Gets the current value of the input.
|
|
48
|
+
* In rawValueMode, returns the raw numeric value without formatting.
|
|
49
|
+
* Otherwise, returns the formatted display value.
|
|
50
|
+
*/
|
|
51
|
+
get value(): string;
|
|
52
|
+
/**
|
|
53
|
+
* Sets the value of the input.
|
|
54
|
+
* In rawValueMode, the value will be formatted for display.
|
|
55
|
+
* Otherwise, sets the value directly.
|
|
56
|
+
*/
|
|
57
|
+
set value(val: string);
|
|
58
|
+
/**
|
|
59
|
+
* Gets the value as a number, similar to HTMLInputElement.valueAsNumber.
|
|
60
|
+
* Returns NaN if the value cannot be converted to a number.
|
|
61
|
+
*/
|
|
62
|
+
get valueAsNumber(): number;
|
|
63
|
+
/**
|
|
64
|
+
* Sets the value from a number, similar to HTMLInputElement.valueAsNumber.
|
|
65
|
+
*/
|
|
66
|
+
set valueAsNumber(num: number);
|
|
67
|
+
}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FormatOn, ThousandStyle } from "./types";
|
|
2
|
+
export declare const DEFAULT_DECIMAL_MAX_LENGTH = 2;
|
|
3
|
+
export declare const DEFAULT_DECIMAL_MIN_LENGTH = 0;
|
|
4
|
+
export declare const DEFAULT_FORMAT_ON = FormatOn.Blur;
|
|
5
|
+
export declare const DEFAULT_THOUSAND_SEPARATOR = ",";
|
|
6
|
+
export declare const DEFAULT_THOUSAND_STYLE = ThousandStyle.None;
|
|
7
|
+
export declare const DEFAULT_DECIMAL_SEPARATOR = ".";
|
|
8
|
+
export declare const DEFAULT_ENABLE_COMPACT_NOTATION = false;
|
|
9
|
+
export declare const DEFAULT_ENABLE_NEGATIVE = false;
|
|
10
|
+
export declare const DEFAULT_ENABLE_LEADING_ZEROS = false;
|
|
11
|
+
export declare const DEFAULT_RAW_VALUE_MODE = false;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expands compact notation (k, m, b, M, T, Qa, Qi, Sx, Sp, O, N) to full numbers using string manipulation.
|
|
3
|
+
* Handles formats like: 1k, 1.5m, 2B, 1M, 2.5T, 3Qa (case-insensitive)
|
|
4
|
+
* Uses string arithmetic to avoid precision loss with large numbers.
|
|
5
|
+
*
|
|
6
|
+
* @param value - The string value that may contain compact notation
|
|
7
|
+
* @returns The expanded numeric string
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* expandCompactNotation("1k") // "1000"
|
|
11
|
+
* expandCompactNotation("1.5m") // "1500000"
|
|
12
|
+
* expandCompactNotation("2B") // "2000000000"
|
|
13
|
+
* expandCompactNotation("1M") // "1000000"
|
|
14
|
+
* expandCompactNotation("2.5T") // "2500000000000"
|
|
15
|
+
* expandCompactNotation("0.5k") // "500"
|
|
16
|
+
*/
|
|
17
|
+
export declare function expandCompactNotation(value: string): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { SeparatorOptions, Separators, FormattingOptions } from '@/types';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes separator configuration with defaults.
|
|
4
|
+
*
|
|
5
|
+
* @param options - Separator configuration options
|
|
6
|
+
* @returns Normalized separator configuration
|
|
7
|
+
*/
|
|
8
|
+
export declare function getSeparators(options: SeparatorOptions | FormattingOptions | undefined): Separators;
|
|
9
|
+
/**
|
|
10
|
+
* Converts comma or dot to the configured decimal separator when thousandStyle is None/undefined.
|
|
11
|
+
* This makes it easier for users to type decimal separators without knowing the exact separator character.
|
|
12
|
+
*
|
|
13
|
+
* @param e - The keyboard event
|
|
14
|
+
* @param inputElement - The input element
|
|
15
|
+
* @param formattingOptions - Optional formatting options
|
|
16
|
+
* @param separators - The separator configuration
|
|
17
|
+
* @returns True if the conversion was handled (event should be prevented), false otherwise
|
|
18
|
+
*/
|
|
19
|
+
export declare function convertCommaOrDotToDecimalSeparatorAndPreventMultimpleDecimalSeparators(e: KeyboardEvent, inputElement: HTMLInputElement, formattingOptions: FormattingOptions | undefined, decimalSeparator: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Trims a string representation of a number to a maximum number of decimal places.
|
|
22
|
+
*
|
|
23
|
+
* @param value - The string to trim.
|
|
24
|
+
* @param decimalMaxLength - The maximum number of decimal places to allow.
|
|
25
|
+
* @param decimalSeparator - The decimal separator character to use.
|
|
26
|
+
* @returns The trimmed string.
|
|
27
|
+
*/
|
|
28
|
+
export declare const trimToDecimalMaxLength: (value: string, decimalMaxLength: number, decimalSeparator?: string) => string;
|
|
29
|
+
/**
|
|
30
|
+
* Removes extra decimal separators, keeping only the first one.
|
|
31
|
+
*
|
|
32
|
+
* @param value - The string value
|
|
33
|
+
* @param decimalSeparator - The decimal separator character
|
|
34
|
+
* @returns The string with only the first decimal separator
|
|
35
|
+
*/
|
|
36
|
+
export declare const removeExtraDecimalSeparators: (value: string, decimalSeparator?: string) => string;
|
|
37
|
+
/**
|
|
38
|
+
* Ensures a numeric string has at least the specified minimum number of decimal places.
|
|
39
|
+
* Pads with zeros if needed, but does not truncate if more decimals exist.
|
|
40
|
+
*
|
|
41
|
+
* @param value - The string value to ensure minimum decimals for
|
|
42
|
+
* @param minDecimals - The minimum number of decimal places (default: 0, meaning no minimum)
|
|
43
|
+
* @param decimalSeparator - The decimal separator character (default: '.')
|
|
44
|
+
* @returns The string with at least minDecimals decimal places
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ensureMinDecimals("1", 2, ".") // "1.00"
|
|
48
|
+
* ensureMinDecimals("1.5", 2, ".") // "1.50"
|
|
49
|
+
* ensureMinDecimals("1.123", 2, ".") // "1.123" (doesn't truncate)
|
|
50
|
+
* ensureMinDecimals("1", 0, ".") // "1" (no minimum)
|
|
51
|
+
*/
|
|
52
|
+
export declare const ensureMinDecimals: (value: string, minDecimals?: number, decimalSeparator?: string) => string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for setting and managing caret position.
|
|
3
|
+
* Includes mobile browser workarounds and retry mechanisms.
|
|
4
|
+
*/
|
|
5
|
+
import type { FormattingOptions, CaretPositionInfo, Separators } from '@/types';
|
|
6
|
+
/**
|
|
7
|
+
* Sets the caret position in an input element.
|
|
8
|
+
* Includes workaround for Chrome/Safari mobile browser bugs.
|
|
9
|
+
*
|
|
10
|
+
* @param el - The input element
|
|
11
|
+
* @param caretPos - The desired caret position
|
|
12
|
+
* @returns True if successful, false otherwise
|
|
13
|
+
*/
|
|
14
|
+
export declare function setCaretPosition(el: HTMLInputElement, caretPos: number): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Sets caret position with retry mechanism for mobile browsers.
|
|
17
|
+
* Mobile Chrome sometimes resets the caret position after we set it,
|
|
18
|
+
* so we retry after a short timeout.
|
|
19
|
+
*
|
|
20
|
+
* @param el - The input element
|
|
21
|
+
* @param caretPos - The desired caret position
|
|
22
|
+
* @param currentValue - The current input value (for validation)
|
|
23
|
+
* @returns Timeout ID that can be cleared if needed
|
|
24
|
+
*/
|
|
25
|
+
export declare function setCaretPositionWithRetry(el: HTMLInputElement, caretPos: number, currentValue: string): ReturnType<typeof setTimeout> | null;
|
|
26
|
+
/**
|
|
27
|
+
* Gets the current caret position from an input element.
|
|
28
|
+
* Uses max of selectionStart and selectionEnd to handle mobile browser quirks.
|
|
29
|
+
*
|
|
30
|
+
* @param el - The input element
|
|
31
|
+
* @returns The current caret position
|
|
32
|
+
*/
|
|
33
|
+
export declare function getInputCaretPosition(el: HTMLInputElement): number;
|
|
34
|
+
/**
|
|
35
|
+
* Skips cursor over thousand separator when deleting/backspacing in 'change' mode.
|
|
36
|
+
* This prevents the cursor from stopping on the separator, making deletion smoother.
|
|
37
|
+
*
|
|
38
|
+
* @param e - The keyboard event
|
|
39
|
+
* @param inputElement - The input element
|
|
40
|
+
* @param formattingOptions - Optional formatting options
|
|
41
|
+
*/
|
|
42
|
+
export declare function skipOverThousandSeparatorOnDelete(e: KeyboardEvent, inputElement: HTMLInputElement, formattingOptions?: FormattingOptions): void;
|
|
43
|
+
/**
|
|
44
|
+
* Updates cursor position after value changes, handling both formatted and unformatted values.
|
|
45
|
+
*
|
|
46
|
+
* @param target - The input element
|
|
47
|
+
* @param oldValue - The value before the change
|
|
48
|
+
* @param newValue - The value after the change
|
|
49
|
+
* @param oldCursorPosition - The cursor position before the change
|
|
50
|
+
* @param caretPositionBeforeChange - Optional caret position info from keydown handler
|
|
51
|
+
* @param separators - Separator configuration
|
|
52
|
+
* @param formattingOptions - Optional formatting options
|
|
53
|
+
*/
|
|
54
|
+
export declare function updateCursorPosition(target: HTMLInputElement, oldValue: string, newValue: string, oldCursorPosition: number, caretPositionBeforeChange: CaretPositionInfo | undefined, separators: Separators, formattingOptions?: FormattingOptions): void;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for detecting changes in input values.
|
|
3
|
+
* Used to distinguish between different editing operations (Delete vs Backspace, etc.)
|
|
4
|
+
*/
|
|
5
|
+
import type { ChangeRange } from './constants';
|
|
6
|
+
/**
|
|
7
|
+
* Determines what changed based on caret positions before and after the change.
|
|
8
|
+
* This is used to distinguish Delete (cursor stays) vs Backspace (cursor moves left).
|
|
9
|
+
*
|
|
10
|
+
* @param caretBefore - The caret position info before the change
|
|
11
|
+
* @param inputValueBefore - The input value before the change
|
|
12
|
+
* @param inputValueAfter - The input value after the change
|
|
13
|
+
* @returns Change range information, or undefined if unable to determine
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Delete key: cursor at 2, endOffset: 1
|
|
17
|
+
* findChangedRangeFromCaretPositions(
|
|
18
|
+
* { selectionStart: 2, selectionEnd: 2, endOffset: 1 },
|
|
19
|
+
* "1,234",
|
|
20
|
+
* "1,34"
|
|
21
|
+
* ) // Returns: { start: 2, end: 3, deletedLength: 1, isDelete: true }
|
|
22
|
+
*/
|
|
23
|
+
export declare function findChangedRangeFromCaretPositions(caretBefore: {
|
|
24
|
+
selectionStart: number;
|
|
25
|
+
selectionEnd: number;
|
|
26
|
+
endOffset?: number;
|
|
27
|
+
}, inputValueBefore: string, inputValueAfter: string): ChangeRange | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Finds the change range by comparing old and new values.
|
|
30
|
+
* This is a fallback when caret position info is not available.
|
|
31
|
+
*
|
|
32
|
+
* @param oldValue - The value before the change
|
|
33
|
+
* @param newValue - The value after the change
|
|
34
|
+
* @returns Change range information, or undefined if unable to determine
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* findChangeRange("1,234", "1,34")
|
|
38
|
+
* // Returns: { start: 2, end: 3, deletedLength: 1, isDelete: true }
|
|
39
|
+
*/
|
|
40
|
+
export declare function findChangeRange(oldValue: string, newValue: string): ChangeRange | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Character equivalence utilities for cursor position calculation.
|
|
3
|
+
*/
|
|
4
|
+
import type { IsCharacterEquivalent } from './cursor-position';
|
|
5
|
+
/**
|
|
6
|
+
* Default character equivalence function.
|
|
7
|
+
* Only considers identical characters as equivalent.
|
|
8
|
+
*/
|
|
9
|
+
export declare const defaultIsCharacterEquivalent: IsCharacterEquivalent;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for different grouping styles used in number formatting.
|
|
3
|
+
*
|
|
4
|
+
* - thousand: Groups by 3 digits (Western style) - 1,234,567
|
|
5
|
+
* - lakh: First group of 3, then groups of 2 (Indian style) - 12,34,567
|
|
6
|
+
* - wan: Groups by 4 digits (Chinese style) - 123,4567
|
|
7
|
+
*/
|
|
8
|
+
export declare const GROUPING_CONFIG: {
|
|
9
|
+
readonly thousand: {
|
|
10
|
+
readonly size: 3;
|
|
11
|
+
};
|
|
12
|
+
readonly lakh: {
|
|
13
|
+
readonly firstGroup: 3;
|
|
14
|
+
readonly restGroup: 2;
|
|
15
|
+
};
|
|
16
|
+
readonly wan: {
|
|
17
|
+
readonly size: 4;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Interface representing a change range in the input value.
|
|
22
|
+
* Used to distinguish between Delete and Backspace operations.
|
|
23
|
+
*/
|
|
24
|
+
export interface ChangeRange {
|
|
25
|
+
start: number;
|
|
26
|
+
end: number;
|
|
27
|
+
deletedLength: number;
|
|
28
|
+
isDelete?: boolean;
|
|
29
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Caret boundary system for defining editable positions in formatted numeric inputs.
|
|
3
|
+
* Prevents cursor from being placed in non-editable areas (separators, prefix, suffix).
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Determines which positions in a formatted value are editable.
|
|
7
|
+
* Returns a boolean array where true = editable position, false = non-editable.
|
|
8
|
+
*
|
|
9
|
+
* @param formattedValue - The formatted string value
|
|
10
|
+
* @param options - Configuration options
|
|
11
|
+
* @returns Boolean array indicating editable positions (length = formattedValue.length + 1)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* getCaretBoundary("1,234.56", { thousandSeparator: ",", decimalSeparator: "." })
|
|
15
|
+
* // Returns: [true, true, false, true, true, true, false, true, true, ...]
|
|
16
|
+
* // (editable at positions 0,1,3,4,5,7,8,...)
|
|
17
|
+
*/
|
|
18
|
+
export declare function getCaretBoundary(formattedValue: string, options?: {
|
|
19
|
+
thousandSeparator?: string;
|
|
20
|
+
decimalSeparator?: string;
|
|
21
|
+
prefix?: string;
|
|
22
|
+
suffix?: string;
|
|
23
|
+
}): boolean[];
|
|
24
|
+
/**
|
|
25
|
+
* Corrects caret position to be within editable boundaries.
|
|
26
|
+
* Moves cursor to nearest editable position if current position is non-editable.
|
|
27
|
+
*
|
|
28
|
+
* @param value - The formatted string value
|
|
29
|
+
* @param caretPos - The current caret position
|
|
30
|
+
* @param boundary - The boundary array from getCaretBoundary()
|
|
31
|
+
* @param direction - Optional direction to search ('left' or 'right')
|
|
32
|
+
* @returns Corrected caret position within editable area
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* const boundary = getCaretBoundary("1,234", { thousandSeparator: "," });
|
|
36
|
+
* getCaretPosInBoundary("1,234", 1, boundary, 'right')
|
|
37
|
+
* // Returns: 2 (moves from separator position to next digit)
|
|
38
|
+
*/
|
|
39
|
+
export declare function getCaretPosInBoundary(value: string, caretPos: number, boundary: boolean[], direction?: 'left' | 'right'): number;
|
|
@@ -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
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './NumoraInput';
|
|
2
|
+
export { ThousandStyle, FormatOn } from './types';
|
|
3
|
+
export { handleOnChangeNumoraInput, handleOnPasteNumoraInput, handleOnKeyDownNumoraInput, } from './utils/event-handlers';
|
|
4
|
+
export { formatValue, processAndFormatValue, } from './utils/format-utils';
|
|
5
|
+
export type { FormattingOptions, CaretPositionInfo } from './types';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare enum FormatOn {
|
|
2
|
+
Blur = "blur",
|
|
3
|
+
Change = "change"
|
|
4
|
+
}
|
|
5
|
+
export declare enum ThousandStyle {
|
|
6
|
+
None = "none",
|
|
7
|
+
Thousand = "thousand",
|
|
8
|
+
Lakh = "lakh",
|
|
9
|
+
Wan = "wan"
|
|
10
|
+
}
|
|
11
|
+
export interface FormattingOptions {
|
|
12
|
+
formatOn?: FormatOn;
|
|
13
|
+
thousandSeparator?: string;
|
|
14
|
+
ThousandStyle?: ThousandStyle;
|
|
15
|
+
enableCompactNotation?: boolean;
|
|
16
|
+
enableNegative?: boolean;
|
|
17
|
+
enableLeadingZeros?: boolean;
|
|
18
|
+
decimalSeparator?: string;
|
|
19
|
+
decimalMinLength?: number;
|
|
20
|
+
rawValueMode?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface CaretPositionInfo {
|
|
23
|
+
selectionStart?: number;
|
|
24
|
+
selectionEnd?: number;
|
|
25
|
+
endOffset?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface SeparatorOptions {
|
|
28
|
+
decimalSeparator?: string;
|
|
29
|
+
thousandSeparator?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface Separators {
|
|
32
|
+
decimalSeparator: string;
|
|
33
|
+
thousandSeparator?: string;
|
|
34
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility functions used across multiple features.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Escapes special regex characters in a string.
|
|
6
|
+
* This is used when building regex patterns from user-provided separator characters.
|
|
7
|
+
*
|
|
8
|
+
* @param str - The string to escape
|
|
9
|
+
* @returns The escaped string safe for use in regex patterns
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* escapeRegExp(".") // Returns: "\\."
|
|
13
|
+
* escapeRegExp("$") // Returns: "\\$"
|
|
14
|
+
* escapeRegExp("1,234") // Returns: "1\\,234"
|
|
15
|
+
*/
|
|
16
|
+
export declare function escapeRegExp(str: string): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type FormattingOptions, type CaretPositionInfo } from '@/types';
|
|
2
|
+
/**
|
|
3
|
+
* Handles the keydown event to prevent the user from entering a second decimal point.
|
|
4
|
+
* Also tracks selection info for Delete/Backspace keys to enable proper cursor positioning.
|
|
5
|
+
* In 'change' mode with formatting, skips cursor over thousand separators on delete/backspace.
|
|
6
|
+
*
|
|
7
|
+
* @param e - The keyboard event triggered by the input.
|
|
8
|
+
* @param formattingOptions - Optional formatting options for separator skipping
|
|
9
|
+
* @returns Caret position info if Delete/Backspace was pressed, undefined otherwise
|
|
10
|
+
*/
|
|
11
|
+
export declare function handleOnKeyDownNumoraInput(e: KeyboardEvent, formattingOptions?: FormattingOptions): CaretPositionInfo | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Handles the input change event to ensure the value does not exceed the maximum number of decimal places,
|
|
14
|
+
* replaces commas with dots, and removes invalid non-numeric characters.
|
|
15
|
+
* Also handles cursor positioning for Delete/Backspace keys.
|
|
16
|
+
* Optionally formats with thousand separators in real-time if formatOn is 'change'.
|
|
17
|
+
*
|
|
18
|
+
* @param e - The event triggered by the input.
|
|
19
|
+
* @param decimalMaxLength - The maximum number of decimal places allowed.
|
|
20
|
+
* @param caretPositionBeforeChange - Optional caret position info from keydown handler
|
|
21
|
+
* @param formattingOptions - Optional formatting options for real-time formatting
|
|
22
|
+
* @returns Object with formatted value and raw value
|
|
23
|
+
*/
|
|
24
|
+
export declare function handleOnChangeNumoraInput(e: Event, decimalMaxLength: number, caretPositionBeforeChange?: CaretPositionInfo, formattingOptions?: FormattingOptions): {
|
|
25
|
+
formatted: string;
|
|
26
|
+
raw: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function handleOnPasteNumoraInput(e: ClipboardEvent, decimalMaxLength: number, formattingOptions?: FormattingOptions): {
|
|
29
|
+
formatted: string;
|
|
30
|
+
raw: string;
|
|
31
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type FormattingOptions } from '@/types';
|
|
2
|
+
/**
|
|
3
|
+
* Processes and formats a numeric input value by sanitizing, trimming decimals, and applying formatting.
|
|
4
|
+
* This is a pure function that doesn't require DOM elements or events.
|
|
5
|
+
*
|
|
6
|
+
* @param rawValue - The raw input value to process
|
|
7
|
+
* @param decimalMaxLength - Maximum number of decimal places allowed
|
|
8
|
+
* @param formattingOptions - Optional formatting options
|
|
9
|
+
* @param shouldRemoveThousandSeparators - Whether to remove thousand separators during sanitization (default: determined by formatOn)
|
|
10
|
+
* @returns Object with formatted value and raw value (raw value is the value before formatting)
|
|
11
|
+
*/
|
|
12
|
+
export declare function processAndFormatValue(rawValue: string, decimalMaxLength: number, formattingOptions?: FormattingOptions, shouldRemoveThousandSeparators?: boolean): {
|
|
13
|
+
formatted: string;
|
|
14
|
+
raw: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Formats a value for display using the provided formatting options.
|
|
18
|
+
* This is a pure function that can be used without DOM events.
|
|
19
|
+
*
|
|
20
|
+
* @param value - The value to format
|
|
21
|
+
* @param decimalMaxLength - Maximum number of decimal places allowed
|
|
22
|
+
* @param formattingOptions - Optional formatting options
|
|
23
|
+
* @returns Object with formatted value and raw value
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatValue(value: string, decimalMaxLength: number, formattingOptions?: FormattingOptions): {
|
|
26
|
+
formatted: string;
|
|
27
|
+
raw: string;
|
|
28
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds an input pattern that allows optional negative sign and a single custom decimal separator.
|
|
3
|
+
* The separator is escaped so any character can be safely used.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getNumoraPattern(decimalSeparator: string, enableNegative: boolean): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FormatOn } from './types';
|
|
2
|
+
import { ThousandStyle } from './types';
|
|
3
|
+
export interface NumoraInputValidationOptions {
|
|
4
|
+
decimalMaxLength?: number;
|
|
5
|
+
decimalMinLength?: number;
|
|
6
|
+
formatOn?: FormatOn;
|
|
7
|
+
thousandSeparator?: string;
|
|
8
|
+
thousandStyle?: ThousandStyle;
|
|
9
|
+
decimalSeparator?: string;
|
|
10
|
+
enableCompactNotation?: boolean;
|
|
11
|
+
enableNegative?: boolean;
|
|
12
|
+
enableLeadingZeros?: boolean;
|
|
13
|
+
rawValueMode?: boolean;
|
|
14
|
+
onChange?: (value: string) => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validates all NumoraInput constructor parameters.
|
|
18
|
+
* Throws descriptive errors for invalid values.
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateNumoraInputOptions(options: NumoraInputValidationOptions): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "numora",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "Precision-first numeric input library for DeFi and financial applications",
|
|
5
5
|
"homepage": "https://numora.xyz/",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"access": "public"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
|
-
"build": "vite build
|
|
64
|
+
"build": "vite build & tsc --emitDeclarationOnly",
|
|
65
65
|
"test": "vitest run",
|
|
66
66
|
"dev": "vite build --watch"
|
|
67
67
|
}
|