numora-react 1.0.7 → 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/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "numora-react",
3
- "version": "1.0.7",
4
- "description": "Numora for React - Headless finance input library",
5
- "homepage": "https://numora.xyz/",
3
+ "version": "2.0.5",
6
4
  "type": "module",
7
- "main": "dist/index.cjs",
8
- "module": "dist/index.esm.js",
9
- "types": "dist/index.d.ts",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "description": "React component wrapper for Numora",
9
+ "homepage": "https://numora.xyz/",
10
10
  "exports": {
11
11
  ".": {
12
12
  "types": "./dist/index.d.ts",
13
- "import": "./dist/index.esm.js",
14
- "require": "./dist/index.cjs"
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
15
  }
16
16
  },
17
17
  "sideEffects": false,
@@ -50,23 +50,19 @@
50
50
  }
51
51
  ],
52
52
  "license": "MIT",
53
- "peerDependencies": {
54
- "react": "^18.0.0 || ^19.0.0",
55
- "react-dom": "^18.0.0 || ^19.0.0"
56
- },
57
53
  "devDependencies": {
58
- "@rollup/plugin-commonjs": "^28.0.3",
59
- "@rollup/plugin-node-resolve": "^16.0.1",
60
- "@rollup/plugin-typescript": "^12.1.2",
61
- "@types/react": "^19.1.0",
62
- "@types/react-dom": "^19.1.2",
63
- "rollup": "^4.38.0",
54
+ "@rollup/plugin-commonjs": "^28.0.9",
55
+ "@rollup/plugin-node-resolve": "^16.0.3",
56
+ "@rollup/plugin-typescript": "^12.3.0",
57
+ "@types/react": "^19.2.7",
58
+ "@types/react-dom": "^19.2.3",
59
+ "numora": "^2.0.5",
60
+ "react": "^19.2.3",
61
+ "react-dom": "^19.2.3",
62
+ "rollup": "^4.53.5",
64
63
  "rollup-plugin-peer-deps-external": "^2.2.4",
65
64
  "tslib": "^2.8.1",
66
- "typescript": "^5.8.2",
67
- "react": "^19.1.0",
68
- "react-dom": "^19.1.0",
69
- "numora": "^2.0.2"
65
+ "typescript": "^5.9.3"
70
66
  },
71
67
  "publishConfig": {
72
68
  "access": "public"
package/rollup.config.mjs CHANGED
@@ -11,6 +11,8 @@ export default {
11
11
  file: packageJson.main,
12
12
  format: 'cjs',
13
13
  sourcemap: true,
14
+ exports: 'named',
15
+ interop: 'auto',
14
16
  },
15
17
  {
16
18
  file: packageJson.module,
@@ -25,4 +27,4 @@ export default {
25
27
  typescript({ tsconfig: './tsconfig.json' }),
26
28
  ],
27
29
  external: ['react', 'react-dom', 'numora'],
28
- };
30
+ };
package/src/handlers.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  handleOnChangeNumoraInput,
4
4
  handleOnKeyDownNumoraInput,
5
5
  handleOnPasteNumoraInput,
6
+ formatValue,
6
7
  type CaretPositionInfo,
7
8
  type FormattingOptions,
8
9
  FormatOn,
