feat(ux): dedupe page links and collapse tree row actions behind an overflow menu - #42
Merged
Merged
Conversation
…verflow menu Links pane extractResolvedLinks emitted one entry per link occurrence, so a body that referenced the same page twice produced duplicate Outgoing links rows, and duplicate Backlinks rows on the target page, with colliding React keys. Dedupe by resolved target path on the server, and defensively in LinkInfo so the pane stays correct against an older backend. Tree navigation Replace the seven hover-only icon buttons on every tree row with a single overflow menu at all breakpoints. The trigger keeps its slot reserved, so revealing it no longer reflows the row or re-truncates the title, and the destructive action no longer sits next to the label. The previous max-md:hidden guard never won the cascade against group-hover:flex, so tapping a row on mobile exposed all eight controls at once. Mobile-first and accessibility - Sidebar search tab swaps the panel in place instead of also raising the modal search dialog on top of it. - Editor unsaved-changes and conflict prompts render through ModalCard, so they get a focus trap, Escape and dialog semantics; editor hotkeys no longer fire from behind an open prompt. - Form fields and the code editor render at 16px on phones to stop iOS Safari auto-zoom, and editor autofocus is gated behind a fine pointer so the keyboard cannot cover the save bar. - Markdown tables scroll inside their own container instead of dragging the article sideways. - 44px touch targets across tree rows, editor toolbar, links pane, history actions and modal dismiss. - Asset manager rows wrap instead of overflowing the dialog; rename moves to its own line and gains a cancel action. - sidebarVisible follows breakpoint changes instead of going stale on rotation. - Chat sends on Enter, keeps Shift+Enter for a newline, and exposes the transcript as a live region. - User deletion uses the in-app confirm dialog instead of window.confirm. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Summary
Fixes two reported defects and the mobile-first issues a UX audit surfaced around them.
Duplicated links at the bottom of a document. The cause was data, not a double render:
extractResolvedLinksemitted one entry per link occurrence, so a body referencing the same page twice produced two identical rows under Outgoing links, and two identical Backlinks rows on the target page. The React keys collided as well. Deduped by resolved target path inWikiApplicationService, plus a defensive pass inLinkInfoso the pane stays correct against an older backend.Tree navigation on desktop. Every row rendered up to seven icon buttons on hover. Moving the pointer onto a row materialised ~214px of controls, re-truncating the title under the cursor, with
Deleteadjacent toConvert. Replaced with a single overflow menu (RadixDropdownMenu) at all breakpoints; the trigger keeps its slot reserved so revealing it causes no reflow.Worth calling out: the old
max-md:hiddenguard on that cluster never won the cascade —(0,1,0)againstgroup-hover:flexat(0,2,0), and media queries add no specificity. Tapping a row on mobile focused the title button, matched:focus-within, and revealed all seven desktop icons plus the mobile overflow button — eight controls in a ≤320px sidebar, collapsing the title to zero width.Also fixed
ModalCard. Hotkeys no longer fire from behind an open prompt(pointer: fine)so the on-screen keyboard no longer covers the fixed save barsidebarVisiblewas seeded once at module load and went stale on rotation; now follows breakpoint crossings while preserving manual toggleswindow.confirm; now uses the same in-app dialog as every other destructive actionaria-expanded/aria-controlson the sidebar toggle, tab/tabpanel semantics,aria-currenton the active tree row