@homebound/beam 2.101.4 → 2.101.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.
|
@@ -19,6 +19,8 @@ export interface NumberFieldProps {
|
|
|
19
19
|
/** Styles overrides */
|
|
20
20
|
xss?: Xss<"textAlign" | "justifyContent">;
|
|
21
21
|
displayDirection?: boolean;
|
|
22
|
+
numFractionDigits?: number;
|
|
23
|
+
truncate?: boolean;
|
|
22
24
|
}
|
|
23
25
|
export declare function NumberField(props: NumberFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
24
|
-
export declare function
|
|
26
|
+
export declare function formatValue(value: number, factor: number, numFractionDigits: number | undefined): number | undefined;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.formatValue = exports.NumberField = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const number_1 = require("@internationalized/number");
|
|
5
6
|
const react_1 = require("react");
|
|
6
7
|
const react_aria_1 = require("react-aria");
|
|
7
8
|
const react_stately_1 = require("react-stately");
|
|
@@ -12,34 +13,34 @@ function NumberField(props) {
|
|
|
12
13
|
// Determine default alignment based on presentation context
|
|
13
14
|
const { fieldProps } = (0, PresentationContext_1.usePresentationContext)();
|
|
14
15
|
const alignment = (fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.numberAlignment) === "right" ? Css_1.Css.tr.jcfe.$ : Css_1.Css.tl.jcfs.$;
|
|
15
|
-
const { disabled = false, required, readOnly = false, type, label, onBlur, onFocus, errorMsg, helperText, value, onChange, xss, displayDirection = false, ...otherProps } = props;
|
|
16
|
+
const { disabled = false, required, readOnly = false, type, label, onBlur, onFocus, errorMsg, helperText, value, onChange, xss, displayDirection = false, numFractionDigits, truncate = false, ...otherProps } = props;
|
|
16
17
|
const factor = type === "percent" || type === "cents" ? 100 : type === "basisPoints" ? 10000 : 1;
|
|
17
18
|
const signDisplay = displayDirection ? "exceptZero" : "auto";
|
|
19
|
+
const fractionFormatOptions = { [truncate ? "maximumFractionDigits" : "minimumFractionDigits"]: numFractionDigits };
|
|
20
|
+
const { locale } = (0, react_aria_1.useLocale)();
|
|
18
21
|
// If formatOptions isn't memo'd, a useEffect in useNumberStateField will cause jank,
|
|
19
22
|
// see: https://github.com/adobe/react-spectrum/issues/1893.
|
|
20
23
|
const formatOptions = (0, react_1.useMemo)(() => {
|
|
21
24
|
return type === "percent"
|
|
22
|
-
? { style: "percent", signDisplay }
|
|
25
|
+
? { style: "percent", signDisplay, ...fractionFormatOptions }
|
|
23
26
|
: type === "basisPoints"
|
|
24
27
|
? { style: "percent", minimumFractionDigits: 2, signDisplay }
|
|
25
28
|
: type === "cents"
|
|
26
29
|
? { style: "currency", currency: "USD", minimumFractionDigits: 2, signDisplay }
|
|
27
30
|
: type === "days"
|
|
28
31
|
? { style: "unit", unit: "day", unitDisplay: "long", maximumFractionDigits: 0, signDisplay }
|
|
29
|
-
:
|
|
32
|
+
: fractionFormatOptions;
|
|
30
33
|
}, [type]);
|
|
34
|
+
const numberParser = (0, react_1.useMemo)(() => new number_1.NumberParser(locale, formatOptions), [locale, formatOptions]);
|
|
31
35
|
const valueRef = (0, react_1.useRef)({ wip: false });
|
|
32
|
-
const { locale } = (0, react_aria_1.useLocale)();
|
|
33
36
|
// We can use this for both useNumberFieldState + useNumberField
|
|
34
37
|
const useProps = {
|
|
35
38
|
locale,
|
|
36
39
|
// We want percents && cents to be integers, useNumberFieldState excepts them as decimals
|
|
37
40
|
value: valueRef.current.wip ? valueRef.current.value : value === undefined ? Number.NaN : value / factor,
|
|
38
|
-
// This is called on blur with the final/committed value.
|
|
41
|
+
// // This is called on blur with the final/committed value.
|
|
39
42
|
onChange: (value) => {
|
|
40
|
-
|
|
41
|
-
// Reverse the integer/decimal conversion
|
|
42
|
-
onChange(Number.isNaN(value) ? undefined : factor !== 1 ? Math.round(value * factor) : value);
|
|
43
|
+
onChange(formatValue(value, factor, numFractionDigits));
|
|
43
44
|
},
|
|
44
45
|
onFocus: () => {
|
|
45
46
|
valueRef.current = { wip: true, value: value === undefined ? Number.NaN : value / factor };
|
|
@@ -71,20 +72,17 @@ function NumberField(props) {
|
|
|
71
72
|
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({ xss: { ...alignment, ...xss }, groupProps: groupProps, labelProps: labelProps, label: label, required: required, inputProps: inputProps,
|
|
72
73
|
// This is called on each DOM change, to push the latest value into the field
|
|
73
74
|
onChange: (rawInputValue) => {
|
|
74
|
-
const
|
|
75
|
-
onChange(
|
|
75
|
+
const parsedValue = numberParser.parse(rawInputValue || "");
|
|
76
|
+
onChange(formatValue(parsedValue, factor, numFractionDigits));
|
|
76
77
|
}, inputRef: inputRef, onBlur: onBlur, onFocus: onFocus, errorMsg: errorMsg, helperText: helperText, readOnly: readOnly }, otherProps), void 0));
|
|
77
78
|
}
|
|
78
79
|
exports.NumberField = NumberField;
|
|
79
|
-
function
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
const value = type === "percent" || type === "basisPoints" ? wip / 100 : wip;
|
|
87
|
-
// Since the values returned is exactly what is in the field
|
|
88
|
-
return factor !== 1 ? Math.round(value * factor) : value;
|
|
80
|
+
function formatValue(value, factor, numFractionDigits) {
|
|
81
|
+
// We treat percents & cents as (mostly) integers, while useNumberField wants decimals, so
|
|
82
|
+
// undo that via `* factor` and `Math.round`, but also keep any specifically-requested `numFractionDigits`,
|
|
83
|
+
// i.e. for `type=percent value=12.34`, `value` will be `0.1234` that we want turn into `12.34`.
|
|
84
|
+
const maybeAdjustForDecimals = numFractionDigits ? Math.pow(10, numFractionDigits) : 1;
|
|
85
|
+
// Reverse the integer/decimal conversion
|
|
86
|
+
return Number.isNaN(value) ? undefined : Math.round(value * factor * maybeAdjustForDecimals) / maybeAdjustForDecimals;
|
|
89
87
|
}
|
|
90
|
-
exports.
|
|
88
|
+
exports.formatValue = formatValue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homebound/beam",
|
|
3
|
-
"version": "2.101.
|
|
3
|
+
"version": "2.101.5",
|
|
4
4
|
"author": "Homebound",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@homebound/form-state": "^2.2.13",
|
|
37
|
+
"@internationalized/number": "^3.0.3",
|
|
37
38
|
"@react-aria/utils": "^3.9.0",
|
|
38
39
|
"@react-hook/resize-observer": "^1.2.2",
|
|
39
40
|
"@types/tinycolor2": "^1.4.2",
|