correct 5.2: the key was never the cause
This commit is contained in:
@@ -345,9 +345,29 @@ threaten whatever the panel was holding; a panel now holds nothing. A chat panel
|
||||
declares free. Fix these for the interaction quality they are genuinely about — scroll position, media
|
||||
playback, transcodes — not as a prerequisite for agent coordination._
|
||||
|
||||
A panel's React identity is its position plus `key={child.node.id}` on its **nearest ancestor group
|
||||
slot** (`WorkspaceRenderer.tsx:178,204`) — the panel's own id is a key nowhere. That's the root cause of
|
||||
the whole table:
|
||||
**Measured `56ca411`.** `WorkspaceRenderer.test.tsx` mounts the real renderer against a mount-counting
|
||||
probe app and lets the real `layout-utils` mutators produce the "after" tree. The table below was written
|
||||
from reading the code; the test disagrees with its *diagnosis* in every row, and found one row it had
|
||||
missed entirely. Read this paragraph before acting on the bullets underneath it.
|
||||
|
||||
- **The key is not the cause.** A panel's React identity is its position plus `key={child.node.id}` on its
|
||||
nearest ancestor group slot, but in each remounting case the **element type** at that position also
|
||||
changes — `PanelSlot` becomes `ResizablePanelGroup`, or the reverse — and React reconciles by type
|
||||
before it looks at keys. Reusing the panel's id so the key does not flip would therefore have changed
|
||||
nothing, at the cost of putting a panel id and a group id into collision, which now matters because a
|
||||
panel id is an agent's address (`agent_panels`).
|
||||
- **The row that was missing was the only cheap one, and it is fixed.** `ChildEntry` returned
|
||||
`<>{children}</>` for the first child and `<><Handle/>{children}</>` for every other, so a panel sat in
|
||||
fragment slot 0 when first and slot 1 when not. Remove the leftmost of three panels and the second one
|
||||
found a `ResizableHandle` in its old slot and remounted — for nothing that happened to it. The handle
|
||||
slot is now always present, holding `null` when unneeded.
|
||||
- **What is left is genuinely structural.** Wrapping a panel in a group, and a two-child group collapsing
|
||||
to its survivor, both change what kind of thing lives at that position. The only fix that survives
|
||||
contact with React is the one the last bullet of this section already points at: render panels from a
|
||||
host that does not move when the tree reshapes, the way maximize is a CSS toggle on the same element.
|
||||
That is a redesign, not a patch, and it is still Tier C.
|
||||
|
||||
The original table, kept because its *observations* hold even where its explanation did not:
|
||||
|
||||
| operation | remounts? | why |
|
||||
| ------------------------------------- | ---------------------- | ------------------------------------------------------------------------- |
|
||||
@@ -360,10 +380,14 @@ the whole table:
|
||||
| mobile panel switch | yes, by design | only the active child renders |
|
||||
| **any ephemeral panel on mobile** | **yes — every panel** | `WorkspaceView.tsx:165` replaces the workspace instead of overlaying |
|
||||
| **viewport crossing 768px** | **yes, full** | `useIsMobile` flips the branch at `WorkspaceView.tsx:165` |
|
||||
| **a panel stops being second** | **was yes — fixed** | `ChildEntry`'s fragment slots shifted under it (`56ca411`) |
|
||||
|
||||
- [ ] **Reuse the panel's id when wrapping it in a new group**, so the ancestor slot key doesn't flip.
|
||||
Kills rows 2 and 3.
|
||||
- [ ] **Don't re-key the survivor when a group collapses** (`layout-utils.ts:68-70, 83-88`). Kills row 4.
|
||||
- [ ] ~~**Reuse the panel's id when wrapping it in a new group**, so the ancestor slot key doesn't flip.
|
||||
Kills rows 2 and 3.~~ **Withdrawn `56ca411`** — measured, and it kills neither. The element type at
|
||||
that position changes too, which React acts on first. It would also collide a panel id with a group
|
||||
id, and a panel id is an agent's address now.
|
||||
- [ ] ~~**Don't re-key the survivor when a group collapses** (`layout-utils.ts:68-70, 83-88`). Kills row
|
||||
4.~~ **Withdrawn `56ca411`**, same reason: the survivor changes type as well as key.
|
||||
- [ ] **Overlay the mobile ephemeral panel instead of replacing the workspace**
|
||||
(`WorkspaceView.tsx:165`). Affects `/files`, `/email`, `/chat`, `/browser`, `/dashboards`.
|
||||
- [ ] **Reference for how it should feel:** maximize (`PanelSlot.tsx:430-457`) is a CSS state toggle on
|
||||
|
||||
Reference in New Issue
Block a user