Skip to content

fix: size ordered list markers to their widest number - #1015

Merged
hryhoriiK97 merged 3 commits into
mainfrom
fix/ordered-list-marker-width
Oct 16, 2026
Merged

hryhoriiK97 merged 3 commits into
mainfrom
fix/ordered-list-marker-width

Conversation

@hryhoriiK97

Copy link
Copy Markdown
Collaborator

What/Why?

Ordered lists that reach 100. clip their markers: the column is sized for 99. and numbers are right-aligned against it, so 100. draws as 00.. Each ordered list now measures its widest marker and widens its own column to fit; markerMinWidth stays the floor, lists under 100 keep the 99. column, and nested lists move with a widened parent.

This carries @mwolson's #1005 (8407374) unchanged as the first commit, plus two follow-up commits from a local review. #1005 stays open for the discussion there; GitHub refuses maintainer pushes to that branch because the fork's parent is pingdotgg/enriched-markdown, so the follow-ups land here instead.

Closes #1003.

Follow-up commits on top of #1005

Library

  • Android, both packages: the nested-item margin lives in BaseListSpan via an overridable markerExtraWidth, so there is one formula for fix(android): align mixed nested list indents with iOS #1006 to extend. ListContextManager saves and restores the widening like the rest of the list state. The column is measured by a companion function instead of a throwaway span, and the new span arguments are named at call sites.
  • Android: the widening is rounded to whole pixels, so the Int leading margins and the float marker positions agree at every nesting depth with proportional fonts.
  • All platforms: a task item inside a widened ordered list moves with its numbered siblings, and so do its children. The Swift package already behaved this way; Android and RN iOS left tasks on the checkbox column, which produced a notch of about 25dp in a list numbered to 1000.
  • iOS: listMarkerOffset is ancestorMarkerOffset to match Android, the per-list extra stays cached on the RN context, and the Swift default column width is an extension on ListStyle instead of a static on a sibling renderer.

Tests

  • Suites are named by feature: ListRenderingTest(s) on every platform, with the checkbox toggle test in TaskListInteractionTest. The RN Android package gets a test/ support package like the standalone one (render helper, AST factory, and the canvas that records drawn markers), shared by both Android packages.
  • Task alignment tests assert the new behavior on Android and RN iOS.

Baselines and docs

  • Android captures for ordered_list_wide_markers_test recaptured on the repo's Pixel 9 API 36 AVD, where the committed ordered-list baselines pass exact-match; the originals from fix: size ordered list markers to their widest number #1005 did not. iOS captures reproduce byte for byte on iPhone 17 / iOS 26.5 and are unchanged.
  • The markerMinWidth rows in the RN and Android docs mention the widening.

Testing

  • Unit: RN Android ListRenderingTest (11) and TaskListInteractionTest (2); standalone Android ListRenderingTest (8) with the full :ui suite; standalone iOS ListRenderingTests (13) with the full package suite; RN iOS ListRenderingTests (6) in the example test target. ktlint, swiftlint --strict and clang-format pass.
  • Maestro, iPhone 17 / iOS 26.5: ordered_list_wide_markers_test in the RN and native iOS examples; captures byte-identical to the committed baselines.
  • Maestro, Pixel 9 API 36: ordered_list_wide_markers_test captured on two consecutive builds with identical output; ordered_list_test and nested_ordered_list_test pass exact-match against their main baselines, so no code path changes for lists under 100 items on React Native and Android, and the existing ordered-list captures match main pixel for pixel.

Notes

PR Checklist

  • Code compiles and runs on iOS
  • Code compiles and runs on Android
  • Updated documentation/README if applicable
  • Ran example app to verify changes
  • E2E tests are passing
  • Required E2E tests have been added (if applicable)

🤖 Generated with Claude Code

mwolson and others added 3 commits October 15, 2026 12:05
…s with it

The nested-item margin lives in BaseListSpan, driven by a markerExtraWidth
that OrderedListSpan and TaskListSpan override, so a later change to nested
margins has one formula to extend. ListContextManager saves and restores
the widening like the rest of the list state, and the column is measured by
a companion function instead of a throwaway span. The extra is rounded to
whole pixels so the Int leading margins and the float marker positions
agree at every depth.

A task item inside a widened ordered list now moves with its numbered
siblings on every platform, as the Swift package already did; before, the
checkbox column stayed put and left a notch in long lists.

iOS names the nesting offset ancestorMarkerOffset like Android, keeps the
per-list extra cached on the context, and derives the default column width
from ListStyle instead of a static on a sibling renderer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The marker width suites become ListRenderingTest(s) on every platform,
growing with later list fixes instead of one file per bug. The checkbox
toggle test moves to TaskListInteractionTest. The RN Android package gets a
test/ support package like the standalone one: a render helper, an AST
factory, and the canvas that records drawn markers, which both Android
packages now share. Task alignment tests assert that every row of a widened
list, tasks and their children included, shifts by the same amount.

The Android baselines for ordered_list_wide_markers_test are recaptured on
the repo's Pixel 9 API 36 AVD, where the committed ordered-list baselines
pass exact-match; the iOS captures reproduce byte for byte and are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@hryhoriiK97
hryhoriiK97 merged commit 9fabe82 into main Oct 16, 2026
16 checks passed
@hryhoriiK97
hryhoriiK97 deleted the fix/ordered-list-marker-width branch October 16, 2026 15:17
eszlamczyk pushed a commit that referenced this pull request Oct 16, 2026
* fix(clipboard): preserve table cell line breaks and math

* fix(ios): keep hard breaks inside their block when exporting HTML

collectParagraphsData split on lineRangeForRange:, which treats the U+2028
a hard break renders as like a paragraph end. A paragraph with a hard break
exported as two <p> blocks and a list item as two <li> items, and with the
new <br> escaping the first half gained a trailing <br>. Split on
paragraphRangeForRange: so the break stays in its block and becomes
<p>line one<br>line two</p>.

Tests are named by feature like #1015: ClipboardExportTests.mm and
ClipboardExportTest.kt, since both cover HTML and Markdown export. Added a
rendered hard-break case on iOS, the code block gate on Android, a run that
mixes escaped characters with a line break, and math nested in strong, on
both platforms.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Yash Singh <saiansh2525@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ordered list markers wider than 99. are clipped

3 participants