@sustaina/shared-ui 1.53.0 → 1.54.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.
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +213 -51
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +213 -51
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -15815,8 +15815,11 @@ var Input2 = React.forwardRef(
|
|
|
15815
15815
|
}
|
|
15816
15816
|
);
|
|
15817
15817
|
Input2.displayName = "Input";
|
|
15818
|
-
|
|
15819
|
-
|
|
15818
|
+
|
|
15819
|
+
// src/components/inputNumber/helper.ts
|
|
15820
|
+
var createSourceInfo = (event) => ({
|
|
15821
|
+
event,
|
|
15822
|
+
source: event ? "event" : "prop"
|
|
15820
15823
|
});
|
|
15821
15824
|
var parseToNumber = (val) => {
|
|
15822
15825
|
if (typeof val === "number") return val;
|
|
@@ -15826,6 +15829,112 @@ var parseToNumber = (val) => {
|
|
|
15826
15829
|
}
|
|
15827
15830
|
return void 0;
|
|
15828
15831
|
};
|
|
15832
|
+
var truncateToFixed = (num, scale) => {
|
|
15833
|
+
if (scale === 0) return Math.trunc(num).toString();
|
|
15834
|
+
const sign = num < 0 ? "-" : "";
|
|
15835
|
+
const abs = Math.abs(num);
|
|
15836
|
+
const str = abs.toString();
|
|
15837
|
+
const dotIndex = str.indexOf(".");
|
|
15838
|
+
let intPart;
|
|
15839
|
+
let fracPart;
|
|
15840
|
+
if (dotIndex === -1) {
|
|
15841
|
+
intPart = str;
|
|
15842
|
+
fracPart = "";
|
|
15843
|
+
} else {
|
|
15844
|
+
intPart = str.slice(0, dotIndex);
|
|
15845
|
+
fracPart = str.slice(dotIndex + 1, dotIndex + 1 + scale);
|
|
15846
|
+
}
|
|
15847
|
+
fracPart = fracPart.padEnd(scale, "0");
|
|
15848
|
+
return `${sign}${intPart}.${fracPart}`;
|
|
15849
|
+
};
|
|
15850
|
+
var truncateStringToFixed = (str, scale) => {
|
|
15851
|
+
const trimmed = str.trim();
|
|
15852
|
+
if (trimmed === "" || trimmed === "-") return "0" + (scale > 0 ? "." + "0".repeat(scale) : "");
|
|
15853
|
+
const negative = trimmed.startsWith("-");
|
|
15854
|
+
const unsigned = negative ? trimmed.slice(1) : trimmed;
|
|
15855
|
+
const dotIndex = unsigned.indexOf(".");
|
|
15856
|
+
let intPart;
|
|
15857
|
+
let fracPart;
|
|
15858
|
+
if (dotIndex === -1) {
|
|
15859
|
+
intPart = unsigned || "0";
|
|
15860
|
+
fracPart = "";
|
|
15861
|
+
} else {
|
|
15862
|
+
intPart = unsigned.slice(0, dotIndex) || "0";
|
|
15863
|
+
fracPart = unsigned.slice(dotIndex + 1, dotIndex + 1 + scale);
|
|
15864
|
+
}
|
|
15865
|
+
if (scale === 0) return (negative ? "-" : "") + intPart;
|
|
15866
|
+
fracPart = fracPart.padEnd(scale, "0");
|
|
15867
|
+
return (negative ? "-" : "") + intPart + "." + fracPart;
|
|
15868
|
+
};
|
|
15869
|
+
var clamp = (value, min, max) => {
|
|
15870
|
+
if (max !== void 0 && value > max) return max;
|
|
15871
|
+
if (min !== void 0 && value < min) return min;
|
|
15872
|
+
return value;
|
|
15873
|
+
};
|
|
15874
|
+
function useAutoFormatDecimal({
|
|
15875
|
+
enabled,
|
|
15876
|
+
decimalScale,
|
|
15877
|
+
value,
|
|
15878
|
+
defaultValue
|
|
15879
|
+
}) {
|
|
15880
|
+
const blurScale = enabled ? decimalScale ?? 2 : void 0;
|
|
15881
|
+
const isUserEditingRef = React.useRef(false);
|
|
15882
|
+
const [formattedValue, setFormattedValue] = React.useState(() => {
|
|
15883
|
+
if (!enabled) return void 0;
|
|
15884
|
+
const scale = decimalScale ?? 2;
|
|
15885
|
+
const initial = parseToNumber(value) ?? parseToNumber(defaultValue);
|
|
15886
|
+
if (initial !== void 0) return truncateToFixed(initial, scale);
|
|
15887
|
+
return void 0;
|
|
15888
|
+
});
|
|
15889
|
+
React.useEffect(() => {
|
|
15890
|
+
if (!enabled) return;
|
|
15891
|
+
const parsed = parseToNumber(value);
|
|
15892
|
+
if (parsed !== void 0) {
|
|
15893
|
+
if (blurScale !== void 0 && !isUserEditingRef.current) {
|
|
15894
|
+
setFormattedValue(truncateToFixed(parsed, blurScale));
|
|
15895
|
+
}
|
|
15896
|
+
} else if (value === void 0 || value === null || value === "") {
|
|
15897
|
+
setFormattedValue(void 0);
|
|
15898
|
+
}
|
|
15899
|
+
}, [value, enabled, blurScale]);
|
|
15900
|
+
const onEdit = React.useCallback(
|
|
15901
|
+
(values, sourceInfo) => {
|
|
15902
|
+
if (!enabled || sourceInfo.source !== "event") return;
|
|
15903
|
+
isUserEditingRef.current = true;
|
|
15904
|
+
setFormattedValue(values.value || void 0);
|
|
15905
|
+
},
|
|
15906
|
+
[enabled]
|
|
15907
|
+
);
|
|
15908
|
+
const onBlur = React.useCallback(
|
|
15909
|
+
(truncatedStr) => {
|
|
15910
|
+
isUserEditingRef.current = false;
|
|
15911
|
+
if (!enabled || blurScale === void 0) return;
|
|
15912
|
+
setFormattedValue(truncatedStr);
|
|
15913
|
+
},
|
|
15914
|
+
[enabled, blurScale]
|
|
15915
|
+
);
|
|
15916
|
+
const resetEditing = React.useCallback(() => {
|
|
15917
|
+
isUserEditingRef.current = false;
|
|
15918
|
+
}, []);
|
|
15919
|
+
return { formattedValue, blurScale, onEdit, onBlur, resetEditing, setFormattedValue };
|
|
15920
|
+
}
|
|
15921
|
+
function useStepper({ value, step, min, max, disabled, onStep }) {
|
|
15922
|
+
const [changed, setChanged] = React.useState(false);
|
|
15923
|
+
const changeValue = React.useCallback(
|
|
15924
|
+
(delta) => {
|
|
15925
|
+
const current = value ?? 0;
|
|
15926
|
+
const clamped = clamp(current + delta, min, max);
|
|
15927
|
+
setChanged(true);
|
|
15928
|
+
onStep(clamped);
|
|
15929
|
+
},
|
|
15930
|
+
[value, max, min, onStep]
|
|
15931
|
+
);
|
|
15932
|
+
const increment = React.useCallback(() => changeValue(step), [changeValue, step]);
|
|
15933
|
+
const decrement = React.useCallback(() => changeValue(-step), [changeValue, step]);
|
|
15934
|
+
const isIncrementDisabled = disabled || max !== void 0 && (value ?? 0) >= max;
|
|
15935
|
+
const isDecrementDisabled = disabled || min !== void 0 && (value ?? 0) <= min;
|
|
15936
|
+
return { changed, increment, decrement, isIncrementDisabled, isDecrementDisabled };
|
|
15937
|
+
}
|
|
15829
15938
|
var InputNumber = ({
|
|
15830
15939
|
customInputProps,
|
|
15831
15940
|
showStepper = false,
|
|
@@ -15838,58 +15947,106 @@ var InputNumber = ({
|
|
|
15838
15947
|
defaultValue,
|
|
15839
15948
|
disabled,
|
|
15840
15949
|
onBlur,
|
|
15950
|
+
isAllowed: isAllowedProp,
|
|
15951
|
+
autoFormatDecimal = false,
|
|
15952
|
+
decimalScale: decimalScaleProp,
|
|
15953
|
+
fixedDecimalScale: fixedDecimalScaleProp,
|
|
15841
15954
|
...props
|
|
15842
15955
|
}) => {
|
|
15843
15956
|
const [internalValue, setInternalValue] = React.useState(
|
|
15844
15957
|
() => parseToNumber(value) ?? parseToNumber(defaultValue)
|
|
15845
15958
|
);
|
|
15846
|
-
const
|
|
15959
|
+
const internalValueRef = React.useRef(internalValue);
|
|
15960
|
+
const rawValueRef = React.useRef("");
|
|
15961
|
+
const isBlurClampedRef = React.useRef(false);
|
|
15847
15962
|
React.useEffect(() => {
|
|
15848
15963
|
const parsed = parseToNumber(value);
|
|
15849
|
-
if (parsed !== void 0)
|
|
15964
|
+
if (parsed !== void 0) {
|
|
15965
|
+
internalValueRef.current = parsed;
|
|
15966
|
+
setInternalValue(parsed);
|
|
15967
|
+
}
|
|
15968
|
+
isBlurClampedRef.current = false;
|
|
15850
15969
|
}, [value]);
|
|
15851
|
-
const
|
|
15852
|
-
|
|
15853
|
-
|
|
15854
|
-
|
|
15855
|
-
|
|
15856
|
-
|
|
15857
|
-
|
|
15970
|
+
const autoFormat = useAutoFormatDecimal({
|
|
15971
|
+
enabled: autoFormatDecimal,
|
|
15972
|
+
decimalScale: decimalScaleProp,
|
|
15973
|
+
value,
|
|
15974
|
+
defaultValue
|
|
15975
|
+
});
|
|
15976
|
+
const notifyChange = React.useCallback(
|
|
15977
|
+
(newValue, event) => {
|
|
15978
|
+
internalValueRef.current = newValue;
|
|
15979
|
+
setInternalValue(newValue);
|
|
15980
|
+
onStepChange?.(newValue);
|
|
15981
|
+
onValueChange?.(
|
|
15982
|
+
{ floatValue: newValue, formattedValue: String(newValue), value: String(newValue) },
|
|
15983
|
+
createSourceInfo(event)
|
|
15984
|
+
);
|
|
15985
|
+
},
|
|
15986
|
+
[onStepChange, onValueChange]
|
|
15987
|
+
);
|
|
15988
|
+
const stepper = useStepper({
|
|
15989
|
+
value: internalValue,
|
|
15990
|
+
step,
|
|
15991
|
+
min,
|
|
15992
|
+
max,
|
|
15993
|
+
disabled,
|
|
15994
|
+
onStep: React.useCallback(
|
|
15995
|
+
(clamped) => {
|
|
15996
|
+
setInternalValue(clamped);
|
|
15997
|
+
if (autoFormat.blurScale !== void 0) {
|
|
15998
|
+
autoFormat.setFormattedValue(truncateToFixed(clamped, autoFormat.blurScale));
|
|
15999
|
+
}
|
|
16000
|
+
notifyChange(clamped);
|
|
15858
16001
|
},
|
|
15859
|
-
|
|
15860
|
-
)
|
|
15861
|
-
};
|
|
15862
|
-
const handleValueChange = (
|
|
15863
|
-
|
|
15864
|
-
|
|
15865
|
-
|
|
15866
|
-
|
|
15867
|
-
|
|
15868
|
-
|
|
15869
|
-
|
|
15870
|
-
|
|
15871
|
-
|
|
15872
|
-
|
|
15873
|
-
|
|
15874
|
-
|
|
15875
|
-
|
|
15876
|
-
|
|
15877
|
-
|
|
15878
|
-
|
|
15879
|
-
|
|
15880
|
-
|
|
15881
|
-
|
|
15882
|
-
|
|
15883
|
-
|
|
15884
|
-
|
|
15885
|
-
|
|
15886
|
-
|
|
15887
|
-
|
|
15888
|
-
|
|
15889
|
-
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
16002
|
+
[autoFormat, notifyChange]
|
|
16003
|
+
)
|
|
16004
|
+
});
|
|
16005
|
+
const handleValueChange = React.useCallback(
|
|
16006
|
+
(values, sourceInfo) => {
|
|
16007
|
+
internalValueRef.current = values.floatValue;
|
|
16008
|
+
rawValueRef.current = values.value;
|
|
16009
|
+
setInternalValue(values.floatValue);
|
|
16010
|
+
if (sourceInfo.source === "event") {
|
|
16011
|
+
isBlurClampedRef.current = false;
|
|
16012
|
+
}
|
|
16013
|
+
onValueChange?.(values, sourceInfo);
|
|
16014
|
+
if (values.floatValue !== void 0) onStepChange?.(values.floatValue);
|
|
16015
|
+
autoFormat.onEdit(values, sourceInfo);
|
|
16016
|
+
},
|
|
16017
|
+
[onValueChange, onStepChange, autoFormat]
|
|
16018
|
+
);
|
|
16019
|
+
const handleBlur = React.useCallback(
|
|
16020
|
+
(event) => {
|
|
16021
|
+
onBlur?.(event);
|
|
16022
|
+
const latestValue = internalValueRef.current;
|
|
16023
|
+
if (latestValue === void 0) {
|
|
16024
|
+
autoFormat.resetEditing();
|
|
16025
|
+
return;
|
|
16026
|
+
}
|
|
16027
|
+
const clamped = clamp(latestValue, min, max);
|
|
16028
|
+
const wasClamped = clamped !== latestValue;
|
|
16029
|
+
if (wasClamped) {
|
|
16030
|
+
isBlurClampedRef.current = true;
|
|
16031
|
+
internalValueRef.current = clamped;
|
|
16032
|
+
rawValueRef.current = String(clamped);
|
|
16033
|
+
setInternalValue(clamped);
|
|
16034
|
+
onValueChange?.(
|
|
16035
|
+
{ floatValue: clamped, formattedValue: String(clamped), value: String(clamped) },
|
|
16036
|
+
createSourceInfo()
|
|
16037
|
+
);
|
|
16038
|
+
onStepChange?.(clamped);
|
|
16039
|
+
}
|
|
16040
|
+
if (autoFormatDecimal && autoFormat.blurScale !== void 0) {
|
|
16041
|
+
const rawStr = wasClamped ? String(clamped) : rawValueRef.current || "0";
|
|
16042
|
+
autoFormat.onBlur(truncateStringToFixed(rawStr, autoFormat.blurScale));
|
|
16043
|
+
} else {
|
|
16044
|
+
autoFormat.resetEditing();
|
|
16045
|
+
}
|
|
16046
|
+
},
|
|
16047
|
+
[onBlur, autoFormatDecimal, autoFormat, min, max, onValueChange, onStepChange]
|
|
16048
|
+
);
|
|
16049
|
+
const effectiveValue = autoFormat.formattedValue !== void 0 ? autoFormat.formattedValue : isBlurClampedRef.current || stepper.changed || autoFormatDecimal ? internalValue : value;
|
|
15893
16050
|
const buttonClass = cn(
|
|
15894
16051
|
"flex items-center justify-center h-3 w-5 transition-colors outline-none",
|
|
15895
16052
|
"text-neutral-400 hover:text-neutral-600 active:text-neutral-900",
|
|
@@ -15899,11 +16056,16 @@ var InputNumber = ({
|
|
|
15899
16056
|
NumericFormat,
|
|
15900
16057
|
{
|
|
15901
16058
|
customInput: Input2,
|
|
15902
|
-
value:
|
|
16059
|
+
value: effectiveValue?.toString(),
|
|
15903
16060
|
defaultValue,
|
|
15904
16061
|
onValueChange: handleValueChange,
|
|
15905
16062
|
onBlur: handleBlur,
|
|
15906
|
-
isAllowed,
|
|
16063
|
+
...isAllowedProp && { isAllowed: isAllowedProp },
|
|
16064
|
+
...!autoFormatDecimal && {
|
|
16065
|
+
decimalScale: decimalScaleProp,
|
|
16066
|
+
fixedDecimalScale: fixedDecimalScaleProp
|
|
16067
|
+
},
|
|
16068
|
+
...autoFormat.formattedValue !== void 0 && { valueIsNumericString: true },
|
|
15907
16069
|
...props,
|
|
15908
16070
|
disabled,
|
|
15909
16071
|
...customInputProps,
|
|
@@ -15912,8 +16074,8 @@ var InputNumber = ({
|
|
|
15912
16074
|
"button",
|
|
15913
16075
|
{
|
|
15914
16076
|
type: "button",
|
|
15915
|
-
onClick:
|
|
15916
|
-
disabled: isIncrementDisabled,
|
|
16077
|
+
onClick: stepper.increment,
|
|
16078
|
+
disabled: stepper.isIncrementDisabled,
|
|
15917
16079
|
className: buttonClass,
|
|
15918
16080
|
tabIndex: -1,
|
|
15919
16081
|
"aria-label": "Increment",
|
|
@@ -15924,8 +16086,8 @@ var InputNumber = ({
|
|
|
15924
16086
|
"button",
|
|
15925
16087
|
{
|
|
15926
16088
|
type: "button",
|
|
15927
|
-
onClick:
|
|
15928
|
-
disabled: isDecrementDisabled,
|
|
16089
|
+
onClick: stepper.decrement,
|
|
16090
|
+
disabled: stepper.isDecrementDisabled,
|
|
15929
16091
|
className: buttonClass,
|
|
15930
16092
|
tabIndex: -1,
|
|
15931
16093
|
"aria-label": "Decrement",
|