Found while implementing objectui#4566 (PR pending). Filed rather than fixed: both surfaces sit outside that card's ruled surface (app-shell is explicitly excluded there, with #4305 / #4549 in flight).
The gap
objectui#4566 gave formatMeasure / formatDimensionValue in @object-ui/core an optional trailing locale parameter and threaded useDisplayLocale() from DatasetWidget. The parameter is OPTIONAL and omitting it reproduces the old machine-locale behaviour byte for byte — deliberately, so the producer could land without dragging every consumer with it.
The consequence is that the consumers which were not threaded still render in the machine's locale. A census of every call site outside plugin-dashboard:
packages/plugin-report/src/DatasetReportRenderer.tsx — 10 sites:
formatMeasure at lines 487, 502, 737, 994, 1005, 1019, 1029
formatDimensionValue at lines 488, 792, 980
packages/app-shell/src/views/metadata-admin/ — 3 sites:
previews/DatasetPreview.tsx:228 (formatMeasure) and :229 (formatDimensionValue)
inspectors/DatasetDefaultInspector.tsx:181 (formatMeasure, the format-hint sample preview)
Why it can be observed
Exactly the symptom objectui#4566 describes, on the surfaces that card did not cover: a German session reads a report measure as 1,234.5 where the convention is 1.234,5, now sitting next to a DASHBOARD measure that (after #4566) renders 1.234,5. The two dataset-bound surfaces are fed by the same function and disagree — which is a sharper inconsistency than the one that existed before #4566, when both were uniformly wrong.
Shape of the fix
Mechanical, and already proven on the dashboard side: read useDisplayLocale() at component level and pass it as the last argument. DatasetReportRenderer and DatasetPreview are both components, so no further plumbing is needed. DatasetDefaultInspector's sample is a preview of authored formatting and should follow the same channel.
Worth checking per site whether any of them format inside a useMemo — the dashboard consumer did not, but objectui#4542 / #4554 / #4565 all did, and the locale has to enter the dependency array where they do.
Relations
Generated by Claude Code
Found while implementing objectui#4566 (PR pending). Filed rather than fixed: both surfaces sit outside that card's ruled surface (
app-shellis explicitly excluded there, with #4305 / #4549 in flight).The gap
objectui#4566 gave
formatMeasure/formatDimensionValuein@object-ui/corean optional trailinglocaleparameter and threadeduseDisplayLocale()fromDatasetWidget. The parameter is OPTIONAL and omitting it reproduces the old machine-locale behaviour byte for byte — deliberately, so the producer could land without dragging every consumer with it.The consequence is that the consumers which were not threaded still render in the machine's locale. A census of every call site outside
plugin-dashboard:packages/plugin-report/src/DatasetReportRenderer.tsx— 10 sites:formatMeasureat lines 487, 502, 737, 994, 1005, 1019, 1029formatDimensionValueat lines 488, 792, 980packages/app-shell/src/views/metadata-admin/— 3 sites:previews/DatasetPreview.tsx:228(formatMeasure) and:229(formatDimensionValue)inspectors/DatasetDefaultInspector.tsx:181(formatMeasure, the format-hint sample preview)Why it can be observed
Exactly the symptom objectui#4566 describes, on the surfaces that card did not cover: a German session reads a report measure as
1,234.5where the convention is1.234,5, now sitting next to a DASHBOARD measure that (after #4566) renders1.234,5. The two dataset-bound surfaces are fed by the same function and disagree — which is a sharper inconsistency than the one that existed before #4566, when both were uniformly wrong.Shape of the fix
Mechanical, and already proven on the dashboard side: read
useDisplayLocale()at component level and pass it as the last argument.DatasetReportRendererandDatasetPrevieware both components, so no further plumbing is needed.DatasetDefaultInspector's sample is a preview of authored formatting and should follow the same channel.Worth checking per site whether any of them format inside a
useMemo— the dashboard consumer did not, but objectui#4542 / #4554 / #4565 all did, and the locale has to enter the dependency array where they do.Relations
Intl.NumberFormat('en-US')— an ordinalField.number(a year) always renders2,026, and no field property can turn it off #4033, Date formatter is half-localized: future relative forms and absolute timestamps stay en-US on a non-English locale #4272, plugin-timeline hardcodes 'en-US' at four date sites, so timeline headers stay English on every non-English session #4513, [plugin-grid] ObjectGrid's record-detail date fallback renders the MACHINE locale #4541, [plugin-gantt] tooltip number / currency / percent rows render in the MACHINE locale, next to date rows that follow the display locale #4553.dataset-format.tsplus the dashboard call sites, and it landed with those consumers complete.Generated by Claude Code