Skip to content

feat(ui): inline page preview on wiki-link hover #421

Description

@amelia751

Summary

When hovering over a [[wiki-link]] in the rendered page view, show an inline preview popover with the linked page's title, first ~200 characters of content, and tags. This is one of Obsidian's most-loved features and significantly improves navigation in densely linked knowledge bases.

Proposed behavior

  1. Hovering over any rendered wiki-link for 300ms opens a preview popover.
  2. The popover shows: title (from frontmatter), path, a content snippet (first ~200 chars of body, stripped of markdown), and tags if present.
  3. Clicking the link navigates as normal. Clicking inside the popover does not navigate.
  4. The popover dismisses on mouse-leave (with ~100ms grace period for moving to the popover itself).
  5. Keyboard: no popover on keyboard focus (keep tab navigation clean).
  6. Data: use GET /api/kiwi/peek?path=<target> which already returns title + snippet without full content.

Implementation notes

  • Prioritize shadcn components. Use shadcn HoverCard (Radix @radix-ui/react-hover-card) — install via npx shadcn@latest add hover-card. This gives accessible open-delay, close-delay, and portal positioning out of the box.
  • Wrap existing wiki-link <a> elements in <HoverCardTrigger> inside the KiwiPage renderer.
  • Fetch preview data lazily on hover (cache in a Map<string, PreviewData> or React Query).
  • Debounce/deduplicate concurrent fetches for the same target.
  • The popover content should use the existing shadcn Card component (@kw/components/ui/card) for consistent styling.
  • Max-width: 320px. Show a loading skeleton while fetching.

Acceptance criteria

  • Hovering over wiki-links shows a preview popover
  • Popover shows title, snippet, tags, and path
  • Data fetched lazily via /api/kiwi/peek
  • Graceful handling of broken links (show "Page not found" in popover)
  • No popover in editor mode (only in read/preview mode)
  • Works on touch devices (long-press or disabled)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions