fix(iOS, Android): list styling - #738
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aligns ordered/unordered list marker indentation and marker-column sizing across iOS and Android, including dynamic ordered-list marker column expansion to prevent marker/text overlap, and adds E2E coverage for the new behavior.
Changes:
- iOS: Fix unordered-list indent calculation to include bullet size, and implement dynamic ordered-list marker column sizing across contiguous lists (including re-styling adjacent lists on edits).
- Android: Remove the previous
olMarginLeft“lead margin” hack and implement dynamic ordered-list marker column sizing (with relayout forcing when margins change). - E2E: Add Maestro flows + baseline updates for dynamic ordered-list markers (single-digit → double-digit transitions).
Reviewed changes
Copilot reviewed 16 out of 58 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| ios/styles/UnorderedListStyle.mm | Includes bulletSize in unordered-list indent computation. |
| ios/styles/OrderedListStyle.mm | Adds dynamic ordered-list marker-column sizing and contiguous-list reindent/recalc logic. |
| ios/interfaces/StyleHeaders.h | Exposes ordered-list recalculation API for edited ranges. |
| ios/inputAttributesManager/InputAttributesManager.mm | Triggers ordered-list margin recalculation around edited ranges. |
| ios/extensions/LayoutManagerExtension.mm | Adjusts iOS ordered-list marker X positioning to align within marker column. |
| apps/example/src/constants/editorConfig.ts | Updates example ol styling values to reflect new behavior. |
| android/src/main/java/com/swmansion/enriched/textinput/watchers/EnrichedSpanWatcher.kt | Updates ordered-list index/margin recomputation call signature. |
| android/src/main/java/com/swmansion/enriched/textinput/styles/ListStyles.kt | Recomputes ordered-list indexes globally, updates marker-column margins, and forces relayout when margins change. |
| android/src/main/java/com/swmansion/enriched/textinput/styles/HtmlStyle.kt | Removes computed olMarginLeft offset; uses configured margin directly. |
| android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputView.kt | Precomputes ordered-list marker-column margins before setText for correct first layout. |
| android/src/main/java/com/swmansion/enriched/text/EnrichedTextView.kt | Ensures ordered-list marker-column margins are computed before/when setting text. |
| android/src/main/java/com/swmansion/enriched/text/EnrichedTextStyle.kt | Removes computed olMarginLeft offset; uses configured margin directly. |
| android/src/main/java/com/swmansion/enriched/common/spans/EnrichedOrderedListSpan.kt | Adds per-list columnMargin + updates marker positioning and leading margin behavior. |
| android/src/main/java/com/swmansion/enriched/common/OrderedListMargins.kt | Introduces shared ordered-list marker-column margin recomputation helper. |
| .maestro/enrichedText/flows/dynamic_ol_markers.yaml | Adds E2E flow verifying dynamic ordered-list marker column behavior in EnrichedText. |
| .maestro/enrichedInput/flows/dynamic_ol_markers.yaml | Adds E2E flow verifying dynamic ordered-list marker column behavior in EnrichedInput while editing. |
Suppressed comments (1)
android/src/main/java/com/swmansion/enriched/common/spans/EnrichedOrderedListSpan.kt:67
widthandxPositionare computed before applyingolMarkerFontWeight, but the marker is drawn after changing the typeface. If the marker font is bolder/wider than the body font, this produces incorrect right-alignment and can reintroduce overlap. Apply marker styling before measuring width/position, then draw.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 71 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
android/src/main/java/com/swmansion/enriched/textinput/styles/ListStyles.kt:112
updateOrderedListIndexesnow scans and sorts ordered-list spans for the entire document (getSpans(0, text.length, ...)) on every ordered-list span add/remove. This is a behavioral change from the prior bounded scan and can become O(N) per edit for large documents.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 70 changed files in this pull request and generated no new comments.
Suppressed comments (4)
android/src/main/java/com/swmansion/enriched/textinput/styles/ListStyles.kt:8
- Unused import:
android.text.style.ParagraphStyleis not referenced in this file, which will trigger lint warnings and adds noise to the imports.
android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputView.kt:17 - Unused import:
android.text.Spannedis not referenced in this file.
android/src/main/java/com/swmansion/enriched/common/OrderedListMargins.kt:10 - The doc comment says this function "Returns true" but the function returns
Unit. This is misleading for callers and future maintenance.
android/src/main/java/com/swmansion/enriched/common/OrderedListMargins.kt:51 forceOrderedListRelayoutcurrently forces a relayout by inserting an EmptySpan from the first ordered-list span to the last ordered-list span in the whole text. If the document has multiple ordered lists separated by other content, this can trigger unnecessarily large relayouts and temporarily apply a ParagraphStyle span across non-list paragraphs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 70 changed files in this pull request and generated no new comments.
Suppressed comments (1)
android/src/main/java/com/swmansion/enriched/common/OrderedListMargins.kt:24
- List boundary detection relies on
span.index > previousIndexwhile iterating spans in reverse. This merges distinct ordered lists when the previous list ends with index 1 and the next list is a single-item list (highest index = 1), because1 > 1is false so the algorithm treats it as the same list and computes a shared column width across both lists.
Summary
There were some inconsistencies regarding the list styling between native platforms
bulletSizewas not applied when computing the list indentolmargins on both platforms. By default it uses the margin provided viahtmlStyle, but if the rendered ordinal doesn't fit in it, it gets sufficiently increased. This solves an issue where markers would overlap the text. Equivalent fix was introduced in fix(web): list styling #730marginLeft, to suppress the issue from the previous point - now this mechanism is removed, as no longer neededTest Plan
experiment around with the htmlStyle in example app's
editorConfig.tsScreenshots / Videos
Before:
After:
You can see the margin got extended, after introducing double-digit ordinals
Compatibility
Checklist