Skip to content

Currency and accounting

Use currency for invoices, prices, and revenue. Use accounting for financial statements where negative amounts and zeros need a distinct presentation. Start with the Number setup; these examples use its DataGridFormattingPlugin registration.

Store the amount as a number in the chosen currency’s major unit. Here 1234.5 means 1,234.50 US dollars, not 1,234.5 cents.

grid.columns = [{
prop: 'amount', name: 'Amount (USD)',
dataGridFormat: { value: {
kind: 'preset', preset: 'currency',
locale: 'en-US', currency: 'USD', decimalPlaces: 2,
} },
}];
grid.source = [{ amount: 1234.5 }, { amount: -50 }, { amount: 0 }];

The first two cells display $1,234.50 and -$50.00. Sorting, calculations, and editing still receive 1234.5 and -50.

Locale controls separators and symbol placement; currency identifies the money. For example, locale: 'de-DE', currency: 'EUR' displays 1234.5 as 1.234,50 €. Choosing EUR does not convert USD into EUR. ECMA-402 defines currency and locale formatting separately.

Change the same column’s value format:

dataGridFormat: { value: {
kind: 'preset', preset: 'accounting',
locale: 'en-US', currency: 'USD', decimalPlaces: 2,
} }

With this locale, -1234.5 displays as ($1,234.50) and 0 as $-. Accounting negative signs follow the locale, so parentheses are not universal. The preset provides accounting text; it does not implement ledger-style alignment of the currency symbol and decimal point in separate regions.

To require parentheses for every negative value independently of a locale’s accounting convention, use the currency preset with negativeStyle: 'parentheses' instead. Red negative text is available through negativeStyle: 'red'; do not communicate a loss using color alone.

Keep the currency code beside the amount. Resolve presentation from the row:

grid.columns = [{
prop: 'amount', name: 'Original amount',
dataGridFormat: ({ model }) => ({ value: {
kind: 'preset', preset: 'currency', locale: 'en-GB',
currency: model.currency, decimalPlaces: model.decimals,
} }),
}];
grid.source = [
{ amount: 1200, currency: 'USD', decimals: 2 },
{ amount: 1200, currency: 'JPY', decimals: 0 },
{ amount: 1.234, currency: 'KWD', decimals: 3 },
];

The formatting preset defaults to two decimal places, including currencies. Set precision explicitly for your data contract; omitting decimalPlaces does not select currency-specific minor-unit precision. This example uses 0 for JPY and 3 for KWD. Validate currency codes in application data; the formatter falls back to USD for malformed codes.

  • Money storage: if an API uses integer cents, convert at the application boundary or in a deliberate display adapter. Do not silently treat cents as major units. Display rounding does not change stored values or implement settlement rounding.
  • Precision: JavaScript numbers use binary floating point. Keep exact decimal or minor-unit arithmetic in the application’s chosen calculation layer; formatting is the final presentation step.
  • Totals: group by currency, or convert with an application-owned rate and valuation date before aggregating. Adding USD and JPY amounts produces an ambiguous total.
  • Symbols: $ can be ambiguous. Include an ISO code in the column heading or a currency column. For currencyDisplay: 'code', use a custom Intl.NumberFormat renderer as in scientific notation and units; the preset does not expose currencyDisplay.
  • Entry: these formats do not parse localized monetary input. Configure the numeric editor separately.

Continue with percentages and rates for margins, tax rates, and return metrics, or Format Cells for interactive formatting and persistence.