@@ -26,22 +27,16 @@ export function handleNumoraOnChange(
26
27
  e: React.ChangeEvent<HTMLInputElement>,
27
28
  options: BaseOptions
28
29
  ): ChangeResult {
29
- handleOnChangeNumoraInput(
30
+ const { formatted, raw } = handleOnChangeNumoraInput(
30
31
  e.nativeEvent as unknown as Event,
31
32
  options.decimalMaxLength,
32
33
  options.caretPositionBeforeChange,
33
34
  options.formattingOptions
34
35
  );
35
36
 
36
- const target = e.target;
37
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
38
- if (rawValue) {
39
- target.removeAttribute('data-raw-value');
40
- }
41
-
42
37
  return {
43
- value: target.value,
44
- rawValue,
38
+ value: formatted,
39
+ rawValue: raw,
45
40
  };
46
41
  }
47
42
 
@@ -49,21 +44,15 @@ export function handleNumoraOnPaste(
49
44
  e: React.ClipboardEvent<HTMLInputElement>,
50
45
  options: Omit<BaseOptions, 'caretPositionBeforeChange'>
51
46
  ): PasteResult {
52
- const value = handleOnPasteNumoraInput(
47
+ const { formatted, raw } = handleOnPasteNumoraInput(
53
48
  e.nativeEvent as ClipboardEvent,
54
49
  options.decimalMaxLength,
55
50
  options.formattingOptions
56
51
  );
57
52
 
58
- const target = e.target as HTMLInputElement;
59
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
60
- if (rawValue) {
61
- target.removeAttribute('data-raw-value');
62
- }
63
-
64
53
  return {
65
- value,
66
- rawValue,
54
+ value: formatted,
55
+ rawValue: raw,
67
56
  };
68
57
  }
69
58
 
@@ -84,24 +73,22 @@ export function handleNumoraOnBlur(
84
73
  formattingOptions: FormattingOptions & { rawValueMode?: boolean };
85
74
  }
86
75
  ): BlurResult {
87
- // If formatOn is blur, force formatting on blur by invoking change handler logic
76
+ // If formatOn is blur, format the value using the pure formatting utility
88
77
  if (options.formattingOptions.formatOn === FormatOn.Blur) {
89
- handleOnChangeNumoraInput(
90
- e.nativeEvent as unknown as Event,
78
+ const { formatted, raw } = formatValue(
79
+ e.target.value,
91
80
  options.decimalMaxLength,
92
- undefined,
93
81
  { ...options.formattingOptions, formatOn: FormatOn.Change }
94
82
  );
95
- }
96
-
97
- const target = e.target;
98
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
99
- if (rawValue) {
100
- target.removeAttribute('data-raw-value');
83
+ e.target.value = formatted;
84
+ return {
85
+ value: formatted,
86
+ rawValue: raw,
87
+ };
101
88
  }
102
89
 
103
90
  return {
104
- value: target.value,
105
- rawValue,
91
+ value: e.target.value,
92
+ rawValue: undefined,
106
93
  };
107
94
  }
package/src/index.tsx CHANGED
@@ -8,9 +8,9 @@ import React, {
8
8
  import {
9
9
  FormatOn,
10
10
  ThousandStyle,
11
+ formatValue,
11
12
  type CaretPositionInfo,
12
13
  type FormattingOptions,
13
- handleOnChangeNumoraInput,
14
14
  } from 'numora';
15
15
  import {
16
16
  handleNumoraOnBlur,
@@ -63,23 +63,6 @@ const NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref)
63
63
  const inputRef = useRef<HTMLInputElement>(null);
64
64
  const caretInfoRef = useRef<CaretPositionInfo | undefined>(undefined);
65
65
 
66
- const [internalValue, setInternalValue] = useState<string>(
67
- controlledValue !== undefined
68
- ? String(controlledValue)
69
- : defaultValue !== undefined
70
- ? String(defaultValue)
71
- : ''
72
- );
73
-
74
- // Keep internal state in sync when controlled
75
- useEffect(() => {
76
- if (controlledValue !== undefined) {
77
- setInternalValue(String(controlledValue));
78
- }
79
- }, [controlledValue]);
80
-
81
- useImperativeHandle(ref, () => inputRef.current as HTMLInputElement, []);
82
-
83
66
  const formattingOptions: FormattingOptions & { rawValueMode?: boolean } = {
84
67
  formatOn,
85
68
  thousandSeparator,
@@ -92,21 +75,61 @@ const NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref)
92
75
  rawValueMode,
93
76
  };
94
77
 
95
- const formatValueWithCore = (value: string): string => {
96
- const el = inputRef.current ?? document.createElement('input');
97
- el.value = value;
98
- const fakeEvent = { target: el } as unknown as Event;
99
- handleOnChangeNumoraInput(fakeEvent, maxDecimals, undefined, formattingOptions);
100
- return el.value;
78
+ const getFormattedDefaultValue = (): string => {
79
+ if (defaultValue !== undefined) {
80
+ const { formatted } = formatValue(String(defaultValue), maxDecimals, formattingOptions);
81
+ return formatted;
82
+ }
83
+ return '';
101
84
  };
102
85
 
86
+ const getInitialControlledValue = (): string => {
87
+ if (controlledValue !== undefined) {
88
+ const { formatted } = formatValue(String(controlledValue), maxDecimals, formattingOptions);
89
+ return formatted;
90
+ }
91
+ return '';
92
+ };
93
+
94
+ const [internalValue, setInternalValue] = useState<string>(getInitialControlledValue);
95
+
96
+ useImperativeHandle(ref, () => inputRef.current as HTMLInputElement, []);
97
+
103
98
  // When controlled value changes, normalize/format it for display
104
99
  useEffect(() => {
105
100
  if (controlledValue !== undefined) {
106
- const formatted = formatValueWithCore(String(controlledValue));
101
+ const { formatted } = formatValue(String(controlledValue), maxDecimals, formattingOptions);
107
102
  setInternalValue(formatted);
108
103
  }
109
- }, [controlledValue, formatOn, thousandSeparator, thousandStyle, decimalSeparator, decimalMinLength, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode, maxDecimals]);
104
+ }, [controlledValue, maxDecimals, formatOn, thousandSeparator, thousandStyle, decimalSeparator, decimalMinLength, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode]);
105
+
106
+ const isControlled = controlledValue !== undefined;
107
+
108
+ const updateValue = (value: string) => {
109
+ if (isControlled) {
110
+ setInternalValue(value);
111
+ }
112
+ };
113
+
114
+ const syncEventValue = (
115
+ target: HTMLInputElement,
116
+ formattedValue: string,
117
+ rawValue?: string
118
+ ): void => {
119
+ Object.defineProperty(target, 'value', {
120
+ writable: true,
121
+ value: formattedValue,
122
+ });
123
+
124
+ if (rawValue !== undefined) {
125
+ Object.defineProperty(target, 'rawValue', {
126
+ writable: true,
127
+ value: rawValue,
128
+ enumerable: true,
129
+ configurable: true,
130
+ });
131
+ }
132
+ };
110
133
 
111
134
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
112
135
  const { value, rawValue } = handleNumoraOnChange(e, {
@@ -116,21 +139,12 @@ const NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref)
116
139
  });
