fix(ios): list markers next to emoji not rendered properly - #704
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes iOS list rendering for emoji and complex grapheme sequences by anchoring markers across full composed characters.
Changes:
- Updates marker anchoring in
ListItemRenderer. - Adds emoji and grapheme list examples to the sample app.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Summary |
|---|---|
packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m |
Uses grapheme-safe marker ranges. Add an iOS Maestro regression fixture. |
apps/react-native-example/src/sampleMarkdown.ts |
Adds emoji and complex grapheme rendering examples. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
When the first character of a list item is an emoji, iOS returns the AppleColorEmoji font for NSFontAttributeName. Its metrics (xHeight, capHeight) are much larger than the actual text font, causing bullet dots and checkboxes to be vertically misplaced. Look past the first composed character sequence to find the real text font used on the line, and fall back to the default font if the only font found is AppleColorEmoji. Co-authored-by: Cursor <cursoragent@cursor.com>
Collaborator
|
@eszlamczyk fyi - pushed a fix in 555c2e5 - ListMarkerDrawer now looks past the leading emoji to use the actual text font's metrics for marker placement.
|
hryhoriiK97
approved these changes
Aug 29, 2026
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.

What/Why?
Fixes #702.
On iOS, an unordered/ordered list item whose text begins with an emoji (e.g.
- 🛒 Groceries) rendered two bugs, both regressions introduced in 1.0.0:Root Cause
In
ListItemRenderer, each item's marker (ListItemMarkerStartAttribute) is anchored on the item's first content character so that items opening with a code block or nested sublist still get a marker (introduced in #478). The anchor was applied overNSMakeRange(anchorLocation, 1)- a single UTF-16 code unit. Emoji are multi-unit graphemes (a surrogate pair like 🛒, or longer ZWJ/flag/variation-selector sequences), so a length-1 attribute run splits the grapheme in two. That split makesNSLayoutManagerfail to form the emoji glyph (dropping it), and shifts the paragraph's first mapped character so the marker drawer's "draw only at paragraph start" check skips every item but the last.Fix
Anchor the marker over the full composed character sequence instead of one code unit
Testing
Added a dedicated "Emoji & Grapheme List Rendering" section to the example app's sampleMarkdown.ts (rendered by the Text screen) covering the issue's exact input plus harder graphemes: ZWJ family sequence, regional-indicator flag, and base+variation-selector, across unordered, ordered, nested, and task lists.
Screenshots
PR Checklist