fix(recipe): stop the rich-text editor writing an undeletable <br> into recipe text - #534
Open
plusmobileapps wants to merge 2 commits into
Open
fix(recipe): stop the rich-text editor writing an undeletable <br> into recipe text#534plusmobileapps wants to merge 2 commits into
plusmobileapps wants to merge 2 commits into
Conversation
…to recipe text PlusMarkdownEditor kept its RichTextState two-way bound to the value no matter which mode was on screen, and compose-rich-editor serializes a run of consecutive blank paragraphs to a literal `<br>` line. In Markdown mode that made pressing enter twice at the end of a field paste a `<br>` into the raw text field, and deleting it put the text back into the state that re-created it — the tag could never be removed. In rich-text mode the tag was invisible in the editor but reached storage, where the detail and cook screens render inline markdown only and printed it as a literal line. Gate both sync effects on richTextMode so the inactive editor never rewrites the value, and normalize `<br>` back to the blank line it stands for on the way out of the rich editor. Recipes already carrying one now render clean: the tag is dropped when splitting lines on the detail and cook screens, in the markdown preview, and in the add-to-grocery-list split, where it had been turning into a grocery item. Also move the resize handle out of the text field's bottom-end corner into its own row below the field. Overlaying it there let detectDragGestures swallow the drags that move the caret and selection handles on touch platforms, which land in exactly that corner on the last line. The gating removes a second source of touch jank: Markdown mode had been running a full markdown parse and serialize on the hidden rich state on every keystroke. This does not fix selection in rich-text mode on phones. compose-rich-editor 1.0.0-rc14 ships adjustTextIndicatorOffset as a workaround for BasicTextField selecting the wrong text in multi-paragraph content, but wires it up on desktop only — the Android and iOS actuals return the modifier unchanged. Ingredients and directions are exactly that multi-paragraph case, so the offsets stay wrong there until the library fixes it; Markdown mode is a plain OutlinedTextField and selects normally. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The markdown editor previews and the EditRecipe screens all grow by the height of the resize handle's own row, now that the handle no longer overlays the text field's bottom-end corner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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 two reported problems with the ingredients and directions inputs.
The undeletable
<br>PlusMarkdownEditorkept itsRichTextStatetwo-way bound tovalueno matter which mode was on screen, and compose-rich-editor serializes a run of consecutive blank paragraphs to a literal<br>line:In Markdown mode that made pressing enter twice at the end of a field paste a
<br>into the raw text field — the hidden rich state parsed"…\n\n"and echoed"…\n\n<br>"back throughonValueChange. Deleting the tag put the text back into the exact state that re-created it, so it could never be removed.In rich-text mode (the default) the tag was invisible in the editor but reached storage, where the detail and cook screens render inline markdown only — no HTML — and printed it as a literal line.
The fix:
withoutLineBreakTags()normalizes<br>back to the blank line it stands for on the way out of the rich editor. A test pins that normalization is a fixed point through the library's parser, so the two halves of the sync can't fight each other.<br>render clean: the tag is dropped when splitting lines on the detail and cook screens, in the markdown preview, and in the add-to-grocery-list split, where it had been turning into a grocery item.Mobile selection
The resize handle was overlaid on the text field's bottom-end corner with
detectDragGestures, swallowing drags in exactly the spot where the caret and selection handles land on the last line. It now sits in its own row below the field. The mode gating removes a second source of touch jank: Markdown mode had been running a full markdown parse and serialize on the hidden rich state on every keystroke.This does not fully fix selection in rich-text mode on phones, and that part is upstream. compose-rich-editor 1.0.0-rc14 ships
adjustTextIndicatorOffsetas its own workaround forBasicTextFieldselecting the wrong text in multi-paragraph content — but wires it up on desktop only; the Android and iOS actuals return the modifier unchanged (= this). Ingredients and directions are exactly that multi-paragraph case, so tap and selection offsets stay wrong there until the library fixes it. Maven shows nothing newer than rc14 to upgrade to. Markdown mode is a plainOutlinedTextFieldand selects normally, so it's the workaround for now; an upstream issue is worth filing.Testing
LineBreakTagsTestcovers the helper and pins the library's<br>serialization plus round-trip stability.client:ui:public,client:recipe:core:implandclient:cook:implsuites pass.Reviewer notes
<br>deliberately does not mark it dirty — the collector compares against the normalized caller value, so you don't get a spurious "discard changes?" prompt just for viewing one. The stored text is repaired the next time that field is genuinely edited and saved, and renders clean in the meantime.🤖 Generated with Claude Code