Merged
Conversation
When the last visible pane is killed or detached, auto-spawn a replacement so the content area is never blank. The replacement receives the removed pane's id as paneToCopy (dead infrastructure for now — future work will copy cwd and terminal kind from it). Split also records paneToCopy → the pane it was split from. Freshly-spawned panes animate in via a clip-path reveal on the dockview group (header + body together). clip-path is used instead of scale so the selection overlay's getBoundingClientRect stays accurate during the animation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
On kill: ghost overlay crushes from the pane's original rect toward the replacer (edge/centerline/bottom-right), and surviving panes FLIP-reveal their newly claimed territory via clip-path. Case detection is rect-based (measure pre/post bounds and classify by which sides grew), so it handles 2-pane, 3+ linear, and nested splits uniformly. Reduced-motion skips the animation entirely. Spawn animation is now directional: - horizontal split → reveal from left edge - vertical split → reveal from top edge - auto-spawn after last-pane kill → reveal from top-left corner Also fixes a one-frame flash where KillConfirmOverlay rendered its viewport-center fallback before the useEffect measured the panel (switched to useLayoutEffect so the rect lands before first paint). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
On last-pane kill/detach, the outgoing-pane animation (crush or detach-to-door) and the incoming-pane reveal used to start at the same time and fight for the same screen region. Now the spawn is deferred by 440ms (the animation duration) so the two play sequentially. If any other action re-populates the pane area during the delay (e.g. door reattach), the deferred spawn becomes a no-op. Reduced-motion skips the delay. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The auto-spawn was introduced with a 440ms delay so the kill/detach animation can finish before the new pane animates in. But detachPanel calls selectDoor(id) synchronously, then 440ms later the delayed spawn called selectPanel(newId) and stole focus off the just-detached door. Only call selectPanel if nothing is selected (the kill path clears selection before the delay). On detach the door selection stays put. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
api.addPanel auto-activates the new panel, firing onDidActivePanelChange, which was calling setSelectedId(panel.id) unconditionally. When the current selection was a door (just-detached last pane), that flipped selectedId to the new pane's id while selectedType stayed 'door' — desyncing the door highlight and stranding SelectionOverlay on a stale door rect. Early-return from the listener when selectedType === 'door'. Also fleshes out docs/specs/layout.md with a new Animations section (spawn / kill crush / FLIP reclaim / auto-spawn delay) and adds a corner case entry for the door-focus preservation above. Updates corner case #10 to reference the 440ms auto-spawn delay. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The directional crush (to-left/right/up/down/hcenter/vcenter/br) added motion that competed with the grower's FLIP reveal, which already carries the direction. Replacing with a uniform opacity fade reads cleaner and eliminates the case-detection branching — every kill path (edge / middle / last-pane) now uses the same .pane-fading-out class. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A same-color ghost over a same-color background had nothing to fade against — the previous fade was effectively invisible. Fade the actual killed pane's group element instead, so the real header/terminal content dissolves. Then finalize removal + FLIP the growers after animationend. killInProgressRef is set across api.removePanel so the onDidRemovePanel auto-spawn handler skips its own 440ms delay — the fade already consumed that time. Detach path is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two fixes to last-pane kill: 1. Auto-spawn was silently dropped. api.addPanel called re-entrantly from inside the onDidRemovePanel handler was not taking effect. Always defer the spawn through setTimeout(spawn, delay), even when delay is 0, so the addPanel runs after the remove event fully settles. 2. The focus ring did not follow the shrinking pane. The shrink was using clip-path (doesn't affect getBoundingClientRect), so the SelectionOverlay never saw a change. Switched to transform: scale() with transform-origin: 100% 100%, and gave the overlay element a matching .ring-shrinking-to-br animation via a new ref so both collapse in lockstep toward their bottom-right corners. The ring class is removed in finalize() before the next overlay render. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… to match in-place fade implementation
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.
So that it is easier to tell what happened to last pane to get killed or the last pane to get detached.