Skip to main content

Number, currency and unit formatting

Generate consistent numeric labels with the same cross-platform script

['number-format', number, options] returns an ordinary string for labels, filters, concat, format and lexical let/var. commonNumberFormat reports the explicit subset documented here.

The five standard options are locale, currency, unit, min-fraction-digits and max-fraction-digits; their values may be expressions. Inputs must be finite numbers. Fraction digits are integers from 0 through 100, with minimum no greater than maximum. Currency and unit are mutually exclusive; unknown options fail explicitly.

import { map } from 'sqsmap';
map.addSource('values', { type: 'geojson', data: {
  type: 'Feature', id: 7, properties: { amount: 1234.5678 },
  geometry: { type: 'Point', coordinates: [116.4, 39.9] }
} });
map.addLayer({ id: 'amounts', type: 'symbol', source: 'values', layout: {
  'text-field': ['number-format', ['get', 'amount'], {
    locale: 'zh-CN', currency: 'CNY',
    'min-fraction-digits': 2, 'max-fraction-digits': 2
  }],
  'text-size': 20
} });
map.jumpTo({ center: [116.4, 39.9], zoom: 12 });
await map.sqs.flush();

Supported locales are en-US, zh-CN, de-DE, fr-FR and ja-JP, case-insensitively. Omitting locale selects en-US consistently across native and WASM, without consulting browser or operating-system language. Other locales and Unicode extensions fail with capability unavailable. This does not claim complete Intl locale coverage.

Currency codes are three ASCII letters, normalized to uppercase. Fixed CLDR data supplies symbols, placement, spacing and minor digits. Unknown valid codes use the code itself and two default fractional digits. Units include all 45 sanctioned ECMA-402 simple units and two-simple-unit -per- combinations, using short forms and plural selection from the formatted value. Decimal formatting defaults to at most three fractional digits; currency uses its minor digits. Setting only minimum or maximum adjusts the other default according to the standard. Decimal rounding, carry, grouping, trailing zeros and negative zero are preserved.

CLDR 48.2.0 data and one common Rust implementation produce the output, without JS Intl, OS locale APIs or an online service. Source SHA records and the complete Unicode license are distributed with the SDK. The MapLibre number-format specification supplies the syntax reference; the engine implementation is independent.

Copy portable-number-format.js, or run the complete browser page. The script compares exact decimal/currency/unit strings for all five locales, dynamic options and atomic failures, then displays an actual numeric label. Other locales, collator, complex text shaping and device/formal-release acceptance remain pending.

Following the reference Intl behavior, percent-per-X displays the percent sign without a denominator. X is still validated as a sanctioned simple unit. This does not multiply by 100 or perform physical unit conversion.