Uecko_ERP/packages/rdx-ui/src/components/form/decimal-field/decimal-field.utils.ts
2026-04-13 13:05:00 +02:00

67 lines
1.6 KiB
TypeScript

export const DECIMAL_INPUT_PATTERN = /^-?\d*([.,]\d*)?$/;
export const normalizeDecimalInput = (value: string): string => {
return value.replace(",", ".");
};
export const trimToScale = (value: string, scale: number): string => {
const normalized = normalizeDecimalInput(value);
if (!normalized.includes(".")) {
return normalized;
}
const [integerPart, decimalPart = ""] = normalized.split(".");
return `${integerPart}.${decimalPart.slice(0, scale)}`;
};
export const parseDecimalOrNull = (value: string): number | null => {
const normalized = normalizeDecimalInput(value).trim();
if (normalized === "") {
return null;
}
if (normalized === "-" || normalized === "." || normalized === "-.") {
return null;
}
const parsed = Number(normalized);
if (!Number.isFinite(parsed)) {
return null;
}
return parsed;
};
export const clampNumber = (value: number, min?: number, max?: number): number => {
if (typeof min === "number" && value < min) {
return min;
}
if (typeof max === "number" && value > max) {
return max;
}
return value;
};
export const formatDecimalValue = (value: number | null | undefined, scale: number): string => {
if (value === null || value === undefined || Number.isNaN(value)) {
return "";
}
const asString = String(value);
if (!asString.includes(".")) {
return asString;
}
const [integerPart, decimalPart = ""] = asString.split(".");
const trimmedDecimalPart = decimalPart.slice(0, scale).replace(/0+$/, "");
return trimmedDecimalPart.length > 0 ? `${integerPart}.${trimmedDecimalPart}` : `${integerPart}`;
};