XGitHub

How It Works

A scannable reference for Numora's event handlers, sanitization steps, formatting stages, and value output. For the long-form narrative with diagrams and demos, see Anatomy of a Numeric Input.

Events

Numora intercepts four input vectors on a single <input type="text">. See Anatomy: event pipeline for the lifecycle and timing of each.

  • keydown - skips the cursor over thousand separators on Delete / Backspace.
  • beforeinput - primary formatting hook. Calls preventDefault() and writes the formatted result via setRangeText, preserving the browser's undo stack.
  • input - single onChange emitter; idempotent on values already produced by the pipeline.
  • paste - splices clipboard text into the selection range, runs the full pipeline, repositions the cursor.
  • focus / blur - strip / re-apply thousand separators in FormatOn.Blur mode only.

Sanitization

Seven steps run in order on every value before formatting is applied. See Anatomy: sanitization for the visual pipeline and per-step demos.

  1. Mobile keyboard artifact filtering
  2. Thousand separator removal
  3. Compact notation expansion (opt-in via enableCompactNotation)
  4. Scientific notation expansion
  5. Non-numeric character removal
  6. Extra decimal separator removal
  7. Leading zero normalization (disable with enableLeadingZeros)

Per-step configuration: see features/sanitization, features/compact-notation, features/scientific-notation, features/leading-zeros.

Formatting

Four stages run after sanitization. See Anatomy: formatting for diagrams and demos.

  1. Decimal trimming to maxDecimals (every keystroke)
  2. Decimal padding to decimalMinLength - display/blur only, never on a keystroke, so a padded field can still receive further digits by typing
  3. Thousand grouping (FormatOn.Change only; deferred to blur in FormatOn.Blur)
  4. Cursor restoration after the formatted value replaces input.value

Per-stage configuration: see features/formatting, features/decimals.

Value output

Every value is emitted as a string. See Anatomy: raw vs formatted for the mental model; features/value-types for the configuration and the valueAsNumber escape hatch.

  • formatted - the display string with thousand separators; always written to input.value.
  • raw - the sanitized string without separators; emitted via onChange when rawValueMode: true.

Value format

String value / setValue are already in the field's display format - locale separators allowed, grouping optional - since that is what every existing caller passes and formatValueForDisplay already strips grouping. A JS number is always dot-decimal, so the valueAsNumber setter converts it to the configured decimal separator before writing, instead of passing the dot through unchanged.

Example: under locale: 'de-DE' ('.' groups, ',' is the decimal mark), instance.valueAsNumber = 1234.5 displays "1.234,5". Passing the raw string '1234.5' to setValue instead displays "12.345" - the dot is read as de-DE's thousand separator and stripped, concatenating the digits. Setting a negative valueAsNumber with enableNegative: false throws a RangeError rather than silently dropping the sign.