Place helper terminals beside their source with an animated shared focus ring - #768
Conversation
Write animator frames straight to the overlay DOM so tweens no longer re-render the whole context; React re-renders only when the side or the available sides change. Reuse lath's Edge/edgeAxis, route Details and placement buttons through ContextAction, drop the unread placement mode and the view's style prop, and trim spec duplication. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts: # scripts/spec-word-budgets.json
Deploying mouseterm with
|
| Latest commit: |
783a971
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://02941c94.mouseterm.pages.dev |
| Branch Preview URL: | https://helper-placement.mouseterm.pages.dev |
dormouse-bot
left a comment
There was a problem hiding this comment.
The Header context menu section in docs/specs/layout.md now has two Source of truth: pointers. The new one sits in the middle of the section, and the existing one at the end still names TerminalLeafOverlay in lib/src/components/wall/LathHost.tsx as a context owner. After this PR that component renders only the alert ring. AGENTS.md → Specs says to "Consolidate Source of truth: pointers at the end of a section", so fold the new entries into the section-end line (the one starting Source of truth: `TerminalContext` in). Replace TerminalLeafOverlay there with TerminalContextOverlay and placeTerminalContext, and add the two new test files. That line is outside the diff, so the inline suggestion only removes the mid-section pointer.
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
Carry the union on the displayed ring frame instead of a side ref, resolve the helper once per effect, skip rewrites when the union is unchanged, and compute the bounds with a plain min/max. The contour returns absolute points, the union corner radius is clamped like ringPoints, and the context overlay drops its dead painted-rect state. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dormouse-bot
left a comment
There was a problem hiding this comment.
Non-blocking: the union ring outlasts the helper on close. contextSourceId stays set while the context is closing, so for TERMINAL_CONTEXT_EXIT_MS (180ms) the ring keeps tracing the helper's full footprint while .terminal-context-exit collapses the helper to a pinhole with clip-path. That clip doesn't change getBoundingClientRect, so neither observer sees it. The ring only snaps back to the source when the context unmounts. Dropping the union once closing is set brings the ring back while the helper animates out.
# Conflicts: # lib/src/stories/Wall.stories.tsx
- Fold the helper's side into the selection-ring identity, deleting the parallel union tween path: opening, closing and side changes still tween, while same-side motion (Wall resize, Lath animation) snaps or retargets instead of restarting a 220ms ease every frame. - The overlay writes its side to the host with its bounds, renders geometry from one imperative writer, and memoizes the panel so LathHost's commit and resize renders no longer re-render the whole context. - Drop the always-true `compact` prop and the unread placement `rect`; extract the placement icon unchanged; name the inset, above-overlap and above-extension constants. - Move the union ring outline's inset and origin math into `unionRingOutline`; drop the helper ResizeObserver the MutationObserver already covers. - Tests and stories: reuse `settleTerminalContext`, drop assertions on a mocked getter, replace a DOM-depth check with `closest`, and pin the new same-side 1:1 tracking. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The helper overlay registers a placer on the engine instead of subscribing to frames. LathHost's paint calls it with the frames it just wrote to the leaves, then notifies chrome, so the selection ring reads the placed helper from the engine where it is painted. - Removes the ring's DOM query and MutationObserver, the `contextSourceId` prop, and the helper's imperative side attribute. - Removes the overlay's per-frame `framesAt` rebuild and its drift from the leaves' paint time; `notifyFrames` is unchanged. - Fixes the subscriber-order race where the ring could measure the helper before it moved, forcing a second layout that frame. - Dismissal still returns the ring to the source alone: the placer publishes no helper while the context is closing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Helper terminals now open beside their source in multi-pane Walls, using available space without resizing the source. Single-pane and zoomed Walls place the helper in the top or bottom half opposite the visible cursor, with a 16px inset and a top default when the cursor is unknown.
Adjacent helpers overlap the source by 16px. Above helpers overlap only 4px and extend upward over neighboring headers. The zoomed-pane halo separates the popup from underlying content, and one animated focus ring follows the source/helper outline without an internal or native ghost ring.
Placement icons beside Close show the current side and let users switch without losing terminal identity, unfinished input, or focus. Placement is chosen automatically on opening; there is no Auto button. Context details always appear, with wrapping and scrolling for small panels.
Validation: