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/dist/index.js +582 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +569 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +18 -22
- package/rollup.config.mjs +3 -1
- package/src/handlers.ts +17 -30
- package/src/index.tsx +59 -56
- package/dist/index.cjs +0 -171
- package/dist/index.cjs.js +0 -171
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.esm.js +0 -162
- package/dist/index.esm.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "numora-react",
|
|
3
|
-
"version": "
|
|
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.
|
|
8
|
-
"module": "dist/index.
|
|
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.
|
|
14
|
-
"require": "./dist/index.
|
|
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.
|
|
59
|
-
"@rollup/plugin-node-resolve": "^16.0.
|
|
60
|
-
"@rollup/plugin-typescript": "^12.
|
|
61
|
-
"@types/react": "^19.
|
|
62
|
-
"@types/react-dom": "^19.
|
|
63
|
-
"
|
|
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.
|
|
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:
|
|
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
|
|
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,
|
|
76
|
+
// If formatOn is blur, format the value using the pure formatting utility
|
|
88
77
|
if (options.formattingOptions.formatOn === FormatOn.Blur) {
|
|
89
|
-
|
|
90
|
-
e.
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return
|
|
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 =
|
|
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
|
|
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
|
-
|
|
120
|
-
|
|
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
|
-
|
|
143
|
-
|
|
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
|
-
|
|
174
|
-
|
|
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
|
-
|
|
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
|