Decimal formatting

The integer part grows freely by default. The fraction is optional and unlimited until decimalPlaces is set. Use text inputs with inputmode="decimal".

Optional fraction (default)

bindDecimal(input)Type 1234, then add .56789; no fixed precision is imposed.

US dollars

bindDecimal(input, { decimalPlaces: 2, prefix: '$' })Fixed cents, comma grouping, and an inert prefix.

Brazilian real

bindDecimal(input, { decimalPlaces: 2, separator: '.', decimalSeparator: ',', prefix: 'R$ ' })Period grouping and a comma decimal separator.

Euros

bindDecimal(input, { decimalPlaces: 2, separator: '.', decimalSeparator: ',', suffix: ' €' })Type a comma to open the fraction; the suffix stays inert.

Whole quantities

bindDecimal(input, { decimalPlaces: 0, suffix: ' units' })No decimal segment; grouping grows with the integer.

Signed balances

bindDecimal(input, { decimalPlaces: 2, prefix: '$', allowNegative: true })Type “-” anywhere to go negative, “+” anywhere to go positive.

No thousands grouping

bindDecimal(input, { decimalPlaces: 2, segmented: false })Useful when the display should stay close to a storage value.

Fixed integer and fraction widths

bindDecimal(input, { numberPlaces: 2, decimalPlaces: 2 })Paste 7.3 to see 07.30; each part is capped at two digits.

Masked value and numeric callback

bindDecimal(input, { suffix: ' kg', onChange: (masked, numeric) => updateOutputs(masked, numeric) })
masked string2.5 kg
numeric value2.5

Set decimalPlaces: 2 for fixed, zero-padded currency decimals, or 0 for integers only. numberPlaces pads and caps the integer part. Here segmented controls thousands grouping; it does not mean independent pattern fields.

Prefixes and suffixes are fixed display text, excluded from numeric parsing even when they contain digits or a decimal separator. Typing inside a prefix inserts at the start of the number; typing inside a suffix inserts at the end. Use the same locale and affix options when formatting and parsing.

Formatting without an input#

Use the pure helpers for initial values, server-rendered output, and programmatic updates. Pass the same options to formatting and parsing.

import { bindDecimal, formatDecimalValue, unmaskDecimal } from 'mother-mask'

const options = {
  decimalPlaces: 2,
  separator: '.',
  decimalSeparator: ',',
  suffix: ' €',
}

input.value = formatDecimalValue(1234.5, options) // '1.234,50 €'
bindDecimal(input, {
  ...options,
  onChange: (value, numericValue) => console.log(value, numericValue),
})
unmaskDecimal('1.234,50 €', options) // 1234.5