feat(input): list state, toolbar, docs, and e2e (lists 5/5)#514
Open
wildseansy wants to merge 5 commits into
Open
feat(input): list state, toolbar, docs, and e2e (lists 5/5)#514wildseansy wants to merge 5 commits into
wildseansy wants to merge 5 commits into
Conversation
Introduces BlockType.ANCHORED (Android) and ENRMBlockTypePersistsWhenEmpty (iOS) and routes the block store's adjust/normalize passes, the formatter's zero-length anchor stamping, and the views' orphan-anchor prune through them instead of heading-only checks. No behavior change — headings are the only anchored type until the list block type lands on top. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
UNORDERED_LIST_ITEM and ORDERED_LIST_ITEM with 0-based nesting depth in the range's level payload, joined to the anchored-type set. The store's list-metadata pass clamps depths to valid ancestry (an item nests at most one level under the previous adjacent item, so every state serializes) and computes each ordered item's 1-based ordinal from its position among adjacent same-depth, same-type siblings. One handler instance per type: Android renders via LeadingMarginSpans (bullet dot/ring/square by depth; right-aligned number for ordered) plus a LineHeightSpan for spacing; iOS reserves the indent column via the paragraph style and draws the glyph or number in the layout manager, with the ordinal stamped as a text attribute. listItemSpacing prop spaces items on both platforms. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parsers map list items to their block type with depth derived from AST UL/OL nesting (never leading spaces); iOS tags MD_BLOCK_LI itself since md4c emits inner paragraphs only for loose lists, clipping each item to its own first line. Serializers emit "- " / computed "N. " via the handler's line prefix, indented a uniform three spaces per depth so ordered and bullet nesting round-trip in any combination; an empty item's line serializes bare — a marker-only line re-parses as a setext underline for the previous line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
toggleUnorderedList / toggleOrderedList / indentList / outdentList on both platforms (indent preserves the item's list type and clamps to the previous item's depth + 1; outdent at depth 0 removes the marker; toggling one list type over the other replaces it). Enter behavior is handler-driven via continuesOnNewline: a non-empty item continues as a same-type sibling at the same depth, an empty item exits the list. Tab indents and Backspace at an item's start outdents/un-lists, including at the document start. Android anchors an empty list line with a ZWSP so its marker draws and the caret indents (a LeadingMarginSpan cannot indent an empty paragraph); iOS drives an explicit empty-line marker through the layout manager and keeps typing attributes block-styled on empty block lines. Edits that change the line count re-stamp the whole document so ordered renumbering and the depth clamp propagate past the edited line. External plain-text paste parses as markdown. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
onChangeState and the context-menu styleState gain unorderedList and
orderedList { isActive, depth }, matching the isActive shape of the other
entries and emitted only when the value changes. Example toolbar gains
bullet / numbered / indent / outdent buttons; INPUT.md and API_REFERENCE.md
document both list types; maestro flow + iOS baseline cover toggle,
continuation, and indent.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 5, 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.
The list stack (per the review ask, now including ordered lists — the shared machinery made them cheap to add):
GitHub can't base a fork PR on another fork branch, so every PR targets
mainand the diff shown for PR N is cumulative — this PR's own change is its last commit (each stage is exactly one commit on the previous branch). We'll merge bottom-up; after each merge the next PR's diff collapses to just its own commit. Checkoutfeat/list-5-stateto test the full feature end-to-end.This PR (last commit)
onChangeStateand the context-menustyleStategainunorderedListandorderedList{ isActive, depth }, matching the{ isActive }shape of the other entries and emitted only on change. Example toolbar gains bullet / numbered / indent / outdent buttons; INPUT.md and API_REFERENCE.md document both list types; the maestro flow + iOS baseline cover toggle, continuation, and indent (the flow scrolls the toolbar first — the list buttons sit past H1–H6 on phone-width viewports).Verified end-to-end on this branch: simulator + emulator runs cover toggle → marker + active state, Enter continuation with correct numbering, indent/outdent renumbering (
1. alpha / 1. beta (nested) / 2. gamma), empty-item exit, nested markdown import, andgetMarkdown()round-trip.🤖 Generated with Claude Code