feat: preview and open the footnote a reference names - #417
Merged
Conversation
The label a caret reads is taken from the projected source rather than the node the session opened on, so a label being edited resolves as it is typed. The reference node stays the fallback for a selection that reaches one before a projection stands in its place.
Navigation takes the modifier click, which is the rule a link already follows, so the plain click keeps opening the reference's own source. The keyboard reaches the same move through the Edit menu's Jump group rather than a shortcut of its own, as Jump to selection does. A reference no definition answers to is only reachable from inside a session: remark reads a label without a definition as literal text, so the state comes from relabelling a reference or deleting the definition it named.
The preview carries no control and takes no focus, so it stays a semantic tooltip rather than a popover. Base UI names a popup through its trigger's aria-describedby, which an anchored, caret-driven preview has none of, so the role and the live region are set on the content itself. The pointer anchors to the rendered reference element; the keyboard anchors to the measured selection, because a reference the caret is reading has been replaced by its projected source and no longer has an element of its own.
The pointer stays on the reference through a modifier click, so without this the preview stayed open over the definition the click had just navigated to. A modifier pressed on its own keeps it, because holding one is how a pointer navigates from the preview it is reading.
The preview is anchored to the reference the label is written on, so the line repeated what the document was already showing under it.
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
A footnote reference exposed its editable
[^label]source but said nothing about the footnote it named, so reading one meant finding the definition elsewhere in the file and then finding the way back. A reference now previews its definition and navigates to it.The issue held three interaction decisions open before
Ready. They are answered here as: the preview holds no control and takes no focus, so it stays a semantic tooltip rather than the popover the issue would otherwise have required; pointer and keyboard reach the preview by their own gestures — hover after a delay, andMod+Alt+Pon the reference the caret reads; and navigation is a separate gesture rather than a control inside the preview.Jumpgroup, with no shortcut of its own, asJump to selectionhas none.aria-describedby, which an anchored, caret-driven preview has none of, so the role and the live region are set on the content itself.mousedown. The pointer stays on the reference through a modifier click, so without that the preview stayed open over the definition the click had just navigated to. A modifier pressed on its own keeps it, because holding one is how a pointer navigates from the preview it is reading.A reference no definition answers to is only reachable from inside a session. A file never opens holding one: remark reads a label without a definition as literal text rather than a reference, so the state arises by relabelling a reference to a name no definition answers to, or by deleting the definition it named. That is what the missing-definition state covers, and it is why the tests build it that way rather than by opening a file that spells it.
Related Issue
Closes #127
Verification
Focused tests drive the editor mount the projection and plugin tests use.
Mod+Alt+Pfrom the caret, carrying the same definition either way, and reports an explicit missing-definition state where the label answers to none.Escape, and on a click, and survives a modifier held on its own.Manually verified in Chrome against a temporary Vite route mounting the editor: the pointer preview opens after its delay anchored above the reference with the definition's text, and a modifier click lands the caret in the matching definition's body.
pnpm check:frontendpasses, and the coverage floor holds. The change is frontend-only.Not verified: the on-screen position of the keyboard preview, and whether the live region announces it. Chrome stopped delivering synthetic input to the ProseMirror surface partway through the manual pass, so the caret could not be placed in a reference there; the anchor it uses is asserted in the tests and is the one the context popup already ships. The desktop E2E suite, which CI runs as its own job, and backend checks, since nothing under
src-tauri/changed.Notes
TooltipContentgains ananchorpassthrough to its positioner, mirroring whatPopoverContentalready exposes. It is a passthrough on an existing primitive rather than a new one.findFootnoteDefinitionsmoves out of the definition-label plugin into the utility both it and the new resolution share, so the document scan has one owner.