Uh oh!
There was an error while loading. Please reload this page.
fix(fields): a detail-page address reads as a formatted address, not stringified JSON - #4215
Merged
Merged
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 11, 2026 03:00
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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#4037
The gap
The display (read) registry mapped
addressstraight toJsonCellRenderer, so a populated address rendered as{"street":"中策路 1 号","city":"杭州",…}on a record detail page — while alocationfield in the same field group rendered formatted, and the create/edit dialog rendered the same value as proper Street / City / State / ZIP / Country inputs. Display-side only: the input registry has always carriedaddress.Premise verified against
origin/mainbefore implementing, and it still holds:packages/fields/src/index.tsxhadaddress: JsonCellRendereringetCellRenderer's map, exactly as the source thread's triage recorded.Both read surfaces, one path
The card names two surfaces — detail read mode and the inline-edit read state.
DetailSectionbuilds onedisplayValue(packages/plugin-detail/src/DetailSection.tsx:244) and renders it from both the mobile read row and the desktop row that carries the pencil affordance, so a single registry entry fixes both. Both are pinned by tests driving the realDetailSection, not the renderer.Layout choice and its source
The layout is not invented here.
AddressField's readonly branch already collapsed a stored address to one line, and that rule is now the only implementation:Street, City, State ZIP, Country—stateand the postal code share one comma group, space-separated inside it ("CA 94102"), either one able to occupy the group alone.It moved into a pure
packages/fields/src/widgets/address-format.tsthat both the widget and the newAddressCellRenderercall, so a readonly form and a detail page cannot spell one stored address two ways. A copy next to the renderer would have been a rule that drifts — which is the failure the issue reports, one surface later. The module is deliberately React-free so the eager barrel can format a cell without pullingAddressFieldand its inputs out of the lazy widget chunk.On locale-aware ordering: the report was zh-CN, and Chinese postal convention is largest-to-smallest (country first). I did not introduce locale-dependent ordering. Neither the issue nor the source thread objectstack#5019 (read in full, including both triage comments) establishes a format ruling, and the sub-field set is the input widget's own. Reordering by locale would make the read line disagree with the readonly form line and with the input order users type in — a bigger inconsistency than the one being fixed, decided unilaterally. The existing single rule is applied uniformly; if the maintainer wants locale-ordered addresses, that is one deliberate change to
formatAddressaffecting every surface at once, which is exactly the point of it having one home.Graceful partials
Absent, non-string and whitespace-only parts collapse and are dropped rather than spaced over: a street-only address is
中策路 1 号, never, , ,and never the stringundefined. Legacy records whose postal code was written underzipCode(objectstack#5143) still render it, matching what the input widget reads.Nothing is silently swallowed: an object carrying no recognized part keeps today's compact-JSON rendering rather than disappearing,
{}and null show the usual empty placeholder, and a plain string address passes straight through.Reverse verification
Predicted direction first, then measured. Reverting only the two fix files to
origin/main(git checkout origin/main -- …, nevergit stash) and re-running:That is the issue's own signature. Two reported deviations from the naive expectation, both honest:
locationalone and is green in both directions, which is what "the sibling formatter is untouched" actually claims.Controls:
location/geolocationformatting unchanged,json/object/composite/recordstill stringify, address inputs unchanged on every surface including the dialog.Verification
npx vitest run packages/fields/ packages/plugin-detail/— 142 files, 1725 tests passedAddressCellRenderer.test.tsx(resolved throughgetCellRenderer, so a registry regression is caught, not merely a formatter change) + 4 inDetailSection.addressDisplay.test.tsxtype-checkboth packages: Done.lintboth packages: 0 errorscheck:control-bytes: OK (3909 files); explicit control-byte self-scan of every touched file: clean@object-ui/fields.plugin-detail's only change is a test, which releases nothingScope
index.tsxdiff is strictly the address entries (one import, one renderer, one registry line) — noImageField(#4141), no app-shell/ListView (#4155), no data-objectstack (#4139), no AppHeader (#4197).Out of scope, filed separately: actively inline-editing an address collapses it into one raw text box reading
[Object]viacoerceToSafeValue, and typing writes a string over the structured value. That is the inline-edit input path missing the address widget, a different defect from this display-registry gap — not fixed here.Generated by Claude Code