@uxf/form 11.100.1 → 11.102.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.
|
@@ -1,16 +1,62 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
"use client";
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
6
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
37
|
exports.NumberInput = NumberInput;
|
|
8
38
|
const translations_1 = require("@uxf/core-react/translations");
|
|
39
|
+
const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
|
|
9
40
|
const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
|
|
10
41
|
const text_input_1 = require("@uxf/ui/text-input");
|
|
11
|
-
const react_1 =
|
|
42
|
+
const react_1 = __importStar(require("react"));
|
|
12
43
|
const react_hook_form_1 = require("react-hook-form");
|
|
13
44
|
const form_context_1 = require("../form-id-context/form-context");
|
|
45
|
+
function normalizeInputValue(value) {
|
|
46
|
+
let result = value;
|
|
47
|
+
const lastComma = result.lastIndexOf(",");
|
|
48
|
+
const lastDot = result.lastIndexOf(".");
|
|
49
|
+
/* this normalizes comma delimiter to dot and then handle other comma/dots separators */
|
|
50
|
+
if (lastComma !== -1 && lastDot < lastComma) {
|
|
51
|
+
const beforeComma = result.slice(0, lastComma).replaceAll(",", "").replaceAll(".", "");
|
|
52
|
+
const afterComma = result.slice(lastComma + 1);
|
|
53
|
+
result = `${beforeComma}.${afterComma}`;
|
|
54
|
+
}
|
|
55
|
+
/* this handles case with dot as delimiter and commas as separators */
|
|
56
|
+
result = result.replaceAll(",", "");
|
|
57
|
+
/* this trim all spaces */
|
|
58
|
+
return result.replace(/\s/g, "");
|
|
59
|
+
}
|
|
14
60
|
function NumberInput(props) {
|
|
15
61
|
var _a, _b, _c, _d, _e, _f;
|
|
16
62
|
const formContext = (0, form_context_1.useFormContext)();
|
|
@@ -50,15 +96,58 @@ function NumberInput(props) {
|
|
|
50
96
|
},
|
|
51
97
|
shouldUnregister: props.shouldUnregister,
|
|
52
98
|
});
|
|
53
|
-
const
|
|
99
|
+
const isPasting = (0, react_1.useRef)(false);
|
|
100
|
+
/* this prevents plus/minus sign inside number and duplicate sign at start */
|
|
101
|
+
const handleBeforeInput = (event) => {
|
|
102
|
+
if ((0, is_not_nil_1.isNotNil)(event.nativeEvent.data) && /[+-]/.test(event.nativeEvent.data)) {
|
|
103
|
+
if ((0, is_not_empty_1.isNotEmpty)(event.currentTarget.value) || event.currentTarget.validity.badInput) {
|
|
104
|
+
event.preventDefault();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const handleBlur = (event) => {
|
|
54
109
|
var _a;
|
|
55
110
|
field.onBlur();
|
|
56
111
|
(_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, event);
|
|
57
112
|
};
|
|
58
|
-
const
|
|
113
|
+
const handleChange = (value, event) => {
|
|
114
|
+
var _a;
|
|
115
|
+
// normalize delimiter, trim spaces
|
|
116
|
+
let rawValue = normalizeInputValue(value);
|
|
117
|
+
// trim extraneous decimal places if specified
|
|
118
|
+
if ((0, is_not_nil_1.isNotNil)(props.decimalPlaces)) {
|
|
119
|
+
const [integers, decimals] = rawValue.split(".");
|
|
120
|
+
if ((0, is_not_nil_1.isNotNil)(decimals) && decimals.length > props.decimalPlaces) {
|
|
121
|
+
if (isPasting.current) {
|
|
122
|
+
// Round on paste
|
|
123
|
+
rawValue = parseFloat(rawValue).toFixed(props.decimalPlaces);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// Trim on type
|
|
127
|
+
rawValue = `${integers}.${decimals.slice(0, props.decimalPlaces)}`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
isPasting.current = false;
|
|
132
|
+
const parsedValue = (0, is_not_nil_1.isNotNil)(props.decimalPlaces) ? parseFloat(rawValue) : parseInt(rawValue, 10);
|
|
133
|
+
const returnValue = isNaN(parsedValue) ? null : parsedValue;
|
|
134
|
+
field.onChange(returnValue);
|
|
135
|
+
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, returnValue, event);
|
|
136
|
+
};
|
|
137
|
+
const handleKeyDown = (event) => {
|
|
59
138
|
var _a;
|
|
60
139
|
// Allow special keys
|
|
61
|
-
const specialKeys = [
|
|
140
|
+
const specialKeys = [
|
|
141
|
+
"Backspace",
|
|
142
|
+
"Delete",
|
|
143
|
+
"ArrowLeft",
|
|
144
|
+
"ArrowRight",
|
|
145
|
+
"ArrowUp",
|
|
146
|
+
"ArrowDown",
|
|
147
|
+
"Tab",
|
|
148
|
+
"Home",
|
|
149
|
+
"End",
|
|
150
|
+
];
|
|
62
151
|
// Allow keys for copy/paste/select/cut
|
|
63
152
|
const controlKeys = ["v", "V", "c", "C", "x", "X", "a", "A"];
|
|
64
153
|
// Allow digits and decimal point (.,)
|
|
@@ -73,15 +162,16 @@ function NumberInput(props) {
|
|
|
73
162
|
}
|
|
74
163
|
(_a = props.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(props, event);
|
|
75
164
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
field.onChange(returnValue);
|
|
83
|
-
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, returnValue, event);
|
|
165
|
+
// rAF resets the flag if onChange never fires (e.g. browser rejects invalid paste)
|
|
166
|
+
const handlePaste = () => {
|
|
167
|
+
isPasting.current = true;
|
|
168
|
+
requestAnimationFrame(() => {
|
|
169
|
+
isPasting.current = false;
|
|
170
|
+
});
|
|
84
171
|
};
|
|
85
|
-
|
|
172
|
+
const step = props.decimalPlaces
|
|
173
|
+
? (1 / Math.pow(10, Math.trunc(props.decimalPlaces))).toString() // trunc is for float>int conversion
|
|
174
|
+
: props.step;
|
|
175
|
+
return (react_1.default.createElement(text_input_1.TextInput, { autoComplete: props.autoComplete, autoFocus: props.autoFocus, className: props.className, enterKeyHint: props.enterKeyHint, form: props.form, helperText: (_e = (_d = fieldState.error) === null || _d === void 0 ? void 0 : _d.message) !== null && _e !== void 0 ? _e : props.helperText, hiddenLabel: props.hiddenLabel, id: id, inputMode: props.decimalPlaces ? "decimal" : "numeric", isDisabled: formContext.isFormDisabled || props.isDisabled, isInvalid: (0, is_not_nil_1.isNotNil)(fieldState.error), isReadOnly: formContext.isFormReadOnly || props.isReadOnly, isRequired: props.isRequired, label: props.label, leftAddon: props.leftAddon, leftElement: props.leftElement, max: props.max, min: props.min, name: field.name, onBeforeInput: handleBeforeInput, onBlur: handleBlur, onChange: handleChange, onFocus: props.onFocus, onKeyDown: handleKeyDown, onPaste: handlePaste, pattern: props.pattern, placeholder: props.placeholder, ref: field.ref, rightAddon: props.rightAddon, rightElement: props.rightElement, size: props.size, step: step, style: props.style, type: "number", value: (_f = field.value) !== null && _f !== void 0 ? _f : "", variant: props.variant }));
|
|
86
176
|
}
|
|
87
177
|
NumberInput.displayName = "UxfFormNumberInput";
|
|
@@ -16,7 +16,7 @@ function Default() {
|
|
|
16
16
|
const storyFormNumberInputs = (control) => (react_1.default.createElement("div", { className: "light mb-4 space-y-4 p-4" },
|
|
17
17
|
react_1.default.createElement(number_input_1.NumberInput, { control: control, label: "Default input", name: "default" }),
|
|
18
18
|
react_1.default.createElement(number_input_1.NumberInput, { control: control, isRequired: true, label: "Required input", name: "required" }),
|
|
19
|
-
react_1.default.createElement(number_input_1.NumberInput, { control: control, decimalPlaces: 3, label: "
|
|
19
|
+
react_1.default.createElement(number_input_1.NumberInput, { control: control, decimalPlaces: 3, label: "Decimal input", name: "decimal" }),
|
|
20
20
|
react_1.default.createElement(number_input_1.NumberInput, { control: control, label: "max50 input", max: 50, name: "max50" }),
|
|
21
21
|
react_1.default.createElement(button_1.Button, { type: "submit" }, "Submit")));
|
|
22
22
|
return (react_1.default.createElement(storybook_form_1.StorybookForm, null, ({ control }) => (react_1.default.createElement("div", { className: "flex flex-col lg:flex-row" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxf/form",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.102.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@uxf/core": "11.100.0",
|
|
20
20
|
"@uxf/core-react": "11.100.0",
|
|
21
|
-
"@uxf/ui": "11.
|
|
21
|
+
"@uxf/ui": "11.102.0",
|
|
22
22
|
"coordinate-parser": "1.0.7",
|
|
23
23
|
"dayjs": "1.11.19",
|
|
24
24
|
"react-hook-form": "7.71.1"
|