You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
formatCurrency drops a real cents digit: an amount of 1234.5 renders $1,234.5, not the $1,234.50 its own contract promises #4332
formatCurrency in packages/fields/src/index.tsx renders a currency amount whose fractional part has one significant digit with one decimal place instead of two. 1234.5 renders as $1,234.5.
Its own doc comment states the opposite contract:
Trailing .00 is dropped when the value is a whole number — Salesforce convention: $1,234.50 keeps cents; $1,234 does not.
So the intended behaviour is documented, and the code does not deliver it.
maximumFractionDigits is correctly switched on wholeness, but minimumFractionDigits is a constant 0. For a non-whole amount that gives the range [0, 2], and Intl then emits the shortest representation — so a genuine cents value of .50 is printed as .5. The intended pairing is minimumFractionDigits: isWhole ? 0 : 2.
Measured directly against the construction:
1234.5 => $1,234.5 (expected $1,234.50)
1234.56 => $1,234.56 (correct)
1234 => $1,234 (correct — the whole-number case the comment describes)
Only the "non-whole, one significant decimal digit" case is wrong, which is why it survived: the whole-number and two-digit cases both look right.
Impact
Reachable on any currency-typed field whose amount ends in a zero cent digit — prices like 19.90, 1234.50, 0.50. Those render as $19.9, $1,234.5, $0.5. This is money on a record page and in grid cells, so it reads as a data error rather than a formatting one.
Consumers of the same function inherit it: CurrencyCellRenderer (packages/fields/src/index.tsx), ObjectGrid (packages/plugin-grid/src/ObjectGrid.tsx), recordFields (packages/plugin-dashboard), and ObjectGantt (packages/plugin-gantt).
Not fixed here, and why
Found while implementing #4033 (number renderers hardcoding Intl.NumberFormat('en-US')). It is out of that card's scope — it is neither a locale defect nor a grouping defect, and #4033's ruling is deliberately narrow — so it is filed rather than folded in.
PR for #4033 pins the current behaviour in a control test (packages/fields/src/__tests__/NumberCellRenderer.grouping.test.tsx, "keeps grouping and the fractional part when the amount is not whole") with a comment pointing here, so this issue's fix will flip a test that is deliberately red-on-fix rather than silently changing an unwatched surface.
Suggested fix
minimumFractionDigits: isWhole ? 0 : 2, plus a pin for the .50 case. Worth checking CurrencyField's formatAmount (packages/fields/src/widgets/CurrencyField.tsx) at the same time — it uses precision for both bounds and so does not have this bug, which makes the two paths disagree today.
Activity
os-zhuang commentedon Aug 11, 2026
Triage:
pm:queue(+bug).minimumFractionDigitsconstant0whilemaximumFractionDigitsswitches on wholeness), with the fix shape stated and a deliberately red-on-fix control test already pinned by Console: number cell/display renderers hardcode a groupingIntl.NumberFormat('en-US')— an ordinalField.number(a year) always renders2,026, and no field property can turn it off #4033's PR. Money rendering$1,234.5reads as a data error to users — clearly dispatchable.origin/main@f046f88:packages/fields/src/index.tsx:376stillminimumFractionDigits: 0in the currency construction.Intl.NumberFormat('en-US')— an ordinalField.number(a year) always renders2,026, and no field property can turn it off #4033 (locale hardcoding) explicitly excludes it; Date formatter is half-localized: future relative forms and absolute timestamps stay en-US on a non-English locale #4272 (date formatter half-localized) is a different formatter. No open card owns the cents digit.Intl.NumberFormat('en-US')— an ordinalField.number(a year) always renders2,026, and no field property can turn it off #4033's PR pins the current behaviour inNumberCellRenderer.grouping.test.tsx— this card's fix must flip that pin knowingly (the pin comment points here), so dispatch after that PR lands or coordinate the pin edit.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
yinlianghui commentedon Aug 11, 2026
PROMOTE + CLAIM — session
session_017Qqyix2QcnpUC9XeYVDzx3(objectui whole-repo PM seat),finding → bug + pm:queue,dispatching now。Branch:claude/issue-4332-currency-cents-digit。范围按卡片:
formatCurrency的minimumFractionDigits恒 0 而 max 按整数性切换,1234.5渲染$1,234.5违背其自身 doc 注释承诺的$1,234.50——修复让 min 跟随分数分支(整数保持现状 0 位,小数补齐 2 位,与 doc 契约一致)。#4333 已在该函数落了 locale/分组改造并留了钉住现状的对照测试(注释指向本卡)——翻转那个被看守的测试就是红先用例;#4333 的 locale pins 不得回退。fields 面自由(#4033 已落)。compact 变体与非 currency 路径不动(对照)。Generated by Claude Code
fix(fields): formatCurrency keeps both cents digits on a fractional a…
fix(fields): currency formatting follows each currency's ISO 4217 min…