Repository navigation
docs(react): the InlineEditContextValue.draft comment teaches the own-key read (objectui#10466) - #10543
Merged
objectstack-fleet[bot] merged 1 commit intoSep 25, 2026
Conversation
…-key read The `draft` member's doc comment told hosts to read a field's live value with a nullish fallback to the saved record. A field the user or a cascade clear emptied is an own draft key with an empty value, so that read handed back the value just removed (the prune loop objectui#7190 measured on the highlights strip). The comment now teaches the staged-record spread: an own draft key wins even when empty, and the saved value is read only when the key is absent. No runtime change. Adds a source-text pin over the comment's code spans, in the pattern of the package's existing doc pins, and a patch changeset for @object-ui/react. Claude-Session: https://claude.ai/code/session_01BA3nKVUwKQJf8DBxrSVtNC Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
objectstack-fleet
Bot
deleted the
claude/issue-10466-inline-edit-draft-read-rule
branch
September 25, 2026 08:24
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 #10466
Clause-②: no
What was wrong
The
draftmember's doc comment on the publishedInlineEditContextValue(packages/react/src/context/InlineEditContext.tsx) ended: "Read a field's live value asdraft[name] ?? data[name]."That read falls back to the saved value whenever the draft value is
nullorundefined. A field the user emptied is an own draft key with an empty value. So is a single select or radio emptied by a cascade clear, which stagesnullsince PR objectui#10464. A host that copied the comment showed the value the user had just removed. On the highlights strip, that read handed an option widget the pruned value again on every render, an endless loop (objectui#7190; relayed from the card, not re-run here). The comment ships in thedisttypings, so it is what a host author sees on hover.Measured first, on
origin/main6881e9e47I looked for every reader of the inline-edit
draft: eachuseInlineEdit()consumer outside tests, bygit grepoverpackages/*/srcandapps/.DetailView(@object-ui/plugin-detail)data={{ ...data, ...editedValues }}, whereeditedValuesis the draftDetailSectiondataprop (the merged record above); from the session it reads onlyfieldErrorsHeaderHighlightstagedRecord = { ...data, ...draft }, thenstagedRecord[field.name]InlineEditSaveBarcontainers.tsx(@object-ui/components).editingonlyin draft,hasOwnProperty,Object.hasOwn), and no exported helper does the merge. So the comment names the spread and points at no helper.ObjectFormand the form renderer keep their own form state, and the grep above finds nouseInlineEdit()call in them.The change
{ ...data, ...draft }. An own draft key wins even when its value is empty (null,undefined,''), anddata[name]is read only when the key is absent. It does not name??. No runtime code changes and nothing new is exported.packages/react/src/context/__tests__/InlineEditContext.draftReadRule-10466.test.ts.@object-ui/react.check-changeset-presencecounts both touchedsrc/files as published source of a released package.Why a pin
This package already pins prescriptive doc text by reading the source:
LazyPluginLoader.jsdocExample.test.tsanduseNavigationOverlay.docExampleRecordSource-7638.test.ts. The new pin follows that pattern and stays loose. It reads only the code spans of thedraftdoc comment, never its prose, and asserts two things:Each matcher has synthetic controls. They show it fires on the old spelling and on the reversed spread, and stays silent on the own-key spellings.
Ablation: put the old doc back, watch the pin go red, restore
ablation-replace.mjsin wrap mode ata0bef54ea, inside a restore trap.8457b8281762to0239d8089256. By grep, spread spans went from 1 to 0 and fallback spans from 0 to 1.Tests 2 failed | 3 passed (5). The two failures were the two assertions on the real comment; the three controls stayed green.8457b8281762), andgit diff HEADis empty (0 bytes)..tsxsource by path, notdist.Local verification (all at
a0bef54ea)pnpm exec vitest run --maxWorkers=2 packages/react/gaveTest Files 96 passed (96)andTests 1303 passed (1303). The pin is in that population:vitest list --filesOnly packages/react/lists 96 files, and the pin is one of them.pnpm --filter '@object-ui/react^...' buildbuilt types, core, data-objectstack and i18n:VERDICT command-exit 0.pnpm --filter @object-ui/react type-checkechoedtsc --noEmit && tsc -p tsconfig.test.json:VERDICT command-exit 0. The test project's--listFilesincludes the pin (1 of its 96 test files).check:control-bytes;check:new-line-citations(0 new citation(s));check-changeset-presence;check:changeset-claims: nothing flagged. The born-false reading found 0 line addresses, the self-contradiction reading was clean, and no pending changeset names a touched file;check:pending-changeset-literals,check-changeset-no-major,check-changeset-fixed,check-changeset-overwrite;check:test-path-roots,check-type-check-coverage,check:spec-symbols,check:shell-escape-residue..md("File ignored because no matching configuration was supplied").--format json: 2 files, 0 errors, 5 warnings. The same file at BASE gives the same 5 warnings (no-explicit-anyx4,react-refresh/only-export-componentsx1), so none of them is new.eslint.config.jsdoes not enable type-aware linting (noprojectService, noparserOptions, noTypeCheckedpreset; typescript-eslint appears 9 times as a control). So this diff cannot change a lint result in any untouched file.pnpm lintis left to CI.Acceptance notes
@object-ui/plugin-detailand@object-ui/app-shellstill quote the old read in their objectui#2407 P2 entries. They are historical record, so they are left alone.HeaderHighlight("An OWN draft key wins even when its value isundefined") already agrees with the new doc, so it is unchanged.Session:
https://claude.ai/code/session_01BA3nKVUwKQJf8DBxrSVtNCGenerated by Claude Code