fix(plugin-detail): record:details edit mode edits a markdown field in a multi-line textarea (objectui#11541) - #11559
Merged
objectstack-fleet[bot] merged 2 commits intoOct 3, 2026
Conversation
…n a multi-line textarea (objectui#11541) A markdown row offered no pencil and no editor in edit mode: the detail hosts consult the fields package's shared inline-edit exclusion, and markdown is in it. #4228 recorded the detail-row reason as "heavy editor; a one-line text box is lossy". The row now routes markdown to the fields package's multi-line TextAreaField through DETAIL_ROUTED_INLINE_TYPES, the carve-out the upload widgets already use, so neither reason applies. The grid cell keeps the exclusion; html and richtext stay excluded. The INLINE_PLAIN_TEXT_FIELD_TYPES docblock no longer says the hosts never open an editor for markdown, and records that the one-line terminal input strips line breaks, which also holds for a multi-line textarea value. Pins: a markdown editor seeded and emitted byte for byte with blank lines and a trailing newline, both detail hosts, a save that reads back unchanged, html/richtext still open none, and the grid gate still refuses markdown. The type-coverage drift guard moves markdown to routed. Claude-Session: https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2 Co-authored-by: Claude <noreply@anthropic.com>
…light fixtures (objectui#11541) Drops two `as any` casts in the new pin file (a plain name/label pair is a HighlightField) and the `any` on the markdown branch's onChange parameter, which TextAreaField already types as string. No behaviour change. Claude-Session: https://claude.ai/code/session_01FjqrwXPfSMkSfkKYDSRkN2 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
|
This was referenced Oct 3, 2026
objectstack-fleet
Bot
deleted the
claude/issue-11541-detail-markdown-editor
branch
October 3, 2026 15:42
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 #11541
Clause-②: no
What changed
record:detailsedit mode now gives amarkdownfield an editor: the fields package's multi-lineTextAreaField.packages/plugin-detail/src/fieldEnrichment.ts:markdownjoinsDETAIL_ROUTED_INLINE_TYPES, the detail page's carve-out from the fields package's sharedINLINE_EXCLUDED_FIELD_TYPES(the carve-out the upload widgets already use). Both detail hosts (DetailSection,HeaderHighlight) read it throughisInlineExcludedDetailFieldType, so both now open the editor.INLINE_EXCLUDED_FIELD_TYPESis untouched, so a grid cell still excludesmarkdown.packages/plugin-detail/src/InlineFieldInput.tsx: a routedmarkdownbranch rendersTextAreaField, andmarkdownjoinsINLINE_ROUTED_FIELD_TYPES. TheINLINE_PLAIN_TEXT_FIELD_TYPESdocblock no longer says the hosts never open an editor for markdown.htmlandrichtext: unchanged, still excluded.inlineEditTypeCoverage.test.tsx:markdownmoves fromexcludedtorouted.@object-ui/plugin-detailpatch changeset.objectui#4228's reason, read first (the ruling's stop condition)
objectui#4228's blast-radius table records its detail-row reason for
markdown: "heavy editor; a one-line text box is lossy". The shared set's own comment is "Heavy / full editors — better in the record form than a cell", which is an argument about a grid cell. Neither holds for a multi-line editor in a detail row, so the stop condition does not fire.Deviation from the ruling's wording:
textareahas no multi-line editor inrecord:detailsThe ruling says "
markdowngets the multi-line editortextareaalready uses inrecord:detailsedit mode". Measured onorigin/mainc476be0:textareais a member ofINLINE_PLAIN_TEXT_FIELD_TYPES, so inrecord:detailsedit mode it edits in the terminal plain-text input, an INPUT element of type text. That is a ONE-line box, the very "one-line text box" objectui#4228 kept markdown out of./opt/pw-browsers/chromium): an INPUT of type text given the value"# T\n\npara\n"reads back"# Tpara". A TEXTAREA reads back the bytes it was given. HTML value sanitization for a text input strips line breaks."# Tpara".c476be0:InlineFieldInputwithtype: 'textarea'and a multi-line value renders that INPUT, its value reads"# TitleFirst paragraph.- a- b", and one keystroke emits the flattened string.Routing markdown onto textarea's branch would therefore land it on the lossy box and fail the ruling's own pin ("its save reads back unchanged, newlines included"). Ablation leg A below measures exactly that. The ruling's intent, a multi-line editor that is lossless for a stored string, is met with
TextAreaField: the fields package's multi-line widget, the one atextareafield edits with in the record form and in a grid cell (FieldEditWidgetmapstextareato it). As a consequencemarkdownlands in the drift guard'sroutedbucket, not intextarea'sbenignone.Pins
New file
InlineFieldInput.markdownEditor-11541.test.tsx. Its values carry blank lines and a trailing newline, and are compared byte for byte.InlineFieldInput: a TEXTAREA seeded with the stored value, never the terminal input; typing emits the exact string;autoFocuslands on it.DetailSection: the pencil shows on a markdown row; edit mode renders one editor, seeded byte-identical.HeaderHighlight: the same editor inside the edit session.InlineEditProvider+DetailSection+InlineEditSaveBarover a store-backedupdate. The PATCH body is exactly the notes field set to the edited string, the store holds it, and re-entering edit seeds the editor with it.html/richtext: no pencil and no editor on either host.plugin-grid'sinline-edit-options.test.tsgains one assertion,isFieldInlineEditable({ type: 'markdown' })is false, at the grid's own gate.Verification
At
950c768(the change itself):pnpm exec turbo run build --filter="@object-ui/plugin-detail^..." --filter="@object-ui/plugin-grid^..." --concurrency=2: 13 of 13 tasks successful.pnpm --filter @object-ui/plugin-detail --filter @object-ui/plugin-grid run type-check: both Done, exit 0.tsc -p tsconfig.test.json --listFilesconfirms both test projects compile the touched test files.pnpm exec vitest run --maxWorkers=2 packages/plugin-detail/ packages/plugin-grid/src/inline-edit-options.test.ts: Test Files 233 passed, 1 skipped (234); Tests 2318 passed, 8 skipped.Ablations, run after the change was committed. Each mutation went through
ablation-replace.mjs(anchor must hit, blob must change) with an EXIT/INT/TERM restore; each restore is proven by the blob hash equal to HEAD's and an emptygit diff HEAD.markdownremoved fromDETAIL_ROUTED_INLINE_TYPES): 7 failed, 160 passed (both hosts, the round trip, the blast-radius row, the drift guard's partition).markdownremoved from the sharedINLINE_EXCLUDED_FIELD_TYPES: the grid pin goes red, 1 failed, 14 passed.At
c65a031(final head; a typing-only follow-up that removes twoas anycasts and oneanyparameter annotation):pnpm --filter @object-ui/plugin-detail run type-check: exit 0.pnpm exec vitest run --maxWorkers=2over the six touched or adjacent test files: 6 files, 215 tests passed.no-explicit-any; one is on a line this PR adds, the new markdown branch'sfield as any, written the way its sibling branches are.check:control-bytes,check:new-line-citations(0 new, HEADc65a031),check:changeset-claims,check:pending-changeset-literals,check-changeset-presence,check-changeset-overwrite,check-changeset-no-major: all exit 0.plugin-detailsuite ran at950c768and was not re-run atc65a031. The difference between them is type-only. CI runs the full farm.Acceptance notes
record:detailsedit mode atextareafield edits in the one-line terminal input, so a stored multi-line value loses its line breaks on the first keystroke and the save writes the flattened text (measured above). This PR leavestextareaalone; theINLINE_PLAIN_TEXT_FIELD_TYPESdocblock now says the line-break loss holds for it, instead of letting "nothing is lost" read as covering it.markdownwithRichTextField(a Textarea plus a format header). This PR follows the ruling's "the multi-line editortextareauses" and routes toTextAreaField. Moving the detail row toRichTextFieldwould be a one-line change if the maintainer prefers the form's own markdown widget.InlineFieldInput.test.tsx; there are none. The round-trip harness followsInlineEditSaveBar.cascadePruneWire-10291.test.tsx.packages/plugin-detail/README.mdis not touched.Generated by Claude Code