Skip to content

Commit 57c69b4

Browse files
author
nedtwigg
committed
Claude Code simplify: remove dead paneToCopyByIdRef code and fix spec to match in-place fade implementation
1 parent 077b535 commit 57c69b4

File tree

2 files changed

+8
-16
lines changed

2 files changed

+8
-16
lines changed

docs/specs/layout.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,14 @@ When a pane is added, its dockview group element gets a directional `.pane-spawn
297297

298298
The direction is carried via `FreshlySpawnedContext` — a `Map<paneId, SpawnDirection>` written by the spawn call site and consumed once by `TerminalPanel`'s `useLayoutEffect` on first mount.
299299

300-
### Kill (ghost fade + FLIP reclaim)
300+
### Kill (in-place fade + FLIP reclaim)
301301

302-
`orchestrateKill(api, killedId)` in `Pond.tsx` runs on kill confirmation:
302+
`orchestrateKill(api, killedId)` in `Pond.tsx` runs on kill confirmation. It fades the real pane element in place (its content dissolves against the same-colored background), then removes the panel and FLIP-reveals the survivors:
303303

304-
1. Snapshot `getBoundingClientRect` for every other panel's group element.
305-
2. `destroyTerminal` + `api.removePanel`; dockview snaps the layout.
306-
3. Measure post-rects. Any panel whose rect grew is a "grower."
307-
4. Mount a solid `var(--color-surface)` ghost overlay at the killed rect (`position: fixed`, `z-index: 55`) with the `.pane-fading-out` class; it removes itself on `animationend` with a 1s timeout safety net. A uniform fade works for every case (edge/middle/last-pane kill) because the directional cue is already carried by the grower's FLIP reveal.
304+
1. Add `.pane-fading-out` (or `.pane-fading-and-shrinking-to-br` for a last-pane kill) to the killed pane's group element. Block pointer events during the fade.
305+
2. On `animationend`, snapshot `getBoundingClientRect` for every surviving panel's group element.
306+
3. `destroyTerminal` + `api.removePanel`; dockview snaps the layout.
307+
4. Measure post-rects. Any panel whose rect grew is a "grower."
308308
5. For each grower, apply an inline `clip-path: inset(...)` with the newly-claimed territory clipped off, force a reflow, then transition to `inset(0)`. This reveals the grower into the vacated space without affecting `getBoundingClientRect`. Clears on `transitionend`.
309309

310310
Case handling is purely rect-based (measure before and after removal), so 2-pane splits, linear 3+ rows/columns, and nested splits all fall through the same code path with no per-case branching.
@@ -326,7 +326,7 @@ The deferred spawn also only calls `selectPanel` if selection is null. The kill
326326
7. **Asymmetric back-navigation**: breadcrumb tracks last direction + origin for opposite-direction return.
327327
8. **Center drop merges panels**: intercepted at group-level `model.onWillDrop` and converted to a swap.
328328
9. **Group drag has null panelId**: falls back to `api.getGroup(groupId).activePanel.id`.
329-
10. **Auto-spawn on empty**: `onDidRemovePanel` creates a new session whenever the last visible pane is removed, whether or not doors exist — there is always a pane visible. The new pane receives the just-removed pane's id as `paneToCopy` for future cwd/terminal-kind inheritance. The `addPanel` call is delayed 440ms (see "Auto-spawn delay" under Animations) so the outgoing kill/detach animation finishes first.
329+
10. **Auto-spawn on empty**: `onDidRemovePanel` creates a new session whenever the last visible pane is removed, whether or not doors exist — there is always a pane visible. The `addPanel` call is delayed 440ms (see "Auto-spawn delay" under Animations) so the outgoing kill/detach animation finishes first.
330330
11. **Door focus survives auto-spawn**: `api.addPanel` auto-activates the new panel, firing `onDidActivePanelChange`. When the current selection is a door (e.g., just-detached last pane), that listener must not flip `selectedId` to the new pane — otherwise `selectedType === 'door'` + `selectedId === newPaneId` desyncs and the door loses its highlight while the SelectionOverlay is stuck on the stale door rect. The listener early-returns when `selectedType === 'door'`.
331331

332332
## Files

lib/src/components/Pond.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,10 +1133,6 @@ export function Pond({
11331133
return `pane-${(++paneCounterRef.current).toString(36)}-${Math.random().toString(36).substring(2, 7)}`;
11341134
}, []);
11351135

1136-
// newPaneId -> sourcePaneId for panes born from a split or the empty-state auto-spawn.
1137-
// Nothing reads this yet; it exists so future work can copy cwd / terminal kind from the source.
1138-
const paneToCopyByIdRef = useRef(new Map<string, string>());
1139-
11401136
// Ids of panes that were just spawned, keyed by id with the direction the spawn
11411137
// should reveal from. TerminalPanel consumes its id on first mount to play the
11421138
// matching directional entrance animation.
@@ -1475,9 +1471,7 @@ export function Pond({
14751471
});
14761472

14771473
// Always keep one pane visible: when the last visible pane is removed (killed
1478-
// or detached), spawn a fresh one — regardless of whether doors exist. Carry
1479-
// the just-removed pane's id forward as paneToCopy so future work can copy
1480-
// cwd / terminal kind from it.
1474+
// or detached), spawn a fresh one — regardless of whether doors exist.
14811475
//
14821476
// Delay the spawn by the kill/detach animation duration so the two animations
14831477
// don't overlap — the outgoing pane crushes/fades first, then the new pane
@@ -1492,7 +1486,6 @@ export function Pond({
14921486
const spawn = () => {
14931487
if (e.api.totalPanels > 0) return;
14941488
const id = generatePaneId();
1495-
paneToCopyByIdRef.current.set(id, removed.id);
14961489
freshlySpawnedRef.current.set(id, 'top-left');
14971490
e.api.addPanel({ id, component: 'terminal', tabComponent: 'terminal', title: '<unnamed>' });
14981491
// Only steal focus if nothing is selected (i.e., the kill path, which
@@ -1941,7 +1934,6 @@ export function Pond({
19411934
if (!api) return;
19421935
const newId = generatePaneId();
19431936
const ref = id && api.getPanel(id) ? id : null;
1944-
if (ref) paneToCopyByIdRef.current.set(newId, ref);
19451937
// Horizontal split places the new pane to the right → reveal from its left edge.
19461938
// Vertical split places it below → reveal from its top edge.
19471939
freshlySpawnedRef.current.set(newId, direction === 'right' ? 'left' : 'top');

0 commit comments

Comments
 (0)