numora-react 1.0.5 → 1.0.7

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.
@@ -0,0 +1,25 @@
1
+ import type React from 'react';
2
+ import { type CaretPositionInfo, type FormattingOptions } from 'numora';
3
+ type ChangeResult = {
4
+ value: string;
5
+ rawValue?: string;
6
+ };
7
+ type PasteResult = ChangeResult;
8
+ type BlurResult = ChangeResult;
9
+ type BaseOptions = {
10
+ decimalMaxLength: number;
11
+ caretPositionBeforeChange?: CaretPositionInfo;
12
+ formattingOptions: FormattingOptions & {
13
+ rawValueMode?: boolean;
14
+ };
15
+ };
16
+ export declare function handleNumoraOnChange(e: React.ChangeEvent<HTMLInputElement>, options: BaseOptions): ChangeResult;
17
+ export declare function handleNumoraOnPaste(e: React.ClipboardEvent<HTMLInputElement>, options: Omit<BaseOptions, 'caretPositionBeforeChange'>): PasteResult;
18
+ export declare function handleNumoraOnKeyDown(e: React.KeyboardEvent<HTMLInputElement>, formattingOptions: FormattingOptions): CaretPositionInfo | undefined;
19
+ export declare function handleNumoraOnBlur(e: React.FocusEvent<HTMLInputElement>, options: {
20
+ decimalMaxLength: number;
21
+ formattingOptions: FormattingOptions & {
22
+ rawValueMode?: boolean;
23
+ };
24
+ }): BlurResult;
25
+ export {};
package/dist/index.cjs ADDED
@@ -0,0 +1,171 @@
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