Number Format
A number formatted for its locale: decimal, currency, percent, compact, or a unit.
Live demo
NumberFormat displays one number through Intl.NumberFormat, so the grouping, the decimal mark, the currency symbol, and the unit all follow the reader's locale rather than whatever the source wrote. format picks the shape: decimal (the default), currency (with an ISO 4217 currency), percent, compact (2.5M), or unit (any unit Intl sanctions, such as kilobyte, celsius, or kilometer-per-hour).
percent follows Intl's semantics, so 0.42 reads 42%; pass the fraction, not the percentage. decimals fixes the fraction digits, and min-decimals / max-decimals override it on either side. sign controls when a sign shows, which is what a delta wants (exceptZero). The locale comes from locale, then the nearest lang attribute up the tree, then the runtime default. Figures are tabular by default so a column of them aligns, and an optional tone inks the number for a gain or a loss. It exists as an element, not only the formatNumber helper, because a fill or a j5ml fragment can place a component but cannot call a function. An empty or non-numeric value renders fallback, and an invalid currency, unit, or locale warns once and falls back to plain decimal formatting rather than throwing. A fill receives the result twice: formatted, the whole string, and parts, the same output split by formatToParts into typed pieces (currency, minusSign, integer, fraction, unit, …), so a mod can style the currency symbol or the cents on their own. formatNumberParts returns those pieces outside the element.
When to use
How this component composes with the rest of the set.
Props
17 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Number; an empty or non-numeric value renders fallback. | ||||
decimal, percent (Intl semantics, so 0.42 reads 42%), currency, compact (Intl's compact notation, 2.5M), or unit. | ||||
format is currency. | ||||
symbol ($), narrowSymbol, code (USD), or name (US dollars). | ||||
kilobyte, celsius, kilometer-per-hour), read when format is unit. | ||||
short (512 kB), long (512 kilobytes), or narrow (512kB). | ||||
decimals. | ||||
decimals. | ||||
auto (negatives only), always, exceptZero (the delta reading), or never. | ||||
grouping="false" turns them off, for an ID or a year. | ||||
lang attribute up the tree, then the runtime default. | ||||
value is empty or not a number. | ||||
Text is inked. Omit to inherit the surrounding color. | ||||
tabular="false" switches to proportional figures. | ||||
Anatomy
The named parts that make up the component. Created from script it renders a shadow root, where a ::part() handle is reachable from your own stylesheet and the class beside it is internal. Upgraded over server-rendered markup it renders light DOM, where the class is the handle.
number
The formatted figure: a <data> element whose value carries the raw number and whose text is the formatted string.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xtyle-default register
(derive(xtyleDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--accent-2-vivid--accent-3-vivid--accent-4-vivid--accent-vivid--black-vivid--blue-vivid--brown-vivid--cyan-vivid--danger-vivid--gray-vivid--green-vivid--info-vivid--neutral-vivid--orange-vivid--pink-vivid--purple-vivid--red-vivid--success-vivid--warn-vivid--white-vivid--yellow-vividAccessibility
Code
Formats
Decimal, currency, percent, compact, a unit, and a de-DE locale override on the same currency value.
<xtyle-number-format value="1234567.891"></xtyle-number-format>
<xtyle-number-format value="1299.5" format="currency" currency="USD"></xtyle-number-format>
<xtyle-number-format value="0.4237" format="percent" decimals="1"></xtyle-number-format>
<xtyle-number-format value="2450000" format="compact"></xtyle-number-format>
<xtyle-number-format value="512" format="unit" unit="kilobyte" unit-display="long"></xtyle-number-format>
<xtyle-number-format value="1299.5" format="currency" currency="EUR" locale="de-DE"></xtyle-number-format><script lang="ts">
import { NumberFormat } from "@xtyle/svelte";
let revenue = $state(1299.5);
</script>
<NumberFormat value={1234567.891} />
<NumberFormat value={revenue} format="currency" currency="USD" />
<NumberFormat value={0.4237} format="percent" decimals={1} />
<NumberFormat value={2450000} format="compact" />
<NumberFormat value={512} format="unit" unit="kilobyte" unitDisplay="long" />
<NumberFormat value={revenue} format="currency" currency="EUR" locale="de-DE" />---
import NumberFormat from "@xtyle/astro/NumberFormat.astro";
---
<NumberFormat value={1234567.891} />
<NumberFormat value={1299.5} format="currency" currency="USD" />
<NumberFormat value={0.4237} format="percent" decimals={1} />
<NumberFormat value={2450000} format="compact" />
<NumberFormat value={512} format="unit" unit="kilobyte" unitDisplay="long" />
<NumberFormat value={1299.5} format="currency" currency="EUR" locale="de-DE" />Deltas and fallback
sign="exceptZero" and a tone for a change, and fallback for a missing value.
<xtyle-number-format value="0.042" format="percent" decimals="1" sign="exceptZero" tone="success"></xtyle-number-format>
<xtyle-number-format value="-0.018" format="percent" decimals="1" sign="exceptZero" tone="danger"></xtyle-number-format>
<xtyle-number-format value="" fallback="n/a"></xtyle-number-format><script lang="ts">
import { NumberFormat } from "@xtyle/svelte";
</script>
<NumberFormat value={0.042} format="percent" decimals={1} sign="exceptZero" tone="success" />
<NumberFormat value={-0.018} format="percent" decimals={1} sign="exceptZero" tone="danger" />
<NumberFormat value={null} fallback="n/a" />---
import NumberFormat from "@xtyle/astro/NumberFormat.astro";
---
<NumberFormat value={0.042} format="percent" decimals={1} sign="exceptZero" tone="success" />
<NumberFormat value={-0.018} format="percent" decimals={1} sign="exceptZero" tone="danger" />
<NumberFormat value={null} fallback="n/a" />Parts for a mod
A fill receives parts beside formatted, the same output split into typed pieces; formatNumberParts gives the same split outside the element.
<!-- a mod's number-format fill reads bindings.parts and wraps each piece, so the currency symbol and the cents style on their own -->
<xtyle-number-format value="1234.5" format="currency" currency="EUR"></xtyle-number-format>
<script type="module">
import { formatNumberParts } from "@xtyle/core";
const parts = formatNumberParts(1234.5, { format: "currency", currency: "EUR", locale: "en-US" });
console.log(parts.map((part) => part.type).join(" "));
</script>