Skip to content

Add document pinning to TextFrame for side-by-side comparison - #58

Open
Korede-TA wants to merge 4 commits into
mainfrom
claude/m4-textframe-comparison
Open

Add document pinning to TextFrame for side-by-side comparison#58
Korede-TA wants to merge 4 commits into
mainfrom
claude/m4-textframe-comparison

Conversation

@Korede-TA

Copy link
Copy Markdown
Contributor

Summary

This PR adds the ability to "pin" a document in the TextFrame, allowing users to view a fixed document's chunks while independently selecting and navigating other nodes elsewhere in the UI. This enables side-by-side comparison workflows.

Key Changes

  • TextFrame refactoring: Split into three sub-components:

    • UnpinnedView: Follow-selection mode (existing behavior)
    • PinnedDocView: Fixed document mode showing all chunks with click-to-select
    • PinBar: Toolbar with document picker dropdown and unpin button
  • View state management:

    • Added textPinned record to ViewState to track pinned documents per pane
    • Added setPinnedDoc() action to manage pinning state
    • Enhanced setLevel() to intelligently carry over selection when changing hierarchy levels (going up walks parent chain, going down collects descendants)
  • Selection and scrolling:

    • Added useEffect hooks to auto-scroll focused nodes into view with smooth behavior
    • Chunks in pinned view are clickable and update selection independently
    • Added data-node-id attributes for DOM query selectors
  • UI/UX:

    • New CSS styles for pin bar, pinned document header, and chunk cards
    • Chunk cards show hover/focused states with visual feedback
    • Pin bar shows document label when pinned, with unpin button
  • Layout:

    • Added 'comparison' preset layout (50/50 split of two text frames)
    • Updated AppShell to pass mosaic path as paneId for multi-pane support
  • Testing:

    • Added comprehensive test suite for setLevel() behavior covering up/down transitions, multi-selection, and edge cases

Implementation Details

  • Pane identification uses mosaic path joined with ':' to support multiple instances of the same frame type
  • Pinning state persists via zustand middleware
  • Smooth scrolling uses scrollIntoView({ behavior: 'smooth', block: 'nearest' })
  • CSS escaping used for node IDs in selectors to handle special characters

https://claude.ai/code/session_01EefsLVhEiLxKsJzAbgC1CQ

@netlify

netlify Bot commented May 29, 2026

Copy link
Copy Markdown

Deploy Preview for akb-suruleredotdev ready!

Name Link
🔨 Latest commit 244429e
🔍 Latest deploy log https://app.netlify.com/projects/akb-suruleredotdev/deploys/6a19135164208d0008cae641
😎 Deploy Preview https://deploy-preview-58--akb-suruleredotdev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Issue #41 - scrollTo focused node:
- Add data-node-id attributes to rendered nodes in TextFrame
- useEffect on selectionStore.focused to smooth-scroll to the focused
  element within the panel; no-ops if the node isn't in scope

Issue #40 - comparison mode / pin TextFrame to a document:
- Add textPinned: Record<string, NodeId | null> to viewStore, keyed by
  mosaic path (unique per pane, enabling two TextFrames with separate pins)
- Add setPinnedDoc(paneId, docId) action, persisted in localStorage
- TextFrame: PinBar shows a document picker select; when pinned, renders
  PinnedDocView — scrollable list of all child chunks of the pinned doc,
  with the focused chunk highlighted via .text-frame-chunk-focused
- Add comparison layout preset { direction: 'row', first: 'text', second: 'text' }
- AppShell: pass path-based paneId to each frame for per-pane uniqueness;
  use path-aware frame removal (updateTree + createRemoveUpdate) so closing
  one text pane in comparison mode doesn't close both

https://claude.ai/code/session_01EefsLVhEiLxKsJzAbgC1CQ
@Korede-TA
Korede-TA force-pushed the claude/m4-textframe-comparison branch from fa143b6 to f2930db Compare May 29, 2026 04:06
claude added 3 commits May 29, 2026 04:07
overflow-y: auto only activates when the element has a constrained
height. Without height: 100%, the flex container grows to fit all
content and never scrolls.

https://claude.ai/code/session_01EefsLVhEiLxKsJzAbgC1CQ
Strip leading non-alphanumeric chars from sort key so items like
'(PDF) Foo' sort under F rather than appearing before letter-starting
entries. Compute the sort key once per item to avoid re-calling
deriveLabel for each comparison.

https://claude.ai/code/session_01EefsLVhEiLxKsJzAbgC1CQ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants