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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/handlers.ts","../src/index.tsx"],"sourcesContent":["import type React from 'react';\nimport {\n handleOnChangeNumoraInput,\n handleOnKeyDownNumoraInput,\n handleOnPasteNumoraInput,\n type CaretPositionInfo,\n type FormattingOptions,\n FormatOn,\n} from 'numora';\n\ntype ChangeResult = {\n value: string;\n rawValue?: string;\n};\n\ntype PasteResult = ChangeResult;\ntype BlurResult = ChangeResult;\n\ntype BaseOptions = {\n decimalMaxLength: number;\n caretPositionBeforeChange?: CaretPositionInfo;\n formattingOptions: FormattingOptions & { rawValueMode?: boolean };\n};\n\nexport function handleNumoraOnChange(\n e: React.ChangeEvent<HTMLInputElement>,\n options: BaseOptions\n): ChangeResult {\n handleOnChangeNumoraInput(\n e.nativeEvent as unknown as Event,\n options.decimalMaxLength,\n options.caretPositionBeforeChange,\n options.formattingOptions\n );\n\n const target = e.target;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value: target.value,\n rawValue,\n };\n}\n\nexport function handleNumoraOnPaste(\n e: React.ClipboardEvent<HTMLInputElement>,\n options: Omit<BaseOptions, 'caretPositionBeforeChange'>\n): PasteResult {\n const value = handleOnPasteNumoraInput(\n e.nativeEvent as ClipboardEvent,\n options.decimalMaxLength,\n options.formattingOptions\n );\n\n const target = e.target as HTMLInputElement;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value,\n rawValue,\n };\n}\n\nexport function handleNumoraOnKeyDown(\n e: React.KeyboardEvent<HTMLInputElement>,\n formattingOptions: FormattingOptions\n): CaretPositionInfo | undefined {\n return handleOnKeyDownNumoraInput(\n e.nativeEvent as unknown as KeyboardEvent,\n formattingOptions\n );\n}\n\nexport function handleNumoraOnBlur(\n e: React.FocusEvent<HTMLInputElement>,\n options: {\n decimalMaxLength: number;\n formattingOptions: FormattingOptions & { rawValueMode?: boolean };\n }\n): BlurResult {\n // If formatOn is blur, force formatting on blur by invoking change handler logic\n if (options.formattingOptions.formatOn === FormatOn.Blur) {\n handleOnChangeNumoraInput(\n e.nativeEvent as unknown as Event,\n options.decimalMaxLength,\n undefined,\n { ...options.formattingOptions, formatOn: FormatOn.Change }\n );\n }\n\n const target = e.target;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value: target.value,\n rawValue,\n };\n}\n","import React, {\n useRef,\n useState,\n useEffect,\n forwardRef,\n useImperativeHandle,\n} from 'react';\nimport {\n FormatOn,\n ThousandStyle,\n type CaretPositionInfo,\n type FormattingOptions,\n handleOnChangeNumoraInput,\n} from 'numora';\nimport {\n handleNumoraOnBlur,\n handleNumoraOnChange,\n handleNumoraOnKeyDown,\n handleNumoraOnPaste,\n} from './handlers';\n\ninterface NumoraInputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'onChange' | 'type' | 'inputMode'\n > {\n maxDecimals?: number;\n onChange?: (e: React.ChangeEvent<HTMLInputElement> | React.ClipboardEvent<HTMLInputElement>) => void;\n\n formatOn?: FormatOn;\n thousandSeparator?: string;\n thousandStyle?: ThousandStyle;\n decimalSeparator?: string;\n decimalMinLength?: number;\n\n enableCompactNotation?: boolean;\n enableNegative?: boolean;\n enableLeadingZeros?: boolean;\n rawValueMode?: boolean;\n}\n\nconst NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref) => {\n const {\n maxDecimals = 2,\n onChange,\n onPaste,\n onBlur,\n onKeyDown,\n formatOn = FormatOn.Blur,\n thousandSeparator = ',',\n thousandStyle = ThousandStyle.Thousand,\n decimalSeparator = '.',\n decimalMinLength,\n enableCompactNotation = false,\n enableNegative = false,\n enableLeadingZeros = false,\n rawValueMode = false,\n value: controlledValue,\n defaultValue,\n ...rest\n } = props;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const caretInfoRef = useRef<CaretPositionInfo | undefined>(undefined);\n\n const [internalValue, setInternalValue] = useState<string>(\n controlledValue !== undefined\n ? String(controlledValue)\n : defaultValue !== undefined\n ? String(defaultValue)\n : ''\n );\n\n // Keep internal state in sync when controlled\n useEffect(() => {\n if (controlledValue !== undefined) {\n setInternalValue(String(controlledValue));\n }\n }, [controlledValue]);\n\n useImperativeHandle(ref, () => inputRef.current as HTMLInputElement, []);\n\n const formattingOptions: FormattingOptions & { rawValueMode?: boolean } = {\n formatOn,\n thousandSeparator,\n ThousandStyle: thousandStyle,\n decimalSeparator,\n decimalMinLength,\n enableCompactNotation,\n enableNegative,\n enableLeadingZeros,\n rawValueMode,\n };\n\n const formatValueWithCore = (value: string): string => {\n const el = inputRef.current ?? document.createElement('input');\n el.value = value;\n const fakeEvent = { target: el } as unknown as Event;\n handleOnChangeNumoraInput(fakeEvent, maxDecimals, undefined, formattingOptions);\n return el.value;\n };\n\n // When controlled value changes, normalize/format it for display\n useEffect(() => {\n if (controlledValue !== undefined) {\n const formatted = formatValueWithCore(String(controlledValue));\n setInternalValue(formatted);\n }\n }, [controlledValue, formatOn, thousandSeparator, thousandStyle, decimalSeparator, decimalMinLength, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode, maxDecimals]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnChange(e, {\n decimalMaxLength: maxDecimals,\n caretPositionBeforeChange: caretInfoRef.current,\n formattingOptions,\n });\n caretInfoRef.current = undefined;\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onChange) {\n onChange(e);\n }\n\n // Optionally expose rawValue via a custom event attribute if needed later\n if (rawValue && e.target && rawValueMode) {\n // Keep the raw value on the input for consumers that read it directly\n e.target.setAttribute('data-raw-value', rawValue);\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnPaste(e, {\n decimalMaxLength: maxDecimals,\n formattingOptions,\n });\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onPaste) {\n onPaste(e);\n }\n if (onChange) {\n onChange(e);\n }\n\n if (rawValue && e.target && rawValueMode) {\n (e.target as HTMLInputElement).setAttribute('data-raw-value', rawValue);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n caretInfoRef.current = handleNumoraOnKeyDown(e, formattingOptions);\n if (onKeyDown) {\n onKeyDown(e);\n }\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnBlur(e, {\n decimalMaxLength: maxDecimals,\n formattingOptions,\n });\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onBlur) {\n onBlur(e);\n }\n\n if (rawValue && e.target && rawValueMode) {\n (e.target as HTMLInputElement).setAttribute('data-raw-value', rawValue);\n }\n };\n\n return (\n <input\n {...rest}\n ref={inputRef}\n value={internalValue}\n onChange={handleChange}\n onPaste={handlePaste}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n type=\"text\"\n inputMode=\"decimal\"\n />\n );\n});\n\nNumoraInput.displayName = 'NumoraInput';\n\nexport { NumoraInput };\nexport { FormatOn, ThousandStyle } from 'numora';\nexport type { FormattingOptions, CaretPositionInfo } from 'numora';\n"],"names":["handleOnChangeNumoraInput","handleOnPasteNumoraInput","handleOnKeyDownNumoraInput","FormatOn","forwardRef","ThousandStyle","useRef","useState","useEffect","useImperativeHandle","_jsx"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/handlers.ts","../src/index.tsx"],"sourcesContent":["import type React from 'react';\nimport {\n handleOnChangeNumoraInput,\n handleOnKeyDownNumoraInput,\n handleOnPasteNumoraInput,\n type CaretPositionInfo,\n type FormattingOptions,\n FormatOn,\n} from 'numora';\n\ntype ChangeResult = {\n value: string;\n rawValue?: string;\n};\n\ntype PasteResult = ChangeResult;\ntype BlurResult = ChangeResult;\n\ntype BaseOptions = {\n decimalMaxLength: number;\n caretPositionBeforeChange?: CaretPositionInfo;\n formattingOptions: FormattingOptions & { rawValueMode?: boolean };\n};\n\nexport function handleNumoraOnChange(\n e: React.ChangeEvent<HTMLInputElement>,\n options: BaseOptions\n): ChangeResult {\n handleOnChangeNumoraInput(\n e.nativeEvent as unknown as Event,\n options.decimalMaxLength,\n options.caretPositionBeforeChange,\n options.formattingOptions\n );\n\n const target = e.target;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value: target.value,\n rawValue,\n };\n}\n\nexport function handleNumoraOnPaste(\n e: React.ClipboardEvent<HTMLInputElement>,\n options: Omit<BaseOptions, 'caretPositionBeforeChange'>\n): PasteResult {\n const value = handleOnPasteNumoraInput(\n e.nativeEvent as ClipboardEvent,\n options.decimalMaxLength,\n options.formattingOptions\n );\n\n const target = e.target as HTMLInputElement;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value,\n rawValue,\n };\n}\n\nexport function handleNumoraOnKeyDown(\n e: React.KeyboardEvent<HTMLInputElement>,\n formattingOptions: FormattingOptions\n): CaretPositionInfo | undefined {\n return handleOnKeyDownNumoraInput(\n e.nativeEvent as unknown as KeyboardEvent,\n formattingOptions\n );\n}\n\nexport function handleNumoraOnBlur(\n e: React.FocusEvent<HTMLInputElement>,\n options: {\n decimalMaxLength: number;\n formattingOptions: FormattingOptions & { rawValueMode?: boolean };\n }\n): BlurResult {\n // If formatOn is blur, force formatting on blur by invoking change handler logic\n if (options.formattingOptions.formatOn === FormatOn.Blur) {\n handleOnChangeNumoraInput(\n e.nativeEvent as unknown as Event,\n options.decimalMaxLength,\n undefined,\n { ...options.formattingOptions, formatOn: FormatOn.Change }\n );\n }\n\n const target = e.target;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value: target.value,\n rawValue,\n };\n}\n","import React, {\n useRef,\n useState,\n useEffect,\n forwardRef,\n useImperativeHandle,\n} from 'react';\nimport {\n FormatOn,\n ThousandStyle,\n type CaretPositionInfo,\n type FormattingOptions,\n handleOnChangeNumoraInput,\n} from 'numora';\nimport {\n handleNumoraOnBlur,\n handleNumoraOnChange,\n handleNumoraOnKeyDown,\n handleNumoraOnPaste,\n} from './handlers';\n\ninterface NumoraInputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'onChange' | 'type' | 'inputMode'\n > {\n maxDecimals?: number;\n onChange?: (e: React.ChangeEvent<HTMLInputElement> | React.ClipboardEvent<HTMLInputElement>) => void;\n\n formatOn?: FormatOn;\n thousandSeparator?: string;\n thousandStyle?: ThousandStyle;\n decimalSeparator?: string;\n decimalMinLength?: number;\n\n enableCompactNotation?: boolean;\n enableNegative?: boolean;\n enableLeadingZeros?: boolean;\n rawValueMode?: boolean;\n}\n\nconst NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref) => {\n const {\n maxDecimals = 2,\n onChange,\n onPaste,\n onBlur,\n onKeyDown,\n formatOn = FormatOn.Blur,\n thousandSeparator = ',',\n thousandStyle = ThousandStyle.Thousand,\n decimalSeparator = '.',\n decimalMinLength,\n enableCompactNotation = false,\n enableNegative = false,\n enableLeadingZeros = false,\n rawValueMode = false,\n value: controlledValue,\n defaultValue,\n ...rest\n } = props;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const caretInfoRef = useRef<CaretPositionInfo | undefined>(undefined);\n\n const [internalValue, setInternalValue] = useState<string>(\n controlledValue !== undefined\n ? String(controlledValue)\n : defaultValue !== undefined\n ? String(defaultValue)\n : ''\n );\n\n // Keep internal state in sync when controlled\n useEffect(() => {\n if (controlledValue !== undefined) {\n setInternalValue(String(controlledValue));\n }\n }, [controlledValue]);\n\n useImperativeHandle(ref, () => inputRef.current as HTMLInputElement, []);\n\n const formattingOptions: FormattingOptions & { rawValueMode?: boolean } = {\n formatOn,\n thousandSeparator,\n ThousandStyle: thousandStyle,\n decimalSeparator,\n decimalMinLength,\n enableCompactNotation,\n enableNegative,\n enableLeadingZeros,\n rawValueMode,\n };\n\n const formatValueWithCore = (value: string): string => {\n const el = inputRef.current ?? document.createElement('input');\n el.value = value;\n const fakeEvent = { target: el } as unknown as Event;\n handleOnChangeNumoraInput(fakeEvent, maxDecimals, undefined, formattingOptions);\n return el.value;\n };\n\n // When controlled value changes, normalize/format it for display\n useEffect(() => {\n if (controlledValue !== undefined) {\n const formatted = formatValueWithCore(String(controlledValue));\n setInternalValue(formatted);\n }\n }, [controlledValue, formatOn, thousandSeparator, thousandStyle, decimalSeparator, decimalMinLength, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode, maxDecimals]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnChange(e, {\n decimalMaxLength: maxDecimals,\n caretPositionBeforeChange: caretInfoRef.current,\n formattingOptions,\n });\n caretInfoRef.current = undefined;\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onChange) {\n onChange(e);\n }\n\n // Optionally expose rawValue via a custom event attribute if needed later\n if (rawValue && e.target && rawValueMode) {\n // Keep the raw value on the input for consumers that read it directly\n e.target.setAttribute('data-raw-value', rawValue);\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnPaste(e, {\n decimalMaxLength: maxDecimals,\n formattingOptions,\n });\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onPaste) {\n onPaste(e);\n }\n if (onChange) {\n onChange(e);\n }\n\n if (rawValue && e.target && rawValueMode) {\n (e.target as HTMLInputElement).setAttribute('data-raw-value', rawValue);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n caretInfoRef.current = handleNumoraOnKeyDown(e, formattingOptions);\n if (onKeyDown) {\n onKeyDown(e);\n }\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnBlur(e, {\n decimalMaxLength: maxDecimals,\n formattingOptions,\n });\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onBlur) {\n onBlur(e);\n }\n\n if (rawValue && e.target && rawValueMode) {\n (e.target as HTMLInputElement).setAttribute('data-raw-value', rawValue);\n }\n };\n\n return (\n <input\n {...rest}\n ref={inputRef}\n value={internalValue}\n onChange={handleChange}\n onPaste={handlePaste}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n type=\"text\"\n inputMode=\"decimal\"\n />\n );\n});\n\nNumoraInput.displayName = 'NumoraInput';\n\nexport { NumoraInput };\nexport { FormatOn, ThousandStyle } from 'numora';\nexport type { FormattingOptions, CaretPositionInfo } from 'numora';\n"],"names":["handleOnChangeNumoraInput","handleOnPasteNumoraInput","handleOnKeyDownNumoraInput","FormatOn","forwardRef","ThousandStyle","useRef","useState","useEffect","useImperativeHandle","_jsx"],"mappings":"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"}
package/dist/index.esm.js DELETED
@@ -1,162 +0,0 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import { forwardRef, useRef, useState, useEffect, useImperativeHandle } from 'react';
3
- import { FormatOn, handleOnChangeNumoraInput, handleOnKeyDownNumoraInput, handleOnPasteNumoraInput, ThousandStyle } from 'numora';
4
- export { FormatOn, ThousandStyle } from 'numora';
5
-
6
- function handleNumoraOnChange(e, options) {
7
- handleOnChangeNumoraInput(e.nativeEvent, options.decimalMaxLength, options.caretPositionBeforeChange, options.formattingOptions);
8
- const target = e.target;
9
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
10
- if (rawValue) {
11
- target.removeAttribute('data-raw-value');
12
- }
13
- return {
14
- value: target.value,
15
- rawValue,
16
- };
17
- }
18
- function handleNumoraOnPaste(e, options) {
19
- const value = handleOnPasteNumoraInput(e.nativeEvent, options.decimalMaxLength, options.formattingOptions);
20
- const target = e.target;
21
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
22
- if (rawValue) {
23
- target.removeAttribute('data-raw-value');
24
- }
25
- return {
26
- value,
27
- rawValue,
28
- };
29
- }
30
- function handleNumoraOnKeyDown(e, formattingOptions) {
31
- return handleOnKeyDownNumoraInput(e.nativeEvent, formattingOptions);
32
- }
33
- function handleNumoraOnBlur(e, options) {
34
- // If formatOn is blur, force formatting on blur by invoking change handler logic
35
- if (options.formattingOptions.formatOn === FormatOn.Blur) {
36
- handleOnChangeNumoraInput(e.nativeEvent, options.decimalMaxLength, undefined, { ...options.formattingOptions, formatOn: FormatOn.Change });
37
- }
38
- const target = e.target;
39
- const rawValue = target.getAttribute('data-raw-value') ?? undefined;
40
- if (rawValue) {
41
- target.removeAttribute('data-raw-value');
42
- }
43
- return {
44
- value: target.value,
45
- rawValue,
46
- };
47
- }
48
-
49
- const NumoraInput = forwardRef((props, ref) => {
50
- const { maxDecimals = 2, onChange, onPaste, onBlur, onKeyDown, formatOn = FormatOn.Blur, thousandSeparator = ',', thousandStyle = ThousandStyle.Thousand, decimalSeparator = '.', decimalMinLength, enableCompactNotation = false, enableNegative = false, enableLeadingZeros = false, rawValueMode = false, value: controlledValue, defaultValue, ...rest } = props;
51
- const inputRef = useRef(null);
52
- const caretInfoRef = useRef(undefined);
53
- const [internalValue, setInternalValue] = useState(controlledValue !== undefined
54
- ? String(controlledValue)
55
- : defaultValue !== undefined
56
- ? String(defaultValue)
57
- : '');
58
- // Keep internal state in sync when controlled
59
- useEffect(() => {
60
- if (controlledValue !== undefined) {
61
- setInternalValue(String(controlledValue));
62
- }
63
- }, [controlledValue]);
64
- useImperativeHandle(ref, () => inputRef.current, []);
65
- const formattingOptions = {
66
- formatOn,
67
- thousandSeparator,
68
- ThousandStyle: thousandStyle,
69
- decimalSeparator,
70
- decimalMinLength,
71
- enableCompactNotation,
72
- enableNegative,
73
- enableLeadingZeros,
74
- rawValueMode,
75
- };
76
- const formatValueWithCore = (value) => {
77
- const el = inputRef.current ?? document.createElement('input');
78
- el.value = value;
79
- const fakeEvent = { target: el };
80
- handleOnChangeNumoraInput(fakeEvent, maxDecimals, undefined, formattingOptions);
81
- return el.value;
82
- };
83
- // When controlled value changes, normalize/format it for display
84
- useEffect(() => {
85
- if (controlledValue !== undefined) {
86
- const formatted = formatValueWithCore(String(controlledValue));
87
- setInternalValue(formatted);
88
- }
89
- }, [controlledValue, formatOn, thousandSeparator, thousandStyle, decimalSeparator, decimalMinLength, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode, maxDecimals]);
90
- const handleChange = (e) => {
91
- const { value, rawValue } = handleNumoraOnChange(e, {
92
- decimalMaxLength: maxDecimals,
93
- caretPositionBeforeChange: caretInfoRef.current,
94
- formattingOptions,
95
- });
96
- caretInfoRef.current = undefined;
97
- if (controlledValue === undefined) {
98
- setInternalValue(value);
99
- }
100
- else {
101
- setInternalValue(value);
102
- }
103
- if (onChange) {
104
- onChange(e);
105
- }
106
- // Optionally expose rawValue via a custom event attribute if needed later
107
- if (rawValue && e.target && rawValueMode) {
108
- // Keep the raw value on the input for consumers that read it directly
109
- e.target.setAttribute('data-raw-value', rawValue);
110
- }
111
- };
112
- const handlePaste = (e) => {
113
- const { value, rawValue } = handleNumoraOnPaste(e, {
114
- decimalMaxLength: maxDecimals,
115
- formattingOptions,
116
- });
117
- if (controlledValue === undefined) {
118
- setInternalValue(value);
119
- }
120
- else {
121
- setInternalValue(value);
122
- }
123
- if (onPaste) {
124
- onPaste(e);
125
- }
126
- if (onChange) {
127
- onChange(e);
128
- }
129
- if (rawValue && e.target && rawValueMode) {
130
- e.target.setAttribute('data-raw-value', rawValue);
131
- }
132
- };
133
- const handleKeyDown = (e) => {
134
- caretInfoRef.current = handleNumoraOnKeyDown(e, formattingOptions);
135
- if (onKeyDown) {
136
- onKeyDown(e);
137
- }
138
- };
139
- const handleBlur = (e) => {
140
- const { value, rawValue } = handleNumoraOnBlur(e, {
141
- decimalMaxLength: maxDecimals,
142
- formattingOptions,
143
- });
144
- if (controlledValue === undefined) {
145
- setInternalValue(value);
146
- }
147
- else {
148
- setInternalValue(value);
149
- }
150
- if (onBlur) {
151
- onBlur(e);
152
- }
153
- if (rawValue && e.target && rawValueMode) {
154
- e.target.setAttribute('data-raw-value', rawValue);
155
- }
156
- };
157
- return (jsx("input", { ...rest, ref: inputRef, value: internalValue, onChange: handleChange, onPaste: handlePaste, onKeyDown: handleKeyDown, onBlur: handleBlur, type: "text", inputMode: "decimal" }));
158
- });
159
- NumoraInput.displayName = 'NumoraInput';
160
-
161
- export { NumoraInput };
162
- //# sourceMappingURL=index.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/handlers.ts","../src/index.tsx"],"sourcesContent":["import type React from 'react';\nimport {\n handleOnChangeNumoraInput,\n handleOnKeyDownNumoraInput,\n handleOnPasteNumoraInput,\n type CaretPositionInfo,\n type FormattingOptions,\n FormatOn,\n} from 'numora';\n\ntype ChangeResult = {\n value: string;\n rawValue?: string;\n};\n\ntype PasteResult = ChangeResult;\ntype BlurResult = ChangeResult;\n\ntype BaseOptions = {\n decimalMaxLength: number;\n caretPositionBeforeChange?: CaretPositionInfo;\n formattingOptions: FormattingOptions & { rawValueMode?: boolean };\n};\n\nexport function handleNumoraOnChange(\n e: React.ChangeEvent<HTMLInputElement>,\n options: BaseOptions\n): ChangeResult {\n handleOnChangeNumoraInput(\n e.nativeEvent as unknown as Event,\n options.decimalMaxLength,\n options.caretPositionBeforeChange,\n options.formattingOptions\n );\n\n const target = e.target;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value: target.value,\n rawValue,\n };\n}\n\nexport function handleNumoraOnPaste(\n e: React.ClipboardEvent<HTMLInputElement>,\n options: Omit<BaseOptions, 'caretPositionBeforeChange'>\n): PasteResult {\n const value = handleOnPasteNumoraInput(\n e.nativeEvent as ClipboardEvent,\n options.decimalMaxLength,\n options.formattingOptions\n );\n\n const target = e.target as HTMLInputElement;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value,\n rawValue,\n };\n}\n\nexport function handleNumoraOnKeyDown(\n e: React.KeyboardEvent<HTMLInputElement>,\n formattingOptions: FormattingOptions\n): CaretPositionInfo | undefined {\n return handleOnKeyDownNumoraInput(\n e.nativeEvent as unknown as KeyboardEvent,\n formattingOptions\n );\n}\n\nexport function handleNumoraOnBlur(\n e: React.FocusEvent<HTMLInputElement>,\n options: {\n decimalMaxLength: number;\n formattingOptions: FormattingOptions & { rawValueMode?: boolean };\n }\n): BlurResult {\n // If formatOn is blur, force formatting on blur by invoking change handler logic\n if (options.formattingOptions.formatOn === FormatOn.Blur) {\n handleOnChangeNumoraInput(\n e.nativeEvent as unknown as Event,\n options.decimalMaxLength,\n undefined,\n { ...options.formattingOptions, formatOn: FormatOn.Change }\n );\n }\n\n const target = e.target;\n const rawValue = target.getAttribute('data-raw-value') ?? undefined;\n if (rawValue) {\n target.removeAttribute('data-raw-value');\n }\n\n return {\n value: target.value,\n rawValue,\n };\n}\n","import React, {\n useRef,\n useState,\n useEffect,\n forwardRef,\n useImperativeHandle,\n} from 'react';\nimport {\n FormatOn,\n ThousandStyle,\n type CaretPositionInfo,\n type FormattingOptions,\n handleOnChangeNumoraInput,\n} from 'numora';\nimport {\n handleNumoraOnBlur,\n handleNumoraOnChange,\n handleNumoraOnKeyDown,\n handleNumoraOnPaste,\n} from './handlers';\n\ninterface NumoraInputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'onChange' | 'type' | 'inputMode'\n > {\n maxDecimals?: number;\n onChange?: (e: React.ChangeEvent<HTMLInputElement> | React.ClipboardEvent<HTMLInputElement>) => void;\n\n formatOn?: FormatOn;\n thousandSeparator?: string;\n thousandStyle?: ThousandStyle;\n decimalSeparator?: string;\n decimalMinLength?: number;\n\n enableCompactNotation?: boolean;\n enableNegative?: boolean;\n enableLeadingZeros?: boolean;\n rawValueMode?: boolean;\n}\n\nconst NumoraInput = forwardRef<HTMLInputElement, NumoraInputProps>((props, ref) => {\n const {\n maxDecimals = 2,\n onChange,\n onPaste,\n onBlur,\n onKeyDown,\n formatOn = FormatOn.Blur,\n thousandSeparator = ',',\n thousandStyle = ThousandStyle.Thousand,\n decimalSeparator = '.',\n decimalMinLength,\n enableCompactNotation = false,\n enableNegative = false,\n enableLeadingZeros = false,\n rawValueMode = false,\n value: controlledValue,\n defaultValue,\n ...rest\n } = props;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const caretInfoRef = useRef<CaretPositionInfo | undefined>(undefined);\n\n const [internalValue, setInternalValue] = useState<string>(\n controlledValue !== undefined\n ? String(controlledValue)\n : defaultValue !== undefined\n ? String(defaultValue)\n : ''\n );\n\n // Keep internal state in sync when controlled\n useEffect(() => {\n if (controlledValue !== undefined) {\n setInternalValue(String(controlledValue));\n }\n }, [controlledValue]);\n\n useImperativeHandle(ref, () => inputRef.current as HTMLInputElement, []);\n\n const formattingOptions: FormattingOptions & { rawValueMode?: boolean } = {\n formatOn,\n thousandSeparator,\n ThousandStyle: thousandStyle,\n decimalSeparator,\n decimalMinLength,\n enableCompactNotation,\n enableNegative,\n enableLeadingZeros,\n rawValueMode,\n };\n\n const formatValueWithCore = (value: string): string => {\n const el = inputRef.current ?? document.createElement('input');\n el.value = value;\n const fakeEvent = { target: el } as unknown as Event;\n handleOnChangeNumoraInput(fakeEvent, maxDecimals, undefined, formattingOptions);\n return el.value;\n };\n\n // When controlled value changes, normalize/format it for display\n useEffect(() => {\n if (controlledValue !== undefined) {\n const formatted = formatValueWithCore(String(controlledValue));\n setInternalValue(formatted);\n }\n }, [controlledValue, formatOn, thousandSeparator, thousandStyle, decimalSeparator, decimalMinLength, enableCompactNotation, enableNegative, enableLeadingZeros, rawValueMode, maxDecimals]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnChange(e, {\n decimalMaxLength: maxDecimals,\n caretPositionBeforeChange: caretInfoRef.current,\n formattingOptions,\n });\n caretInfoRef.current = undefined;\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onChange) {\n onChange(e);\n }\n\n // Optionally expose rawValue via a custom event attribute if needed later\n if (rawValue && e.target && rawValueMode) {\n // Keep the raw value on the input for consumers that read it directly\n e.target.setAttribute('data-raw-value', rawValue);\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnPaste(e, {\n decimalMaxLength: maxDecimals,\n formattingOptions,\n });\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onPaste) {\n onPaste(e);\n }\n if (onChange) {\n onChange(e);\n }\n\n if (rawValue && e.target && rawValueMode) {\n (e.target as HTMLInputElement).setAttribute('data-raw-value', rawValue);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n caretInfoRef.current = handleNumoraOnKeyDown(e, formattingOptions);\n if (onKeyDown) {\n onKeyDown(e);\n }\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\n const { value, rawValue } = handleNumoraOnBlur(e, {\n decimalMaxLength: maxDecimals,\n formattingOptions,\n });\n\n if (controlledValue === undefined) {\n setInternalValue(value);\n } else {\n setInternalValue(value);\n }\n\n if (onBlur) {\n onBlur(e);\n }\n\n if (rawValue && e.target && rawValueMode) {\n (e.target as HTMLInputElement).setAttribute('data-raw-value', rawValue);\n }\n };\n\n return (\n <input\n {...rest}\n ref={inputRef}\n value={internalValue}\n onChange={handleChange}\n onPaste={handlePaste}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n type=\"text\"\n inputMode=\"decimal\"\n />\n );\n});\n\nNumoraInput.displayName = 'NumoraInput';\n\nexport { NumoraInput };\nexport { FormatOn, ThousandStyle } from 'numora';\nexport type { FormattingOptions, CaretPositionInfo } from 'numora';\n"],"names":["_jsx"],"mappings":"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"}