xmlui 0.10.11 → 0.10.12
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/lib/{index-BuIblMfO.mjs → index-CDOoBf2R.mjs} +1241 -1649
- package/dist/lib/index.css +1 -1
- package/dist/lib/{initMock-CV-9AUzP.mjs → initMock-BAV9RKui.mjs} +1 -1
- package/dist/lib/language-server-web-worker.mjs +1 -1
- package/dist/lib/language-server.mjs +1 -1
- package/dist/lib/{metadata-utils-DzONZF-e.mjs → metadata-utils-D90qqMGc.mjs} +1 -1
- package/dist/lib/{server-common-Dsyp3-Ro.mjs → server-common-lmBDLpUh.mjs} +2595 -2571
- package/dist/lib/{transform-CBz7TQJh.mjs → transform-bHBjkKSL.mjs} +2 -1
- package/dist/lib/xmlui-parser.d.ts +17 -8
- package/dist/lib/xmlui-parser.mjs +2 -2
- package/dist/lib/{xmlui-serializer-Bf9bdvlV.mjs → xmlui-serializer-DB6BLiXK.mjs} +1 -1
- package/dist/lib/xmlui.d.ts +2 -0
- package/dist/lib/xmlui.mjs +2 -2
- package/dist/metadata/{collectedComponentMetadata-Cdi6AFD3.mjs → collectedComponentMetadata-Dp8BqWQO.mjs} +1315 -1722
- package/dist/metadata/{initMock-B7OlSKKb.mjs → initMock-BvEO8W8r.mjs} +1 -1
- package/dist/metadata/style.css +1 -1
- package/dist/metadata/xmlui-metadata.mjs +1 -1
- package/dist/metadata/xmlui-metadata.umd.js +3 -3
- package/dist/scripts/package.json +1 -1
- package/dist/scripts/src/components/AppHeader/AppHeaderNative.js +1 -1
- package/dist/scripts/src/components/AutoComplete/AutoComplete.js +5 -1
- package/dist/scripts/src/components/AutoComplete/AutoCompleteNative.js +7 -4
- package/dist/scripts/src/components/Avatar/Avatar.js +1 -1
- package/dist/scripts/src/components/Charts/BarChart/BarChart.js +6 -6
- package/dist/scripts/src/components/Charts/BarChart/BarChartNative.js +25 -15
- package/dist/scripts/src/components/Charts/LineChart/LineChart.js +5 -5
- package/dist/scripts/src/components/Charts/LineChart/LineChartNative.js +14 -4
- package/dist/scripts/src/components/ComponentProvider.js +0 -2
- package/dist/scripts/src/components/Footer/FooterNative.js +1 -1
- package/dist/scripts/src/components/Form/FormNative.js +5 -3
- package/dist/scripts/src/components/FormItem/FormItemNative.js +0 -9
- package/dist/scripts/src/components/FormItem/ItemWithLabel.js +3 -3
- package/dist/scripts/src/components/Icon/IconNative.js +24 -6
- package/dist/scripts/src/components/ModalDialog/ModalDialog.js +8 -0
- package/dist/scripts/src/components/ModalDialog/ModalDialogNative.js +5 -3
- package/dist/scripts/src/components/NumberBox/NumberBoxNative.js +208 -78
- package/dist/scripts/src/components/Spinner/SpinnerNative.js +3 -2
- package/dist/scripts/src/parsers/xmlui-parser/syntax-kind.js +9 -0
- package/dist/scripts/src/parsers/xmlui-parser/transform.js +2 -1
- package/dist/standalone/xmlui-standalone.es.d.ts +2 -0
- package/dist/standalone/xmlui-standalone.umd.js +36 -36
- package/package.json +1 -1
- package/dist/scripts/src/components/NumberBox/NumberBox2.js +0 -99
- package/dist/scripts/src/components/NumberBox/NumberBox2Native.js +0 -420
package/package.json
CHANGED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.numberBox2ComponentRenderer = exports.NumberBoxMd2 = void 0;
|
|
7
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
-
const NumberBox_module_scss_1 = __importDefault(require("./NumberBox.module.scss"));
|
|
9
|
-
const renderers_1 = require("../../components-core/renderers");
|
|
10
|
-
const themeVars_1 = require("../../components-core/theming/themeVars");
|
|
11
|
-
const metadata_helpers_1 = require("../metadata-helpers");
|
|
12
|
-
const NumberBox2Native_1 = require("./NumberBox2Native");
|
|
13
|
-
const COMP = "NumberBox2";
|
|
14
|
-
exports.NumberBoxMd2 = (0, metadata_helpers_1.createMetadata)({
|
|
15
|
-
status: "experimental",
|
|
16
|
-
description: `A \`${COMP}\` component allows users to input numeric values: either integer or floating ` +
|
|
17
|
-
`point numbers. It also accepts empty values, where the stored value will be of type \`null\`.`,
|
|
18
|
-
props: {
|
|
19
|
-
placeholder: (0, metadata_helpers_1.dPlaceholder)(),
|
|
20
|
-
initialValue: (0, metadata_helpers_1.dInitialValue)(),
|
|
21
|
-
label: (0, metadata_helpers_1.dLabel)(),
|
|
22
|
-
labelPosition: (0, metadata_helpers_1.dLabelPosition)(NumberBox2Native_1.defaultProps.labelPosition),
|
|
23
|
-
labelWidth: (0, metadata_helpers_1.dLabelWidth)(COMP),
|
|
24
|
-
labelBreak: (0, metadata_helpers_1.dLabelBreak)(COMP),
|
|
25
|
-
maxLength: (0, metadata_helpers_1.dMaxLength)(),
|
|
26
|
-
autoFocus: (0, metadata_helpers_1.dAutoFocus)(),
|
|
27
|
-
required: (0, metadata_helpers_1.dRequired)(),
|
|
28
|
-
readOnly: (0, metadata_helpers_1.dReadonly)(),
|
|
29
|
-
enabled: (0, metadata_helpers_1.dEnabled)(),
|
|
30
|
-
validationStatus: (0, metadata_helpers_1.dValidationStatus)(),
|
|
31
|
-
startText: (0, metadata_helpers_1.dStartText)(),
|
|
32
|
-
startIcon: (0, metadata_helpers_1.dStartIcon)(),
|
|
33
|
-
endText: (0, metadata_helpers_1.dEndText)(),
|
|
34
|
-
endIcon: (0, metadata_helpers_1.dEndIcon)(),
|
|
35
|
-
hasSpinBox: {
|
|
36
|
-
description: `This boolean prop shows (\`true\`) or hides (\`false\`) the spinner buttons for the input field.`,
|
|
37
|
-
valueType: "boolean",
|
|
38
|
-
defaultValue: NumberBox2Native_1.defaultProps.hasSpinBox,
|
|
39
|
-
},
|
|
40
|
-
spinnerUpIcon: (0, metadata_helpers_1.d)(`Allows setting the icon displayed in the ${COMP} spinner for incrementing values. You can change ` +
|
|
41
|
-
`the default icon for all ${COMP} instances with the "icon.spinnerUp:NumberBox" declaration in the ` +
|
|
42
|
-
`app configuration file.`),
|
|
43
|
-
spinnerDownIcon: (0, metadata_helpers_1.d)(`Allows setting the icon displayed in the ${COMP} spinner for decrementing values. You can change ` +
|
|
44
|
-
`the default icon for all ${COMP} instances with the "icon.spinnerDown:NumberBox" declaration in the ` +
|
|
45
|
-
`app configuration file.`),
|
|
46
|
-
step: {
|
|
47
|
-
description: `This prop governs how big the step when clicking on the spinner of the field.`,
|
|
48
|
-
valueType: "number",
|
|
49
|
-
defaultValue: NumberBox2Native_1.defaultProps.step,
|
|
50
|
-
},
|
|
51
|
-
integersOnly: {
|
|
52
|
-
description: `This boolean property signs whether the input field accepts integers only (\`true\`) ` +
|
|
53
|
-
`or not (\`false\`).`,
|
|
54
|
-
valueType: "boolean",
|
|
55
|
-
defaultValue: NumberBox2Native_1.defaultProps.integersOnly,
|
|
56
|
-
},
|
|
57
|
-
maxFractionDigits: {
|
|
58
|
-
description: `This prop sets the maximum number of decimal places allowed in the input field. ` +
|
|
59
|
-
`If the number of decimal places is greater than this value, the value will be truncated to the maximum allowed decimal places. `,
|
|
60
|
-
valueType: "number",
|
|
61
|
-
defaultValue: NumberBox2Native_1.defaultProps.maxFractionDigits,
|
|
62
|
-
},
|
|
63
|
-
zeroOrPositive: {
|
|
64
|
-
description: `This boolean property determines whether the input value can only be 0 or positive numbers ` +
|
|
65
|
-
`(\`true\`) or also negative (\`false\`).`,
|
|
66
|
-
valueType: "boolean",
|
|
67
|
-
defaultValue: NumberBox2Native_1.defaultProps.zeroOrPositive,
|
|
68
|
-
},
|
|
69
|
-
minValue: (0, metadata_helpers_1.d)(`The minimum value the input field allows. Can be a float or an integer if ` +
|
|
70
|
-
`[\`integersOnly\`](#integersonly) is set to \`false\`, otherwise it can only be an integer.`),
|
|
71
|
-
maxValue: (0, metadata_helpers_1.d)(`The maximum value the input field allows. Can be a float or an integer if ` +
|
|
72
|
-
`[\`integersOnly\`](#integersonly) is set to \`false\`, otherwise it can only be an integer.`),
|
|
73
|
-
},
|
|
74
|
-
events: {
|
|
75
|
-
gotFocus: (0, metadata_helpers_1.dGotFocus)(COMP),
|
|
76
|
-
lostFocus: (0, metadata_helpers_1.dLostFocus)(COMP),
|
|
77
|
-
didChange: (0, metadata_helpers_1.dDidChange)(COMP),
|
|
78
|
-
},
|
|
79
|
-
apis: {
|
|
80
|
-
focus: {
|
|
81
|
-
description: "This method focuses the input field of the component.",
|
|
82
|
-
signature: "focus(): void",
|
|
83
|
-
},
|
|
84
|
-
value: {
|
|
85
|
-
description: "This API retrieves the current value of the component.",
|
|
86
|
-
signature: "get value(): number | undefined",
|
|
87
|
-
},
|
|
88
|
-
setValue: {
|
|
89
|
-
description: "This API sets the value of the component.",
|
|
90
|
-
signature: "setValue(value: number | undefined): void",
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
themeVars: (0, themeVars_1.parseScssVar)(NumberBox_module_scss_1.default.themeVars),
|
|
94
|
-
});
|
|
95
|
-
exports.numberBox2ComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP, exports.NumberBoxMd2, ({ node, state, updateState, lookupEventHandler, extractValue, className, registerComponentApi, }) => {
|
|
96
|
-
return ((0, jsx_runtime_1.jsx)(NumberBox2Native_1.NumberBox2, { className: className, value: state === null || state === void 0 ? void 0 : state.value, initialValue: extractValue.asOptionalString(node.props.initialValue), enabled: extractValue.asOptionalBoolean(node.props.enabled), placeholder: extractValue.asOptionalString(node.props.placeholder), validationStatus: extractValue(node.props.validationStatus), updateState: updateState, onDidChange: lookupEventHandler("didChange"), onFocus: lookupEventHandler("gotFocus"), onBlur: lookupEventHandler("lostFocus"), registerComponentApi: registerComponentApi, hasSpinBox: extractValue.asOptionalBoolean(node.props.hasSpinBox), step: extractValue(node.props.step), integersOnly: extractValue.asOptionalBoolean(node.props.integersOnly), zeroOrPositive: extractValue.asOptionalBoolean(node.props.zeroOrPositive), maxFractionDigits: extractValue.asOptionalNumber(node.props.maxFractionDigits), min: extractValue.asOptionalNumber(node.props.minValue), max: extractValue.asOptionalNumber(node.props.maxValue), startText: extractValue.asOptionalString(node.props.startText), startIcon: extractValue.asOptionalString(node.props.startIcon), endText: extractValue.asOptionalString(node.props.endText), endIcon: extractValue.asOptionalString(node.props.endIcon), spinnerUpIcon: extractValue.asOptionalString(node.props.spinnerUpIcon), spinnerDownIcon: extractValue.asOptionalString(node.props.spinnerDownIcon), autoFocus: extractValue.asOptionalBoolean(node.props.autoFocus), readOnly: extractValue.asOptionalBoolean(node.props.readOnly),
|
|
97
|
-
//maxLength={extractValue(node.props.maxLength)}
|
|
98
|
-
label: extractValue(node.props.label), labelPosition: extractValue(node.props.labelPosition), labelWidth: extractValue(node.props.labelWidth), labelBreak: extractValue.asOptionalBoolean(node.props.labelBreak), required: extractValue.asOptionalBoolean(node.props.required) }));
|
|
99
|
-
});
|
|
@@ -1,420 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
36
|
-
var t = {};
|
|
37
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
38
|
-
t[p] = s[p];
|
|
39
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
40
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
41
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
42
|
-
t[p[i]] = s[p[i]];
|
|
43
|
-
}
|
|
44
|
-
return t;
|
|
45
|
-
};
|
|
46
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
47
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
48
|
-
};
|
|
49
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
-
exports.NumberBox2 = exports.defaultProps = void 0;
|
|
51
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
52
|
-
const react_1 = __importStar(require("react"));
|
|
53
|
-
const classnames_1 = __importDefault(require("classnames"));
|
|
54
|
-
const NumberBox_module_scss_1 = __importDefault(require("./NumberBox.module.scss"));
|
|
55
|
-
const constants_1 = require("../../components-core/constants");
|
|
56
|
-
const misc_1 = require("../../components-core/utils/misc");
|
|
57
|
-
const numberbox_abstractions_1 = require("./numberbox-abstractions");
|
|
58
|
-
const IconNative_1 = require("../Icon/IconNative");
|
|
59
|
-
const InputAdornment_1 = require("../Input/InputAdornment");
|
|
60
|
-
const ButtonNative_1 = require("../Button/ButtonNative");
|
|
61
|
-
const ItemWithLabel_1 = require("../FormItem/ItemWithLabel");
|
|
62
|
-
const lodash_es_1 = require("lodash-es");
|
|
63
|
-
const number_1 = require("@internationalized/number");
|
|
64
|
-
// Default props for NumberBox2 component
|
|
65
|
-
exports.defaultProps = {
|
|
66
|
-
zeroOrPositive: false,
|
|
67
|
-
min: -numberbox_abstractions_1.NUMBERBOX_MAX_VALUE,
|
|
68
|
-
max: numberbox_abstractions_1.NUMBERBOX_MAX_VALUE,
|
|
69
|
-
maxFractionDigits: 3,
|
|
70
|
-
enabled: true,
|
|
71
|
-
integersOnly: false,
|
|
72
|
-
validationStatus: "none",
|
|
73
|
-
hasSpinBox: true,
|
|
74
|
-
step: 1,
|
|
75
|
-
labelPosition: "top",
|
|
76
|
-
};
|
|
77
|
-
exports.NumberBox2 = (0, react_1.forwardRef)(function NumberBox2(_a, forwardedRef) {
|
|
78
|
-
var _b, _c, _d;
|
|
79
|
-
var { id, style, className, value, initialValue, zeroOrPositive = exports.defaultProps.zeroOrPositive, min = zeroOrPositive ? 0 : exports.defaultProps.min, max = exports.defaultProps.max, maxFractionDigits = exports.defaultProps.maxFractionDigits, enabled = exports.defaultProps.enabled, placeholder, step = exports.defaultProps.step, integersOnly = exports.defaultProps.integersOnly, validationStatus = exports.defaultProps.validationStatus, hasSpinBox = exports.defaultProps.hasSpinBox, updateState = constants_1.noop, onDidChange = constants_1.noop, onFocus = constants_1.noop, onBlur = constants_1.noop, registerComponentApi, startText, startIcon, endText, endIcon, spinnerUpIcon, spinnerDownIcon, autoFocus, readOnly, required, label, labelPosition, labelWidth, labelBreak } = _a, rest = __rest(_a, ["id", "style", "className", "value", "initialValue", "zeroOrPositive", "min", "max", "maxFractionDigits", "enabled", "placeholder", "step", "integersOnly", "validationStatus", "hasSpinBox", "updateState", "onDidChange", "onFocus", "onBlur", "registerComponentApi", "startText", "startIcon", "endText", "endIcon", "spinnerUpIcon", "spinnerDownIcon", "autoFocus", "readOnly", "required", "label", "labelPosition", "labelWidth", "labelBreak"]);
|
|
80
|
-
const inputRef = (0, react_1.useRef)(null);
|
|
81
|
-
const upButton = (0, react_1.useRef)(null);
|
|
82
|
-
const downButton = (0, react_1.useRef)(null);
|
|
83
|
-
// Formatter & Parser
|
|
84
|
-
const locale = "en-US";
|
|
85
|
-
const formatOptions = (0, react_1.useMemo)(() => {
|
|
86
|
-
return {
|
|
87
|
-
useGrouping: false,
|
|
88
|
-
minimumFractionDigits: 0,
|
|
89
|
-
maximumFractionDigits: integersOnly ? 0 : maxFractionDigits,
|
|
90
|
-
};
|
|
91
|
-
}, [maxFractionDigits, integersOnly]);
|
|
92
|
-
const formatter = useNumberFormatter(locale, formatOptions);
|
|
93
|
-
const parser = useNumberParser(locale, formatOptions);
|
|
94
|
-
min = (0, numberbox_abstractions_1.clamp)((_b = (0, numberbox_abstractions_1.toUsableNumber)(min, true)) !== null && _b !== void 0 ? _b : (zeroOrPositive ? 0 : -numberbox_abstractions_1.NUMBERBOX_MAX_VALUE), (zeroOrPositive ? 0 : -numberbox_abstractions_1.NUMBERBOX_MAX_VALUE), numberbox_abstractions_1.NUMBERBOX_MAX_VALUE);
|
|
95
|
-
max = (0, numberbox_abstractions_1.clamp)((_c = (0, numberbox_abstractions_1.toUsableNumber)(max, true)) !== null && _c !== void 0 ? _c : (zeroOrPositive ? 0 : -numberbox_abstractions_1.NUMBERBOX_MAX_VALUE), (zeroOrPositive ? 0 : -numberbox_abstractions_1.NUMBERBOX_MAX_VALUE), numberbox_abstractions_1.NUMBERBOX_MAX_VALUE);
|
|
96
|
-
const initializeValue = (0, react_1.useCallback)((value, defaultValue = "") => {
|
|
97
|
-
return (0, numberbox_abstractions_1.isEmptyLike)(value) || (0, lodash_es_1.isNaN)(parser.parse(value.toString()))
|
|
98
|
-
? defaultValue
|
|
99
|
-
: formatter.format((0, numberbox_abstractions_1.clamp)(+value, min, max));
|
|
100
|
-
}, [formatter, parser, min, max]);
|
|
101
|
-
// --- Convert to representable string value (from number | null | undefined)
|
|
102
|
-
const [valueStrRep, setValueStrRep] = react_1.default.useState(initializeValue(value));
|
|
103
|
-
(0, react_1.useLayoutEffect)(() => {
|
|
104
|
-
setValueStrRep(initializeValue(value));
|
|
105
|
-
}, [value, initializeValue]);
|
|
106
|
-
const onFixCursorPosition = useCursorCorrection(valueStrRep, inputRef);
|
|
107
|
-
const _step = (_d = (0, numberbox_abstractions_1.toUsableNumber)(step, true)) !== null && _d !== void 0 ? _d : numberbox_abstractions_1.DEFAULT_STEP;
|
|
108
|
-
const inputMode = (0, react_1.useMemo)(() => {
|
|
109
|
-
// The inputMode attribute influences the software keyboard that is shown on touch devices.
|
|
110
|
-
// Browsers and operating systems are quite inconsistent about what keys are available.
|
|
111
|
-
// We choose between numeric and decimal based on whether we allow negative and fractional numbers,
|
|
112
|
-
// and based on testing on various devices to determine what keys are available in each inputMode.
|
|
113
|
-
const hasDecimals = formatter.resolvedOptions().maximumFractionDigits > 0;
|
|
114
|
-
return hasDecimals ? "decimal" : "numeric";
|
|
115
|
-
}, [formatter]);
|
|
116
|
-
// --- Initialize the related field with the input's initial value
|
|
117
|
-
(0, react_1.useEffect)(() => {
|
|
118
|
-
updateState({ value: initialValue }, { initial: true });
|
|
119
|
-
}, [initialValue, updateState]);
|
|
120
|
-
const clampInputValue = (0, react_1.useCallback)((value) => {
|
|
121
|
-
return (0, numberbox_abstractions_1.clamp)(value, min, max);
|
|
122
|
-
}, [min, max]);
|
|
123
|
-
const clampAndSaveInput = (0, react_1.useCallback)((value) => {
|
|
124
|
-
if ((0, numberbox_abstractions_1.isEmptyLike)(value)) {
|
|
125
|
-
updateState({ value: null });
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
value = value.toString();
|
|
129
|
-
// Set to empty state if input value is empty
|
|
130
|
-
if (!value.length) {
|
|
131
|
-
updateState({ value: null });
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
let parsedValue = parser.parse(value);
|
|
135
|
-
parsedValue = clampInputValue(parsedValue);
|
|
136
|
-
// if it failed to parse, then reset input to formatted version of current number
|
|
137
|
-
if ((0, lodash_es_1.isNaN)(parsedValue)) {
|
|
138
|
-
updateState({ value });
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
// value representation needs to be synchronized with the last parsed value
|
|
142
|
-
setValueStrRep((lastVal) => {
|
|
143
|
-
const formatted = formatter.format(parsedValue);
|
|
144
|
-
if (lastVal !== formatted) {
|
|
145
|
-
return formatted;
|
|
146
|
-
}
|
|
147
|
-
return lastVal;
|
|
148
|
-
});
|
|
149
|
-
updateState({ value: parsedValue });
|
|
150
|
-
}, [clampInputValue, updateState, parser, formatter]);
|
|
151
|
-
// --- Stepper logic
|
|
152
|
-
const increment = (0, react_1.useCallback)(() => {
|
|
153
|
-
if (!enabled)
|
|
154
|
-
return;
|
|
155
|
-
if (readOnly)
|
|
156
|
-
return;
|
|
157
|
-
const currentValue = (0, numberbox_abstractions_1.isEmptyLike)(value) || (0, lodash_es_1.isNaN)(value) ? "0" : value.toString();
|
|
158
|
-
const newValue = handleChangingValue(currentValue, parser, "increase", _step, min, max);
|
|
159
|
-
updateState({ value: newValue });
|
|
160
|
-
}, [value, enabled, readOnly, parser, _step, min, max, updateState]);
|
|
161
|
-
const decrement = (0, react_1.useCallback)(() => {
|
|
162
|
-
if (!enabled)
|
|
163
|
-
return;
|
|
164
|
-
if (readOnly)
|
|
165
|
-
return;
|
|
166
|
-
const currentValue = (0, numberbox_abstractions_1.isEmptyLike)(value) || (0, lodash_es_1.isNaN)(value) ? "0" : value.toString();
|
|
167
|
-
const newValue = handleChangingValue(currentValue, parser, "decrease", _step, min, max);
|
|
168
|
-
updateState({ value: newValue });
|
|
169
|
-
}, [value, enabled, readOnly, parser, _step, min, max, updateState]);
|
|
170
|
-
// --- Register stepper logic to buttons
|
|
171
|
-
useLongPress(upButton.current, increment);
|
|
172
|
-
useLongPress(downButton.current, decrement);
|
|
173
|
-
// --- Handle input
|
|
174
|
-
const _onBeforeInput = (0, react_1.useCallback)((event) => {
|
|
175
|
-
var _a, _b, _c;
|
|
176
|
-
const target = event.target;
|
|
177
|
-
const nextValue = parser.parse(target.value.slice(0, (_a = target.selectionStart) !== null && _a !== void 0 ? _a : undefined) +
|
|
178
|
-
((_b = event.nativeEvent.data) !== null && _b !== void 0 ? _b : "") +
|
|
179
|
-
target.value.slice((_c = target.selectionEnd) !== null && _c !== void 0 ? _c : undefined)).toString();
|
|
180
|
-
// pre-validate
|
|
181
|
-
if (!parser.isValidPartialNumber(nextValue, min, max)) {
|
|
182
|
-
event.preventDefault();
|
|
183
|
-
}
|
|
184
|
-
}, [parser, min, max]);
|
|
185
|
-
const _onChange = (0, react_1.useCallback)((event) => {
|
|
186
|
-
const strValue = event.target.value;
|
|
187
|
-
let parsed = clampInputValue(parser.parse(event.target.value));
|
|
188
|
-
if (integersOnly && Number.isInteger(parsed)) {
|
|
189
|
-
parsed = Math.trunc(parsed);
|
|
190
|
-
}
|
|
191
|
-
// NOTE: This is the most important part.
|
|
192
|
-
// We only synchronize values when they are a valid number
|
|
193
|
-
// Otherwise we only update the local string representation and
|
|
194
|
-
// synchronize the value from state when the input is blurred.
|
|
195
|
-
if (canSynchronizeValue(strValue, locale, formatOptions)) {
|
|
196
|
-
updateState({ value: parsed });
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
setValueStrRep(strValue);
|
|
200
|
-
}
|
|
201
|
-
// TODO: this needs to be adjusted based on the number of group separators (no group separators yet)
|
|
202
|
-
onFixCursorPosition(event);
|
|
203
|
-
onDidChange(parsed);
|
|
204
|
-
}, [
|
|
205
|
-
clampInputValue,
|
|
206
|
-
parser,
|
|
207
|
-
onDidChange,
|
|
208
|
-
locale,
|
|
209
|
-
formatOptions,
|
|
210
|
-
onFixCursorPosition,
|
|
211
|
-
updateState,
|
|
212
|
-
integersOnly,
|
|
213
|
-
]);
|
|
214
|
-
const _onFocus = (0, react_1.useCallback)(() => {
|
|
215
|
-
onFocus === null || onFocus === void 0 ? void 0 : onFocus();
|
|
216
|
-
}, [onFocus]);
|
|
217
|
-
const _onBlur = (0, react_1.useCallback)((event) => {
|
|
218
|
-
const value = event.target.value;
|
|
219
|
-
clampAndSaveInput(value);
|
|
220
|
-
onBlur();
|
|
221
|
-
}, [clampAndSaveInput, onBlur]);
|
|
222
|
-
const _onKeyDown = (0, react_1.useCallback)((event) => {
|
|
223
|
-
if (event.key === "Enter") {
|
|
224
|
-
clampAndSaveInput(value);
|
|
225
|
-
}
|
|
226
|
-
if (event.code === "ArrowUp") {
|
|
227
|
-
event.preventDefault();
|
|
228
|
-
increment();
|
|
229
|
-
}
|
|
230
|
-
if (event.code === "ArrowDown") {
|
|
231
|
-
event.preventDefault();
|
|
232
|
-
decrement();
|
|
233
|
-
}
|
|
234
|
-
}, [clampAndSaveInput, increment, decrement, value]);
|
|
235
|
-
// --- Register API events
|
|
236
|
-
const focus = (0, react_1.useCallback)(() => {
|
|
237
|
-
var _a;
|
|
238
|
-
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
239
|
-
}, []);
|
|
240
|
-
(0, react_1.useEffect)(() => {
|
|
241
|
-
if (autoFocus) {
|
|
242
|
-
setTimeout(() => {
|
|
243
|
-
var _a;
|
|
244
|
-
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
245
|
-
}, 0);
|
|
246
|
-
}
|
|
247
|
-
}, [autoFocus]);
|
|
248
|
-
const setValue = (0, misc_1.useEvent)((newValue) => {
|
|
249
|
-
updateState({ value: newValue });
|
|
250
|
-
});
|
|
251
|
-
(0, react_1.useEffect)(() => {
|
|
252
|
-
registerComponentApi === null || registerComponentApi === void 0 ? void 0 : registerComponentApi({
|
|
253
|
-
focus,
|
|
254
|
-
setValue,
|
|
255
|
-
});
|
|
256
|
-
}, [focus, registerComponentApi, setValue]);
|
|
257
|
-
return ((0, jsx_runtime_1.jsx)(ItemWithLabel_1.ItemWithLabel, Object.assign({}, rest, { ref: forwardedRef, labelPosition: labelPosition, label: label, labelWidth: labelWidth, labelBreak: labelBreak, required: required, enabled: enabled, onFocus: onFocus, onBlur: onBlur, style: style, className: className, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(NumberBox_module_scss_1.default.inputRoot, {
|
|
258
|
-
[NumberBox_module_scss_1.default.readOnly]: readOnly,
|
|
259
|
-
[NumberBox_module_scss_1.default.disabled]: !enabled,
|
|
260
|
-
[NumberBox_module_scss_1.default.noSpinBox]: !hasSpinBox,
|
|
261
|
-
[NumberBox_module_scss_1.default.error]: validationStatus === "error",
|
|
262
|
-
[NumberBox_module_scss_1.default.warning]: validationStatus === "warning",
|
|
263
|
-
[NumberBox_module_scss_1.default.valid]: validationStatus === "valid",
|
|
264
|
-
}), tabIndex: -1, onFocus: () => {
|
|
265
|
-
var _a;
|
|
266
|
-
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
267
|
-
}, children: [(0, jsx_runtime_1.jsx)(InputAdornment_1.Adornment, { text: startText, iconName: startIcon, className: NumberBox_module_scss_1.default.adornment }), (0, jsx_runtime_1.jsx)("input", { id: id, ref: inputRef, type: "text", placeholder: placeholder, required: required, readOnly: readOnly, disabled: !enabled, inputMode: inputMode, className: (0, classnames_1.default)(NumberBox_module_scss_1.default.input), value: valueStrRep, min: min, max: max, autoFocus: autoFocus, onBeforeInput: _onBeforeInput, onChange: _onChange, onFocus: _onFocus, onBlur: _onBlur, onKeyDown: _onKeyDown }), (0, jsx_runtime_1.jsx)(InputAdornment_1.Adornment, { text: endText, iconName: endIcon, className: NumberBox_module_scss_1.default.adornment }), hasSpinBox && ((0, jsx_runtime_1.jsxs)("div", { className: NumberBox_module_scss_1.default.spinnerBox, children: [(0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-spinner": "up", type: "button", variant: "ghost", themeColor: "secondary", tabIndex: -1, className: NumberBox_module_scss_1.default.spinnerButton, disabled: !enabled || readOnly, ref: upButton, children: (0, jsx_runtime_1.jsx)(IconNative_1.Icon, { name: spinnerUpIcon || "spinnerUp:NumberBox", fallback: "chevronup", size: "sm" }) }), (0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-spinner": "down", type: "button", tabIndex: -1, variant: "ghost", themeColor: "secondary", className: NumberBox_module_scss_1.default.spinnerButton, disabled: !enabled || readOnly, ref: downButton, children: (0, jsx_runtime_1.jsx)(IconNative_1.Icon, { name: spinnerDownIcon || "spinnerDown:NumberBox", fallback: "chevrondown", size: "sm" }) })] }))] }) })));
|
|
268
|
-
});
|
|
269
|
-
function useNumberFormatter(locale, options) {
|
|
270
|
-
return (0, react_1.useMemo)(() => {
|
|
271
|
-
return new number_1.NumberFormatter(locale, options);
|
|
272
|
-
}, [locale, options]);
|
|
273
|
-
}
|
|
274
|
-
function useNumberParser(locale, options) {
|
|
275
|
-
return (0, react_1.useMemo)(() => {
|
|
276
|
-
return new number_1.NumberParser(locale, options);
|
|
277
|
-
}, [locale, options]);
|
|
278
|
-
}
|
|
279
|
-
function useLongPress(elementRef, action, delay = 500) {
|
|
280
|
-
const timeoutId = (0, react_1.useRef)(0);
|
|
281
|
-
const intervalId = (0, react_1.useRef)(0);
|
|
282
|
-
const savedAction = (0, react_1.useRef)(action);
|
|
283
|
-
// Remember the latest action callback, since it is different every render
|
|
284
|
-
(0, react_1.useEffect)(() => {
|
|
285
|
-
savedAction.current = action;
|
|
286
|
-
}, [action]);
|
|
287
|
-
(0, react_1.useEffect)(() => {
|
|
288
|
-
const onMouseDown = () => {
|
|
289
|
-
var _a;
|
|
290
|
-
(_a = savedAction.current) === null || _a === void 0 ? void 0 : _a.call(savedAction);
|
|
291
|
-
timeoutId.current = window.setTimeout(() => {
|
|
292
|
-
intervalId.current = window.setInterval(() => {
|
|
293
|
-
var _a;
|
|
294
|
-
(_a = savedAction.current) === null || _a === void 0 ? void 0 : _a.call(savedAction);
|
|
295
|
-
}, 100);
|
|
296
|
-
}, delay);
|
|
297
|
-
};
|
|
298
|
-
const onMouseUp = () => {
|
|
299
|
-
clearTimeout(timeoutId.current);
|
|
300
|
-
clearInterval(intervalId.current);
|
|
301
|
-
};
|
|
302
|
-
const onMouseOut = () => {
|
|
303
|
-
clearTimeout(timeoutId.current);
|
|
304
|
-
clearInterval(intervalId.current);
|
|
305
|
-
};
|
|
306
|
-
elementRef === null || elementRef === void 0 ? void 0 : elementRef.addEventListener("mousedown", onMouseDown);
|
|
307
|
-
elementRef === null || elementRef === void 0 ? void 0 : elementRef.addEventListener("mouseup", onMouseUp);
|
|
308
|
-
elementRef === null || elementRef === void 0 ? void 0 : elementRef.addEventListener("mouseout", onMouseOut);
|
|
309
|
-
return () => {
|
|
310
|
-
elementRef === null || elementRef === void 0 ? void 0 : elementRef.removeEventListener("mousedown", onMouseDown);
|
|
311
|
-
elementRef === null || elementRef === void 0 ? void 0 : elementRef.removeEventListener("mouseup", onMouseUp);
|
|
312
|
-
elementRef === null || elementRef === void 0 ? void 0 : elementRef.removeEventListener("mouseout", onMouseOut);
|
|
313
|
-
};
|
|
314
|
-
}, [elementRef, action, delay]);
|
|
315
|
-
}
|
|
316
|
-
function handleChangingValue(value, parser, type, step = 1, min = -numberbox_abstractions_1.NUMBERBOX_MAX_VALUE, max = numberbox_abstractions_1.NUMBERBOX_MAX_VALUE) {
|
|
317
|
-
const currentInputValue = parser.parse(value !== null && value !== void 0 ? value : "");
|
|
318
|
-
if ((0, lodash_es_1.isNaN)(currentInputValue)) {
|
|
319
|
-
return min !== null && min !== void 0 ? min : 0;
|
|
320
|
-
}
|
|
321
|
-
if (type === "increase") {
|
|
322
|
-
return (0, numberbox_abstractions_1.clamp)(currentInputValue + (step !== null && step !== void 0 ? step : 1), min, max);
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
return (0, numberbox_abstractions_1.clamp)(currentInputValue - (step !== null && step !== void 0 ? step : 1), min, max);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
function canSynchronizeValue(value, locale, options) {
|
|
329
|
-
if (value.trim() === "")
|
|
330
|
-
return true;
|
|
331
|
-
if ((0, lodash_es_1.isNaN)(value))
|
|
332
|
-
return false;
|
|
333
|
-
if (hasLeadingZeros(value, locale, options))
|
|
334
|
-
return false;
|
|
335
|
-
if (isFloatWithTrailingZeros(value, locale, options))
|
|
336
|
-
return false;
|
|
337
|
-
if (overMaximumFractionDigits(value, locale, options))
|
|
338
|
-
return false;
|
|
339
|
-
return true;
|
|
340
|
-
}
|
|
341
|
-
function hasLeadingZeros(input, locale = "en-US", options) {
|
|
342
|
-
var _a, _b;
|
|
343
|
-
// Create a formatter to detect locale-specific separators
|
|
344
|
-
const formatter = new Intl.NumberFormat(locale, options);
|
|
345
|
-
const parts = formatter.formatToParts(1234.5);
|
|
346
|
-
const group = ((_a = parts.find((p) => p.type === "group")) === null || _a === void 0 ? void 0 : _a.value) || "";
|
|
347
|
-
const decimal = ((_b = parts.find((p) => p.type === "decimal")) === null || _b === void 0 ? void 0 : _b.value) || "";
|
|
348
|
-
// Normalize separators for parsing
|
|
349
|
-
const normalized = (group === "" ? input : input.replace(new RegExp(`\\${group}`, "g"), "")).replace(decimal, ".");
|
|
350
|
-
if (!/^-?\d*\.?\d*$/.test(normalized))
|
|
351
|
-
return false;
|
|
352
|
-
const [integer, fraction] = normalized.split(".");
|
|
353
|
-
// Integer validation
|
|
354
|
-
if (!fraction) {
|
|
355
|
-
return integer.length > 1 && integer.startsWith("0");
|
|
356
|
-
}
|
|
357
|
-
// Float validation
|
|
358
|
-
const leadingIntegerZeros = integer.startsWith("0") && integer.length >= 1;
|
|
359
|
-
const leadingFractionZeros = (fraction.match(/^0+/) || [""])[0].length >= 2;
|
|
360
|
-
return leadingIntegerZeros || leadingFractionZeros;
|
|
361
|
-
}
|
|
362
|
-
function isFloatWithTrailingZeros(input, locale = "en-US", options) {
|
|
363
|
-
var _a, _b;
|
|
364
|
-
// Create formatter to detect locale-specific separators
|
|
365
|
-
const formatter = new Intl.NumberFormat(locale, options);
|
|
366
|
-
const parts = formatter.formatToParts(1234.5);
|
|
367
|
-
const group = ((_a = parts.find((p) => p.type === "group")) === null || _a === void 0 ? void 0 : _a.value) || "";
|
|
368
|
-
const decimal = ((_b = parts.find((p) => p.type === "decimal")) === null || _b === void 0 ? void 0 : _b.value) || ".";
|
|
369
|
-
// Normalize separators for parsing
|
|
370
|
-
const normalized = (group === "" ? input : input.replace(new RegExp(`\\${group}`, "g"), "")).replace(decimal, ".");
|
|
371
|
-
// Validate numeric format
|
|
372
|
-
if (!/^-?\d*\.?\d*$/.test(normalized))
|
|
373
|
-
return false;
|
|
374
|
-
// Check if it's a float (has decimal point)
|
|
375
|
-
if (!normalized.includes("."))
|
|
376
|
-
return false;
|
|
377
|
-
// Split into integer and fractional parts
|
|
378
|
-
const [_, fraction] = normalized.split(".");
|
|
379
|
-
// Must have fractional digits to be a float -> integers get a pass
|
|
380
|
-
if (!fraction || fraction.length === 0)
|
|
381
|
-
return true;
|
|
382
|
-
// Check for trailing zeros in the fractional part
|
|
383
|
-
return /0+$/.test(fraction);
|
|
384
|
-
}
|
|
385
|
-
function overMaximumFractionDigits(input, locale = "en-US", options) {
|
|
386
|
-
var _a, _b;
|
|
387
|
-
// Create a formatter to detect locale-specific separators
|
|
388
|
-
const formatter = new Intl.NumberFormat(locale, options);
|
|
389
|
-
const parts = formatter.formatToParts(1234.5);
|
|
390
|
-
const group = ((_a = parts.find((p) => p.type === "group")) === null || _a === void 0 ? void 0 : _a.value) || "";
|
|
391
|
-
const decimal = ((_b = parts.find((p) => p.type === "decimal")) === null || _b === void 0 ? void 0 : _b.value) || "";
|
|
392
|
-
// Normalize separators for parsing
|
|
393
|
-
const normalized = (group === "" ? input : input.replace(new RegExp(`\\${group}`, "g"), "")).replace(decimal, ".");
|
|
394
|
-
if (!/^-?\d*\.?\d*$/.test(normalized))
|
|
395
|
-
return false;
|
|
396
|
-
const [_, fraction] = normalized.split(".");
|
|
397
|
-
// Integer validation
|
|
398
|
-
if (!fraction) {
|
|
399
|
-
return false;
|
|
400
|
-
}
|
|
401
|
-
// Float validation
|
|
402
|
-
return fraction.length > options.maximumFractionDigits;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Solution comes from: https://giacomocerquone.com/blog/keep-input-cursor-still/
|
|
406
|
-
*/
|
|
407
|
-
function useCursorCorrection(value, inputRef) {
|
|
408
|
-
const position = (0, react_1.useRef)({
|
|
409
|
-
beforeStart: 0,
|
|
410
|
-
beforeEnd: 0,
|
|
411
|
-
});
|
|
412
|
-
(0, react_1.useLayoutEffect)(() => {
|
|
413
|
-
inputRef.current.setSelectionRange(position.current.beforeStart, position.current.beforeEnd);
|
|
414
|
-
}, [value]);
|
|
415
|
-
const onInputChange = (event) => {
|
|
416
|
-
position.current.beforeStart = event.target.selectionStart;
|
|
417
|
-
position.current.beforeEnd = event.target.selectionEnd;
|
|
418
|
-
};
|
|
419
|
-
return onInputChange;
|
|
420
|
-
}
|