117
140
  caretInfoRef.current = undefined;
118
141
 
119
- if (controlledValue === undefined) {
120
- setInternalValue(value);
121
- } else {
122
- setInternalValue(value);
123
- }
142
+ syncEventValue(e.target, value, rawValue);
143
+ updateValue(value);
124
144
 
125
145
  if (onChange) {
126
146
  onChange(e);
127
147
  }
128
-
129
- // Optionally expose rawValue via a custom event attribute if needed later
130
- if (rawValue && e.target && rawValueMode) {
131
- // Keep the raw value on the input for consumers that read it directly
132
- e.target.setAttribute('data-raw-value', rawValue);
133
- }
134
148
  };
135
149
 
136
150
  const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {
@@ -139,11 +153,8 @@ const NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref)
139
153
  formattingOptions,
140
154
  });
141
155
 
142
- if (controlledValue === undefined) {
143
- setInternalValue(value);
144
- } else {
145
- setInternalValue(value);
146
- }
156
+ syncEventValue(e.target as HTMLInputElement, value, rawValue);
157
+ updateValue(value);
147
158
 
148
159
  if (onPaste) {
149
160
  onPaste(e);
@@ -151,10 +162,6 @@ const NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref)
151
162
  if (onChange) {
152
163
  onChange(e);
153
164
  }
154
-
155
- if (rawValue && e.target && rawValueMode) {
156
- (e.target as HTMLInputElement).setAttribute('data-raw-value', rawValue);
157
- }
158
165
  };
159
166
 
160
167
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
@@ -170,26 +177,22 @@ const NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref)
170
177
  formattingOptions,
171
178
  });
172
179
 
173
- if (controlledValue === undefined) {
174
- setInternalValue(value);
175
- } else {
176
- setInternalValue(value);
177
- }
180
+ syncEventValue(e.target, value, rawValue);
181
+ updateValue(value);
178
182
 
179
183
  if (onBlur) {
180
184
  onBlur(e);
181
185
  }
182
-
183
- if (rawValue && e.target && rawValueMode) {
184
- (e.target as HTMLInputElement).setAttribute('data-raw-value', rawValue);
185
- }
186
186
  };
187
187
 
