numora 3.0.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,281 +3,70 @@
3
3
  [![npm version](https://img.shields.io/npm/v/numora.svg)](https://www.npmjs.com/package/numora)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/numora.svg)](https://www.npmjs.com/package/numora)
5
5
 
6
- A lightweight, framework-agnostic numeric input library for handling currency and decimal inputs in **financial/DeFi** applications. Built with TypeScript and designed for modern web applications with:
6
+ A lightweight, framework-agnostic numeric input library. Zero dependencies, TypeScript-first.
7
7
 
8
- - **Zero dependencies** - minimal footprint for your bundle
9
- - **Type safety** - fully typed API for better developer experience
10
- - **Framework agnostic** - use with any framework or vanilla JavaScript
11
- - **Customizable** - extensive options to fit your specific needs
12
-
13
- ## Demo
14
-
15
- Check out the [live demo](https://numora.xyz/) to see Numora in action.
16
-
17
- ## Features
18
-
19
- | Feature | Description |
20
- |---------|-------------|
21
- | **⭐️ Zero Dependencies** | No external dependencies, minimal bundle size |
22
- | **⭐️ Framework Agnostic** | Works with any framework or vanilla JavaScript |
23
- | **Decimal Precision Control** | Configure minimum and maximum decimal places (`decimalMinLength`, `decimalMaxLength`) |
24
- | **Minimum Decimal Places** | Automatically pad values with zeros to ensure minimum decimal places (e.g., `"1"` with `decimalMinLength: 2` becomes `"1.00"`) |
25
- | **Thousand Separators** | Customizable thousand separators with multiple grouping styles (`Thousand`, `Lakh`, `Wan`, `None`) |
26
- | **Custom Decimal Separator** | Support for different decimal separators (e.g., `.` or `,`) |
27
- | **Format on Blur/Change** | Choose when to apply formatting: `on blur (clean editing)` or `on change (real-time)` |
28
- | **Compact Notation Expansion** | When enabled, expands compact notation during paste/setValue (e.g., `"1k"` → `"1000"`, `"1.5m"` → `"1500000"`, `"2B"` → `"2000000000"`) |
29
- | **Scientific Notation Expansion** | Always automatically expands scientific notation (e.g., `"1.5e-7"` → `"0.00000015"`, `"2e+5"` → `"200000"`) |
30
- | **Negative Number Support** | Optional support for negative numbers with `enableNegative` |
31
- | **Leading Zeros Support** | Control leading zero behavior with `enableLeadingZeros` |
32
- | **Raw Value Mode** | Get unformatted numeric values while displaying formatted values |
33
- | **Paste Event Handling** | Intelligent paste handling with automatic sanitization, formatting, and cursor positioning |
34
- | **Cursor Position Preservation** | Smart cursor positioning that works with thousand separators, even during formatting |
35
- | **Thousand Separator Skipping** | On delete/backspace, cursor automatically skips over thousand separators for better UX |
36
- | **Mobile Keyboard Optimization** | Automatic `inputmode="decimal"` for mobile numeric keyboards |
37
- | **Mobile Keyboard Filtering** | Automatically filters non-breaking spaces and Unicode whitespace artifacts from mobile keyboards |
38
- | **Non-numeric Character Filtering** | Automatic removal of invalid characters |
39
- | **Comma/Dot Conversion** | When `thousandStyle` is `None`, typing comma or dot automatically converts to the configured `decimalSeparator` |
40
- | **Character Equivalence** | Automatic conversion of commas to dots (or custom decimal separator) for easier input |
41
- | **Sanitization** | Comprehensive input sanitization for security and data integrity |
42
- | **TypeScript Support** | Full TypeScript definitions included |
43
-
44
- ## Display Formatting Utilities
45
-
46
- Numora also exports utility functions for formatting numbers for display (outside of the input component):
47
-
48
- | Utility | Description | Example |
49
- |---------|-------------|---------|
50
- | `formatPercent` | Format decimal values as percentages | `formatPercent("0.01", 2)` → `"1.00%"` |
51
- | `formatLargePercent` | Format large percentages with scale notation (k, M, T, etc.) | `formatLargePercent("1000", 2)` → `"100000%"` |
52
- | `formatLargeNumber` | Format large numbers with scale notation | `formatLargeNumber("1234")` → `"1.23k"` |
53
- | `condenseDecimalZeros` | Condense leading decimal zeros to subscript notation | `condenseDecimalZeros("0.000001", 8)` → `"0₆1"` |
54
-
55
- These utilities use string arithmetic to avoid floating-point precision issues.
56
-
57
- ## 📊 Comparison
58
-
59
- | Feature | Numora | react-number-format | Native Number Input |
60
- |---------|--------|---------------------|---------------------|
61
- | **Framework Support** | ✅ All frameworks | ❌ React only | ✅ All frameworks |
62
- | **Dependencies** | ✅ Zero | ⚠️ React required | ✅ Zero |
63
- | **Raw Value Mode** | ✅ Yes | ⚠️ Limited | ❌ No |
64
- | **Comma/Dot Conversion** | ✅ Yes | ⚠️ Limited | ❌ No |
65
- | **Scientific Notation** | ✅ Auto-expand | ❌ No | ❌ No |
66
- | **Display Formatting Utils** | ✅ Yes | ❌ No | ❌ No |
67
- | **Compact Notation** | ✅ Auto-expand | ❌ No | ❌ No |
68
- | **Mobile Support** | ✅ Yes | ✅ Yes | ⚠️ Limited |
69
- | **Decimal Precision Control** | ✅ Yes | ✅ Yes | ❌ Limited |
70
- | **Thousand Separators** | ✅ Customizable | ✅ Yes | ❌ No |
71
- | **Custom Decimal Separator** | ✅ Yes | ✅ Yes | ❌ No (always `.`) |
72
- | **Formatting Options** | ✅ Blur/Change modes | ✅ Multiple modes | ❌ No |
73
- | **Cursor Preservation** | ✅ Advanced | ✅ Basic | ❌ N/A |
74
- | **TypeScript Support** | ✅ Yes | ✅ Yes | ⚠️ Partial |
75
- | **Paste Handling** | ✅ Intelligent | ✅ Yes | ⚠️ Basic |
76
- | **Grouping Styles** | ✅ Thousand/Lakh/Wan | ✅ Thousand/Lakh/Wan | ❌ No |
77
- | **Leading Zeros Control** | ✅ Yes | ✅ Yes | ❌ No |
78
-
79
- ## Installation
8
+ ## Install
80
9
 
81
10
  ```bash
82
11
  npm install numora
83
- # or
84
- bun add numora
85
- # or
86
- pnpm add numora
12
+ # or pnpm add numora / bun add numora
87
13
  ```
88
14
 
89
15
  ## Usage
90
16
 
91
- ### Basic Example
92
-
93
- ```typescript
94
- import { NumoraInput } from 'numora';
95
-
96
- // Get the container element where you want to mount the input
97
- const container = document.querySelector('#my-input-container');
98
-
99
- // Create a new NumoraInput instance
100
- const numoraInput = new NumoraInput(container, {
101
- decimalMaxLength: 2,
102
- onChange: (value) => {
103
- console.log('Value changed:', value);
104
- },
105
- });
106
- ```
107
-
108
- ### Advanced Example
109
-
110
17
  ```typescript
111
18
  import { NumoraInput, FormatOn, ThousandStyle } from 'numora';
112
19
 
113
- const container = document.querySelector('#my-input-container');
114
-
115
- const numoraInput = new NumoraInput(container, {
116
- // Decimal options
117
- decimalMaxLength: 18,
118
- decimalMinLength: 2, // Pads with zeros: "1" becomes "1.00"
119
- decimalSeparator: '.',
120
-
121
- // Thousand separator options
20
+ const input = new NumoraInput(document.querySelector('#amount'), {
21
+ decimalMaxLength: 2,
22
+ decimalMinLength: 2,
122
23
  thousandSeparator: ',',
123
24
  thousandStyle: ThousandStyle.Thousand,
124
- formatOn: FormatOn.Change, // or FormatOn.Blur
125
-
126
- // Additional features
127
- enableCompactNotation: true, // Expands "1k" → "1000" on paste/setValue
128
- enableNegative: false,
129
- enableLeadingZeros: false,
130
- rawValueMode: true, // Get unformatted values in onChange
131
-
132
- // Standard input properties
133
- placeholder: 'Enter amount',
134
- className: 'numora-input',
135
-
136
- // Event handler
137
- onChange: (value) => {
138
- console.log('Raw value:', value); // Unformatted if rawValueMode is true
139
- console.log('Display value:', numoraInput.value); // Formatted display value
140
- console.log('As number:', numoraInput.valueAsNumber); // Parsed as number
141
- },
142
- });
143
- ```
144
-
145
- ### Compact Notation Example
146
-
147
- ```typescript
148
- import { NumoraInput } from 'numora';
149
-
150
- const container = document.querySelector('#my-input-container');
151
-
152
- const numoraInput = new NumoraInput(container, {
153
- enableCompactNotation: true,
154
- onChange: (value) => {
155
- console.log('Value:', value);
156
- },
157
- });
158
-
159
- // When user pastes "1.5k" or you call setValue("1.5k")
160
- // It automatically expands to "1500"
161
- numoraInput.setValue('1.5k'); // Display: "1,500" (if thousand separator enabled)
162
- ```
163
-
164
- ### Scientific Notation Example
165
-
166
- ```typescript
167
- import { NumoraInput } from 'numora';
168
-
169
- const container = document.querySelector('#my-input-container');
170
-
171
- const numoraInput = new NumoraInput(container, {
172
- decimalMaxLength: 18,
173
- onChange: (value) => {
174
- console.log('Value:', value);
175
- },
176
- });
177
-
178
- // Scientific notation is ALWAYS automatically expanded
179
- // User can paste "1.5e-7" and it becomes "0.00000015"
180
- // User can paste "2e+5" and it becomes "200000"
181
- ```
182
-
183
- ### Comma/Dot Conversion Example
184
-
185
- ```typescript
186
- import { NumoraInput, ThousandStyle } from 'numora';
187
-
188
- const container = document.querySelector('#my-input-container');
189
-
190
- const numoraInput = new NumoraInput(container, {
191
- decimalSeparator: ',', // European format
192
- thousandStyle: ThousandStyle.None, // Required for comma/dot conversion
193
- decimalMaxLength: 2,
25
+ formatOn: FormatOn.Blur,
26
+ onChange: (value) => console.log(value),
194
27
  });
195
28
 
196
- // When thousandStyle is None:
197
- // - User types "." → automatically converted to ","
198
- // - User types "," → automatically converted to ","
199
- // This makes it easier for users without knowing the exact separator
29
+ // Get / set value
30
+ input.value = '1234.56';
31
+ console.log(input.valueAsNumber); // 1234.56
200
32
  ```
201
33
 
202
- ### Using Display Formatting Utilities
203
-
204
- ```typescript
205
- import { formatPercent, formatLargePercent, formatLargeNumber, condenseDecimalZeros } from 'numora';
206
-
207
- // Format as percentage
208
- const percent = formatPercent('0.01', 2); // "1.00%"
209
- const largePercent = formatLargePercent('1000', 2); // "100000%"
210
-
211
- // Format large numbers with scale notation
212
- const large = formatLargeNumber('1234567'); // "1.23M"
213
- const small = formatLargeNumber('1234'); // "1.23k"
214
-
215
- // Condense decimal zeros
216
- const condensed = condenseDecimalZeros('0.000001', 8); // "0₆1"
217
- const condensed2 = condenseDecimalZeros('0.000123', 8); // "0₃123"
218
- ```
219
-
220
- ### Programmatic Value Control
221
-
222
- ```typescript
223
- // Get the current value
224
- const currentValue = numoraInput.getValue();
225
- // or
226
- const currentValue = numoraInput.value;
227
-
228
- // Set a new value
229
- numoraInput.setValue('1234.56');
230
- // or
231
- numoraInput.value = '1234.56';
232
-
233
- // Set from a number
234
- numoraInput.valueAsNumber = 1234.56;
235
-
236
- // Get as a number
237
- const numericValue = numoraInput.valueAsNumber;
238
-
239
- // Enable/disable the input
240
- numoraInput.disable();
241
- numoraInput.enable();
34
+ ## Features
242
35
 
243
- // Access the underlying HTMLInputElement
244
- const inputElement = numoraInput.getElement();
245
- inputElement.addEventListener('focus', () => {
246
- console.log('Input focused');
247
- });
248
- ```
36
+ - [Sanitization](https://numora.xyz/docs/numora/features/sanitization) - filters invalid characters and mobile keyboard artifacts
37
+ - [Formatting](https://numora.xyz/docs/numora/features/formatting) - thousand separators (Thousand/Lakh/Wan), format on blur or change
38
+ - [Decimals](https://numora.xyz/docs/numora/features/decimals) - min/max decimal places, custom decimal separator, raw value mode
39
+ - [Compact Notation](https://numora.xyz/docs/numora/features/compact-notation) - expands "1k" → "1000" on paste/setValue (opt-in)
40
+ - [Scientific Notation](https://numora.xyz/docs/numora/features/scientific-notation) - always expands "1.5e-7" → "0.00000015" automatically
41
+ - [Leading Zeros](https://numora.xyz/docs/numora/features/leading-zeros) - configurable leading zero behavior
249
42
 
250
43
  ## Options
251
44
 
252
- The NumoraInput constructor accepts the following options:
253
-
254
45
  | Option | Type | Default | Description |
255
46
  |--------|------|---------|-------------|
256
- | `decimalMaxLength` | `number` | `2` | Maximum number of decimal places allowed |
257
- | `decimalMinLength` | `number` | `0` | Minimum number of decimal places (pads with zeros) |
258
- | `decimalSeparator` | `string` | `'.'` | Character used as decimal separator |
259
- | `thousandSeparator` | `string` | `','` | Character used as thousand separator (set to empty string to disable) |
47
+ | `decimalMaxLength` | `number` | `2` | Maximum decimal places allowed |
48
+ | `decimalMinLength` | `number` | `0` | Minimum decimal places (pads with zeros) |
49
+ | `decimalSeparator` | `string` | `'.'` | Decimal separator character |
50
+ | `thousandSeparator` | `string` | `','` | Thousand separator character |
260
51
  | `thousandStyle` | `ThousandStyle` | `ThousandStyle.None` | Grouping style: `Thousand`, `Lakh`, `Wan`, or `None` |
261
52
  | `formatOn` | `FormatOn` | `FormatOn.Blur` | When to apply formatting: `Blur` or `Change` |
262
- | `enableCompactNotation` | `boolean` | `false` | Enable expansion of compact notation (e.g., "1k" → "1000") on paste/setValue |
53
+ | `enableCompactNotation` | `boolean` | `false` | Expand compact notation on paste/setValue |
263
54
  | `enableNegative` | `boolean` | `false` | Allow negative numbers |
264
- | `enableLeadingZeros` | `boolean` | `false` | Allow leading zeros before decimal point |
265
- | `rawValueMode` | `boolean` | `false` | Return unformatted values in `onChange` callback |
266
- | `onChange` | `(value: string) => void` | `undefined` | Callback function that runs when the input value changes |
267
- | `value` | `string` | `undefined` | Initial value (controlled mode) |
268
- | `defaultValue` | `string` | `undefined` | Initial default value (uncontrolled mode) |
55
+ | `enableLeadingZeros` | `boolean` | `false` | Allow leading zeros |
56
+ | `rawValueMode` | `boolean` | `false` | Return unformatted values in `onChange` |
57
+ | `onChange` | `(value: string) => void` | `undefined` | Called when value changes |
58
+ | `value` | `string` | `undefined` | Initial value (controlled) |
59
+ | `defaultValue` | `string` | `undefined` | Initial value (uncontrolled) |
269
60
 
270
- All standard HTMLInputElement properties are also supported (e.g., `placeholder`, `className`, `disabled`, `id`, etc.).
61
+ All standard `HTMLInputElement` properties are also supported (`placeholder`, `className`, `disabled`, etc.).
271
62
 
272
- **Note:** Scientific notation expansion (e.g., `"1.5e-7"` → `"0.00000015"`) always happens automatically and is not configurable.
63
+ ## Documentation
273
64
 
274
- ## Framework Adapters
65
+ Full docs and live demo at [numora.xyz/docs/numora](https://numora.xyz/docs/numora).
275
66
 
276
- Numora is also available for popular frameworks:
67
+ ## Framework Adapters
277
68
 
278
- - **React**: [`numora-react`](../react/README.md) - React component wrapper
279
- - **Vue**: Coming soon
280
- - **Svelte**: Use the core package directly
69
+ - **React**: [`numora-react`](../react/README.md)
281
70
 
282
71
  ## License
283
72
 
@@ -16,7 +16,6 @@ export interface NumoraInputOptions extends Partial<Omit<HTMLInputElement, 'valu
16
16
  }
17
17
  export declare class NumoraInput {
18
18
  private element;
19
- private options;
20
19
  private resolvedOptions;
21
20
  private rawValue;
22
21
  private caretPositionBeforeChange?;
@@ -1,6 +1,10 @@
1
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)
2
+ * Static regex patterns for compact notation processing.
3
+ * Defined at module level to avoid recompilation on each function call.
4
+ */
5
+ /**
6
+ * Expands compact notation (k, m, b, t) to full numbers using string manipulation.
7
+ * Handles formats like: 1k, 1.5m, 2B, 1M, 2.5T (case-insensitive)
4
8
  * Uses string arithmetic to avoid precision loss with large numbers.
5
9
  *
6
10
  * @param value - The string value that may contain compact notation
@@ -1,6 +1,48 @@
1
1
  /**
2
2
  * Advanced cursor position calculation for formatted numeric inputs.
3
3
  * Handles cursor preservation during formatting changes, insertion, and deletion operations.
4
+ *
5
+ * ## Algorithm Overview
6
+ *
7
+ * The cursor position calculation uses a "meaningful digit" approach:
8
+ * 1. Count the number of actual digits (0-9) before the cursor, ignoring separators
9
+ * 2. After formatting, find the position that has the same number of digits before it
10
+ * 3. Apply adjustments for separator boundaries and special cases
11
+ *
12
+ * ## Processing Flow
13
+ *
14
+ * ```
15
+ * calculateCursorPositionAfterFormatting()
16
+ * ├── Guard clauses (empty values, out of bounds)
17
+ * ├── Compact notation detection (1k → 1000)
18
+ * ├── Character mapping approach (optional, for complex transformations)
19
+ * └── Route to handler based on operation type:
20
+ * ├── handleDeletion() - for backspace/delete operations
21
+ * │ ├── handleSeparatorDeletion() - cursor was on separator
22
+ * │ ├── Calculate target digit count
23
+ * │ └── Find new position + fine-tune for separators
24
+ * └── handleInsertion() - for typing/paste operations
25
+ * ├── Handle cursor at end
26
+ * └── Find position maintaining digit-relative position
27
+ * ```
28
+ *
29
+ * ## Key Concepts
30
+ *
31
+ * - **Meaningful digits**: Numeric characters (0-9) that represent actual value
32
+ * - **Separators**: Thousand separators that are formatting-only (not part of value)
33
+ * - **Digit index**: The nth digit from the start (ignoring separators)
34
+ * - **ChangeRange**: Info about what was typed/deleted to distinguish Delete vs Backspace
35
+ *
36
+ * ## Edge Cases Handled
37
+ *
38
+ * - Cursor at start/end of input
39
+ * - Cursor on separator during deletion
40
+ * - Delete key vs Backspace key (different cursor behavior)
41
+ * - Compact notation expansion (1k → 1000)
42
+ * - Integer/decimal part transitions
43
+ * - Boundary constraints (prefix/suffix)
44
+ *
45
+ * @module cursor-position
4
46
  */
5
47
  import type { ChangeRange } from './constants';
6
48
  import { ThousandStyle } from '@/types';
@@ -15,6 +57,7 @@ export type IsCharacterEquivalent = (char1: string, char2: string, context: {
15
57
  oldIndex: number;
16
58
  newIndex: number;
17
59
  }) => boolean;
60
+ export declare const defaultIsCharacterEquivalent: IsCharacterEquivalent;
18
61
  /**
19
62
  * Options for cursor position calculation.
20
63
  */
@@ -36,7 +79,7 @@ export interface CursorPositionOptions {
36
79
  * @param newFormattedValue - The formatted value after formatting
37
80
  * @param oldCursorPosition - The cursor position in the old formatted value
38
81
  * @param separator - The thousand separator character used in formatting
39
- * @param _groupStyle - The grouping style used (unused but kept for API compatibility)
82
+ * Will be removed in a future major version. Pass any value; it is ignored.
40
83
  * @param changeRange - Optional change range info to distinguish Delete vs Backspace
41
84
  * @param decimalSeparator - The decimal separator character (default: '.')
42
85
  * @param options - Additional options for cursor calculation
@@ -1,23 +1,48 @@
1
1
  /**
2
2
  * Utilities for counting and locating meaningful digits in formatted numbers.
3
- * "Meaningful digits" are actual numeric digits, excluding separators and decimal points.
3
+ *
4
+ * ## Core Concept
5
+ *
6
+ * "Meaningful digits" are the actual numeric characters (0-9) in a formatted string,
7
+ * excluding formatting characters like thousand separators and decimal points.
8
+ *
9
+ * For example, in "1,234.56":
10
+ * - Meaningful digits: 1, 2, 3, 4, 5, 6 (count = 6)
11
+ * - Non-meaningful: comma (,) and period (.)
12
+ *
13
+ * ## Usage in Cursor Positioning
14
+ *
15
+ * These utilities enable cursor preservation during formatting by:
16
+ * 1. Counting digits before cursor in OLD value
17
+ * 2. Finding position with same digit count in NEW value
18
+ *
19
+ * Example: Typing "0" in "99|" (cursor at end)
20
+ * - Old value: "99" → 2 digits before cursor
21
+ * - User types: "0" → becomes "990"
22
+ * - Formatting: "990" → "990" (no separator yet)
23
+ * - New cursor: position after 3rd digit = position 3
24
+ *
25
+ * Example: Typing "9" in "99|9" → "9,999"
26
+ * - Old value: "999" → 3 digits before cursor at position 2
27
+ * - After formatting: "9,999"
28
+ * - Find position with 3 digits before it → position 4 (after "9,99")
29
+ *
30
+ * @module digit-counting
4
31
  */
5
32
  /**
6
- * Counts meaningful digits (non-separator, non-decimal) before a position.
33
+ * Counts meaningful non-thousand-separator characters (digits and decimal separator) before a position.
7
34
  * This is the core digit counting logic used throughout cursor positioning.
8
35
  *
9
36
  * @param value - The formatted string value
10
37
  * @param position - The position to count up to
11
38
  * @param separator - The thousand separator character
12
- * @param decimalSeparator - The decimal separator character (default: '.')
13
39
  * @returns The count of meaningful digits before the position
14
40
  *
15
41
  * @example
16
42
  * 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
43
+ * countMeaningfulDigitsBeforePosition("1,234.56", 8, ",") // Returns: 7
19
44
  */
20
- export declare function countMeaningfulDigitsBeforePosition(value: string, position: number, separator: string, _decimalSeparator?: string): number;
45
+ export declare function countMeaningfulDigitsBeforePosition(value: string, position: number, separator: string): number;
21
46
  /**
22
47
  * Finds the position in the string for a specific digit index.
23
48
  * Returns the position AFTER the digit at targetDigitIndex.
@@ -25,13 +50,12 @@ export declare function countMeaningfulDigitsBeforePosition(value: string, posit
25
50
  * @param value - The formatted string value
26
51
  * @param targetDigitIndex - The zero-based index of the target digit
27
52
  * @param separator - The thousand separator character
28
- * @param decimalSeparator - The decimal separator character (default: '.')
29
53
  * @returns The position after the target digit
30
54
  *
31
55
  * @example
32
- * findPositionForDigitIndex("1,234", 2, ",") // Returns: 4 (after digit "3")
56
+ * findPositionForDigitIndex("1,234", 3, ",") // Returns: 4 (after digit "3")
33
57
  */
34
- export declare function findPositionForDigitIndex(value: string, targetDigitIndex: number, separator: string, _decimalSeparator?: string): number;
58
+ export declare function findPositionForDigitIndex(value: string, targetDigitIndex: number, separator: string): number;
35
59
  /**
36
60
  * Finds the position in the string where the digit count equals targetDigitCount.
37
61
  * Returns the position after reaching the target count.
@@ -39,13 +63,12 @@ export declare function findPositionForDigitIndex(value: string, targetDigitInde
39
63
  * @param value - The formatted string value
40
64
  * @param targetDigitCount - The target number of digits
41
65
  * @param separator - The thousand separator character
42
- * @param decimalSeparator - The decimal separator character (default: '.')
43
66
  * @returns The position where digit count equals target
44
67
  *
45
68
  * @example
46
- * findPositionWithMeaningfulDigitCount("1,234", 3, ",") // Returns: 5 (after "2,3")
69
+ * findPositionWithMeaningfulDigitCount("1,234", 3, ",") // Returns: 4 (after "2,3")
47
70
  */
48
- export declare function findPositionWithMeaningfulDigitCount(value: string, targetDigitCount: number, separator: string, _decimalSeparator?: string): number;
71
+ export declare function findPositionWithMeaningfulDigitCount(value: string, targetDigitCount: number, separator: string): number;
49
72
  /**
50
73
  * Checks if a position in the string is on a separator character.
51
74
  *
@@ -14,7 +14,3 @@ export { findChangedRangeFromCaretPositions, findChangeRange } from './change-de
14
14
  export { getCaretBoundary, getCaretPosInBoundary } from './cursor-boundary';
15
15
  export { setCaretPosition, setCaretPositionWithRetry, getInputCaretPosition, updateCursorPosition, skipOverThousandSeparatorOnDelete } from './caret-position-utils';
16
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';
20
- export { applyDecimalPrecision, applyScaleNotation, compareStrings, isVeryLarge } from './numeric-formatting-utils';
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Removes non-numeric characters from a string, preserving the decimal separator.
3
+ * Uses cached regex for performance optimization.
3
4
  *
4
5
  * @param value - The string to sanitize
5
6
  * @param enableNegative - Whether to allow negative sign
@@ -1,7 +1,7 @@
1
1
  import type { FormattingOptions, Separators } from '@/types';
2
2
  /**
3
3
  * Removes all occurrences of thousand separator from a string.
4
- * Escapes special regex characters in the separator to ensure safe pattern matching.
4
+ * Uses cached regex for performance optimization.
5
5
  *
6
6
  * @param value - The string to remove separators from
7
7
  * @param thousandSeparator - The thousand separator character to remove
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Static regex patterns for scientific notation processing.
3
+ * Defined at module level to avoid recompilation on each function call.
4
+ */
1
5
  /**
2
6
  * Expands scientific notation to decimal notation using string manipulation only.
3
7
  * Handles formats like: 1.5e-7, 2e+5, 1.23e-4, etc.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  export * from './NumoraInput';
2
2
  export { ThousandStyle, FormatOn } from './types';
3
+ export { getSeparatorsFromLocale, resolveLocaleOptions } from './utils/locale';
3
4
  export { handleOnChangeNumoraInput, handleOnPasteNumoraInput, handleOnKeyDownNumoraInput, } from './utils/event-handlers';
4
5
  export { formatValueForDisplay, formatInputValue, } from './utils/format-utils';
5
6
  export type { FormattingOptions, CaretPositionInfo } from './types';
6
- export { formatPercent, formatLargePercent } from './features/formatting/percent';
7
- export { formatLargeNumber, type FormatLargeNumberOptions } from './features/formatting/large-number';
8
- export { condenseDecimalZeros } from './features/formatting/subscript-notation';
9
7
  export { removeThousandSeparators } from './features/sanitization';
8
+ export { validateNumoraInputOptions } from './validation';
9
+ export { getNumoraPattern } from './utils/input-pattern';