What happens
- Open a board in the inspector.
- Click the
<> button at the top right of the stage to collapse the details rail.
- Click any other board on the canvas.
The rail is back. The same is true of the panel width, the rail width and the
layers/properties split: drag any of them, click another board, and they snap
back to their defaults.
Collapsing the rail is a statement about how someone wants to work — usually
"I want the board big, I'm done reading layers" — so having the next board
undo it means the setting only ever survives until the next click.
Why
App.tsx renders the panel keyed by the board:
<InspectorPanel key={inspecting.path} … />
which is right, and the comment there says why: a different board should get a
fresh panel rather than one that resets its state in an effect. But the key
throws away all the panel's state, and four pieces of it are not about the
board at all — they are about how the person wants the panel arranged:
railOpen — useState(true)
panelW — useState(PANEL_W)
railW — useState(RAIL_W)
layersH — useState(() => initialLayersH(window.innerHeight))
Every one of them restarts from a constant on each mount.
The selection, the report, the hovered layer and the tab are genuinely
per-board and should keep resetting.
Suggested fix
Hold those four outside the panel's lifetime. A small hook that mirrors the
value into sessionStorage keeps the change local to InspectorPanel.tsx and
needs no new props, and it puts the arrangement next to sp:inspecting — which
already restores the open board across a reload — so a reload does not undo it
either:
function useStickyPanelState<T>(key: string, initial: T) {
const [value, setValue] = useState<T>(() => {
try {
const saved = sessionStorage.getItem(key)
return saved === null ? initial : (JSON.parse(saved) as T)
} catch {
return initial
}
})
useEffect(() => {
try {
sessionStorage.setItem(key, JSON.stringify(value))
} catch {
// No storage to write to: the panel goes back to forgetting between boards.
}
}, [key, value])
return [value, setValue] as const
}
The widths need no extra clamping: nextPanelW / nextRailW / nextLayersH
already re-clamp on every render against the current window, so a width
restored into a smaller window is corrected before it is used.
Verified against canvas/ 1.0.0: collapse the rail, click a second board — it
stays collapsed; expand it, click a third — it stays open. A rail width stored
as 360 comes back at 360 on the next board instead of the 300 default.
What happens
<>button at the top right of the stage to collapse the details rail.The rail is back. The same is true of the panel width, the rail width and the
layers/properties split: drag any of them, click another board, and they snap
back to their defaults.
Collapsing the rail is a statement about how someone wants to work — usually
"I want the board big, I'm done reading layers" — so having the next board
undo it means the setting only ever survives until the next click.
Why
App.tsxrenders the panel keyed by the board:which is right, and the comment there says why: a different board should get a
fresh panel rather than one that resets its state in an effect. But the key
throws away all the panel's state, and four pieces of it are not about the
board at all — they are about how the person wants the panel arranged:
railOpen—useState(true)panelW—useState(PANEL_W)railW—useState(RAIL_W)layersH—useState(() => initialLayersH(window.innerHeight))Every one of them restarts from a constant on each mount.
The selection, the report, the hovered layer and the tab are genuinely
per-board and should keep resetting.
Suggested fix
Hold those four outside the panel's lifetime. A small hook that mirrors the
value into
sessionStoragekeeps the change local toInspectorPanel.tsxandneeds no new props, and it puts the arrangement next to
sp:inspecting— whichalready restores the open board across a reload — so a reload does not undo it
either:
The widths need no extra clamping:
nextPanelW/nextRailW/nextLayersHalready re-clamp on every render against the current window, so a width
restored into a smaller window is corrected before it is used.
Verified against
canvas/1.0.0: collapse the rail, click a second board — itstays collapsed; expand it, click a third — it stays open. A rail width stored
as 360 comes back at 360 on the next board instead of the 300 default.