fix(editor): add mobile indent/outdent controls for lists (#51) - #62
Conversation
Touch keyboards on iOS and Android have no Tab key, so the desktop Tab / Shift-Tab shortcuts that nest and un-nest list items were unreachable on mobile — there was no way to indent a list at all. Add a small on-screen toolbar with indent and outdent buttons that appears (mobile viewports only) when the editor is focused with the cursor in a list item. It rides just above the on-screen keyboard via the visualViewport API. The indent/outdent logic lives in a small, unit-tested helper module (listIndent.ts) wrapping ProseMirror's sinkListItem / liftListItem. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ABfY4ijSST2YQYFZJSeTBG
|
🤖 Starting work on this now. |
|
🤖 Watch live or take over the session here: https://claude.ai/code/session_01GVtQavpUmth8CnsSgGfdS9 |
There was a problem hiding this comment.
Review: approve — no changes requested.
Solid, well-scoped fix for #51. The indent/outdent logic is pulled into a testable listIndent.ts helper and the toolbar is correctly mobile-gated. A few things I specifically verified that hold up:
LIST_ITEM = 'listItem'matches the real schema —TaskLinkExtensionextends StarterKit'sListItem(src/lib/editor/schema.ts:46,49), and it covers both bullet and ordered lists since both uselistItem.- The
sinkListItem/liftListItemchains return a meaningful boolean (the first-item no-op returnsfalse), and the new unit tests assert exactly that. position: fixedfor.list-toolbaris safe — notransform/filterancestor that would reparent the fixed positioning context.updateKeyboardInsetdegrades sensibly across iOS (innerHeightstays,visualViewport.heightshrinks → inset = keyboard height) and Android's resizes-content mode (layout viewport shrinks → inset ≈ 0, toolbar already sits above the keyboard).onpointerdown+preventDefaultreliably suppresses the focus/blur steal for touch input (the only path where the toolbar is visible), so the command runs before the editor blurs.
Test coverage is appropriate: indent, outdent, top-level lift-out, and the in-list selection check are all exercised. The toolbar's visibility/positioning is inherently DOM/visualViewport-driven and not reachable in jsdom, which the PR honestly calls out.
All CI checks are passing as of this review (frontend unit tests, svelte-check, e2e-local, e2e-api). Nothing blocking — good to go.
|
Review posted successfully. SummaryI reviewed PR #62 ("fix(editor): add mobile indent/outdent controls for lists"). I checked out the branch Verdict: clean approval — no changes requested. Posted as a review comment on the PR (my integration can't submit an What I verified
✅ Opened pull request: imaustink/glyph#62 |
|
🤖 Starting work on this now. |
|
🤖 Watch live or take over the session here: https://claude.ai/code/session_01LvarsPqmJUpqYwcXJgwXRK |
|
🤖 Picked this PR back up under the ai-triage label. Summary of what I did: Review feedbackThe only review on this PR is the automated k5s-bot review, which was a clean approval with no changes requested and no inline review comments. It specifically verified the schema match ( Sync with base
Verification after the merge
Deliberately not done
Note: the pushed merge commit will kick off a fresh CI run; the pre-merge run was already fully green, and the local unit + svelte-check runs above pass, but the new run may still be in progress at the time of this comment. |
|
Done. The PR is ready to merge. SummaryPR: #62 — fix(editor): add mobile indent/outdent controls for lists (#51) Feedback found: The only review was the automated k5s-bot review — a clean approval, no changes requested, no inline comments. All CI checks on the PR were already passing. There was therefore no code feedback to act on, and I made no functional changes to the feature (staying within scope). What I changed:
Deliberately not done: No changes to the indent/o… ✅ Opened pull request: imaustink/glyph#62 |
Summary
Fixes #51 — "Users are unable to indent lists in mobile view."
List nesting in the editor relies on Tab / Shift-Tab (StarterKit's
ListItemkeyboard shortcuts). Touch keyboards on iOS and Android have no Tab key, so on mobile there was no way to indent (nest) or outdent a list item at all.What changed
src/lib/editor/listIndent.ts(new) — small, dependency-light helper module wrapping ProseMirror'ssinkListItem/liftListItem, plus aselectionInListItemcheck. Kept out of the Svelte component so it's unit-testable.Editor.svelte— a compact on-screen toolbar with outdent and indent buttons that:max-width: 768pxbreakpoint; desktop keeps using Tab / Shift-Tab);visualViewportAPI;pointerdownpreventDefaultso tapping a button doesn't blur the editor before the command runs.Icon.svelte— addedindent/outdenticons (Feather-style, matching the existing icon set).The issue suggested adding a button to the iOS/Android keyboard itself. Web apps can't inject custom keys into the system keyboard, so the equivalent web-native solution is an in-editor toolbar surfaced on mobile — implemented here.
Testing
src/lib/editor/listIndent.test.tscover indent, outdent, the top-level lift-out case, and the in-list selection check.pnpm test).svelte-check: 0 errors, 0 warnings.Notes for other things spotted (not done, out of scope)
Maintainers: apply the ai-review label to this PR to request an automated code review, or the ai-triage label to have the review feedback addressed and the branch brought back in sync with its base. (The automation can't apply either label to its own PR, so a human needs to add it.)
🤖 Generated with Claude Code
https://claude.ai/code/session_01ABfY4ijSST2YQYFZJSeTBG