fix(fields): the date formatter's last three en-US channels thread the display locale (#4272) - #4544
Merged
Merged
Conversation
…e display locale (#4272) PR #4512 (via #4468) pointed every date renderer at useDisplayLocale(). Three channels were out of its reach because they are properties of the formatter's signature and of its callers rather than of any renderer: - formatDate's 'short' branch hardcoded toLocaleDateString('en-US', ...), so it ignored a locale even when the caller had threaded one into that very call. Its only consumers are ObjectGrid's two mobile-card date cells, which threaded no locale — fixing either half alone moves nothing, so both land together. - formatDateTime took no options parameter at all, so no caller could localize it; it always handed Intl an undefined tag, i.e. the MACHINE's locale. The optional parameter lands with its consumers, plugin-gantt's four call sites. - RecordPickerDialog's MongoDB $date fallback called a bare toLocaleDateString(). One resolver everywhere: useDisplayLocale() (tenant regional default → active UI language → 'en'). Intl accepts 'zh' verbatim, so there is still no mapping table. English output is byte-identical at every touched site: en and en-US agree on all twelve short month names, measured. Only the month token of the 'short' form is localized — the compact "Jan 15, '24" layout around it is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Collaborator
Author
|
PM step-7 复核 — ACCEPT (session_017Qqyix2QcnpUC9XeYVDzx3)
Auto-merge armed (squash) — landing verified per the merge-queue discipline. Generated by Claude Code Generated by Claude Code |
yinlianghui
marked this pull request as ready for review
August 13, 2026 07:25
This was referenced Aug 13, 2026
Closed
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4272
PR #4512 (via #4468) pointed every date renderer at
useDisplayLocale(). Three channels were out of its reach because they are properties of the formatter's signature and of its callers rather than of any renderer. This is the residue scope the card was re-scoped to, taken as one pass.The three channels
1.
formatDate's'short'branch hardcodedtoLocaleDateString('en-US', { month: 'short' }), so it rendered an English month even when the caller had threadedoptions.localeinto that very call. Its only consumers are ObjectGrid's two mobile-card date cells, and they threaded no locale.Fixing either half alone moves nothing — that is why both halves are in this PR and not split. The formatter would keep ignoring a locale nobody passed; the call sites would keep passing a locale the formatter discarded.
2.
formatDateTimetook no options parameter at all, so no caller could localize it however hard it tried — it always handedIntlanundefinedtag, which means the machine's locale, neither of the repo's two locale channels. The parameter is optional and lands with its consumers (plugin-gantt's four tooltip call sites), not speculatively.3.
RecordPickerDialog's MongoDB$datefallback called a baretoLocaleDateString()with no tag.One resolver everywhere, unchanged from #4512:
useDisplayLocale()(tenant regional default → active UI language →'en').Intlaccepts'zh'verbatim, so there is still no mapping table anywhere.Sites touched
packages/fields/src/index.tsxformatDate's'short'branch;formatDateTime's new optionaloptionspackages/fields/src/widgets/RecordPickerDialog.tsx$datefallback + itsuseCallbackdeppackages/plugin-grid/src/ObjectGrid.tsx'short'date cellspackages/plugin-gantt/src/ObjectGantt.tsxtasksmemo depThe plugin-grid sites were re-located by content, since the file moved under #4531. The residue comment named
ObjectGrid.tsx:2778,2795; both are the calls passing'short', and they shift by a constant −121 line offset against #4531's parent (2899/2916). A thirdformatDatesite in that file does not fit that mapping, so it was never one of the two — filed separately as #4541 rather than fixed here.Hooks are read unconditionally at component level in all three components.
displayLocaleis added to the gantttasksmemo's dependencies because the tooltip strings are formatted eagerly inside it — without it a language switch would leave built tooltips on the previous locale.Red-first, and honest direction labelling
Predicted in writing before the tests were run, then run against unfixed code: 7 red, 8 green-both-sides. Actual matched per case.
Measured on the runner (node v22.22.2, ICU 78.2, TZ=UTC, machine locale
en-US):enanden-USproduce identical{month:'short'}output for all twelve months. So everyencase in these suites is a pin — the byte-identical must-not-change half — and not red evidence. They are labelled that way in the files rather than presented as proof the fix works. Expectations spell'en'/'zh'/'de'explicitly; none is computed from a baretoLocale*call against the runner (the #4513 trap).The genuine reds, verbatim:
The tenant-over-UI-language precedence case uses
dedeliberately:11.8.2026matches neither the machine's8/11/2026norzh's2026/8/11, so it is genuinely red before the fix instead of passing by coincidence.Reverse verification took the fix out with a patch file plus
git checkout(nevergit stash), re-ran, got exactly the same 7 reds, and restored with a sha256-verified match on all four files. A second, type-level reverse signal: with the fix removed the new tests do not even compile —error TS2554: Expected 1 arguments, but got 2on theformatDateTimecalls.Verification
packages/fields+packages/plugin-grid+packages/plugin-ganttfull suites: 192 files, 2324 tests, all passing, including fix(i18n): every date branch threads the active locale — future-relative and absolute forms localize (#4468) #4512'sdate-locale-channel.test.tsx(its six landed sites untouched) and the fix(plugin-grid): the cross-page select-all banner works under external pagination (#4464) #4503/fix(plugin-grid): select-all-matching replays the host's real query — or abstains — instead of fanning out unfiltered (#4501) #4510/fix(plugin-grid): the link column renders a real anchor when the host publishes record URLs (#4490) #4531 grid pins.type-checkgreen for all three packages (bothtsc --noEmitand the test tsconfig).index.tsx127,RecordPickerDialog.tsx43,ObjectGantt.tsx99,ObjectGrid.tsx244). No new findings.check:control-bytes,check:phantom-deps,changeset:check(fixed group + no-major) all green.Changeset, by
.d.tsmeasurement.d.tsbuilt both ways withdist/and tsbuildinfo cleared between builds:@object-ui/fields— minor.formatDateTime's optional parameter is visible in the package's entry.d.ts(export declare function formatDateTime(value: string | Date | number, options?: DateDisplayOptions): string), i.e. entry-reachable — the fix(plugin-timeline): dates follow the active locale instead of hardcoded en-US (#4513) #4523 precedent.@object-ui/plugin-grid/@object-ui/plugin-gantt— patch. Their own.d.tsfiles are byte-identical, so the change is module-local (fix(app-shell): organization & invitation UI translates its six English holdouts (#4474) #4496).No major.
Scope notes
Only the month token of the
'short'form is localized; the compact"Jan 15, '24"layout around it is a deliberate fixed shape for narrow cards and is unchanged — handing the whole form toIntlwould have moved the English output too (losing the apostrophe-year), which this card pins as must-not-change. Recorded as observation-class #4543.Out-of-scope findings filed, not fixed here: #4541 (ObjectGrid's record-detail date fallback, a third site outside the ruled two), #4542 (the gantt
tasksmemo omitstenantCurrency— pre-existing, same class in the currency channel), #4543.Zero config files touched in
packages/fieldsor anywhere (#4006 mutual exclusion); no LinkCell / kebab / rowCrudAffordances code disturbed in ObjectGrid (#4531 / #4296); app-shell, plugin-charts, plugin-timeline andcontent/docs/releases/untouched.Generated by Claude Code