src/lib/decimal-entry.ts
Rama main · réplica de lectura del repositorio original.
// A number as a person types it, on whichever keyboard their phone shows.
//
// iOS's decimal keypad types the separator of the device's region, so half of
// Europe gets a comma and no point. A `type="number"` field drops that comma in
// WebKit - "1,5" arrives as 15 - which is why a touch device enters these
// numbers as text, and why the text is read here with either separator.
const DECIMAL = /^[+-]?(?:\d+\.?\d*|\.\d+)$/;
/**
* The number in `text`, written with a point or a comma before its decimals, or
* `NaN` when it is not one - including when it carries both, which is a
* thousands separator and a guess this does not make.
*/
export function parseDecimal(text: string): number {
const trimmed = text.trim();
if (trimmed.includes(".") && trimmed.includes(",")) return NaN;
const normalized = trimmed.replace(",", ".");
return DECIMAL.test(normalized) ? Number(normalized) : NaN;
}
/**
* What is wrong with `text` as a number between `min` and `max`, in the words a
* form shows under its field, or `""` when nothing is - an empty box included,
* which is a required check's business rather than this one's.
*/
export function decimalEntryMessage(
text: string,
min?: number,
max?: number,
): string {
if (text.trim() === "") return "";
const value = parseDecimal(text);
if (Number.isNaN(value)) return "Enter a number.";
if (min != null && value < min) return `Enter ${min} or more.`;
if (max != null && value > max) return `Enter ${max} or less.`;
return "";
}