188
188
  return (
189
189
  <input
190
190
  {...rest}
191
191
  ref={inputRef}
192
- value={internalValue}
192
+ {...(isControlled
193
+ ? { value: internalValue }
194
+ : { defaultValue: getFormattedDefaultValue() }
195
+ )}
193
196
  onChange={handleChange}
194
197
  onPaste={handlePaste}
195
198
  onKeyDown={handleKeyDown}
package/dist/index.cjs DELETED
@@ -1,171 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var react = require('react');
5
- var numora = require('numora');
6
-
7
- function handleNumoraOnChange(e, options) {
8
- numora.handleOnChangeNumoraInput(e.nativeEvent, options.decimalMaxLength, options.caretPositionBeforeChange, options.formattingOptions);
9
- const target = e.target;
10
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
11
- if (rawValue) {
12
- target.removeAttribute('data-raw-value');
13
- }
14
- return {
15
- value: target.value,
16
- rawValue,
17
- };
18
- }
19
- function handleNumoraOnPaste(e, options) {
20
- const value = numora.handleOnPasteNumoraInput(e.nativeEvent, options.decimalMaxLength, options.formattingOptions);
21
- const target = e.target;
22
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
23
- if (rawValue) {
24
- target.removeAttribute('data-raw-value');
25
- }
26
- return {
27
- value,
28
- rawValue,
29
- };
30
- }
31
- function handleNumoraOnKeyDown(e, formattingOptions) {
32
- return numora.handleOnKeyDownNumoraInput(e.nativeEvent, formattingOptions);
33
- }
34
- function handleNumoraOnBlur(e, options) {
35
- // If formatOn is blur, force formatting on blur by invoking change handler logic
36
- if (options.formattingOptions.formatOn === numora.FormatOn.Blur) {
37
- numora.handleOnChangeNumoraInput(e.nativeEvent, options.decimalMaxLength, undefined, { ...options.formattingOptions, formatOn: numora.FormatOn.Change });
38
- }
39
- const target = e.target;
40
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
41
- if (rawValue) {
42
- target.removeAttribute('data-raw-value');
43
- }
44
- return {
45
- value: target.value,
46
- rawValue,
47
- };
48
- }
49
-
50
- const NumoraInput = react.forwardRef((props, ref) => {
51
- const { maxDecimals = 2, onChange, onPaste, onBlur, onKeyDown, formatOn = numora.FormatOn.Blur, thousandSeparator = ',', thousandStyle = numora.ThousandStyle.Thousand, decimalSeparator = '.', decimalMinLength, enableCompactNotation = false, enableNegative = false, enableLeadingZeros = false, rawValueMode = false, value: controlledValue, defaultValue, ...rest } = props;
52
- const inputRef = react.useRef(null);
53
- const caretInfoRef = react.useRef(undefined);
54
- const [internalValue, setInternalValue] = react.useState(controlledValue !== undefined
55
- ? String(controlledValue)
56
- : defaultValue !== undefined
57
- ? String(defaultValue)
58
- : '');
59
- // Keep internal state in sync when controlled
60
- react.useEffect(() => {
61
- if (controlledValue !== undefined) {
62
- setInternalValue(String(controlledValue));
63
- }
64
- }, [controlledValue]);
65
- react.useImperativeHandle(ref, () => inputRef.current, []);
66
- const formattingOptions = {
67
- formatOn,
68
- thousandSeparator,
69
- ThousandStyle: thousandStyle,
70
- decimalSeparator,
71
- decimalMinLength,
72
- enableCompactNotation,
73
- enableNegative,
74
- enableLeadingZeros,
75
- rawValueMode,
76
- };
77
- const formatValueWithCore = (value) => {
78
- const el = inputRef.current ?? document.createElement('input');
79
- el.value = value;
80
- const fakeEvent = { target: el };
81
- numora.handleOnChangeNumoraInput(fakeEvent, maxDecimals, undefined, formattingOptions);
82
- return el.value;
83
- };
84
- // When controlled value changes, normalize/format it for display
85
- react.useEffect(() => {
86
- if (controlledValue !== undefined) {
87
- const formatted = formatValueWithCore(String(controlledValue));
88
- setInternalValue(formatted);
89
- }
90
- }, [controlledValue, formatOn, thousandSeparator, thousandStyle, decimalSeparator, decimalMinLength, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode, maxDecimals]);
91
- const handleChange = (e) => {
92
- const { value, rawValue } = handleNumoraOnChange(e, {
93
- decimalMaxLength: maxDecimals,
94
- caretPositionBeforeChange: caretInfoRef.current,
95
- formattingOptions,
96
- });
97
- caretInfoRef.current = undefined;
98
- if (controlledValue === undefined) {
99
- setInternalValue(value);
100
- }
101
- else {
102
- setInternalValue(value);
103
- }
104
- if (onChange) {
105
- onChange(e);
106
- }
107
- // Optionally expose rawValue via a custom event attribute if needed later
108
- if (rawValue && e.target && rawValueMode) {
109
- // Keep the raw value on the input for consumers that read it directly
110
- e.target.setAttribute('data-raw-value', rawValue);
111
- }
112
- };
113
- const handlePaste = (e) => {
114
- const { value, rawValue } = handleNumoraOnPaste(e, {
115
- decimalMaxLength: maxDecimals,
116
- formattingOptions,
117
- });
118
- if (controlledValue === undefined) {
119
- setInternalValue(value);
120
- }
121
- else {
122
- setInternalValue(value);
123
- }
124
- if (onPaste) {
125
- onPaste(e);
126
- }
127
- if (onChange) {
128
- onChange(e);
129
- }
130
- if (rawValue && e.target && rawValueMode) {
131
- e.target.setAttribute('data-raw-value', rawValue);
132
- }
133
- };
134
- const handleKeyDown = (e) => {
135
- caretInfoRef.current = handleNumoraOnKeyDown(e, formattingOptions);
136
- if (onKeyDown) {
137
- onKeyDown(e);
138
- }
139
- };
140
- const handleBlur = (e) => {
141
- const { value, rawValue } = handleNumoraOnBlur(e, {
142
- decimalMaxLength: maxDecimals,
143
- formattingOptions,
144
- });
145
- if (controlledValue === undefined) {
146
- setInternalValue(value);
147
- }
148
- else {
149
- setInternalValue(value);
150
- }
151
- if (onBlur) {
152
- onBlur(e);
153
- }
154
- if (rawValue && e.target && rawValueMode) {
155
- e.target.setAttribute('data-raw-value', rawValue);
156
- }
157
- };
158
- return (jsxRuntime.jsx("input", { ...rest, ref: inputRef, value: internalValue, onChange: handleChange, onPaste: handlePaste, onKeyDown: handleKeyDown, onBlur: handleBlur, type: "text", inputMode: "decimal" }));
159
- });
160
- NumoraInput.displayName = 'NumoraInput';
161
-
162
- Object.defineProperty(exports, "FormatOn", {
163
- enumerable: true,
164
- get: function () { return numora.FormatOn; }
165
- });
166
- Object.defineProperty(exports, "ThousandStyle", {
167
- enumerable: true,
168
- get: function () { return numora.ThousandStyle; }
169
- });
170
- exports.NumoraInput = NumoraInput;
171
- //# sourceMappingURL=index.cjs.map
package/dist/index.cjs.js DELETED
@@ -1,171 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var react = require('react');
5
- var numora = require('numora');
6
-
7
- function handleNumoraOnChange(e, options) {
8
- numora.handleOnChangeNumoraInput(e.nativeEvent, options.decimalMaxLength, options.caretPositionBeforeChange, options.formattingOptions);
9
- const target = e.target;
10
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
11
- if (rawValue) {
12
- target.removeAttribute('data-raw-value');
13
- }
14
- return {
15
- value: target.value,
16
- rawValue,
17
- };
18
- }
19
- function handleNumoraOnPaste(e, options) {
20
- const value = numora.handleOnPasteNumoraInput(e.nativeEvent, options.decimalMaxLength, options.formattingOptions);
21
- const target = e.target;
22
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
23
- if (rawValue) {
24
- target.removeAttribute('data-raw-value');
25
- }
26
- return {
27
- value,
28
- rawValue,
29
- };
30
- }
31
- function handleNumoraOnKeyDown(e, formattingOptions) {
32
- return numora.handleOnKeyDownNumoraInput(e.nativeEvent, formattingOptions);
33
- }
34
- function handleNumoraOnBlur(e, options) {
35
- // If formatOn is blur, force formatting on blur by invoking change handler logic
36
- if (options.formattingOptions.formatOn === numora.FormatOn.Blur) {
37
- numora.handleOnChangeNumoraInput(e.nativeEvent, options.decimalMaxLength, undefined, { ...options.formattingOptions, formatOn: numora.FormatOn.Change });
38
- }
39
- const target = e.target;
40
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
41
- if (rawValue) {
42
- target.removeAttribute('data-raw-value');
43
- }
44
- return {
45
- value: target.value,
46
- rawValue,
47
- };
48
- }
49
-
50
- const NumoraInput = react.forwardRef((props, ref) => {
51
- const { maxDecimals = 2, onChange, onPaste, onBlur, onKeyDown, formatOn = numora.FormatOn.Blur, thousandSeparator = ',', thousandStyle = numora.ThousandStyle.Thousand, decimalSeparator = '.', decimalMinLength, enableCompactNotation = false, enableNegative = false, enableLeadingZeros = false, rawValueMode = false, value: controlledValue, defaultValue, ...rest } = props;
52
- const inputRef = react.useRef(null);
53
- const caretInfoRef = react.useRef(undefined);
54
- const [internalValue, setInternalValue] = react.useState(controlledValue !== undefined
55
- ? String(controlledValue)
56
- : defaultValue !== undefined
57
- ? String(defaultValue)
58
- : '');
59
- // Keep internal state in sync when controlled
60
- react.useEffect(() => {
61
- if (controlledValue !== undefined) {
62
- setInternalValue(String(controlledValue));
63
- }
64
- }, [controlledValue]);
65
- react.useImperativeHandle(ref, () => inputRef.current, []);
66
- const formattingOptions = {
67
- formatOn,
68
- thousandSeparator,
69
- ThousandStyle: thousandStyle,
70
- decimalSeparator,
71
- decimalMinLength,
72
- enableCompactNotation,
73
- enableNegative,
74
- enableLeadingZeros,
75
- rawValueMode,
76
- };
77
- const formatValueWithCore = (value) => {
78
- const el = inputRef.current ?? document.createElement('input');
79
- el.value = value;
80
- const fakeEvent = { target: el };
81
- numora.handleOnChangeNumoraInput(fakeEvent, maxDecimals, undefined, formattingOptions);
82
- return el.value;
83
- };
84
- // When controlled value changes, normalize/format it for display
85
- react.useEffect(() => {
86
- if (controlledValue !== undefined) {
87
- const formatted = formatValueWithCore(String(controlledValue));
88
- setInternalValue(formatted);
89
- }
90
- }, [controlledValue, formatOn, thousandSeparator, thousandStyle, decimalSeparator, decimalMinLength, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode, maxDecimals]);
91
- const handleChange = (e) => {
92
- const { value, rawValue } = handleNumoraOnChange(e, {
93
- decimalMaxLength: maxDecimals,
94
- caretPositionBeforeChange: caretInfoRef.current,
95
- formattingOptions,
96
- });
97
- caretInfoRef.current = undefined;
98
- if (controlledValue === undefined) {
99
- setInternalValue(value);
100
- }
101
- else {
102
- setInternalValue(value);
103
- }
104
- if (onChange) {
105
- onChange(e);
106
- }
107
- // Optionally expose rawValue via a custom event attribute if needed later
108
- if (rawValue && e.target && rawValueMode) {
109
- // Keep the raw value on the input for consumers that read it directly
110
- e.target.setAttribute('data-raw-value', rawValue);
111
- }
112
- };
113
- const handlePaste = (e) => {
114
- const { value, rawValue } = handleNumoraOnPaste(e, {
115
- decimalMaxLength: maxDecimals,
116
- formattingOptions,
117
- });
118
- if (controlledValue === undefined) {
119
- setInternalValue(value);
120
- }
121
- else {
122
- setInternalValue(value);
123
- }
124
- if (onPaste) {
125
- onPaste(e);
126
- }
127
- if (onChange) {
128
- onChange(e);
129
- }
130
- if (rawValue && e.target && rawValueMode) {
131
- e.target.setAttribute('data-raw-value', rawValue);
132
- }
133
- };
134
- const handleKeyDown = (e) => {
135
- caretInfoRef.current = handleNumoraOnKeyDown(e, formattingOptions);
136
- if (onKeyDown) {
137
- onKeyDown(e);
138
- }
139
- };
140
- const handleBlur = (e) => {
141
- const { value, rawValue } = handleNumoraOnBlur(e, {
142
- decimalMaxLength: maxDecimals,
143
- formattingOptions,
144
- });
145
- if (controlledValue === undefined) {
146
- setInternalValue(value);
147
- }
148
- else {
149
- setInternalValue(value);
150
- }
151
- if (onBlur) {
152
- onBlur(e);
153
- }
154
- if (rawValue && e.target && rawValueMode) {
155
- e.target.setAttribute('data-raw-value', rawValue);
156
- }
157
- };
158
- return (jsxRuntime.jsx("input", { ...rest, ref: inputRef, value: internalValue, onChange: handleChange, onPaste: handlePaste, onKeyDown: handleKeyDown, onBlur: handleBlur, type: "text", inputMode: "decimal" }));
159
- });
160
- NumoraInput.displayName = 'NumoraInput';
161
-
162
- Object.defineProperty(exports, "FormatOn", {
163
- enumerable: true,
164
- get: function () { return numora.FormatOn; }
165
- });
166
- Object.defineProperty(exports, "ThousandStyle", {
167
- enumerable: true,
168
- get: function () { return numora.ThousandStyle; }
169
- });
170
- exports.NumoraInput = NumoraInput;
171
- //# sourceMappingURL=index.cjs.js.map