raqam 0.4.1 → 0.4.2
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/README.md +3 -1
- package/dist/chunk-NIPT3LT6.js +2 -0
- package/dist/chunk-NIPT3LT6.js.map +1 -0
- package/dist/chunk-PM3EDICU.cjs +2 -0
- package/dist/chunk-PM3EDICU.cjs.map +1 -0
- package/dist/chunk-XCKMM244.cjs +2 -0
- package/dist/chunk-XCKMM244.cjs.map +1 -0
- package/dist/chunk-YKK5OGE4.js +2 -0
- package/dist/chunk-YKK5OGE4.js.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.d.cts +49 -49
- package/dist/core.d.ts +49 -49
- package/dist/core.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -1
- package/dist/locales/index.d.cts +1 -1
- package/dist/locales/index.d.ts +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.d.cts +62 -63
- package/dist/react.d.ts +62 -63
- package/dist/react.js +1 -1
- package/package.json +30 -30
- package/dist/chunk-4BC3KFIL.js +0 -2
- package/dist/chunk-4BC3KFIL.js.map +0 -1
- package/dist/chunk-7D2IPNCM.cjs +0 -2
- package/dist/chunk-7D2IPNCM.cjs.map +0 -1
- package/dist/chunk-SQWLQ664.js +0 -2
- package/dist/chunk-SQWLQ664.js.map +0 -1
- package/dist/chunk-UUHQOMSX.cjs +0 -2
- package/dist/chunk-UUHQOMSX.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/cursor.ts","../src/core/formatter.ts","../src/core/parser.ts"],"names":["isAccepted","ch","info","countAcceptedBefore","str","cursor","count","i","getCaretBoundary","formattedValue","len","boundary","computeNewCursorPosition","oldInput","oldCursor","newFormatted","inputType","normalised","normalizeDigits","acceptedCount","before","minusBeforeCaret","newHasMinus","normNew","pos","snapToBoundary","warnedInvalidOptions","warnInvalidFormatOptions","err","FORMATTER_CACHE_MAX","formatterCache","getFormatter","locale","options","key","cached","fmt","oldest","extractLocaleInfo","styledFmt","probeFmt","parts","decimalSeparator","groupingSeparator","minusSign","zero","part","rtlLocales","resolvedLocale","isRTL","resolveEffectiveFractions","opts","allowDecimal","createFormatter","intlOptions","intlFmt","cachedLocaleInfo","getLocaleInfo","formatToParts","value","result","format","formatted","formatResult","MAX_PARSE_INPUT","isIntermediateStripped","stripped","createParser","allowNegative","isPercent","currencySymbol","p","exponentSeparator","notation","sep","stripAffordances","raw","s","accountingMatch","st","sci","negative","parse","input","n","isIntermediate"],"mappings":"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","file":"chunk-PM3EDICU.cjs","sourcesContent":["import { normalizeDigits } from \"./normalizer.js\";\nimport type { CaretBoundary, LocaleInfo } from \"./types.js\";\n\n// ── Accepted-character helpers ────────────────────────────────────────────────\n\n/**\n * Returns true if `ch` is an \"accepted\" character — one that the user typed\n * intentionally and that contributes to the numeric value:\n * - ASCII digit 0-9\n * - The locale decimal separator\n * - The locale minus sign\n */\nfunction isAccepted(ch: string, info: LocaleInfo): boolean {\n if (ch >= \"0\" && ch <= \"9\") return true;\n if (ch === info.decimalSeparator) return true;\n if (ch === info.minusSign || ch === \"-\") return true;\n // ASCII \".\" stands in for the decimal point in locales whose separator is\n // non-ASCII (ar/fa: ٫) — but not when \".\" is the grouping separator (de-DE).\n if (ch === \".\" && info.decimalSeparator !== \".\" && info.groupingSeparator !== \".\") return true;\n return false;\n}\n\n/**\n * Count how many \"accepted\" characters appear before position `cursor` in `str`.\n * `str` must already be digit-normalised (ASCII); the sole caller normalises once\n * and shares the result, so re-normalising here would just repeat that scan.\n */\nfunction countAcceptedBefore(str: string, cursor: number, info: LocaleInfo): number {\n let count = 0;\n for (let i = 0; i < cursor && i < str.length; i++) {\n if (isAccepted(str[i]!, info)) count++;\n }\n return count;\n}\n\n// ── Caret boundary ────────────────────────────────────────────────────────────\n\n/**\n * Build a boolean array of length `formattedValue.length + 1`.\n * `true` → cursor may rest at this position.\n * `false` → cursor must snap away (sits inside a formatting-only character\n * such as a grouping separator or a currency prefix).\n *\n * Rules:\n * - Start and end positions are always valid.\n * - A position immediately AFTER a grouping separator is invalid (the\n * cursor would look like it's between two digits but moving left would\n * skip the comma).\n * - A position immediately BEFORE a grouping separator is valid.\n */\nexport function getCaretBoundary(formattedValue: string, info: LocaleInfo): CaretBoundary {\n const len = formattedValue.length;\n const boundary: CaretBoundary = new Array(len + 1).fill(true) as boolean[];\n\n for (let i = 0; i < len; i++) {\n const ch = formattedValue[i]!;\n if (ch === info.groupingSeparator) {\n // Position immediately after the grouping separator is invalid\n boundary[i + 1] = false;\n }\n }\n\n // First and last are always valid\n boundary[0] = true;\n boundary[len] = true;\n\n return boundary;\n}\n\n// ── Cursor computation ────────────────────────────────────────────────────────\n\n/**\n * Compute the new cursor position in `newFormatted` that corresponds\n * semantically to `oldCursor` in `oldInput`.\n *\n * Algorithm (3 stages from the spec):\n *\n * 1. Count accepted characters before `oldCursor` in `oldInput`.\n * 2. Adjust for backspace-over-separator edge case.\n * 3. Walk `newFormatted` to find the position where the same count of\n * accepted chars precede it; snap to the nearest valid boundary.\n *\n * @param oldInput The raw string the user just typed into (pre-format)\n * @param oldCursor selectionStart captured from the native event\n * @param newFormatted The formatted string we're about to display\n * @param info Locale separators\n * @param inputType e.nativeEvent.inputType (optional — for backspace detection)\n */\nexport function computeNewCursorPosition(\n oldInput: string,\n oldCursor: number,\n newFormatted: string,\n info: LocaleInfo,\n inputType?: string\n): number {\n const normalised = normalizeDigits(oldInput);\n\n // Stage 1: count accepted chars before cursor in old input\n let acceptedCount = countAcceptedBefore(normalised, oldCursor, info);\n\n // Stage 1b: accounting/parens negatives drop the minus sign. If a minus was\n // counted before the caret but the reformatted output represents the sign\n // without one (e.g. \"($1.00)\"), the accepted-char counts are off by one —\n // correct for it so integer digits don't land inside the fraction.\n const before = oldInput.slice(0, oldCursor);\n const minusBeforeCaret = before.includes(\"-\") || before.includes(info.minusSign);\n const newHasMinus = newFormatted.includes(\"-\") || newFormatted.includes(info.minusSign);\n if (minusBeforeCaret && !newHasMinus) {\n acceptedCount = Math.max(0, acceptedCount - 1);\n }\n\n // Stage 2: backspace on grouping separator — also delete the preceding digit\n if (\n inputType === \"deleteContentBackward\" &&\n oldCursor > 0 &&\n oldInput[oldCursor - 1] === info.groupingSeparator\n ) {\n // The separator was deleted but we want to remove the preceding digit too\n acceptedCount = Math.max(0, acceptedCount - 1);\n }\n\n // Stage 3: build boundary and walk new formatted string\n const boundary = getCaretBoundary(newFormatted, info);\n const normNew = normalizeDigits(newFormatted);\n let count = 0;\n let pos = 0;\n\n for (let i = 0; i < normNew.length; i++) {\n if (count === acceptedCount) {\n pos = i;\n break;\n }\n if (isAccepted(normNew[i]!, info)) count++;\n pos = i + 1;\n }\n\n // If we ran through the entire string without reaching the target count,\n // place the cursor at the end. Note: acceptedCount === 0 means we correctly\n // want pos = 0 (set in the loop), so we must NOT override that case.\n if (acceptedCount > 0 && count < acceptedCount) {\n pos = newFormatted.length;\n }\n\n // Snap to nearest valid boundary\n pos = snapToBoundary(pos, boundary);\n\n return pos;\n}\n\n/**\n * If `pos` is at a false (invalid) boundary position, find the nearest\n * true position. Prefers moving forward; falls back to backward.\n */\nfunction snapToBoundary(pos: number, boundary: CaretBoundary): number {\n if (boundary[pos]) return pos;\n\n // Try forward first\n for (let i = pos + 1; i < boundary.length; i++) {\n if (boundary[i]) return i;\n }\n // Fall back to backward\n for (let i = pos - 1; i >= 0; i--) {\n if (boundary[i]) return i;\n }\n return 0;\n}\n","import type { FormatResult, LocaleInfo } from \"./types.js\";\n\n// ── Internal ──────────────────────────────────────────────────────────────────\n\n// Locally declared so the dev-only gate type-checks without @types/node.\ndeclare const process: { env?: Record<string, string | undefined> } | undefined;\n\nlet warnedInvalidOptions = false;\n/**\n * Warn once (dev only) when invalid formatOptions/locale force a fallback. The\n * `process.env.NODE_ENV !== \"production\"` token is statically replaced and the\n * branch dead-code-eliminated by production bundlers that define NODE_ENV\n * (webpack, Vite, Next, esbuild --minify/--define) — and by raqam's own minified\n * build — so this message ships zero bytes in production while still surfacing in\n * development. The `typeof process` / `process.env` guards keep it crash-safe\n * under raw-browser ESM (no `process`) and partial `process` shims (no `env`);\n * both sit on the eliminated side of the token, so they cost nothing in prod.\n */\nfunction warnInvalidFormatOptions(err: unknown): void {\n if (typeof process !== \"undefined\" && process.env && process.env.NODE_ENV !== \"production\") {\n if (warnedInvalidOptions) return;\n warnedInvalidOptions = true;\n console.warn(\"[raqam] Invalid formatOptions/locale — using a safe fallback.\", err);\n }\n}\n\n/** Probe value that will surface decimal AND grouping parts */\nconst PROBE_VALUE = 12345.6;\n\n/**\n * LRU cache of Intl.NumberFormat instances, keyed by locale + JSON.stringify\n * (options). Bounded so apps that vary formatOptions at high cardinality —\n * per-row currencies in a large table, per-keystroke fraction-digit changes —\n * don't grow it without limit for the process lifetime.\n */\nconst FORMATTER_CACHE_MAX = 256;\nconst formatterCache = new Map<string, Intl.NumberFormat>();\n\nfunction getFormatter(\n locale: string | undefined,\n options: Intl.NumberFormatOptions | undefined\n): Intl.NumberFormat {\n const key = `${locale ?? \"\"}::${JSON.stringify(options ?? {})}`;\n const cached = formatterCache.get(key);\n if (cached) {\n // Mark most-recently-used by re-inserting at the end of the Map's order.\n formatterCache.delete(key);\n formatterCache.set(key, cached);\n return cached;\n }\n // Invalid options/locale (e.g. style:\"currency\" without `currency`,\n // maximumFractionDigits out of range, a bad BCP-47 tag) make the constructor\n // throw. Don't let that crash the render/SSR tree — fall back to a safe\n // formatter (drop the offending options, then the locale) and warn in dev.\n let fmt: Intl.NumberFormat;\n try {\n fmt = new Intl.NumberFormat(locale, options);\n } catch (err) {\n warnInvalidFormatOptions(err);\n try {\n fmt = new Intl.NumberFormat(locale);\n } catch {\n fmt = new Intl.NumberFormat();\n }\n }\n formatterCache.set(key, fmt);\n // Evict the least-recently-used entry (the first key) when over capacity.\n if (formatterCache.size > FORMATTER_CACHE_MAX) {\n const oldest = formatterCache.keys().next().value;\n if (oldest !== undefined) formatterCache.delete(oldest);\n }\n return fmt;\n}\n\n/** Extract locale meta from formatToParts — never hardcoded. */\nfunction extractLocaleInfo(\n locale: string | undefined,\n options: Intl.NumberFormatOptions | undefined\n): LocaleInfo {\n const styledFmt = getFormatter(locale, options);\n\n // Probe the separators with a NEUTRAL decimal formatter (same locale +\n // numbering system, but plain decimal style with a forced fraction). The\n // styled formatter can hide them — e.g. percent scales the probe so it has no\n // fraction (decimal separator invisible) and a positive value never yields a\n // minusSign. A negative, fractional decimal probe always surfaces all four.\n const probeFmt = getFormatter(locale, {\n minimumFractionDigits: 1,\n maximumFractionDigits: 1,\n numberingSystem: options?.numberingSystem,\n });\n const parts = probeFmt.formatToParts(-PROBE_VALUE);\n\n let decimalSeparator = \".\";\n let groupingSeparator = \",\";\n let minusSign = \"-\";\n let zero = \"0\";\n\n for (const part of parts) {\n if (part.type === \"decimal\") decimalSeparator = part.value;\n if (part.type === \"group\") groupingSeparator = part.value;\n if (part.type === \"minusSign\") minusSign = part.value;\n }\n\n // Detect locale zero digit\n for (const part of probeFmt.formatToParts(0)) {\n if (part.type === \"integer\") {\n zero = part.value;\n break;\n }\n }\n\n // RTL locales: Arabic / Hebrew / Persian / Urdu / Syriac etc.\n const rtlLocales = /^(ar|he|fa|ur|syc|nqo|ug|yi)/i;\n const resolvedLocale = styledFmt.resolvedOptions().locale;\n const isRTL = rtlLocales.test(resolvedLocale);\n\n return { decimalSeparator, groupingSeparator, minusSign, zero, isRTL };\n}\n\n/**\n * Resolve the effective fraction-digit settings for a field. When decimals are\n * disallowed, fraction padding/scale is forced to 0 so currency /\n * fixedDecimalScale never pad \".00\" (which the dot-strip would then re-read,\n * exploding the value). Shared by useNumberFieldState and useNumberField so the\n * editable display and the on-commit display stay in lockstep.\n */\nexport function resolveEffectiveFractions(opts: {\n allowDecimal?: boolean;\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n fixedDecimalScale?: boolean;\n}): {\n effMinFrac: number | undefined;\n effMaxFrac: number | undefined;\n effFixedScale: boolean | undefined;\n} {\n const allowDecimal = opts.allowDecimal ?? true;\n return {\n effMinFrac: allowDecimal ? opts.minimumFractionDigits : 0,\n effMaxFrac: allowDecimal ? opts.maximumFractionDigits : 0,\n effFixedScale: allowDecimal ? opts.fixedDecimalScale : false,\n };\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport interface FormatterOptions {\n locale?: string;\n formatOptions?: Intl.NumberFormatOptions;\n prefix?: string;\n suffix?: string;\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n fixedDecimalScale?: boolean;\n}\n\nexport interface Formatter {\n format(value: number): string;\n formatToParts(value: number): Intl.NumberFormatPart[];\n getLocaleInfo(): LocaleInfo;\n formatResult(value: number): FormatResult;\n}\n\n/**\n * Create a formatter instance. Intl.NumberFormat is cached — safe to call\n * on every render.\n */\nexport function createFormatter(opts: FormatterOptions): Formatter {\n // Merge fraction digit overrides into formatOptions\n const intlOptions: Intl.NumberFormatOptions = { ...opts.formatOptions };\n\n if (opts.minimumFractionDigits !== undefined) {\n intlOptions.minimumFractionDigits = opts.minimumFractionDigits;\n }\n if (opts.maximumFractionDigits !== undefined) {\n intlOptions.maximumFractionDigits = opts.maximumFractionDigits;\n }\n if (opts.fixedDecimalScale && opts.maximumFractionDigits !== undefined) {\n intlOptions.minimumFractionDigits = opts.maximumFractionDigits;\n intlOptions.maximumFractionDigits = opts.maximumFractionDigits;\n }\n\n const intlFmt = getFormatter(opts.locale, intlOptions);\n // Lazy — computed once on first call\n let cachedLocaleInfo: LocaleInfo | null = null;\n\n function getLocaleInfo(): LocaleInfo {\n if (!cachedLocaleInfo) {\n cachedLocaleInfo = extractLocaleInfo(opts.locale, intlOptions);\n }\n return cachedLocaleInfo;\n }\n\n function formatToParts(value: number): Intl.NumberFormatPart[] {\n const parts = intlFmt.formatToParts(value);\n if (!opts.prefix && !opts.suffix) return parts;\n\n const result: Intl.NumberFormatPart[] = [];\n if (opts.prefix) result.push({ type: \"literal\", value: opts.prefix });\n result.push(...parts);\n if (opts.suffix) result.push({ type: \"literal\", value: opts.suffix });\n return result;\n }\n\n function format(value: number): string {\n if (!Number.isFinite(value)) return \"\";\n const formatted = intlFmt.format(value);\n return (opts.prefix ?? \"\") + formatted + (opts.suffix ?? \"\");\n }\n\n function formatResult(value: number): FormatResult {\n const parts = formatToParts(value);\n const formatted = parts.map((p) => p.value).join(\"\");\n return { formatted, parts };\n }\n\n return { format, formatToParts, getLocaleInfo, formatResult };\n}\n","import { createFormatter } from \"./formatter.js\";\nimport { normalizeDigits } from \"./normalizer.js\";\nimport type { LocaleInfo, ParseResult } from \"./types.js\";\n\n/** Upper bound on input length accepted by parse(); see the guard in parse(). */\nconst MAX_PARSE_INPUT = 256;\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/**\n * Given an ASCII-normalised numeric string (`stripped` — digits, an optional\n * leading \"-\", and at most one \".\"), report whether it is a valid-but-incomplete\n * value that must NOT be reformatted while the user is still typing:\n * \"1.\" trailing decimal separator\n * \"1.0\" trailing zero after decimal\n * \"1.50\" trailing zeros after decimal\n * \".5\" leading decimal point (normalised to \"0.5\" only on blur)\n *\n * This runs on the *stripped* string, so grouping separators, prefixes,\n * suffixes and currency symbols never break the detection.\n */\nfunction isIntermediateStripped(stripped: string, allowDecimal: boolean): boolean {\n if (!allowDecimal) return false;\n if (/^-0+$/.test(stripped)) return true; // \"-0\" — user may still type \"-0.5\"\n if (/\\.$/.test(stripped)) return true; // \"1.\", \"-1.\"\n if (/\\.\\d*0$/.test(stripped)) return true; // \"1.0\", \"1.50\", \"1.230\"\n if (/^-?\\.\\d+$/.test(stripped)) return true; // \".5\", \"-.5\"\n return false;\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport interface ParserOptions {\n locale?: string;\n formatOptions?: Intl.NumberFormatOptions;\n allowNegative?: boolean;\n allowDecimal?: boolean;\n prefix?: string;\n suffix?: string;\n}\n\nexport interface Parser {\n parse(input: string): ParseResult;\n isIntermediate(input: string): boolean;\n getLocaleInfo(): LocaleInfo;\n /**\n * Strip formatting affordances (grouping separators, currency symbol, prefix/\n * suffix, percent sign…) from `input`, returning the bare numeric string\n * (ASCII digits, an optional leading \"-\", and at most one \".\"). Trailing zeros\n * the user typed are preserved. Useful for deriving a precision-preserving raw\n * value from a formatted display string.\n */\n strip(input: string): string;\n}\n\n/**\n * Create a locale-aware parser. Separator characters are extracted from\n * Intl.NumberFormat — never hardcoded.\n */\nexport function createParser(opts: ParserOptions = {}): Parser {\n const allowNegative = opts.allowNegative ?? true;\n const allowDecimal = opts.allowDecimal ?? true;\n // Percent fields hold the *fraction* (Intl multiplies by 100 on display), so\n // typed digits must be divided by 100: typing \"50\" means 50% i.e. value 0.5.\n const isPercent = opts.formatOptions?.style === \"percent\";\n\n // Re-use the formatter to get locale info\n const fmt = createFormatter({\n locale: opts.locale,\n formatOptions: opts.formatOptions,\n prefix: opts.prefix,\n suffix: opts.suffix,\n });\n\n // The literal currency symbol (e.g. \"$\", \"€\", or Arabic \"ج.م.\" which embeds\n // ASCII dots). Captured so it can be removed wholesale before separator\n // handling — otherwise its dots would be mistaken for a decimal point.\n let currencySymbol = \"\";\n if (opts.formatOptions?.style === \"currency\") {\n try {\n currencySymbol = fmt\n .formatToParts(1)\n .filter((p) => p.type === \"currency\")\n .map((p) => p.value)\n .join(\"\");\n } catch {\n currencySymbol = \"\";\n }\n }\n\n // Locale's scientific/engineering exponent separator. Most locales use \"E\"\n // (handled directly by the exponent regex), but some localize it — ar \"أس\",\n // fa \"×۱۰^\", sv \"×10^\". Captured (digit-normalized) so it can be mapped to \"e\"\n // before exponent handling; otherwise the generic strip would delete it and\n // glue the exponent digits onto the mantissa (\"1.234×10^3\" -> \"1.234103\").\n let exponentSeparator = \"\";\n const notation = opts.formatOptions?.notation;\n if (notation === \"scientific\" || notation === \"engineering\") {\n try {\n const sep = normalizeDigits(\n fmt\n .formatToParts(1234)\n .filter((p) => p.type === \"exponentSeparator\")\n .map((p) => p.value)\n .join(\"\")\n );\n // Plain ASCII \"E\"/\"e\" is already handled by the exponent regex.\n if (sep && sep !== \"e\" && sep !== \"E\") exponentSeparator = sep;\n } catch {\n exponentSeparator = \"\";\n }\n }\n\n function getLocaleInfo(): LocaleInfo {\n return fmt.getLocaleInfo();\n }\n\n function stripAffordances(raw: string): string {\n const info = getLocaleInfo();\n\n // 1. Normalise non-Latin digits to ASCII\n let s = normalizeDigits(raw);\n\n // 1a. Strip Unicode bidi control marks. RTL locales' accounting currency\n // format prepends an invisible LRM/RLM (e.g. fa-IR: \"(ریال ۱٬۲۳۴)\") before\n // the \"(\", which would defeat the index-0-anchored accounting match below and\n // silently drop the negative sign.\n s = s.replace(/[--]/g, \"\");\n\n // 1a2. Map a localized scientific exponent separator (ar \"أس\", fa \"×۱۰^\",\n // sv \"×10^\") to \"e\" so the exponent handling below recognizes it instead of\n // the generic strip mangling it (\"1.234×10^3\" -> \"1.234103\").\n if (exponentSeparator) {\n s = s.split(exponentSeparator).join(\"e\");\n }\n\n // 1b. Remove the currency symbol wholesale (before separators are touched),\n // so a symbol containing ASCII dots — e.g. Arabic \"ج.م.\" — does not leave\n // stray \".\" that the numeric validation would reject.\n if (currencySymbol) {\n s = s.split(currencySymbol).join(\"\");\n }\n\n // 2. Accounting format: \"(1,234.56)\" or \"($1,234.56)\" → negative\n // Intl.NumberFormat with currencySign:\"accounting\" wraps negatives in parens\n const accountingMatch = s.match(/^\\((.+)\\)$/);\n if (accountingMatch) {\n s = `-${accountingMatch[1]}`;\n }\n\n // 3. Strip prefix / suffix\n if (opts.prefix && s.startsWith(opts.prefix)) {\n s = s.slice(opts.prefix.length);\n }\n if (opts.suffix && s.endsWith(opts.suffix)) {\n s = s.slice(0, -opts.suffix.length);\n }\n\n // 4. Strip grouping separators (escape special chars)\n if (info.groupingSeparator) {\n s = s.split(info.groupingSeparator).join(\"\");\n }\n\n // 5. Replace locale decimal separator with ASCII \".\"\n if (info.decimalSeparator !== \".\") {\n s = s.split(info.decimalSeparator).join(\".\");\n }\n\n // 6. Replace locale minus sign with ASCII \"-\"\n if (info.minusSign !== \"-\") {\n s = s.split(info.minusSign).join(\"-\");\n }\n // Also normalise the Unicode minus U+2212 (used by fa/sv/fi/nb… and often\n // pasted) so it is never stripped as a non-numeric character below.\n if (s.includes(\"−\")) {\n s = s.split(\"−\").join(\"-\");\n }\n\n // Run the exponent checks on a copy with surrounding whitespace removed — the\n // regexes are anchored, so \" 1e3 \" would otherwise miss and get its \"E\"\n // char-stripped to \"13\". Only leading/trailing spaces are trimmed (not\n // internal ones), so \"1.5 each\" stays a space-separated word, not \"1.5each\"\n // (which would look like a malformed exponent).\n const st = s.trim();\n\n // 7a. Preserve a clean exponent (e.g. \"1.234E3\") so scientific/engineering\n // notation round-trips through parse(): the generic char-strip below would\n // delete the \"E\", gluing mantissa and exponent into a wrong value\n // (\"1.234E3\" -> \"1.2343\"). A complete exponent may be followed by trailing\n // affordances — a percent sign (\"5E1%\"), a unit (\" km\", \" meters\"), etc. —\n // which are dropped here (parse() re-applies percent scaling via isPercent).\n // The remainder is only treated as an affordance when it carries no further\n // digit AND does not start with an exponent-syntax char (e/E/+/-): a real\n // affordance never starts with one, whereas \"1e3e\", \"1e3+\", \"1e2e3\" are\n // malformed/continued exponents that must fall through to the guard / strip.\n // Returning early also skips the minus-collapse (step 8) so a negative\n // exponent's sign survives; the mantissa carries at most one leading \"-\".\n // The mantissa allows a leading \"+\" too: signDisplay \"always\"/\"exceptZero\"\n // formats positives as \"+1.234E3\"; Number() accepts the \"+\" and the regular\n // path already tolerates a leading \"+\" (the strip removes it).\n const sci = st.match(/^([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+))[eE]([+-]?\\d+)(.*)$/);\n if (sci && !/\\d/.test(sci[3]) && !/^[eE+-]/.test(sci[3])) {\n return `${sci[1]}e${sci[2]}`;\n }\n\n // 7b. MALFORMED exponent: a valid mantissa immediately followed by \"e\"/\"E\"\n // that is not a complete scientific number (\"1e\", \"1e+\", \"1efoo\", \"1EUR\").\n // The strip below would silently delete the \"e\" and yield a wrong value (1),\n // so return the string with the marker intact — parse()'s exponent branch\n // then rejects it instead of mis-parsing.\n if (/^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)[eE]/.test(st)) {\n return st;\n }\n\n // 7. Strip currency symbol, percent sign, spaces that Intl might prepend/append\n // Strip any remaining non-numeric chars except digits, \".\", \"-\"\n // (handles currency prefixes/suffixes from Intl)\n s = s.replace(/[^\\d.-]/g, \"\").trim();\n\n // 8. Collapse minus signs to a single leading one, so stray minuses typed in\n // the middle (\"1-23\") or doubled (\"--5\") never invalidate the whole value.\n if (s.includes(\"-\")) {\n const negative = s.startsWith(\"-\");\n s = s.replace(/-/g, \"\");\n if (negative) s = `-${s}`;\n }\n\n return s;\n }\n\n function parse(input: string): ParseResult {\n if (!input || input.trim() === \"\") {\n return { value: null, isValid: false, isIntermediate: false };\n }\n\n // Bound the input length before any regex/scan work. Real numeric input is\n // short; an unbounded attacker-controlled string (e.g. a crafted paste)\n // could otherwise drive worst-case backtracking. 256 chars is far beyond any\n // legitimate number (≈250-digit precision) yet keeps all scans trivial.\n if (input.length > MAX_PARSE_INPUT) {\n return { value: null, isValid: false, isIntermediate: false };\n }\n\n // Strip *first*, so intermediate detection never trips over grouping\n // separators, prefixes, suffixes or currency symbols.\n const stripped = stripAffordances(input);\n\n if (stripped === \"\") {\n return { value: null, isValid: false, isIntermediate: false };\n }\n\n // Lone minus — intermediate only if negatives are allowed.\n if (stripped === \"-\") {\n return { value: null, isValid: false, isIntermediate: allowNegative };\n }\n\n // Lone decimal point (\".\" or \"-.\") — intermediate only if decimals allowed.\n if (stripped === \".\" || stripped === \"-.\") {\n return {\n value: null,\n isValid: false,\n isIntermediate: allowDecimal && (stripped === \".\" || allowNegative),\n };\n }\n\n if (!allowNegative && stripped.startsWith(\"-\")) {\n return { value: null, isValid: false, isIntermediate: false };\n }\n\n if (!allowDecimal && stripped.includes(\".\")) {\n return { value: null, isValid: false, isIntermediate: false };\n }\n\n // Scientific / exponent notation, preserved by stripAffordances (step 7a).\n // Handle it explicitly: Number() reads it, but the plain validation regex\n // below would reject the \"e\". A malformed exponent is rejected rather than\n // silently corrupted.\n if (/[eE]/.test(stripped)) {\n if (!/^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)[eE][+-]?\\d+$/.test(stripped)) {\n return { value: null, isValid: false, isIntermediate: false };\n }\n let n = Number(stripped);\n if (!Number.isFinite(n)) {\n return { value: null, isValid: false, isIntermediate: false };\n }\n // A fractional exponent value (e.g. \"5e-1\" = 0.5) has no literal \".\" to\n // trip the allowDecimal guard above, so reject it here for parity with the\n // plain-decimal path when decimals are disallowed.\n if (!allowDecimal && !Number.isInteger(n)) {\n return { value: null, isValid: false, isIntermediate: false };\n }\n if (Object.is(n, -0)) n = 0;\n if (isPercent && n !== 0) n = Number((n / 100).toPrecision(15));\n return { value: n, isValid: true, isIntermediate: false };\n }\n\n // Accept integers and decimals with the dot either trailing (\"1.\") or\n // leading (\".5\") so partially-typed values still yield a numeric value. The\n // pattern is written without an ambiguous alternation so it matches in linear\n // time (the empty / lone-\"-\" / lone-\".\" cases are handled above).\n if (!/^-?\\d*(?:\\.\\d*)?$/.test(stripped)) {\n return { value: null, isValid: false, isIntermediate: false };\n }\n\n let n = Number.parseFloat(stripped);\n if (!Number.isFinite(n)) {\n return { value: null, isValid: false, isIntermediate: false };\n }\n // Normalise negative zero so consumers never receive -0 from onChange.\n if (Object.is(n, -0)) n = 0;\n // Percent: divide by 100, snapping to canonical precision so the IEEE-754\n // division artifact (12.99/100 = 0.12990000000000002) never surfaces.\n if (isPercent && n !== 0) n = Number((n / 100).toPrecision(15));\n\n // A trailing-zero / trailing-dot / leading-dot value is still a real number\n // (so it is never wiped on blur) but must not be reformatted mid-typing.\n return {\n value: n,\n isValid: true,\n isIntermediate: isIntermediateStripped(stripped, allowDecimal),\n };\n }\n\n function isIntermediate(input: string): boolean {\n return parse(input).isIntermediate;\n }\n\n return { parse, isIntermediate, getLocaleInfo, strip: stripAffordances };\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var chunkPM3EDICU_cjs=require('./chunk-PM3EDICU.cjs'),chunkZKLZ7UKZ_cjs=require('./chunk-ZKLZ7UKZ.cjs'),at=require('react'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var at__default=/*#__PURE__*/_interopDefault(at);var nt=at.createContext(null);function X(){let t=at.useContext(nt);if(!t)throw typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production"?new Error("[raqam] NumberField sub-components must be used inside <NumberField.Root>."):new Error("[raqam] <NumberField.Root> missing");return t}function rt(t,e={}){let{delay:r=400,interval:n=200,disabled:i=false}=e,o=at.useRef(t);at.useEffect(()=>{o.current=t;});let l=at.useRef(r);at.useEffect(()=>{l.current=r;});let a=at.useRef(n);at.useEffect(()=>{a.current=n;});let v=at.useRef(i);at.useEffect(()=>{v.current=i;});let g=at.useRef(null),I=at.useRef(null),L=at.useRef(false),R=at.useCallback(()=>{L.current=false,g.current!==null&&(clearTimeout(g.current),g.current=null),I.current!==null&&(clearTimeout(I.current),I.current=null);},[]),F=at.useCallback(C=>{if(!L.current||v.current){R();return}o.current();let B=Math.max(50,Math.floor(C/2));I.current=setTimeout(()=>{F(B);},C);},[R]),x=at.useCallback(C=>{i||C.button!==0&&C.pointerType==="mouse"||(o.current(),L.current=true,g.current=setTimeout(()=>{F(a.current);},l.current));},[i,F]),D=at.useCallback(C=>{C.preventDefault(),R();},[R]),M=at.useCallback(C=>{R();},[R]),re=at.useCallback(C=>{R();},[R]),q=at.useCallback(C=>{R();},[R]);return at.useEffect(()=>{i&&R();},[i,R]),at.useEffect(()=>R,[R]),{onPointerDown:x,onPointerUp:D,onPointerLeave:M,onPointerCancel:re,onLostPointerCapture:q}}var lt=typeof window<"u"?at.useLayoutEffect:at.useEffect;function st(t){return t.replace(/[.*+?^${}()|[\]\\-]/g,"\\$&")}function ct(){let t=at.useRef(0),[e,r]=at.useState(false),n=at.useCallback(i=>{i?(t.current+=1,r(true)):t.current>0&&(t.current-=1,t.current===0&&r(false));},[]);return [e,n]}function dt(t){let e=t?.getRootNode();return e&&"activeElement"in e?e.activeElement:typeof document<"u"?document.activeElement:null}var At={k:1e3,thousand:1e3,m:1e6,million:1e6,b:1e9,billion:1e9,t:1e12,trillion:1e12};function Ot(t){if(t.length>256)return null;let e=t.replace(/\s+/g,"");if(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)[eE][+-]?\d+$/.test(e)){let n=Number(e);return Number.isFinite(n)?n:null}let r=e.match(/^([+-]?(?:\d+(?:\.\d*)?|\.\d+))(k|m|b|t|thousand|million|billion|trillion)$/i);if(r){let n=Number(r[1])*At[r[2].toLowerCase()];return Number.isFinite(n)?n:null}return null}function mt(t,e,r){let{locale:n,formatOptions:i,minValue:o,maxValue:l,allowNegative:a=true,allowDecimal:v=true,allowMouseWheel:g=false,liveFormat:I=true,prefix:L,suffix:R,name:F,disabled:x,readOnly:D,required:M,onFocus:re,onBlur:q,maximumFractionDigits:C,minimumFractionDigits:B,fixedDecimalScale:H,copyBehavior:u="formatted",stepHoldDelay:W=400,stepHoldInterval:j=200,incrementLabel:se="Increase",decrementLabel:ie="Decrease",formatValue:E,parseValue:_,onValueCommitted:O}=t,G=Number.isFinite(o)?o:void 0,J=Number.isFinite(l)?l:void 0,K=i?.notation,ce=I&&K!=="compact"&&K!=="scientific"&&K!=="engineering",ve=JSON.stringify(i),{step:ae=1,largeStep:U=ae*10,smallStep:Me=ae*.1}=e.options,ge=at.useId(),Re=t.id??`raqam-${ge}`,Se=`${Re}-label`,Te=`${Re}-description`,Ce=`${Re}-error`,{effMinFrac:we,effMaxFrac:Le,effFixedScale:Ae}=chunkPM3EDICU_cjs.c({allowDecimal:v,minimumFractionDigits:B,maximumFractionDigits:C,fixedDecimalScale:H}),N=at.useMemo(()=>chunkPM3EDICU_cjs.d({locale:n,formatOptions:i,prefix:L,suffix:R,minimumFractionDigits:we,maximumFractionDigits:Le,fixedDecimalScale:Ae}),[n,ve,L,R,we,Le,Ae]),qe=i?.style==="percent",Oe=v?qe?20:Le:0,Q=at.useMemo(()=>chunkPM3EDICU_cjs.d({locale:n,formatOptions:i,prefix:L,suffix:R,minimumFractionDigits:0,maximumFractionDigits:Oe,fixedDecimalScale:false}),[n,ve,L,R,Oe]),$=at.useMemo(()=>chunkPM3EDICU_cjs.e({locale:n,formatOptions:i,allowNegative:a,allowDecimal:v,prefix:L,suffix:R}),[n,ve,a,v,L,R]),de=at.useCallback((s,f)=>{let y=N.getLocaleInfo(),d=f.lastIndexOf(y.decimalSeparator);if(d===-1&&y.decimalSeparator!=="."&&y.groupingSeparator!=="."&&(d=f.lastIndexOf(".")),d===-1||!/\d/.test(chunkZKLZ7UKZ_cjs.b(f.slice(0,d))))return null;let S=chunkZKLZ7UKZ_cjs.b(f.slice(d+1)).match(/^\d+/);if(!S)return null;let m=Math.min(S[0].length,Le??20,20);return m===0?null:chunkPM3EDICU_cjs.d({locale:n,formatOptions:i,prefix:L,suffix:R,minimumFractionDigits:m,maximumFractionDigits:m}).format(s)},[N,n,ve,L,R,Le]),w=at.useRef(null),ke=at.useRef(e);ke.current=e,lt(()=>{w.current!==null&&r.current&&dt(r.current)===r.current&&(r.current.setSelectionRange(w.current,w.current),w.current=null);},[e.inputValue,r]),at.useEffect(()=>{let s=r.current;if(!s||!g)return;let f=y=>{if(x||D||dt(s)!==s)return;y.preventDefault();let d=ke.current;d._setLastChangeReason("wheel"),y.deltaY<0?d.increment():d.decrement();};return s.addEventListener("wheel",f,{passive:false}),()=>s.removeEventListener("wheel",f)},[g,x,D,r]);let Z=at.useRef(false),_e=at.useCallback(()=>{Z.current=true;},[]),Ve=at.useCallback(s=>{Z.current=false;let f=s.currentTarget.value,y=N.getLocaleInfo(),d=chunkZKLZ7UKZ_cjs.b(f),S,m;if(_){let p=_(d);m=p.value,p.isIntermediate?S=d:p.value!==null&&E?S=E(p.value):p.value!==null?S=N.format(p.value):S=d,w.current=S.length;}else if(ce){let p=$.parse(d);p.isIntermediate?S=chunkZKLZ7UKZ_cjs.c(d,y.zero):p.value!==null?S=E?E(p.value):Q.format(p.value):S=d===""?"":d,w.current=chunkPM3EDICU_cjs.b(f,f.length,S,y,"insertCompositionText");}else S=d,w.current=d.length;e._setLastChangeReason("input"),e.setInputValue(S,m);},[N,Q,$,ce,e,E,_]),Be=at.useCallback(s=>{let f=s.target.value,y=s.target.selectionStart??f.length,d=s.nativeEvent.inputType,S=N.getLocaleInfo();if(Z.current){e.setInputValue(f);return}let m=chunkZKLZ7UKZ_cjs.b(f);a||(m=m.split("-").join("").split(S.minusSign).join("")),v?S.decimalSeparator!=="."&&S.groupingSeparator!=="."&&(m=m.replace(/\./g,(A,b,P)=>/\d/.test(P[b-1]??"")||/\d/.test(P[b+1]??"")?S.decimalSeparator:".")):m=m.split(".").join("").split(S.decimalSeparator).join("");let p,fe;if(_){let A=_(m);fe=A.value,A.isIntermediate?p=m:A.value!==null?p=E?E(A.value):N.format(A.value):m===""?p="":p=m,w.current=p.length;}else if(ce){let A=$.parse(m);if(A.isIntermediate)p=(!E&&A.value!==null?de(A.value,m):null)??chunkZKLZ7UKZ_cjs.c(m,S.zero);else if(A.value!==null)if(E)p=E(A.value);else {p=Q.format(A.value);let b=$.parse(p).value;fe=b!==null&&Number.isFinite(b)&&Q.format(b)===p?b:A.value;}else m===""||!/\d/.test(m)?p="":p=m;E?w.current=p.length:w.current=chunkPM3EDICU_cjs.b(f,y,p,S,d);}else p=m,w.current=y;e._setLastChangeReason(p===""?"clear":"input"),e.setInputValue(p,fe);},[N,Q,$,ce,e,E,_,de]),me=at.useCallback(s=>{s.preventDefault();let f=s.clipboardData.getData("text/plain");if(!f||f.length>1e3)return;let y=f.replace(/[€$£¥₹₺₽﷼฿₩¢₦₨₪₫₱]/g,"").trim(),d=chunkZKLZ7UKZ_cjs.b(y);if(!a){let P=N.getLocaleInfo();d=d.split("-").join("").split(P.minusSign).join("");}if(!v){let P=N.getLocaleInfo();d=d.split(".").join("").split(P.decimalSeparator).join("");}if(e._setLastChangeReason("paste"),_){let P=_(d);if(P.value!==null){let k=E?E(P.value):N.format(P.value);e.setInputValue(k,P.value),w.current=k.length;}return}let S=Ot(d);if(S!==null){let k=i?.style==="percent"?S/100:S,he=E?E(k):N.format(k);e.setInputValue(he,k),w.current=he.length;return}let m=$.parse(d);if(m.value!==null){let P=N.format(m.value);e.setInputValue(P,m.value),w.current=P.length;return}let p=N.getLocaleInfo(),fe=new RegExp(`[^0-9${st(p.decimalSeparator)}${st(p.minusSign)}-]`,"g"),A=d.replace(fe,""),b=$.parse(A);if(b.value!==null){let P=N.format(b.value);e.setInputValue(P,b.value),w.current=P.length;}},[$,N,e,E,_]),We=at.useCallback(s=>{if(u==="formatted")return;s.preventDefault();let f=String(e.numberValue??"");s.clipboardData.setData("text/plain",f);},[u,e.numberValue]),ee=at.useCallback(s=>{if(u==="formatted")return;s.preventDefault();let f=String(e.numberValue??"");s.clipboardData.setData("text/plain",f),e._setLastChangeReason("clear"),e.setInputValue("");},[u,e]),Ge=at.useCallback(s=>{if(x||D)return;let f=s.key;if(!s.metaKey&&!s.ctrlKey&&!s.altKey&&v){let y=N.getLocaleInfo();if(f===y.decimalSeparator||f==="."&&y.decimalSeparator!=="."&&y.groupingSeparator!=="."){let S=r.current;if(S){let m=S.value.indexOf(y.decimalSeparator);if(m!==-1){s.preventDefault(),S.setSelectionRange(m+1,m+1);return}}}}if(f==="Backspace"&&!s.shiftKey&&!s.altKey&&!s.metaKey&&!s.ctrlKey){let y=r.current;if(y){let d=y.selectionStart??0,S=y.selectionEnd??d,m=y.value,p=N.getLocaleInfo();if(d===S&&d>=2&&m[d-1]===p.groupingSeparator){s.preventDefault();let b=m.slice(0,d-2)+m.slice(d),P=$.parse(b);e._setLastChangeReason("input");let k;P.value!==null?(k=de(P.value,b)??Q.format(P.value),e.setInputValue(k,P.value)):(k=b,b===""&&e._setLastChangeReason("clear"),e.setInputValue(b)),w.current=chunkPM3EDICU_cjs.b(b,d-2,k,p,"deleteContentBackward");return}let fe=b=>b!==void 0&&/\p{Nd}/u.test(b),A=b=>b!==void 0&&!fe(b)&&b!==p.decimalSeparator&&b!==p.minusSign&&b!=="-";if(d===S&&d===m.length&&d>=1&&A(m[d-1])){let b=d;for(;b>0&&A(m[b-1]);)b--;if(b>0&&fe(m[b-1])){s.preventDefault();let P=m.slice(0,b-1)+m.slice(b),k=$.parse(P);e._setLastChangeReason("input");let he;k.value!==null&&/\p{Nd}/u.test(P)?(he=de(k.value,P)??Q.format(k.value),e.setInputValue(he,k.value)):(he="",e._setLastChangeReason("clear"),e.setInputValue("")),w.current=chunkPM3EDICU_cjs.b(P,b-1,he,p,"deleteContentBackward");return}}}}if(f==="ArrowUp"||f==="ArrowDown"){s.preventDefault();let y=f==="ArrowUp"?1:-1;e._setLastChangeReason("keyboard"),s.shiftKey?y>0?e.increment(U):e.decrement(U):s.metaKey||s.ctrlKey?y>0?e.increment(Me):e.decrement(Me):y>0?e.increment():e.decrement();return}if(f==="PageUp"){s.preventDefault(),e._setLastChangeReason("keyboard"),e.increment(U);return}if(f==="PageDown"){s.preventDefault(),e._setLastChangeReason("keyboard"),e.decrement(U);return}if(f==="Home"){G!==void 0&&(s.preventDefault(),e._setLastChangeReason("keyboard"),e.decrementToMin());return}if(f==="End"){J!==void 0&&(s.preventDefault(),e._setLastChangeReason("keyboard"),e.incrementToMax());return}if(f==="Enter"){e._setLastChangeReason("blur");let y=e.commit();O?.(y,{reason:"keyboard"});return}},[x,D,e,U,Me,G,J,N,Q,$,r,v,de,O]),ue=at.useCallback(s=>{e.setIsFocused(false),e._setLastChangeReason("blur");let f=e.commit();O?.(f,{reason:"blur"}),q?.(s);},[e,q,O]),Xe=at.useCallback(s=>{e.setIsFocused(true),re?.(s);},[e,re]),Je=rt(()=>{e._setLastChangeReason("increment"),e.increment();},{delay:W,interval:j,disabled:x||!e.canIncrement}),Qe=rt(()=>{e._setLastChangeReason("decrement"),e.decrement();},{delay:W,interval:j,disabled:x||!e.canDecrement}),Ze=at.useMemo(()=>{if(e.numberValue!=null)return E?E(e.numberValue):N.format(e.numberValue)},[e.numberValue,N,E]),je=N.getLocaleInfo(),De=e.numberValue!==null&&(G!==void 0&&e.numberValue<G||J!==void 0&&e.numberValue>J)||e.validationState==="invalid",[et,c]=ct(),h=t["aria-labelledby"]??(t["aria-label"]?void 0:et?Se:void 0),[V,T]=ct(),oe=[t["aria-describedby"],V?Te:null].filter(Boolean).join(" ")||void 0,Ee={id:Se,htmlFor:Re,ref:c},Pt={role:"group","aria-labelledby":h},Tt={id:Re,type:"text",inputMode:"decimal",role:"spinbutton",autoComplete:"off",autoCorrect:"off",spellCheck:false,"aria-label":t["aria-label"],"aria-labelledby":h,"aria-describedby":oe,"aria-valuenow":e.numberValue??void 0,"aria-valuemin":G,"aria-valuemax":J,"aria-valuetext":Ze,"aria-disabled":x||void 0,"aria-readonly":D||void 0,"aria-required":M||void 0,"aria-invalid":De?true:void 0,"aria-errormessage":De&&e.validationError?Ce:void 0,disabled:x,readOnly:D,required:M,value:e.inputValue,onChange:Be,onKeyDown:Ge,onBlur:ue,onFocus:Xe,onPaste:me,onCopy:u!=="formatted"?We:void 0,onCut:u!=="formatted"?ee:void 0,onCompositionStart:_e,onCompositionEnd:Ve,style:je.isRTL?{direction:"ltr",textAlign:"right",unicodeBidi:"plaintext"}:void 0,"data-disabled":x?"":void 0,"data-readonly":D?"":void 0,"data-required":M?"":void 0,"data-invalid":De?"":void 0,"data-rtl":je.isRTL?"":void 0},Ft=F?{type:"hidden",name:F,value:e.numberValue??"","aria-hidden":true}:null,xt={type:"button",tabIndex:-1,"aria-label":se,disabled:x||!e.canIncrement,...Je,"data-disabled":x||!e.canIncrement?"":void 0},Nt={type:"button",tabIndex:-1,"aria-label":ie,disabled:x||!e.canDecrement,...Qe,"data-disabled":x||!e.canDecrement?"":void 0};return {labelProps:Ee,groupProps:Pt,inputProps:Tt,hiddenInputProps:Ft,incrementButtonProps:xt,decrementButtonProps:Nt,descriptionProps:{id:Te,ref:T},errorMessageProps:{id:Ce,role:"alert","aria-live":"polite"}}}function ft({value:t,defaultValue:e,onChange:r}){let n=t!==void 0,i=at.useRef(n);typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production"&&i.current!==n&&console.warn("[raqam] Switching between controlled and uncontrolled. Pick one and keep it.");let[o,l]=at.useState(e),a=at.useCallback(v=>{let g=typeof v=="function"?v(n?t:o):v;n||l(g),r?.(g);},[n,t,o,r]);return [n?t:o,a]}function it(t,e,r){let n=t;return e!==void 0&&Number.isFinite(e)&&(n=Math.max(n,e)),r!==void 0&&Number.isFinite(r)&&(n=Math.min(n,r)),n}function pt(t,e){let r=Math.max(bt(t),bt(e));if(r>15)return t+e;let n=10**r,i=t*n,o=e*n;return !Number.isSafeInteger(Math.round(i))||!Number.isSafeInteger(Math.round(o))?t+e:Math.round(i+o)/n}function bt(t){if(!Number.isFinite(t))return 0;let e=String(t),r=e.indexOf("e");if(r!==-1){let i=Number(e.slice(r+1)),o=e.indexOf("."),l=o===-1?0:r-o-1;return Math.max(0,l-i)}let n=e.indexOf(".");return n===-1?0:e.length-n-1}function vt(t){let{locale:e,formatOptions:r,minValue:n,maxValue:i,step:o=1,largeStep:l,smallStep:a,allowNegative:v=true,allowDecimal:g=true,maximumFractionDigits:I,minimumFractionDigits:L,fixedDecimalScale:R,clampBehavior:F="blur",prefix:x,suffix:D,allowOutOfRange:M=false,validate:re,onRawChange:q,formatValue:C}=t,B=Number.isFinite(o)&&o>0?o:1,H=Number.isFinite(n)?n:void 0,u=Number.isFinite(i)?i:void 0,{effMinFrac:W,effMaxFrac:j,effFixedScale:se}=chunkPM3EDICU_cjs.c({allowDecimal:g,minimumFractionDigits:L,maximumFractionDigits:I,fixedDecimalScale:R}),ie=JSON.stringify(r??{}),E=at.useMemo(()=>chunkPM3EDICU_cjs.d({locale:e,formatOptions:r,prefix:x,suffix:D,minimumFractionDigits:W,maximumFractionDigits:j,fixedDecimalScale:se}),[e,ie,x,D,W,j,se]),_=at.useMemo(()=>chunkPM3EDICU_cjs.e({locale:e,formatOptions:r,allowNegative:v,allowDecimal:g,prefix:x,suffix:D}),[e,ie,v,g,x,D]),[O,G]=ft({value:t.value,defaultValue:t.defaultValue??null,onChange:t.onChange}),J=at.useRef(t.value??t.defaultValue??null),K=at.useCallback(c=>C?C(Object.is(c,-0)?0:c):E.format(Object.is(c,-0)?0:c),[E,C]),ce=at.useMemo(()=>t.defaultValue!=null?K(t.defaultValue):t.value!=null?K(t.value):"",[]),[ve,ae]=at.useState(ce),U=at.useRef(ce),Me=at.useCallback(()=>U.current,[]),ge=at.useRef(ce),[Re,Se]=at.useState(t.defaultValue!=null?String(t.defaultValue):null),Te=at.useCallback(c=>{if(!re)return {validationState:"valid",validationError:null};let h=re(c);return h===false?{validationState:"invalid",validationError:null}:typeof h=="string"?{validationState:"invalid",validationError:h}:{validationState:"valid",validationError:null}},[re]),Ce=at.useMemo(()=>{let c=t.defaultValue??t.value??null;return Te(c??null)},[]),[we,Le]=at.useState(Ce.validationState),[Ae,N]=at.useState(Ce.validationError),[qe,Oe]=at.useState(false),[Q,$]=at.useState(false),de=at.useRef("input"),w=at.useCallback(c=>{de.current=c;},[]),ke=at.useCallback(()=>de.current,[]),Z=t.value,_e=at.useRef(Z);if(!Object.is(_e.current,Z)&&(_e.current=Z,!Object.is(Z,J.current))){J.current=Z;let c=Object.is(Z,-0)?0:Z,h=c!=null&&Number.isFinite(c),V=h?K(c):"";ge.current=V,U.current=V,ae(V),Se(h?String(c):null);}let Ve=`${e??""}|${ie}|${x??""}|${D??""}|${W??""}|${j??""}|${se??""}`,Be=at.useRef(Ve);if(Be.current!==Ve&&(Be.current=Ve,O!=null&&Number.isFinite(O)&&!Q)){let c=K(O);c!==ve&&(ae(c),ge.current=c,U.current=c);}let me=at.useCallback(c=>{let{validationState:h,validationError:V}=Te(c);Le(h),N(V);},[Te]),We=at.useCallback((c,h)=>{let V=_.parse(c),T=h!==void 0?h:V.value;if(F==="strict"&&!M&&T!==null&&(H!==void 0&&T<H||u!==void 0&&T>u))return;U.current=c,ae(c),J.current=T,G(T);let oe=null;if(T!==null){let Ee=_.strip(c);/\d/.test(Ee)&&Number(Ee)===T?oe=T===0&&Ee.startsWith("-")?Ee.slice(1):Ee:oe=String(T);}Se(oe),q?.(oe),me(T);},[_,F,M,H,u,G,q,me]),ee=at.useCallback(c=>{let h=c!==null&&!Number.isFinite(c)?null:c,V=h!=null?K(h):"";if(U.current=V,J.current=h,G(h),ae(V),ge.current=V,h!=null){let T=String(h);Se(T),q?.(T);}else Se(null),q?.(null);me(h);},[K,G,q,me]),Ge=at.useCallback(()=>{if(O==null||!Number.isFinite(O))return U.current="",ae(""),ge.current="",null;let c=O;F==="blur"&&!M&&(c=it(O,H,u)),Object.is(c,-0)&&(c=0);let h=K(c);U.current=h,ae(h),ge.current=h;let V=c;if(!C){let T=_.parse(h).value;T!==null&&Number.isFinite(T)&&K(T)===h&&(V=T);}return V!==O&&(J.current=V,G(V)),me(V),V},[O,F,M,H,u,_,K,C,G,me]),ue=O!=null&&Number.isFinite(O)?O:null,Xe=Number.isFinite(l)&&l>0?l:B*10,Je=Number.isFinite(a)&&a>0?a:B*.1,Qe=!t.disabled&&!t.readOnly&&(M||u===void 0||(ue??Number.NEGATIVE_INFINITY)<u),Ze=!t.disabled&&!t.readOnly&&(M||H===void 0||(ue??Number.POSITIVE_INFINITY)>H),je=at.useCallback(c=>{let T=pt(ue??0,c??B),oe=M?T:it(T,H,u);ee(oe);},[ue,B,H,u,M,ee]),ut=at.useCallback(c=>{let T=pt(ue??0,-(c??B)),oe=M?T:it(T,H,u);ee(oe);},[ue,B,H,u,M,ee]),De=at.useCallback(()=>{u!==void 0&&ee(u);},[u,ee]),et=at.useCallback(()=>{H!==void 0&&ee(H);},[H,ee]);return {inputValue:ve,numberValue:ue,rawValue:Re,canIncrement:Qe,canDecrement:Ze,isScrubbing:qe,setIsScrubbing:Oe,isFocused:Q,setIsFocused:$,validationState:we,validationError:Ae,_setLastChangeReason:w,_getLastChangeReason:ke,_getLatestDisplay:Me,setInputValue:We,setNumberValue:ee,commit:Ge,increment:je,decrement:ut,incrementToMax:De,decrementToMin:et,options:{...t,step:B,largeStep:Xe,smallStep:Je,minValue:H,maxValue:u}}}function St(t,e={}){let{direction:r="horizontal",pixelSensitivity:n=4,label:i="Scrub to change value"}=e,[o,l]=at.useState(false),a=at.useRef(t);a.current=t;let v=at.useRef(r);v.current=r;let g=at.useRef(n);g.current=n;let I=at.useRef(false),L=at.useRef(0),R=at.useRef(null),F=at.useRef({x:0,y:0}),[x,D]=at.useState({x:0,y:0}),M=at.useRef(u=>{if(!I.current)return;let W=F.current.x+u.movementX,j=F.current.y+u.movementY;F.current={x:W,y:j},D({x:W,y:j});let se=v.current,ie=0;se==="horizontal"?ie=u.movementX:se==="vertical"?ie=-u.movementY:ie=Math.abs(u.movementX)>=Math.abs(u.movementY)?u.movementX:-u.movementY,L.current+=ie;let E=Math.max(1,g.current);for((L.current>=E||L.current<=-E)&&a.current._setLastChangeReason("scrub");L.current>=E;)a.current.increment(),L.current-=E;for(;L.current<=-E;)a.current.decrement(),L.current+=E;}),re=at.useRef(()=>{document.pointerLockElement===R.current?(I.current=true,L.current=0,l(true),a.current.setIsScrubbing(true),document.addEventListener("mousemove",M.current)):(I.current=false,L.current=0,document.removeEventListener("mousemove",M.current),l(false),a.current.setIsScrubbing(false));});at.useEffect(()=>{let u=re.current;return document.addEventListener("pointerlockchange",u),()=>{document.removeEventListener("pointerlockchange",u),document.removeEventListener("mousemove",M.current),typeof document.exitPointerLock=="function"&&document.pointerLockElement&&document.pointerLockElement===R.current&&document.exitPointerLock(),I.current&&(I.current=false,L.current=0,a.current.setIsScrubbing(false));}},[]);let q=at.useCallback(u=>{if(a.current.options.disabled||a.current.options.readOnly||u.button!==0)return;let W=u.currentTarget;R.current=W,F.current={x:u.clientX,y:u.clientY},D({x:u.clientX,y:u.clientY});let j=W.requestPointerLock();j&&typeof j.then=="function"&&j.catch(()=>{R.current=null;});},[]),C=at.useCallback(u=>{a.current.options.disabled||a.current.options.readOnly||(u.key==="ArrowRight"||u.key==="ArrowUp"?(u.preventDefault(),a.current._setLastChangeReason("scrub"),a.current.increment()):(u.key==="ArrowLeft"||u.key==="ArrowDown")&&(u.preventDefault(),a.current._setLastChangeReason("scrub"),a.current.decrement()));},[]),B=r==="horizontal"?"ew-resize":r==="vertical"?"ns-resize":"move",H={role:"slider",tabIndex:t.options.disabled?-1:0,style:{cursor:t.options.disabled?void 0:B,userSelect:"none",WebkitUserSelect:"none"},"aria-label":i,"aria-valuenow":t.numberValue??void 0,"aria-valuemin":t.options.minValue,"aria-valuemax":t.options.maxValue,"aria-valuetext":t.inputValue||void 0,"aria-disabled":t.options.disabled?true:void 0,"data-scrubbing":o?"":void 0,onPointerDown:q,onKeyDown:C};return {isScrubbing:o,scrubAreaProps:H,virtualCursor:x}}function be(t,e,r,n){if(!e)return t;let i={...t.props};if(n!=null&&(i.ref=n),typeof e=="function")return e(i,r);let o=Object.assign({},i,e.props);return n!=null&&(o.ref=n),at__default.default.cloneElement(e,o)}var Et=Number.parseInt(at__default.default.version,10)>=19,Kt=Et;function Ut(t){return Et?t.props.ref:t.ref}function ht(...t){let e=n=>{let i=[];for(let o of t)if(o!=null)if(typeof o=="function"){let l=o(n);i.push(typeof l=="function"?l:()=>o(null));}else o.current=n,i.push(()=>{o.current=null;});return i};if(Kt)return n=>{let i=e(n);return ()=>{for(let o of i)o();}};let r=[];return n=>{for(let i of r)i();r=n==null?[]:e(n);}}function $t(t,e){let{options:r}=t;return {"data-disabled":r.disabled?"":void 0,"data-readonly":r.readOnly?"":void 0,"data-required":r.required?"":void 0,"data-scrubbing":t.isScrubbing?"":void 0,"data-focused":t.isFocused?"":void 0,"data-invalid":e?"":void 0}}var zt=new Set(["className","style","id","tabIndex","title","role","aria-label","data-testid","onClick","onMouseEnter","onMouseLeave"]);function Yt(t){let e={},r={};for(let[n,i]of Object.entries(t))zt.has(n)||n.startsWith("data-")||n.startsWith("aria-")?r[n]=i:e[n]=i;return {fieldProps:e,divProps:r}}var qt=at.forwardRef(function({children:e,onValueChange:r,onValueCommitted:n,...i},o){let l=at.useRef(null),{fieldProps:a,divProps:v}=Yt(i),g=a,I=at.useRef(r);I.current=r;let L=at.useRef(null),R={...g,onValueCommitted:n,onChange:M=>{g.onChange?.(M),I.current&&L.current&&I.current(M,{reason:L.current._getLastChangeReason(),formattedValue:L.current._getLatestDisplay()});}},F=vt(R);L.current=F;let x=mt(R,F,l),D=F.validationState==="invalid"||F.numberValue!==null&&(g.minValue!==void 0&&F.numberValue<g.minValue||g.maxValue!==void 0&&F.numberValue>g.maxValue);return jsxRuntime.jsx(nt.Provider,{value:{state:F,aria:x,inputRef:l,props:R},children:jsxRuntime.jsx("div",{ref:o,...v,...$t(F,D),children:e})})}),Wt=at.forwardRef(function({render:e,children:r,...n},i){let{aria:o,state:l}=X(),{ref:a,...v}=o.labelProps,g=at__default.default.isValidElement(e)?Ut(e):void 0,I=at.useMemo(()=>ht(i,a,g),[i,a,g]),L=jsxRuntime.jsx("label",{ref:I,...v,...n,children:r});return be(L,e,l,I)}),Gt=at.forwardRef(function({render:e,children:r,...n},i){let{aria:o,state:l}=X(),a=jsxRuntime.jsx("div",{ref:i,...o.groupProps,...n,children:r});return be(a,e,l)}),Xt=at.forwardRef(function({render:e,...r},n){let{aria:i,state:o,inputRef:l}=X(),a=[r["aria-describedby"],i.inputProps["aria-describedby"]].filter(Boolean).join(" ")||void 0,v=jsxRuntime.jsx("input",{ref:l,...i.inputProps,...r,"aria-describedby":a});return be(v,e,o)}),Jt=at.forwardRef(function({render:e,children:r,...n},i){let{aria:o,state:l}=X(),a=jsxRuntime.jsx("button",{ref:i,...o.incrementButtonProps,...n,children:r??"+"});return be(a,e,l)}),Qt=at.forwardRef(function({render:e,children:r,...n},i){let{aria:o,state:l}=X(),a=jsxRuntime.jsx("button",{ref:i,...o.decrementButtonProps,...n,children:r??"\u2212"});return be(a,e,l)}),Zt=function(){let{aria:e}=X();return e.hiddenInputProps?jsxRuntime.jsx("input",{...e.hiddenInputProps}):null},en=at.forwardRef(function({render:e,children:r,direction:n="horizontal",pixelSensitivity:i=4,label:o,...l},a){let{state:v}=X(),{scrubAreaProps:g}=St(v,{direction:n,pixelSensitivity:i,label:o}),I=jsxRuntime.jsx("span",{ref:a,...g,...l,children:r});return be(I,e,v)}),tn=at.forwardRef(function({render:e,children:r,style:n,...i},o){let{state:l}=X();if(!l.isScrubbing)return null;let a=jsxRuntime.jsx("span",{ref:o,style:{position:"fixed",pointerEvents:"none",zIndex:9999,...n},...i,children:r});return be(a,e,l)}),nn=at.forwardRef(function({children:e,...r},n){let{aria:i}=X(),{ref:o,...l}=i.descriptionProps,a=at.useMemo(()=>ht(n,o),[n,o]);return jsxRuntime.jsx("p",{ref:a,...l,...r,children:e})}),rn=at.forwardRef(function({children:e,...r},n){let{aria:i,state:o}=X(),l=e??o.validationError??null;return l?jsxRuntime.jsx("p",{ref:n,...i.errorMessageProps,...r,children:l}):null}),on=at.forwardRef(function({render:e,style:r,...n},i){let{state:o,aria:l}=X(),a=l.inputProps.style!=null,v=a?{direction:"ltr",textAlign:"right",unicodeBidi:"plaintext",...r}:{unicodeBidi:"isolate",...r},g=jsxRuntime.jsx("span",{ref:i,"aria-hidden":"true","data-rtl":a?"":void 0,style:v,...n,children:o.inputValue});return be(g,e,o)}),An={Root:qt,Label:Wt,Group:Gt,Input:Xt,Increment:Jt,Decrement:Qt,HiddenInput:Zt,ScrubArea:en,ScrubAreaCursor:tn,Description:nn,ErrorMessage:rn,Formatted:on};function jn(t,e={}){let{locale:r,formatOptions:n,prefix:i,suffix:o,minimumFractionDigits:l,maximumFractionDigits:a,fixedDecimalScale:v}=e,g=at.useMemo(()=>chunkPM3EDICU_cjs.d({locale:r,formatOptions:n,prefix:i,suffix:o,minimumFractionDigits:l,maximumFractionDigits:a,fixedDecimalScale:v}),[r,JSON.stringify(n),i,o,l,a,v]);return at.useMemo(()=>t==null?"":g.format(t),[t,g])}exports.a=nt;exports.b=X;exports.c=rt;exports.d=mt;exports.e=ft;exports.f=vt;exports.g=St;exports.h=An;exports.i=jn;//# sourceMappingURL=chunk-XCKMM244.cjs.map
|
|
2
|
+
//# sourceMappingURL=chunk-XCKMM244.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/context.ts","../src/react/usePressAndHold.ts","../src/react/useIsomorphicLayoutEffect.ts","../src/react/useNumberField.ts","../src/react/useControllableState.ts","../src/react/useNumberFieldState.ts","../src/react/useScrubArea.ts","../src/react/NumberField.tsx","../src/react/useNumberFieldFormat.ts"],"names":["NumberFieldContext","createContext","useNumberFieldContext","ctx","useContext","usePressAndHold","callback","options","delay","interval","disabled","callbackRef","useRef","useEffect","delayRef","intervalRef","disabledRef","delayTimerRef","repeatTimerRef","isHeldRef","clearTimers","useCallback","scheduleRepeat","currentInterval","nextInterval","onPointerDown","e","onPointerUp","onPointerLeave","onPointerCancel","onLostPointerCapture","useIsomorphicLayoutEffect","useLayoutEffect","escapeRegex","s","useMountedFlag","countRef","mounted","setMounted","useState","ref","node","activeElementWithin","root","MAGNITUDE_MULTIPLIERS","parseSpecialNotation","t","m","useNumberField","props","state","inputRef","locale","formatOptions","rawMinValue","rawMaxValue","allowNegative","allowDecimal","allowMouseWheel","rawLiveFormat","prefix","suffix","name","readOnly","required","onFocus","onBlur","maximumFractionDigits","minimumFractionDigits","fixedDecimalScale","copyBehavior","stepHoldDelay","stepHoldInterval","incrementLabel","decrementLabel","customFormatValue","customParseValue","onValueCommitted","minValue","maxValue","notation","liveFormat","formatOptionsKey","step","largeStep","smallStep","autoId","useId","inputId","labelId","descriptionId","errorId","effMinFrac","effMaxFrac","effFixedScale","resolveEffectiveFractions","formatter","useMemo","createFormatter","isPercentStyle","liveMaxFrac","liveFormatter","parser","createParser","formatGroupedFraction","value","source","info","decIdx","normalizeDigits","fracMatch","fracLen","pendingCursor","stateRef","el","handler","isComposing","handleCompositionStart","handleCompositionEnd","composedValue","normalized","displayValue","composedKnownValue","result","localizeDigits","computeNewCursorPosition","handleChange","rawInputValue","cursorPos","inputType","_m","offset","str","knownValue","rt","handlePaste","text","stripped","li","formatted","special","sval","localeInfo","allowedCharsPattern","stripped2","result2","handleCopy","handleCut","handleKeyDown","key","input","decPos","cursor","selEnd","currentValue","rawEdited","parseResult","nextDisplay","isDigitChar","ch","isAffordanceChar","i","direction","committed","handleBlur","handleFocus","incrementHold","decrementHold","ariaValueText","isInvalid","hasLabel","labelRef","ariaLabelledBy","hasDescription","descriptionRef","ariaDescribedBy","labelProps","groupProps","inputProps","hiddenInputProps","incrementButtonProps","decrementButtonProps","useControllableState","defaultValue","onChange","isControlled","wasControlled","internalValue","setInternalValue","set","next","nextValue","clamp","min","max","v","preciseAdd","a","b","precision","decimalPlaces","factor","sa","sb","n","eIdx","exp","dotIdx","idx","useNumberFieldState","rawStep","rawLargeStep","rawSmallStep","clampBehavior","allowOutOfRange","validate","onRawChange","numberValue","setNumberValue","lastEmittedRef","formatDisplay","initialDisplay","inputValue","setInputValueRaw","latestDisplayRef","_getLatestDisplay","lastFormattedRef","rawValue","setRawValueState","runValidation","val","initialValidation","initVal","validationState","setValidationState","validationError","setValidationError","isScrubbing","setIsScrubbing","isFocused","setIsFocused","lastChangeReasonRef","_setLastChangeReason","reason","_getLastChangeReason","externalValue","prevExternalValueRef","ev","finite","formatKey","prevFormatKeyRef","applyValidation","vs","ve","setInputValue","parsed","raw","setNumericValue","rawVal","rawStr","commit","clamped","reparsed","safeNumberValue","resolvedLargeStep","resolvedSmallStep","canIncrement","canDecrement","increment","amount","decrement","incrementToMax","decrementToMin","useScrubArea","pixelSensitivity","label","setIsScrubbingLocal","directionRef","sensitivityRef","isScrubbingRef","accumulatorRef","elementRef","virtualCursorRef","virtualCursor","setVirtualCursor","stableMouseMove","nx","ny","dir","delta","sensitivity","stablePointerLockChange","onKeyDown","cursorStyle","scrubAreaProps","renderWith","defaultElement","render","forwardedRef","baseProps","merged","React","REF_IN_PROPS","SUPPORTS_REF_CLEANUP","getElementRef","mergeRefs","refs","attach","cleanups","cleanup","stateDataAttrs","DIV_ONLY_KEYS","splitProps","fieldProps","divProps","Root","forwardRef","children","onValueChange","allProps","onValueChangeRef","wrappedProps","aria","jsx","Label","rest","renderRef","mergedRef","Group","Input","_ref","describedBy","Increment","Decrement","HiddenInput","ScrubArea","ScrubAreaCursor","style","Description","descRef","descriptionProps","ErrorMessage","content","Formatted","isRTL","mergedStyle","NumberField","useNumberFieldFormat"],"mappings":"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","file":"chunk-XCKMM244.cjs","sourcesContent":["import type { RefObject } from \"react\";\nimport { createContext, useContext } from \"react\";\nimport type { NumberFieldAria, NumberFieldState, UseNumberFieldProps } from \"../core/types.js\";\n\n// Locally declared so the dev-only gate type-checks without @types/node.\ndeclare const process: { env?: Record<string, string | undefined> } | undefined;\n\nexport interface NumberFieldContextValue {\n state: NumberFieldState;\n aria: NumberFieldAria;\n inputRef: RefObject<HTMLInputElement | null>;\n props: UseNumberFieldProps;\n}\n\nexport const NumberFieldContext = createContext<NumberFieldContextValue | null>(null);\n\n/**\n * Hook for sub-components to access the NumberField context.\n * Throws if used outside NumberField.Root.\n */\nexport function useNumberFieldContext(): NumberFieldContextValue {\n const ctx = useContext(NumberFieldContext);\n if (!ctx) {\n // Full guidance in dev; production bundlers strip the guarded branch and ship\n // only the short identifiable message below. The `typeof process` /\n // `process.env` guards keep it crash-safe under raw-browser ESM and partial\n // `process` shims; both sit on the eliminated side of the NODE_ENV token.\n if (typeof process !== \"undefined\" && process.env && process.env.NODE_ENV !== \"production\") {\n throw new Error(\"[raqam] NumberField sub-components must be used inside <NumberField.Root>.\");\n }\n throw new Error(\"[raqam] <NumberField.Root> missing\");\n }\n return ctx;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\n\nexport interface UsePressAndHoldOptions {\n /** Milliseconds before repeating starts (default: 400) */\n delay?: number;\n /** Initial milliseconds between repeats — halves each tick, floors at 50 (default: 200) */\n interval?: number;\n /** Whether the element is disabled */\n disabled?: boolean;\n}\n\nexport interface PressAndHoldProps {\n onPointerDown: (e: React.PointerEvent) => void;\n onPointerUp: (e: React.PointerEvent) => void;\n onPointerLeave: (e: React.PointerEvent) => void;\n onPointerCancel: (e: React.PointerEvent) => void;\n onLostPointerCapture: (e: React.PointerEvent) => void;\n}\n\n/**\n * Returns pointer event handlers that call `callback` immediately on press,\n * then repeatedly with accelerating frequency while held down.\n *\n * Acceleration schedule (default settings):\n * immediate → 400ms wait → 200ms → 100ms → 50ms (floor, stays until release)\n *\n * All timing is handled via refs — zero state updates, zero re-renders.\n */\nexport function usePressAndHold(\n callback: () => void,\n options: UsePressAndHoldOptions = {}\n): PressAndHoldProps {\n const { delay = 400, interval = 200, disabled = false } = options;\n\n // Stable refs so handlers don't re-create on every render\n const callbackRef = useRef(callback);\n useEffect(() => {\n callbackRef.current = callback;\n });\n\n const delayRef = useRef(delay);\n useEffect(() => {\n delayRef.current = delay;\n });\n\n const intervalRef = useRef(interval);\n useEffect(() => {\n intervalRef.current = interval;\n });\n\n // Track disabled in a ref so an in-flight repeat loop can stop the instant the\n // control becomes disabled (e.g. the value hits min/max) — a disabled <button>\n // stops dispatching the pointerup/leave that would normally clear the timer.\n const disabledRef = useRef(disabled);\n useEffect(() => {\n disabledRef.current = disabled;\n });\n\n // Timer handle refs (null = no active timer)\n const delayTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const repeatTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isHeldRef = useRef(false);\n\n const clearTimers = useCallback(() => {\n isHeldRef.current = false;\n if (delayTimerRef.current !== null) {\n clearTimeout(delayTimerRef.current);\n delayTimerRef.current = null;\n }\n if (repeatTimerRef.current !== null) {\n clearTimeout(repeatTimerRef.current);\n repeatTimerRef.current = null;\n }\n }, []);\n\n // Recursive accelerating repeat\n const scheduleRepeat = useCallback(\n (currentInterval: number) => {\n if (!isHeldRef.current || disabledRef.current) {\n clearTimers();\n return;\n }\n callbackRef.current();\n const nextInterval = Math.max(50, Math.floor(currentInterval / 2));\n repeatTimerRef.current = setTimeout(() => {\n scheduleRepeat(nextInterval);\n }, currentInterval);\n },\n [clearTimers]\n );\n\n const onPointerDown = useCallback(\n (e: React.PointerEvent) => {\n if (disabled) return;\n // Only primary button (left mouse / single touch / pen)\n if (e.button !== 0 && e.pointerType === \"mouse\") return;\n\n // Fire immediately\n callbackRef.current();\n isHeldRef.current = true;\n\n // After initial delay, start accelerating repeats\n delayTimerRef.current = setTimeout(() => {\n scheduleRepeat(intervalRef.current);\n }, delayRef.current);\n },\n [disabled, scheduleRepeat]\n );\n\n const onPointerUp = useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n clearTimers();\n },\n [clearTimers]\n );\n\n const onPointerLeave = useCallback(\n (e: React.PointerEvent) => {\n void e;\n clearTimers();\n },\n [clearTimers]\n );\n\n // Touch interruptions (scroll/gesture) and pointer-capture loss must also stop\n // the repeat — otherwise the timer keeps firing with no release event.\n const onPointerCancel = useCallback(\n (e: React.PointerEvent) => {\n void e;\n clearTimers();\n },\n [clearTimers]\n );\n\n const onLostPointerCapture = useCallback(\n (e: React.PointerEvent) => {\n void e;\n clearTimers();\n },\n [clearTimers]\n );\n\n // Stop an in-flight repeat as soon as the control becomes disabled — a disabled\n // <button> no longer fires pointerup/leave, so the loop would otherwise run on.\n useEffect(() => {\n if (disabled) clearTimers();\n }, [disabled, clearTimers]);\n\n // Safety: clear on unmount\n useEffect(() => clearTimers, [clearTimers]);\n\n return { onPointerDown, onPointerUp, onPointerLeave, onPointerCancel, onLostPointerCapture };\n}\n","\"use client\";\n\nimport { useEffect, useLayoutEffect } from \"react\";\n\n/**\n * `useLayoutEffect` in the browser, `useEffect` on the server — avoids React's\n * \"useLayoutEffect does nothing on the server\" warning for SSR consumers while\n * keeping synchronous cursor restoration on the client.\n */\nexport const useIsomorphicLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n","\"use client\";\n\nimport { useCallback, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport { computeNewCursorPosition } from \"../core/cursor.js\";\nimport { createFormatter, resolveEffectiveFractions } from \"../core/formatter.js\";\nimport { localizeDigits, normalizeDigits } from \"../core/normalizer.js\";\nimport { createParser } from \"../core/parser.js\";\nimport type { NumberFieldAria, NumberFieldState, UseNumberFieldProps } from \"../core/types.js\";\nimport { useIsomorphicLayoutEffect } from \"./useIsomorphicLayoutEffect.js\";\nimport { usePressAndHold } from \"./usePressAndHold.js\";\n\n// ── Tiny helper to safely escape regex special chars (including hyphen) ──────\n\nfunction escapeRegex(s: string): string {\n // The hyphen is kept last in the character class so it reads as a literal\n // rather than a range indicator, no escape needed.\n return s.replace(/[.*+?^${}()|[\\]\\\\-]/g, \"\\\\$&\");\n}\n\n/**\n * Track whether at least one element registered through the returned ref\n * callback is currently mounted. Lets `aria-labelledby` / `aria-describedby`\n * point at the label / description only while one truly exists — for any render\n * path (built-in component, custom primitive, or headless) — instead of\n * dangling at an element that isn't rendered. Ref-counted so multiple mounts and\n * StrictMode's double-invoke settle to the correct flag.\n */\nfunction useMountedFlag(): [boolean, React.RefCallback<HTMLElement>] {\n const countRef = useRef(0);\n const [mounted, setMounted] = useState(false);\n const ref = useCallback<React.RefCallback<HTMLElement>>((node) => {\n if (node) {\n countRef.current += 1;\n setMounted(true);\n } else if (countRef.current > 0) {\n countRef.current -= 1;\n if (countRef.current === 0) setMounted(false);\n }\n }, []);\n return [mounted, ref];\n}\n\n/**\n * The focused element resolved through the node's *root* — `document` in the\n * light DOM, or the containing `ShadowRoot` when the field is inside a shadow\n * tree (where `document.activeElement` only reports the host). Falls back to\n * `document.activeElement` when no node is available.\n */\nfunction activeElementWithin(node: Element | null): Element | null {\n const root = node?.getRootNode() as Document | ShadowRoot | undefined;\n if (root && \"activeElement\" in root) return root.activeElement;\n return typeof document !== \"undefined\" ? document.activeElement : null;\n}\n\n// Magnitude suffixes for compact-notation paste (\"1.5K\", \"3.4M\"). Module-scoped\n// so it isn't rebuilt on every paste.\nconst MAGNITUDE_MULTIPLIERS: Record<string, number> = {\n k: 1e3,\n thousand: 1e3,\n m: 1e6,\n million: 1e6,\n b: 1e9,\n billion: 1e9,\n t: 1e12,\n trillion: 1e12,\n};\n\n/**\n * Parse scientific (\"1e3\", \"1.23E4\") and compact (\"1.5K\", \"3.4M\") notation that\n * the plain locale parser cannot handle. Used on paste so values copied from\n * spreadsheets / dashboards round-trip instead of being mangled by char-strip.\n * Returns null when `s` is not one of these forms.\n */\nfunction parseSpecialNotation(s: string): number | null {\n // Bound length before the regexes (this runs on attacker-controllable paste\n // text). The patterns are also de-ambiguated below so they match in linear\n // time — together this closes the ReDoS on the paste path.\n if (s.length > 256) return null;\n const t = s.replace(/\\s+/g, \"\");\n // Note the de-ambiguated mantissa `\\d+(?:\\.\\d*)?|\\.\\d+` (no overlapping\n // `\\d+\\.?\\d*` alternation) — the old form backtracked quadratically on a long\n // failing input.\n if (/^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)[eE][+-]?\\d+$/.test(t)) {\n const n = Number(t);\n return Number.isFinite(n) ? n : null;\n }\n const m = t.match(/^([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+))(k|m|b|t|thousand|million|billion|trillion)$/i);\n if (m) {\n const n = Number(m[1]) * MAGNITUDE_MULTIPLIERS[m[2].toLowerCase()]!;\n return Number.isFinite(n) ? n : null;\n }\n return null;\n}\n\nexport function useNumberField(\n props: UseNumberFieldProps,\n state: NumberFieldState,\n inputRef: React.RefObject<HTMLInputElement | null>\n): NumberFieldAria {\n const {\n locale,\n formatOptions,\n minValue: rawMinValue,\n maxValue: rawMaxValue,\n allowNegative = true,\n allowDecimal = true,\n allowMouseWheel = false,\n liveFormat: rawLiveFormat = true,\n prefix,\n suffix,\n name,\n disabled,\n readOnly,\n required,\n onFocus,\n onBlur,\n maximumFractionDigits,\n minimumFractionDigits,\n fixedDecimalScale,\n copyBehavior = \"formatted\",\n stepHoldDelay = 400,\n stepHoldInterval = 200,\n incrementLabel = \"Increase\",\n decrementLabel = \"Decrease\",\n formatValue: customFormatValue,\n parseValue: customParseValue,\n onValueCommitted,\n } = props; // formatValue/parseValue are on UseNumberFieldStateOptions (inherited)\n\n // Drop non-finite bounds (mirrors useNumberFieldState) so aria-valuemin/max\n // never render \"NaN\"/\"Infinity\" and out-of-range / Home / End never act on a\n // bad bound.\n const minValue = Number.isFinite(rawMinValue) ? rawMinValue : undefined;\n const maxValue = Number.isFinite(rawMaxValue) ? rawMaxValue : undefined;\n\n // Compact/scientific/engineering notation produce formatted strings (\"2.5K\",\n // \"1.5E3\") whose suffix/exponent characters collide with continued typing, so\n // we keep the raw typed digits live and only format on blur/commit.\n const notation = formatOptions?.notation;\n const liveFormat =\n rawLiveFormat &&\n notation !== \"compact\" &&\n notation !== \"scientific\" &&\n notation !== \"engineering\";\n\n // Serialize formatOptions once per render — it feeds four useMemo dependency\n // arrays below and JSON.stringify is not free for non-trivial option objects.\n const formatOptionsKey = JSON.stringify(formatOptions);\n\n const { step = 1, largeStep = step * 10, smallStep = step * 0.1 } = state.options;\n\n const autoId = useId();\n const inputId = props.id ?? `raqam-${autoId}`;\n const labelId = `${inputId}-label`;\n const descriptionId = `${inputId}-description`;\n const errorId = `${inputId}-error`;\n\n // ── Formatter & parser (kept in sync with state's) ──────────────────────\n // Same effective-fraction resolution as the state hook, via one shared helper,\n // so the live-typing and on-commit displays can never drift apart.\n const { effMinFrac, effMaxFrac, effFixedScale } = resolveEffectiveFractions({\n allowDecimal,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n });\n\n const formatter = useMemo(\n () =>\n createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits: effMinFrac,\n maximumFractionDigits: effMaxFrac,\n fixedDecimalScale: effFixedScale,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, prefix, suffix, effMinFrac, effMaxFrac, effFixedScale]\n );\n\n // Live-typing formatter: keeps grouping + currency symbol but drops the\n // minimum-fraction *padding* (\".00\") so currency / fixedDecimalScale fields\n // group correctly while typing and never accumulate padding zeros. The full\n // `formatter` (with padding) is applied on commit/blur.\n //\n // Percent fields default to maximumFractionDigits:0, which would round away\n // the fraction the user is typing (\"12.5\" → \"13%\") and — because the rounded\n // string is shorter — corrupt the next keystroke. Give the percent live\n // formatter room so typing never rounds; commit() rounds to the real scale.\n const isPercentStyle = formatOptions?.style === \"percent\";\n const liveMaxFrac = allowDecimal ? (isPercentStyle ? 20 : effMaxFrac) : 0;\n const liveFormatter = useMemo(\n () =>\n createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits: 0,\n maximumFractionDigits: liveMaxFrac,\n fixedDecimalScale: false,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, prefix, suffix, liveMaxFrac]\n );\n\n const parser = useMemo(\n () =>\n createParser({\n locale,\n formatOptions,\n allowNegative,\n allowDecimal,\n prefix,\n suffix,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, allowNegative, allowDecimal, prefix, suffix]\n );\n\n // Re-format `value` so its integer part groups while the EXACT typed fraction\n // (incl. trailing zeros) from `source` is preserved. Returns null when there is\n // no integer part (leading-dot \".5\" — keep it raw to avoid a \"0\" prepend that\n // would shift the caret) or no fraction (trailing dot). Used by the typing path\n // and the grouping-comma / trailing-affordance backspace paths so they all\n // preserve typed trailing zeros consistently.\n const formatGroupedFraction = useCallback(\n (value: number, source: string): string | null => {\n const info = formatter.getLocaleInfo();\n let decIdx = source.lastIndexOf(info.decimalSeparator);\n // Fall back to an ASCII \".\" only when it stands in for the decimal point\n // (not when \".\" is the grouping separator, e.g. de-DE — see Fix J).\n if (decIdx === -1 && info.decimalSeparator !== \".\" && info.groupingSeparator !== \".\") {\n decIdx = source.lastIndexOf(\".\");\n }\n if (decIdx === -1) return null;\n if (!/\\d/.test(normalizeDigits(source.slice(0, decIdx)))) return null; // leading dot\n const fracMatch = normalizeDigits(source.slice(decIdx + 1)).match(/^\\d+/);\n if (!fracMatch) return null; // trailing dot\n const fracLen = Math.min(fracMatch[0].length, effMaxFrac ?? 20, 20);\n if (fracLen === 0) return null;\n return createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits: fracLen,\n maximumFractionDigits: fracLen,\n }).format(value);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [formatter, locale, formatOptionsKey, prefix, suffix, effMaxFrac]\n );\n\n // ── Cursor engine ────────────────────────────────────────────────────────\n const pendingCursor = useRef<number | null>(null);\n\n // Stable handle to the latest state so listeners/effects that only *invoke*\n // state methods don't have to list the (per-render fresh) `state` object as a\n // dependency — keeps the native wheel listener from re-subscribing every render.\n const stateRef = useRef(state);\n stateRef.current = state;\n\n // Restore cursor synchronously after React commits the new value to DOM\n useIsomorphicLayoutEffect(() => {\n if (\n pendingCursor.current !== null &&\n inputRef.current &&\n activeElementWithin(inputRef.current) === inputRef.current\n ) {\n inputRef.current.setSelectionRange(pendingCursor.current, pendingCursor.current);\n pendingCursor.current = null;\n }\n // Run after every inputValue change\n }, [state.inputValue, inputRef]);\n\n // ── Mouse wheel (non-passive native listener) ────────────────────────────\n // React's synthetic onWheel is passive in React 17+; it cannot call\n // preventDefault(). We must attach a native, non-passive listener instead.\n useEffect(() => {\n const el = inputRef.current;\n if (!el || !allowMouseWheel) return;\n\n const handler = (e: WheelEvent) => {\n if (disabled || readOnly) return;\n if (activeElementWithin(el) !== el) return;\n e.preventDefault();\n const s = stateRef.current;\n s._setLastChangeReason(\"wheel\");\n if (e.deltaY < 0) {\n s.increment();\n } else {\n s.decrement();\n }\n };\n\n el.addEventListener(\"wheel\", handler, { passive: false });\n return () => el.removeEventListener(\"wheel\", handler);\n }, [allowMouseWheel, disabled, readOnly, inputRef]);\n\n // ── IME Composition state ────────────────────────────────────────────────\n // During CJK IME input, partial composed characters must not trigger live\n // formatting. We suspend formatting during composition and resume on end.\n const isComposing = useRef(false);\n\n const handleCompositionStart = useCallback(() => {\n isComposing.current = true;\n }, []);\n\n const handleCompositionEnd = useCallback(\n (e: React.CompositionEvent<HTMLInputElement>) => {\n isComposing.current = false;\n // After composition ends, run the full format cycle on the composed value\n const composedValue = e.currentTarget.value;\n const info = formatter.getLocaleInfo();\n const normalized = normalizeDigits(composedValue);\n\n let displayValue: string;\n // Thread the custom parser's value through to state — otherwise the state\n // hook re-derives it with the BUILT-IN parser, discarding the custom result.\n let composedKnownValue: number | null | undefined;\n if (customParseValue) {\n const result = customParseValue(normalized);\n // Honor an explicit null too (a custom parser rejecting the composed\n // text), so the built-in parser can't re-derive a value for it.\n composedKnownValue = result.value;\n if (result.isIntermediate) {\n displayValue = normalized;\n } else if (result.value !== null && customFormatValue) {\n displayValue = customFormatValue(result.value);\n } else if (result.value !== null) {\n displayValue = formatter.format(result.value);\n } else {\n displayValue = normalized;\n }\n // Disable cursor engine for custom format/parse\n pendingCursor.current = displayValue.length;\n } else if (liveFormat) {\n const result = parser.parse(normalized);\n if (result.isIntermediate) {\n // Keep the still-typing display in the locale's native digit script.\n displayValue = localizeDigits(normalized, info.zero);\n } else if (result.value !== null) {\n displayValue = customFormatValue\n ? customFormatValue(result.value)\n : liveFormatter.format(result.value);\n } else {\n displayValue = normalized === \"\" ? \"\" : normalized;\n }\n pendingCursor.current = computeNewCursorPosition(\n composedValue,\n composedValue.length,\n displayValue,\n info,\n \"insertCompositionText\"\n );\n } else {\n displayValue = normalized;\n pendingCursor.current = normalized.length;\n }\n\n state._setLastChangeReason(\"input\");\n state.setInputValue(displayValue, composedKnownValue);\n },\n [formatter, liveFormatter, parser, liveFormat, state, customFormatValue, customParseValue]\n );\n\n // ── onChange handler ─────────────────────────────────────────────────────\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const rawInputValue = e.target.value;\n const cursorPos = e.target.selectionStart ?? rawInputValue.length;\n const inputType = (e.nativeEvent as InputEvent).inputType;\n const info = formatter.getLocaleInfo();\n\n // During IME composition, skip live formatting — just track the raw value\n if (isComposing.current) {\n state.setInputValue(rawInputValue);\n return;\n }\n\n // Normalise non-Latin digits\n let normalized = normalizeDigits(rawInputValue);\n\n // Drop characters disallowed by the constraint flags *live*, so the field\n // never shows an invalid string that gets wiped on blur. The minus / dot\n // keys simply do nothing instead of poisoning the value.\n if (!allowNegative) {\n normalized = normalized.split(\"-\").join(\"\").split(info.minusSign).join(\"\");\n }\n if (!allowDecimal) {\n normalized = normalized.split(\".\").join(\"\").split(info.decimalSeparator).join(\"\");\n } else if (info.decimalSeparator !== \".\" && info.groupingSeparator !== \".\") {\n // Latin-keyboard users type the ASCII \".\" as the decimal point even in\n // locales whose separator is non-ASCII (ar/fa: ٫). Map a \".\" that is part\n // of a number (adjacent to a digit) onto the locale separator so the value\n // parses and the caret engine (which only tracks the locale separator)\n // doesn't strand the dot. Dots inside a symbol (e.g. the Arabic currency\n // symbol \"ج.م.\") are NOT adjacent to digits, so they stay untouched.\n // Skipped entirely when \".\" is the grouping separator (e.g. de-DE).\n normalized = normalized.replace(/\\./g, (_m, offset: number, str: string) =>\n /\\d/.test(str[offset - 1] ?? \"\") || /\\d/.test(str[offset + 1] ?? \"\")\n ? info.decimalSeparator\n : \".\"\n );\n }\n\n let displayValue: string;\n let knownValue: number | null | undefined;\n\n // Custom parse/format escape hatch\n if (customParseValue) {\n const result = customParseValue(normalized);\n // Thread the custom parser's value through to state — including an\n // explicit null (a custom parser that rejects input). Otherwise the\n // state hook re-parses the display with the BUILT-IN parser and could\n // emit a number the custom parser deliberately rejected.\n knownValue = result.value;\n if (result.isIntermediate) {\n displayValue = normalized;\n } else if (result.value !== null) {\n displayValue = customFormatValue\n ? customFormatValue(result.value)\n : formatter.format(result.value);\n } else if (normalized === \"\") {\n displayValue = \"\";\n } else {\n displayValue = normalized;\n }\n // Can't predict cursor position with custom formatter — place at end\n pendingCursor.current = displayValue.length;\n } else if (liveFormat) {\n const result = parser.parse(normalized);\n\n if (result.isIntermediate) {\n // A trailing-zero decimal (e.g. \"12.50\") is intermediate, but its\n // integer part should still group live (insert \"99\" into \"$12.50\" must\n // show \"$9,912.50\"). Re-format preserving the typed fraction; lone \"-\",\n // trailing \".\" and leading \".\" keep the raw form.\n const grouped =\n !customFormatValue && result.value !== null\n ? formatGroupedFraction(result.value, normalized)\n : null;\n displayValue = grouped ?? localizeDigits(normalized, info.zero);\n } else if (result.value !== null) {\n if (customFormatValue) {\n displayValue = customFormatValue(result.value);\n } else {\n displayValue = liveFormatter.format(result.value);\n // The display will be re-parsed by setInputValue. For invertible\n // formats that round-trips (and rounds the value to the displayed\n // precision); for non-invertible notation (compact \"2.5K\",\n // scientific, unit) re-parsing destroys magnitude — so pass the\n // exact typed value through when the format does not round-trip.\n const rt = parser.parse(displayValue).value;\n knownValue =\n rt !== null && Number.isFinite(rt) && liveFormatter.format(rt) === displayValue\n ? rt\n : result.value;\n }\n } else if (normalized === \"\" || !/\\d/.test(normalized)) {\n // Empty, or only formatting affordances left (a lone \"%\", suffix, etc.\n // after deleting the last digit) — clear the field instead of stranding\n // the orphaned characters.\n displayValue = \"\";\n } else {\n // Invalid input — keep the raw normalised string so the user can\n // see what they typed (they'll get corrected on blur)\n displayValue = normalized;\n }\n\n if (customFormatValue) {\n // Custom format: can't predict cursor, place at end\n pendingCursor.current = displayValue.length;\n } else {\n // Compute and stash cursor position for the isomorphic layout effect\n pendingCursor.current = computeNewCursorPosition(\n rawInputValue,\n cursorPos,\n displayValue,\n info,\n inputType\n );\n }\n } else {\n // No live format — just pass through normalised digits\n displayValue = normalized;\n pendingCursor.current = cursorPos;\n }\n\n // An edit that empties the field reports the dedicated \"clear\" reason so\n // consumers can distinguish a deletion-to-empty from ordinary typing.\n state._setLastChangeReason(displayValue === \"\" ? \"clear\" : \"input\");\n state.setInputValue(displayValue, knownValue);\n },\n [\n formatter,\n liveFormatter,\n parser,\n liveFormat,\n state,\n customFormatValue,\n customParseValue,\n formatGroupedFraction,\n ]\n );\n\n // ── Paste handler ────────────────────────────────────────────────────────\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n e.preventDefault();\n const text = e.clipboardData.getData(\"text/plain\");\n if (!text) return;\n // Discard absurdly long clipboard payloads up front — no legitimate number\n // is this long, and it bounds every downstream scan/regex on this\n // attacker-controllable input.\n if (text.length > 1000) return;\n\n // 1. Strip common currency symbols (global currencies)\n const stripped = text.replace(/[€$£¥₹₺₽﷼฿₩¢₦₨₪₫₱]/g, \"\").trim();\n\n // 2. Normalize non-Latin digits to ASCII\n let normalized = normalizeDigits(stripped);\n\n // Honour the constraint flags on paste too (drop minus / decimal).\n if (!allowNegative) {\n const li = formatter.getLocaleInfo();\n normalized = normalized.split(\"-\").join(\"\").split(li.minusSign).join(\"\");\n }\n if (!allowDecimal) {\n const li = formatter.getLocaleInfo();\n normalized = normalized.split(\".\").join(\"\").split(li.decimalSeparator).join(\"\");\n }\n\n state._setLastChangeReason(\"paste\");\n\n // Custom parse escape hatch\n if (customParseValue) {\n const result = customParseValue(normalized);\n if (result.value !== null) {\n const formatted = customFormatValue\n ? customFormatValue(result.value)\n : formatter.format(result.value);\n // Pass the known value so a non-invertible format (compact/scientific)\n // is not re-parsed into a wrong magnitude.\n state.setInputValue(formatted, result.value);\n pendingCursor.current = formatted.length;\n }\n return;\n }\n\n // 2.5 Scientific / compact notation (1e3, 1.23E4, 1.5K…) before the\n // locale parser, whose char-strip would otherwise mangle the e / K.\n const special = parseSpecialNotation(normalized);\n if (special !== null) {\n const isPercent = formatOptions?.style === \"percent\";\n const sval = isPercent ? special / 100 : special;\n const formatted = customFormatValue ? customFormatValue(sval) : formatter.format(sval);\n state.setInputValue(formatted, sval);\n pendingCursor.current = formatted.length;\n return;\n }\n\n // 3. Try parse with current locale parser\n const result = parser.parse(normalized);\n\n if (result.value !== null) {\n const formatted = formatter.format(result.value);\n state.setInputValue(formatted, result.value);\n pendingCursor.current = formatted.length;\n return;\n }\n\n // 4. Fallback: strip everything except digits, locale decimal, minus sign\n const localeInfo = formatter.getLocaleInfo();\n const allowedCharsPattern = new RegExp(\n `[^0-9${escapeRegex(localeInfo.decimalSeparator)}${escapeRegex(localeInfo.minusSign)}-]`,\n \"g\"\n );\n const stripped2 = normalized.replace(allowedCharsPattern, \"\");\n const result2 = parser.parse(stripped2);\n\n if (result2.value !== null) {\n const formatted = formatter.format(result2.value);\n state.setInputValue(formatted, result2.value);\n pendingCursor.current = formatted.length;\n }\n // If still invalid, silently discard — don't paste garbage into the field\n },\n [parser, formatter, state, customFormatValue, customParseValue]\n );\n\n // ── Copy / Cut handlers ──────────────────────────────────────────────────\n const handleCopy = useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n if (copyBehavior === \"formatted\") return; // browser handles it natively\n\n e.preventDefault();\n const text = String(state.numberValue ?? \"\");\n e.clipboardData.setData(\"text/plain\", text);\n },\n [copyBehavior, state.numberValue]\n );\n\n const handleCut = useCallback(\n (e: React.ClipboardEvent<HTMLInputElement>) => {\n if (copyBehavior === \"formatted\") return; // browser handles it\n\n e.preventDefault();\n const text = String(state.numberValue ?? \"\");\n e.clipboardData.setData(\"text/plain\", text);\n // Clear the field after cut — report the dedicated \"clear\" reason.\n state._setLastChangeReason(\"clear\");\n state.setInputValue(\"\");\n },\n [copyBehavior, state]\n );\n\n // ── Keyboard handler ─────────────────────────────────────────────────────\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly) return;\n\n const key = e.key;\n\n // Smart backspace: when cursor is immediately after a grouping separator\n // (no selection active, no modifier keys), delete both the separator and\n // the preceding digit so the user can backspace through formatted numbers\n // without the comma \"blocking\" deletion.\n //\n // This must be handled in keydown — by the time onChange fires, the\n // browser has already removed the separator character, making it\n // impossible to detect what was deleted.\n // Smart decimal: when the user types the decimal separator but one already\n // exists in the formatted value (e.g. \"1.00\" with fixedDecimalScale),\n // move the cursor to just after the decimal separator instead of inserting\n // a duplicate. This enables the financial UX pattern:\n // \"1.00\" → type \".\" → cursor jumps after \".\" → type \"5\" → \"1.50\"\n // Same applies for negative values: \"-1.00\" → type \".\" → cursor after \".\"\n if (!e.metaKey && !e.ctrlKey && !e.altKey && allowDecimal) {\n const localeInfo = formatter.getLocaleInfo();\n // Match the locale's decimal separator key (e.g. \".\" for en-US, \",\" for\n // de-DE), plus the ASCII \".\" when it stands in for a non-ASCII separator\n // (ar/fa). Do NOT match \".\" when it is the grouping separator (de-DE).\n const isDecimalKey =\n key === localeInfo.decimalSeparator ||\n (key === \".\" &&\n localeInfo.decimalSeparator !== \".\" &&\n localeInfo.groupingSeparator !== \".\");\n if (isDecimalKey) {\n const input = inputRef.current;\n if (input) {\n const decPos = input.value.indexOf(localeInfo.decimalSeparator);\n if (decPos !== -1) {\n e.preventDefault();\n input.setSelectionRange(decPos + 1, decPos + 1);\n return;\n }\n }\n }\n }\n\n if (key === \"Backspace\" && !e.shiftKey && !e.altKey && !e.metaKey && !e.ctrlKey) {\n const input = inputRef.current;\n if (input) {\n const cursor = input.selectionStart ?? 0;\n const selEnd = input.selectionEnd ?? cursor;\n const currentValue = input.value;\n const info = formatter.getLocaleInfo();\n\n if (\n cursor === selEnd && // no text selection — single caret\n cursor >= 2 &&\n currentValue[cursor - 1] === info.groupingSeparator\n ) {\n e.preventDefault();\n // Remove the grouping separator (cursor-1) AND the digit before it (cursor-2)\n const rawEdited = currentValue.slice(0, cursor - 2) + currentValue.slice(cursor);\n const parseResult = parser.parse(rawEdited);\n\n state._setLastChangeReason(\"input\");\n let nextDisplay: string;\n if (parseResult.value !== null) {\n // Preserve typed trailing zeros; use the LIVE formatter (no\n // min-fraction padding) so editing matches the typing display.\n nextDisplay =\n formatGroupedFraction(parseResult.value, rawEdited) ??\n liveFormatter.format(parseResult.value);\n state.setInputValue(nextDisplay, parseResult.value);\n } else {\n // Empty or intermediate — store as-is (blur will clean up). If the\n // edit emptied the field, report the dedicated \"clear\" reason.\n nextDisplay = rawEdited;\n if (rawEdited === \"\") state._setLastChangeReason(\"clear\");\n state.setInputValue(rawEdited);\n }\n // Remap the caret through the cursor engine so re-grouping shifts\n // (e.g. \"1,234,567\" → \"123,567\") never leave it stranded after a comma.\n pendingCursor.current = computeNewCursorPosition(\n rawEdited,\n cursor - 2,\n nextDisplay,\n info,\n \"deleteContentBackward\"\n );\n return;\n }\n\n // Backspace over a trailing affordance (% sign, suffix like \" kg\") —\n // the browser would delete the affordance char, but the formatter\n // immediately re-appends it, so the field never changes. Instead delete\n // the digit that precedes the affordance run. Digit detection is\n // script-aware (\\p{Nd}) so it works for native digits (fa/ar) too.\n const isDigitChar = (ch: string | undefined): boolean =>\n ch !== undefined && /\\p{Nd}/u.test(ch);\n const isAffordanceChar = (ch: string | undefined): boolean =>\n ch !== undefined &&\n !isDigitChar(ch) &&\n ch !== info.decimalSeparator &&\n ch !== info.minusSign &&\n ch !== \"-\";\n if (\n cursor === selEnd &&\n cursor === currentValue.length &&\n cursor >= 1 &&\n isAffordanceChar(currentValue[cursor - 1])\n ) {\n // Walk back over the trailing affordance run to the last real char.\n let i = cursor;\n while (i > 0 && isAffordanceChar(currentValue[i - 1])) i--;\n if (i > 0 && isDigitChar(currentValue[i - 1])) {\n e.preventDefault();\n const rawEdited = currentValue.slice(0, i - 1) + currentValue.slice(i);\n const parseResult = parser.parse(rawEdited);\n state._setLastChangeReason(\"input\");\n let nextDisplay: string;\n if (parseResult.value !== null && /\\p{Nd}/u.test(rawEdited)) {\n // Use the LIVE formatter (no min-fraction padding) so the display\n // matches the typing path — never re-pad \".00\" mid-edit.\n nextDisplay =\n formatGroupedFraction(parseResult.value, rawEdited) ??\n liveFormatter.format(parseResult.value);\n state.setInputValue(nextDisplay, parseResult.value);\n } else {\n // No digits left — clear the field (don't strand the affordance).\n // Report the dedicated \"clear\" reason like the onChange path.\n nextDisplay = \"\";\n state._setLastChangeReason(\"clear\");\n state.setInputValue(\"\");\n }\n pendingCursor.current = computeNewCursorPosition(\n rawEdited,\n i - 1,\n nextDisplay,\n info,\n \"deleteContentBackward\"\n );\n return;\n }\n }\n }\n }\n\n if (key === \"ArrowUp\" || key === \"ArrowDown\") {\n e.preventDefault();\n const direction = key === \"ArrowUp\" ? 1 : -1;\n state._setLastChangeReason(\"keyboard\");\n if (e.shiftKey) {\n direction > 0 ? state.increment(largeStep) : state.decrement(largeStep);\n } else if (e.metaKey || e.ctrlKey) {\n direction > 0 ? state.increment(smallStep) : state.decrement(smallStep);\n } else {\n direction > 0 ? state.increment() : state.decrement();\n }\n return;\n }\n\n if (key === \"PageUp\") {\n e.preventDefault();\n state._setLastChangeReason(\"keyboard\");\n state.increment(largeStep);\n return;\n }\n\n if (key === \"PageDown\") {\n e.preventDefault();\n state._setLastChangeReason(\"keyboard\");\n state.decrement(largeStep);\n return;\n }\n\n if (key === \"Home\") {\n if (minValue !== undefined) {\n e.preventDefault();\n state._setLastChangeReason(\"keyboard\");\n state.decrementToMin();\n }\n return;\n }\n\n if (key === \"End\") {\n if (maxValue !== undefined) {\n e.preventDefault();\n state._setLastChangeReason(\"keyboard\");\n state.incrementToMax();\n }\n return;\n }\n\n if (key === \"Enter\") {\n state._setLastChangeReason(\"blur\");\n const committed = state.commit();\n onValueCommitted?.(committed, { reason: \"keyboard\" });\n return;\n }\n },\n [\n disabled,\n readOnly,\n state,\n largeStep,\n smallStep,\n minValue,\n maxValue,\n formatter,\n liveFormatter,\n parser,\n inputRef,\n allowDecimal,\n formatGroupedFraction,\n onValueCommitted,\n ]\n );\n\n // ── Blur handler ─────────────────────────────────────────────────────────\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n state.setIsFocused(false);\n state._setLastChangeReason(\"blur\");\n const committed = state.commit();\n onValueCommitted?.(committed, { reason: \"blur\" });\n onBlur?.(e);\n },\n [state, onBlur, onValueCommitted]\n );\n\n // ── Focus handler ────────────────────────────────────────────────────────\n const handleFocus = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n state.setIsFocused(true);\n onFocus?.(e);\n },\n [state, onFocus]\n );\n\n // ── Press-and-hold for increment/decrement buttons ───────────────────────\n const incrementHold = usePressAndHold(\n () => {\n state._setLastChangeReason(\"increment\");\n state.increment();\n },\n {\n delay: stepHoldDelay,\n interval: stepHoldInterval,\n disabled: disabled || !state.canIncrement,\n }\n );\n\n const decrementHold = usePressAndHold(\n () => {\n state._setLastChangeReason(\"decrement\");\n state.decrement();\n },\n {\n delay: stepHoldDelay,\n interval: stepHoldInterval,\n disabled: disabled || !state.canDecrement,\n }\n );\n\n // ── ARIA valuetext ───────────────────────────────────────────────────────\n const ariaValueText = useMemo(() => {\n if (state.numberValue == null) return undefined;\n return customFormatValue\n ? customFormatValue(state.numberValue)\n : formatter.format(state.numberValue);\n }, [state.numberValue, formatter, customFormatValue]);\n\n // ── RTL detection ────────────────────────────────────────────────────────\n const localeInfo = formatter.getLocaleInfo();\n\n // ── Out-of-range + validation detection (for aria-invalid + data-invalid) ─\n const isOutOfRange =\n state.numberValue !== null &&\n ((minValue !== undefined && state.numberValue < minValue) ||\n (maxValue !== undefined && state.numberValue > maxValue));\n\n const isInvalid = isOutOfRange || state.validationState === \"invalid\";\n\n // ── Prop maps ────────────────────────────────────────────────────────────\n\n // Track whether a label element is actually mounted. `labelProps.ref` (below)\n // registers/unregisters as it mounts, so `aria-labelledby` only points at the\n // label when it truly exists — for any render path (built-in component, custom\n // primitive, or fully headless), not just one that runs a specific effect.\n const [hasLabel, labelRef] = useMountedFlag();\n\n // Fall back to the internal label id only when the consumer hasn't supplied\n // their own accessible name AND a label is actually rendered. Defaulting to\n // `labelId` otherwise points `aria-labelledby` at a `<label>` that may not\n // exist (e.g. when only `aria-label` is passed), producing a dangling ref.\n const ariaLabelledBy =\n props[\"aria-labelledby\"] ?? (props[\"aria-label\"] ? undefined : hasLabel ? labelId : undefined);\n\n // Mirror the label registration for the description so the input's\n // aria-describedby points at <NumberField.Description> only while one is\n // actually mounted — avoiding a dangling reference (the same class of bug fixed\n // for aria-labelledby) when no description is rendered.\n const [hasDescription, descriptionRef] = useMountedFlag();\n\n // Combine the consumer's own aria-describedby with the internal description id\n // (when present) so the description is announced by assistive technology.\n const ariaDescribedBy =\n [props[\"aria-describedby\"], hasDescription ? descriptionId : null].filter(Boolean).join(\" \") ||\n undefined;\n\n const labelProps: NumberFieldAria[\"labelProps\"] = {\n id: labelId,\n htmlFor: inputId,\n ref: labelRef,\n };\n\n const groupProps: React.HTMLAttributes<HTMLDivElement> = {\n role: \"group\",\n \"aria-labelledby\": ariaLabelledBy,\n };\n\n const inputProps: React.InputHTMLAttributes<HTMLInputElement> = {\n id: inputId,\n type: \"text\",\n inputMode: \"decimal\",\n role: \"spinbutton\",\n autoComplete: \"off\",\n autoCorrect: \"off\",\n spellCheck: false,\n \"aria-label\": props[\"aria-label\"],\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-valuenow\": state.numberValue ?? undefined,\n \"aria-valuemin\": minValue,\n \"aria-valuemax\": maxValue,\n \"aria-valuetext\": ariaValueText,\n \"aria-disabled\": disabled || undefined,\n \"aria-readonly\": readOnly || undefined,\n \"aria-required\": required || undefined,\n \"aria-invalid\": isInvalid ? true : undefined,\n \"aria-errormessage\": isInvalid && state.validationError ? errorId : undefined,\n disabled,\n readOnly,\n required,\n value: state.inputValue,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n onBlur: handleBlur,\n onFocus: handleFocus,\n onPaste: handlePaste,\n onCopy: copyBehavior !== \"formatted\" ? handleCopy : undefined,\n onCut: copyBehavior !== \"formatted\" ? handleCut : undefined,\n onCompositionStart: handleCompositionStart,\n onCompositionEnd: handleCompositionEnd,\n // RTL: keep the number LTR and align it to the right in RTL contexts.\n // unicodeBidi \"plaintext\" auto-detects each run's direction, so the digits\n // stay LTR while an RTL suffix / Arabic currency name falls to its natural\n // side (\"embed\" forced the whole field LTR, mis-ordering those affordances).\n style: localeInfo.isRTL\n ? { direction: \"ltr\", textAlign: \"right\", unicodeBidi: \"plaintext\" }\n : undefined,\n // Data attributes for CSS styling\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-readonly\": readOnly ? \"\" : undefined,\n \"data-required\": required ? \"\" : undefined,\n \"data-invalid\": isInvalid ? \"\" : undefined,\n \"data-rtl\": localeInfo.isRTL ? \"\" : undefined,\n } as React.InputHTMLAttributes<HTMLInputElement>;\n\n const hiddenInputProps: React.InputHTMLAttributes<HTMLInputElement> | null = name\n ? {\n type: \"hidden\",\n name,\n value: state.numberValue ?? \"\",\n \"aria-hidden\": true,\n }\n : null;\n\n const incrementButtonProps: React.ButtonHTMLAttributes<HTMLButtonElement> = {\n type: \"button\",\n tabIndex: -1,\n \"aria-label\": incrementLabel,\n disabled: disabled || !state.canIncrement,\n // Press-and-hold handlers replace simple onClick\n ...incrementHold,\n \"data-disabled\": disabled || !state.canIncrement ? \"\" : undefined,\n } as React.ButtonHTMLAttributes<HTMLButtonElement>;\n\n const decrementButtonProps: React.ButtonHTMLAttributes<HTMLButtonElement> = {\n type: \"button\",\n tabIndex: -1,\n \"aria-label\": decrementLabel,\n disabled: disabled || !state.canDecrement,\n // Press-and-hold handlers replace simple onClick\n ...decrementHold,\n \"data-disabled\": disabled || !state.canDecrement ? \"\" : undefined,\n } as React.ButtonHTMLAttributes<HTMLButtonElement>;\n\n const descriptionProps: NumberFieldAria[\"descriptionProps\"] = {\n id: descriptionId,\n ref: descriptionRef,\n };\n\n const errorMessageProps: React.HTMLAttributes<HTMLElement> = {\n id: errorId,\n role: \"alert\",\n \"aria-live\": \"polite\",\n } as React.HTMLAttributes<HTMLElement>;\n\n return {\n labelProps,\n groupProps,\n inputProps,\n hiddenInputProps,\n incrementButtonProps,\n decrementButtonProps,\n descriptionProps,\n errorMessageProps,\n };\n}\n","import { useCallback, useRef, useState } from \"react\";\n\n// Locally declared so the dev-only gate type-checks without @types/node.\ndeclare const process: { env?: Record<string, string | undefined> } | undefined;\n\ninterface UseControllableStateOptions<T> {\n value?: T;\n defaultValue?: T;\n onChange?: (value: T) => void;\n}\n\ntype ControllableSetter<T> = (next: T | ((prev: T | undefined) => T)) => void;\n\n/**\n * Manages controlled vs uncontrolled state.\n * - If `value` is provided, the component is controlled.\n * - Otherwise it manages its own state starting from `defaultValue`.\n * Warns in dev mode if the component switches between controlled/uncontrolled.\n *\n * Overloads narrow the returned value to `T` (no `| undefined`) when a `value`\n * or `defaultValue` is supplied, so callers that guarantee one don't have to\n * null-check the result.\n */\nexport function useControllableState<T>(options: {\n value: T;\n defaultValue?: T;\n onChange?: (value: T) => void;\n}): [T, ControllableSetter<T>];\nexport function useControllableState<T>(options: {\n value?: T;\n defaultValue: T;\n onChange?: (value: T) => void;\n}): [T, ControllableSetter<T>];\nexport function useControllableState<T>(\n options: UseControllableStateOptions<T>\n): [T | undefined, ControllableSetter<T>];\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: UseControllableStateOptions<T>): [T | undefined, ControllableSetter<T>] {\n const isControlled = value !== undefined;\n const wasControlled = useRef(isControlled);\n\n // Dev-only warning. The `process.env.NODE_ENV !== \"production\"` token is\n // statically replaced and the branch eliminated by production bundlers that\n // define NODE_ENV (and by raqam's minified build), so this ships zero bytes in\n // production. The `typeof process` / `process.env` guards keep it crash-safe\n // under raw-browser ESM and partial `process` shims — this runs on every\n // render, so a throw here would break rendering, not just an error path.\n if (\n typeof process !== \"undefined\" &&\n process.env &&\n process.env.NODE_ENV !== \"production\" &&\n wasControlled.current !== isControlled\n ) {\n console.warn(\"[raqam] Switching between controlled and uncontrolled. Pick one and keep it.\");\n }\n\n const [internalValue, setInternalValue] = useState<T | undefined>(defaultValue);\n\n const set = useCallback(\n (next: T | ((prev: T | undefined) => T)) => {\n const nextValue =\n typeof next === \"function\"\n ? (next as (prev: T | undefined) => T)(isControlled ? value : internalValue)\n : next;\n\n if (!isControlled) {\n setInternalValue(nextValue);\n }\n onChange?.(nextValue);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [isControlled, value, internalValue, onChange]\n );\n\n return [isControlled ? value : internalValue, set];\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport { createFormatter, resolveEffectiveFractions } from \"../core/formatter.js\";\nimport { createParser } from \"../core/parser.js\";\nimport type { ChangeReason, NumberFieldState, UseNumberFieldStateOptions } from \"../core/types.js\";\nimport { useControllableState } from \"./useControllableState.js\";\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction clamp(value: number, min?: number, max?: number): number {\n let v = value;\n // Ignore non-finite bounds (NaN/Infinity) — Math.max/Math.min would otherwise\n // return NaN and poison the committed value.\n if (min !== undefined && Number.isFinite(min)) v = Math.max(v, min);\n if (max !== undefined && Number.isFinite(max)) v = Math.min(v, max);\n return v;\n}\n\nfunction preciseAdd(a: number, b: number): number {\n // Float precision fix — avoids 0.1 + 0.2 = 0.30000000000000004. The scaling\n // trick is only valid while the scaled operands stay within Number.MAX_SAFE_\n // INTEGER (2^53). Fall back to plain addition when scaling would be unsafe:\n // - precision > 15: the operands can't be represented at that scale; capping\n // instead would round a tiny addend (e.g. 1e-20) to 0, dropping the step.\n // - scaled operand exceeds MAX_SAFE_INTEGER: rounding can drop the step or\n // move the value backwards.\n const precision = Math.max(decimalPlaces(a), decimalPlaces(b));\n if (precision > 15) return a + b;\n const factor = 10 ** precision;\n const sa = a * factor;\n const sb = b * factor;\n if (!Number.isSafeInteger(Math.round(sa)) || !Number.isSafeInteger(Math.round(sb))) {\n return a + b;\n }\n return Math.round(sa + sb) / factor;\n}\n\nfunction decimalPlaces(n: number): number {\n if (!Number.isFinite(n)) return 0;\n const s = String(n);\n // Exponential form (e.g. \"1e-7\", \"1.5e-7\") — String() uses it below 1e-6.\n const eIdx = s.indexOf(\"e\");\n if (eIdx !== -1) {\n const exp = Number(s.slice(eIdx + 1));\n const dotIdx = s.indexOf(\".\");\n const fracLen = dotIdx === -1 ? 0 : eIdx - dotIdx - 1;\n return Math.max(0, fracLen - exp);\n }\n const idx = s.indexOf(\".\");\n return idx === -1 ? 0 : s.length - idx - 1;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────────────────\n\nexport function useNumberFieldState(options: UseNumberFieldStateOptions): NumberFieldState {\n const {\n locale,\n formatOptions,\n minValue: rawMinValue,\n maxValue: rawMaxValue,\n step: rawStep = 1,\n largeStep: rawLargeStep,\n smallStep: rawSmallStep,\n allowNegative = true,\n allowDecimal = true,\n maximumFractionDigits,\n minimumFractionDigits,\n fixedDecimalScale,\n clampBehavior = \"blur\",\n prefix,\n suffix,\n allowOutOfRange = false,\n validate,\n onRawChange,\n formatValue: customFormatValue,\n } = options;\n\n // Sanitize numeric config. A non-finite/non-positive step would emit NaN or\n // Infinity through increment/decrement (or dead-end stepping for 0), and\n // non-finite bounds would poison clamp and the committed value. Drop bad\n // values to safe defaults / undefined.\n const step = Number.isFinite(rawStep) && rawStep > 0 ? rawStep : 1;\n const minValue = Number.isFinite(rawMinValue) ? rawMinValue : undefined;\n const maxValue = Number.isFinite(rawMaxValue) ? rawMaxValue : undefined;\n\n // When decimals are disallowed, fraction padding/scale is forced to 0 so\n // currency / fixedDecimalScale never pad \".00\" (which the dot-strip would then\n // re-read, exploding the value). Shared with useNumberField via one helper so\n // the editable and on-commit displays can never drift apart.\n const { effMinFrac, effMaxFrac, effFixedScale } = resolveEffectiveFractions({\n allowDecimal,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n });\n\n // Serialize formatOptions once per render — it feeds two useMemo dependency\n // arrays and the runtime-reformat key below, and JSON.stringify is not free\n // for non-trivial option objects.\n const formatOptionsKey = JSON.stringify(formatOptions ?? {});\n\n // ── Formatter & parser (re-created only when deps change) ──────────────────\n const formatter = useMemo(\n () =>\n createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits: effMinFrac,\n maximumFractionDigits: effMaxFrac,\n fixedDecimalScale: effFixedScale,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, prefix, suffix, effMinFrac, effMaxFrac, effFixedScale]\n );\n\n const parser = useMemo(\n () =>\n createParser({\n locale,\n formatOptions,\n allowNegative,\n allowDecimal,\n prefix,\n suffix,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale, formatOptionsKey, allowNegative, allowDecimal, prefix, suffix]\n );\n\n // ── Controlled/uncontrolled numeric value ──────────────────────────────────\n const [numberValue, setNumberValue] = useControllableState<number | null>({\n value: options.value,\n defaultValue: options.defaultValue ?? null,\n onChange: options.onChange,\n });\n\n // Last numeric value we emitted ourselves — used to tell our own onChange echo\n // apart from a genuine external controlled-value change (see sync block below).\n const lastEmittedRef = useRef<number | null | undefined>(\n options.value ?? options.defaultValue ?? null\n );\n\n // ── Display string ─────────────────────────────────────────────────────────\n // Stored in local state — can transiently diverge from numberValue\n // (e.g. while typing \"1.\" which isn't a valid JS number yet)\n const formatDisplay = useCallback(\n (n: number): string =>\n // Normalise -0 so it never renders as \"-0\" on any path (mount included).\n customFormatValue\n ? customFormatValue(Object.is(n, -0) ? 0 : n)\n : formatter.format(Object.is(n, -0) ? 0 : n),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [formatter, customFormatValue]\n );\n\n const initialDisplay = useMemo(() => {\n if (options.defaultValue != null) {\n return formatDisplay(options.defaultValue);\n }\n if (options.value != null) {\n return formatDisplay(options.value);\n }\n return \"\";\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []); // Only on mount\n\n const [inputValue, setInputValueRaw] = useState<string>(initialDisplay);\n\n // Mirror of the display string, updated SYNCHRONOUSLY before each setNumberValue\n // (which fires onChange). `inputValue` state only reflects the *previous* render\n // at onChange time, so consumers reading the formatted value via onValueChange\n // must read this ref to get the value that matches the just-emitted number.\n const latestDisplayRef = useRef<string>(initialDisplay);\n const _getLatestDisplay = useCallback((): string => latestDisplayRef.current, []);\n\n // Track last formatted value so we can sync controlled value changes\n const lastFormattedRef = useRef<string>(initialDisplay);\n\n // ── Raw value (precision-preserving string) ────────────────────────────────\n const [rawValue, setRawValueState] = useState<string | null>(\n options.defaultValue != null ? String(options.defaultValue) : null\n );\n\n // ── Validation state ───────────────────────────────────────────────────────\n const runValidation = useCallback(\n (\n val: number | null\n ): { validationState: \"valid\" | \"invalid\"; validationError: string | null } => {\n if (!validate) return { validationState: \"valid\", validationError: null };\n const result = validate(val);\n if (result === false) return { validationState: \"invalid\", validationError: null };\n if (typeof result === \"string\")\n return { validationState: \"invalid\", validationError: result };\n return { validationState: \"valid\", validationError: null };\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [validate]\n );\n\n const initialValidation = useMemo(() => {\n const initVal = options.defaultValue ?? options.value ?? null;\n return runValidation(initVal != null ? initVal : null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []); // Only on mount\n\n const [validationState, setValidationState] = useState<\"valid\" | \"invalid\">(\n initialValidation.validationState\n );\n const [validationError, setValidationError] = useState<string | null>(\n initialValidation.validationError\n );\n\n // ── isScrubbing / isFocused state ──────────────────────────────────────────\n const [isScrubbing, setIsScrubbing] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n // ── Change reason ref (no re-render needed) ────────────────────────────────\n const lastChangeReasonRef = useRef<ChangeReason>(\"input\");\n const _setLastChangeReason = useCallback((reason: ChangeReason) => {\n lastChangeReasonRef.current = reason;\n }, []);\n\n const _getLastChangeReason = useCallback((): ChangeReason => {\n return lastChangeReasonRef.current;\n }, []);\n\n // ── Sync controlled value → display string when value changes externally ───\n // We must distinguish a *genuine* external change (parent set a new value,\n // form reset/prefill, etc.) from the echo of our own onChange. `lastEmittedRef`\n // tracks the value we last emitted; if the incoming controlled value differs\n // from it, the change came from outside and the display must be re-synced.\n const externalValue = options.value;\n const prevExternalValueRef = useRef(externalValue);\n // Object.is (not !==) so a controlled value of NaN compares equal to itself\n // and never triggers an unconditional render-phase setState → infinite loop.\n if (!Object.is(prevExternalValueRef.current, externalValue)) {\n prevExternalValueRef.current = externalValue;\n if (!Object.is(externalValue, lastEmittedRef.current)) {\n lastEmittedRef.current = externalValue;\n // Normalise -0 so a controlled value of -0 displays as \"0\", matching the\n // typed and commit paths.\n const ev = Object.is(externalValue, -0) ? 0 : externalValue;\n const finite = ev != null && Number.isFinite(ev);\n const formatted = finite ? formatDisplay(ev as number) : \"\";\n lastFormattedRef.current = formatted;\n latestDisplayRef.current = formatted;\n setInputValueRaw(formatted);\n setRawValueState(finite ? String(ev) : null);\n }\n }\n\n // ── Reformat the display when locale / formatOptions change at runtime ──────\n // When the field is not being actively edited, a locale or format change must\n // re-render the existing value in the new format (e.g. switching en-US → de-DE).\n const formatKey = `${locale ?? \"\"}|${formatOptionsKey}|${prefix ?? \"\"}|${suffix ?? \"\"}|${effMinFrac ?? \"\"}|${effMaxFrac ?? \"\"}|${effFixedScale ?? \"\"}`;\n const prevFormatKeyRef = useRef(formatKey);\n if (prevFormatKeyRef.current !== formatKey) {\n prevFormatKeyRef.current = formatKey;\n if (numberValue != null && Number.isFinite(numberValue) && !isFocused) {\n const formatted = formatDisplay(numberValue);\n if (formatted !== inputValue) {\n setInputValueRaw(formatted);\n lastFormattedRef.current = formatted;\n latestDisplayRef.current = formatted;\n }\n }\n }\n\n // ── Internal helper: apply validation after a value change ────────────────\n const applyValidation = useCallback(\n (val: number | null) => {\n const { validationState: vs, validationError: ve } = runValidation(val);\n setValidationState(vs);\n setValidationError(ve);\n },\n [runValidation]\n );\n\n // ── setInputValue ──────────────────────────────────────────────────────────\n // `knownValue` lets the caller supply the exact numeric value when `val` is a\n // formatted string the parser cannot faithfully reverse (compact \"2.5K\",\n // scientific, unit). Without it, the value is derived by parsing `val`.\n const setInputValue = useCallback(\n (val: string, knownValue?: number | null) => {\n const parsed = parser.parse(val);\n const value = knownValue !== undefined ? knownValue : parsed.value;\n\n // Strict clamping: reject input that goes out of range (skipped when allowOutOfRange)\n if (clampBehavior === \"strict\" && !allowOutOfRange && value !== null) {\n if (minValue !== undefined && value < minValue) return;\n if (maxValue !== undefined && value > maxValue) return;\n }\n\n latestDisplayRef.current = val;\n setInputValueRaw(val);\n lastEmittedRef.current = value;\n setNumberValue(value);\n\n // rawValue is the *unformatted*, precision-preserving string — not the\n // grouped / currency-decorated display. Prefer the affordance-stripped form\n // (digits + \".\" + sign, trailing zeros intact) since it keeps the exact\n // digits the user typed — but only when it numerically denotes `value`.\n // strip() is NOT the inverse of parse() for rescaling styles (percent\n // divides typed digits by 100: \"50%\" strips to \"50\" but means 0.5) or for\n // non-invertible notation (compact \"2.5K\", scientific, unit, custom\n // formatters); there, fall back to the canonical numeric string.\n let raw: string | null = null;\n if (value !== null) {\n const stripped = parser.strip(val);\n if (/\\d/.test(stripped) && Number(stripped) === value) {\n // `value` is -0-normalized everywhere, so never surface a \"-0\" raw.\n raw = value === 0 && stripped.startsWith(\"-\") ? stripped.slice(1) : stripped;\n } else {\n raw = String(value);\n }\n }\n setRawValueState(raw);\n onRawChange?.(raw);\n applyValidation(value);\n },\n [\n parser,\n clampBehavior,\n allowOutOfRange,\n minValue,\n maxValue,\n setNumberValue,\n onRawChange,\n applyValidation,\n ]\n );\n\n // ── setNumberValue (external) ──────────────────────────────────────────────\n const setNumericValue = useCallback(\n (rawVal: number | null) => {\n // Never emit a non-finite value (NaN/Infinity) to onChange/ARIA/forms —\n // treat it as empty. A catch-all behind the config sanitization above.\n const val = rawVal !== null && !Number.isFinite(rawVal) ? null : rawVal;\n // Compute the display and update latestDisplayRef BEFORE setNumberValue, so\n // the onChange it triggers reports the matching formatted value (not the\n // previous render's).\n const formatted = val != null ? formatDisplay(val) : \"\";\n latestDisplayRef.current = formatted;\n lastEmittedRef.current = val;\n setNumberValue(val);\n setInputValueRaw(formatted);\n lastFormattedRef.current = formatted;\n if (val != null) {\n const rawStr = String(val);\n setRawValueState(rawStr);\n onRawChange?.(rawStr);\n } else {\n setRawValueState(null);\n onRawChange?.(null);\n }\n applyValidation(val);\n },\n [formatDisplay, setNumberValue, onRawChange, applyValidation]\n );\n\n // ── commit (called on blur) ────────────────────────────────────────────────\n const commit = useCallback((): number | null => {\n // Treat empty AND non-finite (NaN/Infinity from a bad controlled/default\n // value) as empty on commit, so blur/Enter never returns or emits a\n // non-finite value even though the field renders empty.\n if (numberValue == null || !Number.isFinite(numberValue)) {\n latestDisplayRef.current = \"\";\n setInputValueRaw(\"\");\n lastFormattedRef.current = \"\";\n return null;\n }\n\n let clamped = numberValue;\n // Clamp on blur, unless allowOutOfRange is true\n if (clampBehavior === \"blur\" && !allowOutOfRange) {\n clamped = clamp(numberValue, minValue, maxValue);\n }\n // Normalise negative zero so \"-0\" commits as plain \"0\"\n if (Object.is(clamped, -0)) clamped = 0;\n\n const formatted = formatDisplay(clamped);\n latestDisplayRef.current = formatted;\n setInputValueRaw(formatted);\n lastFormattedRef.current = formatted;\n\n // Round the committed value to the displayed precision so the numeric value\n // never diverges from what is shown (e.g. a percent field that rounds the\n // live-typed fraction down to its configured scale on blur). Only adopt the\n // reparsed value when it round-trips exactly back to `formatted` — this skips\n // non-invertible notations (compact \"2.5K\", scientific, unit) and any custom\n // formatter whose output the parser cannot faithfully reverse.\n let committed = clamped;\n if (!customFormatValue) {\n const reparsed = parser.parse(formatted).value;\n if (reparsed !== null && Number.isFinite(reparsed) && formatDisplay(reparsed) === formatted) {\n committed = reparsed;\n }\n }\n\n if (committed !== numberValue) {\n lastEmittedRef.current = committed;\n setNumberValue(committed);\n }\n applyValidation(committed);\n return committed;\n }, [\n numberValue,\n clampBehavior,\n allowOutOfRange,\n minValue,\n maxValue,\n parser,\n formatDisplay,\n customFormatValue,\n setNumberValue,\n applyValidation,\n ]);\n\n // Treat a non-finite value (NaN/Infinity from a bad default/controlled value)\n // as empty so it never reaches ARIA, the hidden form input, or arithmetic.\n const safeNumberValue = numberValue != null && Number.isFinite(numberValue) ? numberValue : null;\n\n // ── Step computation ───────────────────────────────────────────────────────\n const resolvedLargeStep =\n Number.isFinite(rawLargeStep) && (rawLargeStep as number) > 0\n ? (rawLargeStep as number)\n : step * 10;\n const resolvedSmallStep =\n Number.isFinite(rawSmallStep) && (rawSmallStep as number) > 0\n ? (rawSmallStep as number)\n : step * 0.1;\n\n const canIncrement =\n !options.disabled &&\n !options.readOnly &&\n (allowOutOfRange ||\n maxValue === undefined ||\n (safeNumberValue ?? Number.NEGATIVE_INFINITY) < maxValue);\n\n const canDecrement =\n !options.disabled &&\n !options.readOnly &&\n (allowOutOfRange ||\n minValue === undefined ||\n (safeNumberValue ?? Number.POSITIVE_INFINITY) > minValue);\n\n const increment = useCallback(\n (amount?: number) => {\n const s = amount ?? step;\n const base = safeNumberValue ?? 0;\n const raw = preciseAdd(base, s);\n const next = allowOutOfRange ? raw : clamp(raw, minValue, maxValue);\n setNumericValue(next);\n },\n [safeNumberValue, step, minValue, maxValue, allowOutOfRange, setNumericValue]\n );\n\n const decrement = useCallback(\n (amount?: number) => {\n const s = amount ?? step;\n const base = safeNumberValue ?? 0;\n const raw = preciseAdd(base, -s);\n const next = allowOutOfRange ? raw : clamp(raw, minValue, maxValue);\n setNumericValue(next);\n },\n [safeNumberValue, step, minValue, maxValue, allowOutOfRange, setNumericValue]\n );\n\n const incrementToMax = useCallback(() => {\n if (maxValue !== undefined) setNumericValue(maxValue);\n }, [maxValue, setNumericValue]);\n\n const decrementToMin = useCallback(() => {\n if (minValue !== undefined) setNumericValue(minValue);\n }, [minValue, setNumericValue]);\n\n return {\n inputValue,\n numberValue: safeNumberValue,\n rawValue,\n canIncrement,\n canDecrement,\n isScrubbing,\n setIsScrubbing,\n isFocused,\n setIsFocused,\n validationState,\n validationError,\n _setLastChangeReason,\n _getLastChangeReason,\n _getLatestDisplay,\n setInputValue,\n setNumberValue: setNumericValue,\n commit,\n increment,\n decrement,\n incrementToMax,\n decrementToMin,\n options: {\n ...options,\n step,\n largeStep: resolvedLargeStep,\n smallStep: resolvedSmallStep,\n // Expose the sanitized bounds so every consumer (e.g. useScrubArea's\n // aria-valuemin/max) sees cleaned values, not raw NaN/Infinity.\n minValue,\n maxValue,\n },\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { NumberFieldState, ScrubAreaOptions } from \"../core/types.js\";\n\nexport interface ScrubAreaReturn {\n /** Whether pointer lock is currently active */\n isScrubbing: boolean;\n /** Props to spread on the scrub area element */\n scrubAreaProps: {\n role: string;\n tabIndex: number;\n style: React.CSSProperties;\n \"aria-label\": string;\n \"aria-valuenow\": number | undefined;\n \"aria-valuemin\": number | undefined;\n \"aria-valuemax\": number | undefined;\n \"aria-valuetext\": string | undefined;\n \"aria-disabled\": true | undefined;\n \"data-scrubbing\": string | undefined;\n onPointerDown: (e: React.PointerEvent) => void;\n onKeyDown: (e: React.KeyboardEvent) => void;\n };\n /**\n * Virtual cursor position (screen coordinates, updated by mousemove\n * during pointer lock). Use for positioning the ScrubAreaCursor.\n */\n virtualCursor: { x: number; y: number };\n}\n\n/**\n * Implements Pointer Lock API–based drag-to-scrub behavior.\n *\n * Flow:\n * 1. User presses pointer down → element requests pointer lock\n * 2. Browser hides cursor, starts delivering movementX/Y on mousemove\n * 3. Accumulated movement ÷ pixelSensitivity → increment/decrement calls\n * 4. Pointer lock exits on Escape key or programmatic exit\n */\nexport function useScrubArea(\n state: NumberFieldState,\n options: ScrubAreaOptions = {}\n): ScrubAreaReturn {\n const {\n direction = \"horizontal\",\n pixelSensitivity = 4,\n label = \"Scrub to change value\",\n } = options;\n\n const [isScrubbing, setIsScrubbingLocal] = useState(false);\n\n // Keep stable refs to avoid stale closures in event listeners\n const stateRef = useRef(state);\n stateRef.current = state;\n\n const directionRef = useRef(direction);\n directionRef.current = direction;\n\n const sensitivityRef = useRef(pixelSensitivity);\n sensitivityRef.current = pixelSensitivity;\n\n const isScrubbingRef = useRef(false);\n const accumulatorRef = useRef(0);\n const elementRef = useRef<Element | null>(null);\n const virtualCursorRef = useRef({ x: 0, y: 0 });\n const [virtualCursor, setVirtualCursor] = useState({ x: 0, y: 0 });\n\n // Stable mousemove handler (always reads latest state via refs)\n const stableMouseMove = useRef((e: MouseEvent) => {\n if (!isScrubbingRef.current) return;\n\n // Update virtual cursor\n const nx = virtualCursorRef.current.x + e.movementX;\n const ny = virtualCursorRef.current.y + e.movementY;\n virtualCursorRef.current = { x: nx, y: ny };\n setVirtualCursor({ x: nx, y: ny });\n\n // Determine delta based on direction\n const dir = directionRef.current;\n let delta = 0;\n if (dir === \"horizontal\") {\n delta = e.movementX;\n } else if (dir === \"vertical\") {\n delta = -e.movementY;\n } else {\n delta = Math.abs(e.movementX) >= Math.abs(e.movementY) ? e.movementX : -e.movementY;\n }\n\n accumulatorRef.current += delta;\n\n // Fire step when accumulated movement exceeds sensitivity. Clamp to ≥ 1px:\n // a zero or negative sensitivity would make the loops below never progress\n // (or fire millions of steps), hanging the tab.\n const sensitivity = Math.max(1, sensitivityRef.current);\n if (accumulatorRef.current >= sensitivity || accumulatorRef.current <= -sensitivity) {\n stateRef.current._setLastChangeReason(\"scrub\");\n }\n while (accumulatorRef.current >= sensitivity) {\n stateRef.current.increment();\n accumulatorRef.current -= sensitivity;\n }\n while (accumulatorRef.current <= -sensitivity) {\n stateRef.current.decrement();\n accumulatorRef.current += sensitivity;\n }\n });\n\n // Stable pointer lock change handler\n const stablePointerLockChange = useRef(() => {\n if (document.pointerLockElement === elementRef.current) {\n // Lock acquired — start scrubbing\n isScrubbingRef.current = true;\n accumulatorRef.current = 0;\n setIsScrubbingLocal(true);\n stateRef.current.setIsScrubbing(true);\n document.addEventListener(\"mousemove\", stableMouseMove.current);\n } else {\n // Lock released — stop scrubbing\n isScrubbingRef.current = false;\n accumulatorRef.current = 0;\n document.removeEventListener(\"mousemove\", stableMouseMove.current);\n setIsScrubbingLocal(false);\n stateRef.current.setIsScrubbing(false);\n }\n });\n\n // Register stable pointerlockchange listener once on mount\n useEffect(() => {\n const handler = stablePointerLockChange.current;\n document.addEventListener(\"pointerlockchange\", handler);\n return () => {\n document.removeEventListener(\"pointerlockchange\", handler);\n document.removeEventListener(\"mousemove\", stableMouseMove.current);\n // If this element still owns the pointer lock when it unmounts mid-scrub,\n // release it so the user isn't stranded with a hidden cursor / locked page.\n if (\n typeof document.exitPointerLock === \"function\" &&\n document.pointerLockElement &&\n document.pointerLockElement === elementRef.current\n ) {\n document.exitPointerLock();\n }\n // The pointerlockchange handler is already detached above, so its release\n // path won't run. Reset the shared scrubbing state here so a still-mounted\n // Root (e.g. when only the ScrubArea is conditionally unmounted) doesn't\n // keep data-scrubbing / ScrubAreaCursor stuck on.\n if (isScrubbingRef.current) {\n isScrubbingRef.current = false;\n accumulatorRef.current = 0;\n stateRef.current.setIsScrubbing(false);\n }\n };\n }, []); // Empty deps — truly stable refs, no need to re-register\n\n const onPointerDown = useCallback(\n (e: React.PointerEvent) => {\n if (stateRef.current.options.disabled || stateRef.current.options.readOnly) return;\n if (e.button !== 0) return;\n\n const el = e.currentTarget as HTMLElement;\n elementRef.current = el;\n virtualCursorRef.current = { x: e.clientX, y: e.clientY };\n setVirtualCursor({ x: e.clientX, y: e.clientY });\n\n // requestPointerLock() returns a promise in newer browsers and rejects\n // when the lock can't be acquired (not user-gesture-driven, already exiting,\n // etc.). Swallow it so it isn't an unhandled rejection, and reset pending\n // scrub state.\n const result = el.requestPointerLock() as unknown as Promise<void> | undefined;\n if (result && typeof result.then === \"function\") {\n result.catch(() => {\n elementRef.current = null;\n });\n }\n },\n [] // No deps — reads via refs\n );\n\n // Keyboard support: arrow keys while scrub area is focused\n const onKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (stateRef.current.options.disabled || stateRef.current.options.readOnly) return;\n if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n stateRef.current._setLastChangeReason(\"scrub\");\n stateRef.current.increment();\n } else if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n stateRef.current._setLastChangeReason(\"scrub\");\n stateRef.current.decrement();\n }\n }, []);\n\n // Cursor CSS based on direction\n const cursorStyle =\n direction === \"horizontal\" ? \"ew-resize\" : direction === \"vertical\" ? \"ns-resize\" : \"move\";\n\n const scrubAreaProps = {\n role: \"slider\",\n tabIndex: state.options.disabled ? -1 : 0,\n style: {\n cursor: state.options.disabled ? undefined : cursorStyle,\n userSelect: \"none\" as const,\n WebkitUserSelect: \"none\" as const,\n } satisfies React.CSSProperties,\n \"aria-label\": label,\n // role=\"slider\" requires the current value (and ideally the range) to be\n // exposed, else assistive tech announces a value-less slider with no feedback\n // when the user scrubs with the arrow keys.\n \"aria-valuenow\": state.numberValue ?? undefined,\n \"aria-valuemin\": state.options.minValue,\n \"aria-valuemax\": state.options.maxValue,\n \"aria-valuetext\": state.inputValue || undefined,\n \"aria-disabled\": state.options.disabled ? (true as const) : undefined,\n \"data-scrubbing\": isScrubbing ? \"\" : undefined,\n onPointerDown,\n onKeyDown,\n };\n\n return { isScrubbing, scrubAreaProps, virtualCursor };\n}\n","\"use client\";\n\nimport React, { forwardRef, useMemo, useRef } from \"react\";\nimport type {\n NumberFieldRootProps,\n NumberFieldState,\n RenderProp,\n ScrubAreaCursorProps,\n ScrubAreaProps,\n} from \"../core/types.js\";\nimport { NumberFieldContext, useNumberFieldContext } from \"./context.js\";\nimport { useNumberField } from \"./useNumberField.js\";\nimport { useNumberFieldState } from \"./useNumberFieldState.js\";\nimport { useScrubArea } from \"./useScrubArea.js\";\n\n// ── Render prop utility ───────────────────────────────────────────────────────\n\n/**\n * Merge component props with a `render` prop.\n * Accepts either a React element or a render function.\n *\n * `forwardedRef` is threaded through explicitly because React 18 keeps `ref`\n * out of `element.props`, so a render-prop element would otherwise lose refs the\n * default element depends on — e.g. the label-registration ref carried by\n * `labelProps`. When provided, it takes precedence over the render element's own\n * `ref`; callers that need to keep a consumer ref must compose it into\n * `forwardedRef` themselves (see `<NumberField.Label>`), where it can be\n * memoized for a stable identity.\n */\nfunction renderWith(\n defaultElement: React.ReactElement,\n render: RenderProp | undefined,\n state: NumberFieldState,\n forwardedRef?: React.Ref<unknown>\n): React.ReactElement {\n if (!render) return defaultElement;\n\n const baseProps = { ...(defaultElement.props as Record<string, unknown>) };\n if (forwardedRef != null) baseProps.ref = forwardedRef;\n\n if (typeof render === \"function\") {\n return render(baseProps, state);\n }\n\n // Element form: clone with merged props.\n const merged = Object.assign({}, baseProps, render.props as Record<string, unknown>);\n if (forwardedRef != null) merged.ref = forwardedRef;\n return React.cloneElement(render, merged);\n}\n\n// ── Ref helpers ───────────────────────────────────────────────────────────────\n\n// React 19 exposes a React element's `ref` as a regular prop; React ≤18 stores\n// it on the element itself (and reading `element.ref` on React 19 logs a\n// deprecation warning), so branch on the version to read it without warnings.\n// The same version boundary marks where callback refs may return a cleanup\n// function: React 19 runs it on detach, React ≤18 ignores it (and warns).\nconst REF_IN_PROPS = Number.parseInt(React.version, 10) >= 19;\nconst SUPPORTS_REF_CLEANUP = REF_IN_PROPS;\n\nfunction getElementRef(el: React.ReactElement): React.Ref<unknown> | undefined {\n if (REF_IN_PROPS) return (el.props as { ref?: React.Ref<unknown> }).ref;\n return (el as unknown as { ref?: React.Ref<unknown> }).ref;\n}\n\n/**\n * Compose multiple refs (callback or object) into one callback ref while\n * preserving each ref's cleanup. For every ref we capture a cleanup — a function\n * ref's returned cleanup, a synthesized `ref(null)` for legacy refs, or\n * `current = null` for object refs — so consumer cleanups aren't dropped on\n * unmount or ref change.\n *\n * The two React eras differ in HOW the combined cleanup gets back to React:\n * - React 19 runs a cleanup returned from a callback ref, so we return one.\n * - React ≤18 ignores (and warns about) a returned function and instead calls\n * the ref with `null` on detach, so we stash the cleanups in a closure and run\n * them on that `null` call rather than returning a function.\n */\nfunction mergeRefs<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> {\n const attach = (node: T | null): (() => void)[] => {\n const cleanups: (() => void)[] = [];\n for (const ref of refs) {\n if (ref == null) continue;\n if (typeof ref === \"function\") {\n const result = ref(node);\n cleanups.push(typeof result === \"function\" ? result : () => ref(null));\n } else {\n (ref as React.MutableRefObject<T | null>).current = node;\n cleanups.push(() => {\n (ref as React.MutableRefObject<T | null>).current = null;\n });\n }\n }\n return cleanups;\n };\n\n if (SUPPORTS_REF_CLEANUP) {\n return (node) => {\n const cleanups = attach(node);\n return () => {\n for (const cleanup of cleanups) cleanup();\n };\n };\n }\n\n // React ≤18: drive cleanups off the `null` detach call instead of a return.\n let cleanups: (() => void)[] = [];\n return (node) => {\n for (const cleanup of cleanups) cleanup();\n cleanups = node == null ? [] : attach(node);\n };\n}\n\n// ── Data attributes helper ────────────────────────────────────────────────────\n\nfunction stateDataAttrs(\n state: NumberFieldState,\n isInvalid: boolean\n): Record<string, string | undefined> {\n const { options } = state;\n return {\n \"data-disabled\": options.disabled ? \"\" : undefined,\n \"data-readonly\": options.readOnly ? \"\" : undefined,\n \"data-required\": options.required ? \"\" : undefined,\n \"data-scrubbing\": state.isScrubbing ? \"\" : undefined,\n \"data-focused\": state.isFocused ? \"\" : undefined,\n \"data-invalid\": isInvalid ? \"\" : undefined,\n };\n}\n\n// ── Root ──────────────────────────────────────────────────────────────────────\n\n// HTML attributes that belong on the wrapper div (not passed to state/aria hooks)\nconst DIV_ONLY_KEYS = new Set([\n \"className\",\n \"style\",\n \"id\",\n \"tabIndex\",\n \"title\",\n \"role\",\n \"aria-label\",\n \"data-testid\",\n \"onClick\",\n \"onMouseEnter\",\n \"onMouseLeave\",\n]);\n\nfunction splitProps(props: Record<string, unknown>) {\n const fieldProps: Record<string, unknown> = {};\n const divProps: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(props)) {\n if (DIV_ONLY_KEYS.has(key) || key.startsWith(\"data-\") || key.startsWith(\"aria-\")) {\n divProps[key] = val;\n } else {\n fieldProps[key] = val;\n }\n }\n return { fieldProps, divProps };\n}\n\nconst Root = forwardRef<HTMLDivElement, NumberFieldRootProps>(function NumberFieldRoot(\n { children, onValueChange, onValueCommitted, ...allProps },\n ref\n) {\n const inputRef = useRef<HTMLInputElement>(null);\n const { fieldProps, divProps } = splitProps(allProps as Record<string, unknown>);\n const props = fieldProps as Omit<\n NumberFieldRootProps,\n \"children\" | \"onValueChange\" | \"onValueCommitted\"\n >;\n\n // Keep a stable ref to onValueChange so the onChange closure never goes stale\n const onValueChangeRef = useRef(onValueChange);\n onValueChangeRef.current = onValueChange;\n\n // Keep a stable ref to the state object so onChange can read the current reason\n const stateRef = useRef<NumberFieldState | null>(null);\n\n // Wrap onChange to also fire onValueChange with the tracked reason.\n // This closure captures stateRef (stable) not state (changes each render).\n // _setLastChangeReason is called synchronously BEFORE the state mutation\n // that triggers onChange, so stateRef.current._getLastChangeReason() always\n // returns the correct reason at the time onChange fires.\n const wrappedProps = {\n ...props,\n // Forward onValueCommitted to the behavior hook, which fires it on blur/Enter.\n onValueCommitted,\n onChange: (value: number | null) => {\n props.onChange?.(value);\n if (onValueChangeRef.current && stateRef.current) {\n onValueChangeRef.current(value, {\n reason: stateRef.current._getLastChangeReason(),\n // _getLatestDisplay (not .inputValue) — at onChange time `inputValue`\n // state still holds the previous render's value; the ref is updated\n // synchronously before the emission, so it matches `value`.\n formattedValue: stateRef.current._getLatestDisplay(),\n });\n }\n },\n };\n\n const state = useNumberFieldState(wrappedProps);\n stateRef.current = state; // always keep stateRef pointing to current state\n\n const aria = useNumberField(wrappedProps, state, inputRef);\n\n // Determine if field is invalid (out-of-range or failed validate)\n const isInvalid =\n state.validationState === \"invalid\" ||\n (state.numberValue !== null &&\n ((props.minValue !== undefined && state.numberValue < props.minValue) ||\n (props.maxValue !== undefined && state.numberValue > props.maxValue)));\n\n return (\n <NumberFieldContext.Provider value={{ state, aria, inputRef, props: wrappedProps }}>\n <div\n ref={ref}\n {...(divProps as React.HTMLAttributes<HTMLDivElement>)}\n {...stateDataAttrs(state, isInvalid)}\n >\n {children}\n </div>\n </NumberFieldContext.Provider>\n );\n});\n\n// ── Label ─────────────────────────────────────────────────────────────────────\n\ninterface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {\n render?: RenderProp;\n children?: React.ReactNode;\n}\n\nconst Label = forwardRef<HTMLLabelElement, LabelProps>(function NumberFieldLabel(\n { render, children, ...rest },\n ref\n) {\n const { aria, state } = useNumberFieldContext();\n // labelProps carries a registration ref; merge it with the forwarded ref and,\n // for the element render-prop form, the consumer's own ref on that element, so\n // all fire (the registration is what keeps Input/Group's aria-labelledby).\n // Memoized for a stable identity so React doesn't detach/reattach (and re-run\n // ref cleanups) every render — including across the hasLabel re-render.\n const { ref: labelRef, ...labelProps } = aria.labelProps;\n const renderRef = React.isValidElement(render) ? getElementRef(render) : undefined;\n const mergedRef = useMemo(() => mergeRefs(ref, labelRef, renderRef), [ref, labelRef, renderRef]);\n const el = (\n <label ref={mergedRef} {...labelProps} {...rest}>\n {children}\n </label>\n );\n return renderWith(el, render, state, mergedRef);\n});\n\n// ── Group ─────────────────────────────────────────────────────────────────────\n\ninterface GroupProps extends React.HTMLAttributes<HTMLDivElement> {\n render?: RenderProp;\n children?: React.ReactNode;\n}\n\nconst Group = forwardRef<HTMLDivElement, GroupProps>(function NumberFieldGroup(\n { render, children, ...rest },\n ref\n) {\n const { aria, state } = useNumberFieldContext();\n const el = (\n <div ref={ref} {...aria.groupProps} {...rest}>\n {children}\n </div>\n );\n return renderWith(el, render, state);\n});\n\n// ── Input ─────────────────────────────────────────────────────────────────────\n\ninterface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"type\"> {\n render?: RenderProp;\n}\n\nconst Input = forwardRef<HTMLInputElement, InputProps>(function NumberFieldInput(\n { render, ...rest },\n _ref\n) {\n const { aria, state, inputRef } = useNumberFieldContext();\n // Merge a consumer aria-describedby (passed on <Input>) with the hook's\n // auto-wired value (the mounted <Description> id) instead of letting the\n // rest-spread clobber it — otherwise putting aria-describedby on the input\n // would silently drop the description association.\n const describedBy =\n [rest[\"aria-describedby\"], aria.inputProps[\"aria-describedby\"]].filter(Boolean).join(\" \") ||\n undefined;\n const el = (\n <input\n ref={inputRef as React.RefObject<HTMLInputElement>}\n {...aria.inputProps}\n {...rest}\n aria-describedby={describedBy}\n />\n );\n return renderWith(el, render, state);\n});\n\n// ── Increment ─────────────────────────────────────────────────────────────────\n\ninterface IncrementProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n render?: RenderProp;\n children?: React.ReactNode;\n}\n\nconst Increment = forwardRef<HTMLButtonElement, IncrementProps>(function NumberFieldIncrement(\n { render, children, ...rest },\n ref\n) {\n const { aria, state } = useNumberFieldContext();\n const el = (\n <button ref={ref} {...aria.incrementButtonProps} {...rest}>\n {children ?? \"+\"}\n </button>\n );\n return renderWith(el, render, state);\n});\n\n// ── Decrement ─────────────────────────────────────────────────────────────────\n\ninterface DecrementProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n render?: RenderProp;\n children?: React.ReactNode;\n}\n\nconst Decrement = forwardRef<HTMLButtonElement, DecrementProps>(function NumberFieldDecrement(\n { render, children, ...rest },\n ref\n) {\n const { aria, state } = useNumberFieldContext();\n const el = (\n <button ref={ref} {...aria.decrementButtonProps} {...rest}>\n {children ?? \"−\"}\n </button>\n );\n return renderWith(el, render, state);\n});\n\n// ── HiddenInput ───────────────────────────────────────────────────────────────\n\nconst HiddenInput = function NumberFieldHiddenInput() {\n const { aria } = useNumberFieldContext();\n if (!aria.hiddenInputProps) return null;\n return <input {...aria.hiddenInputProps} />;\n};\n\n// ── ScrubArea ─────────────────────────────────────────────────────────────────\n\nconst ScrubArea = forwardRef<HTMLSpanElement, ScrubAreaProps>(function NumberFieldScrubArea(\n { render, children, direction = \"horizontal\", pixelSensitivity = 4, label, ...rest },\n ref\n) {\n const { state } = useNumberFieldContext();\n const { scrubAreaProps } = useScrubArea(state, { direction, pixelSensitivity, label });\n\n const el = (\n <span ref={ref} {...scrubAreaProps} {...(rest as React.HTMLAttributes<HTMLSpanElement>)}>\n {children}\n </span>\n );\n return renderWith(el, render, state);\n});\n\n// ── ScrubAreaCursor ───────────────────────────────────────────────────────────\n//\n// Renders a custom cursor element positioned at the virtual cursor location\n// during pointer lock. Use this to show a drag handle icon while scrubbing.\n// Rendered only when isScrubbing is true.\n\nconst ScrubAreaCursor = forwardRef<HTMLSpanElement, ScrubAreaCursorProps>(\n function NumberFieldScrubAreaCursor({ render, children, style, ...rest }, ref) {\n const { state } = useNumberFieldContext();\n\n if (!state.isScrubbing) return null;\n\n const el = (\n <span\n ref={ref}\n style={{\n position: \"fixed\",\n pointerEvents: \"none\",\n zIndex: 9999,\n ...style,\n }}\n {...(rest as React.HTMLAttributes<HTMLSpanElement>)}\n >\n {children}\n </span>\n );\n return renderWith(el, render, state);\n }\n);\n\n// ── Description ───────────────────────────────────────────────────────────────\n\ninterface DescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {\n children?: React.ReactNode;\n}\n\nconst Description = forwardRef<HTMLParagraphElement, DescriptionProps>(\n function NumberFieldDescription({ children, ...rest }, ref) {\n const { aria } = useNumberFieldContext();\n // descriptionProps carries a registration ref (like labelProps) so the input's\n // aria-describedby only points here while a Description is mounted. Merge it\n // with the forwarded ref so both fire.\n const { ref: descRef, ...descriptionProps } = aria.descriptionProps;\n const mergedRef = useMemo(() => mergeRefs(ref, descRef), [ref, descRef]);\n return (\n <p ref={mergedRef} {...descriptionProps} {...rest}>\n {children}\n </p>\n );\n }\n);\n\n// ── ErrorMessage ──────────────────────────────────────────────────────────────\n\ninterface ErrorMessageProps extends React.HTMLAttributes<HTMLParagraphElement> {\n children?: React.ReactNode;\n}\n\nconst ErrorMessage = forwardRef<HTMLParagraphElement, ErrorMessageProps>(\n function NumberFieldErrorMessage({ children, ...rest }, ref) {\n const { aria, state } = useNumberFieldContext();\n // If no children provided, fall back to the validation error string (if any)\n const content = children ?? state.validationError ?? null;\n if (!content) return null;\n return (\n <p ref={ref} {...aria.errorMessageProps} {...rest}>\n {content}\n </p>\n );\n }\n);\n\n// ── Formatted ─────────────────────────────────────────────────────────────────\n//\n// Read-only display of the current formatted value. Useful for showing the\n// formatted number inline without an editable input (e.g., in a data table).\n\ninterface FormattedProps extends React.HTMLAttributes<HTMLSpanElement> {\n render?: RenderProp;\n}\n\nconst Formatted = forwardRef<HTMLSpanElement, FormattedProps>(function NumberFieldFormatted(\n { render, style, ...rest },\n ref\n) {\n const { state, aria } = useNumberFieldContext();\n // The input only sets `style` for RTL locales, so its presence flags RTL.\n const isRTL = aria.inputProps.style != null;\n // Isolate the number from surrounding bidi text (and mirror the input's RTL\n // alignment + data-rtl hook) so an inline formatted value renders correctly\n // next to RTL copy instead of inheriting the wrong direction.\n const mergedStyle: React.CSSProperties = isRTL\n ? { direction: \"ltr\", textAlign: \"right\", unicodeBidi: \"plaintext\", ...style }\n : { unicodeBidi: \"isolate\", ...style };\n const el = (\n <span\n ref={ref}\n aria-hidden=\"true\"\n data-rtl={isRTL ? \"\" : undefined}\n style={mergedStyle}\n {...rest}\n >\n {state.inputValue}\n </span>\n );\n return renderWith(el, render, state);\n});\n\n// ── Namespace export ──────────────────────────────────────────────────────────\n\nexport const NumberField = {\n Root,\n Label,\n Group,\n Input,\n Increment,\n Decrement,\n HiddenInput,\n ScrubArea,\n ScrubAreaCursor,\n Description,\n ErrorMessage,\n Formatted,\n};\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport { createFormatter } from \"../core/formatter.js\";\nimport type { UseNumberFieldStateOptions } from \"../core/types.js\";\n\ntype FormatOptions = Pick<\n UseNumberFieldStateOptions,\n | \"locale\"\n | \"formatOptions\"\n | \"prefix\"\n | \"suffix\"\n | \"minimumFractionDigits\"\n | \"maximumFractionDigits\"\n | \"fixedDecimalScale\"\n>;\n\n/**\n * Lightweight display-only formatting hook. Returns the formatted string for\n * a numeric value using the same Intl.NumberFormat engine as the full input.\n *\n * Use this when you need to display a formatted number in a read-only context\n * (table cells, summaries, labels) without the overhead of a full input state machine.\n *\n * @example\n * const price = useNumberFieldFormat(1234567.89, {\n * locale: 'en-US',\n * formatOptions: { style: 'currency', currency: 'USD' },\n * })\n * // price === \"$1,234,567.89\"\n *\n * @example\n * const pct = useNumberFieldFormat(0.4267, {\n * formatOptions: { style: 'percent', maximumFractionDigits: 1 },\n * })\n * // pct === \"42.7%\"\n */\nexport function useNumberFieldFormat(value: number | null, options: FormatOptions = {}): string {\n const {\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n } = options;\n\n const formatter = useMemo(\n () =>\n createFormatter({\n locale,\n formatOptions,\n prefix,\n suffix,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n locale,\n JSON.stringify(formatOptions),\n prefix,\n suffix,\n minimumFractionDigits,\n maximumFractionDigits,\n fixedDecimalScale,\n ]\n );\n\n return useMemo(() => {\n if (value === null || value === undefined) return \"\";\n return formatter.format(value);\n }, [value, formatter]);\n}\n"]}
|