# When a panel closes and immediately reopens

> A correct final screen can hide conflicting state changes. Trace every writer of the affected state, decide what the event should mean, and test the full transition.

Repository: syntaxskills/muxmap · Category: Interaction stability · Status: Active

Keywords: outside click, dismiss, flicker, useEffect, state ownership, transient state

## When to use this lesson

- A panel disappears and returns after a click elsewhere.
- The final state is correct, but there is a flash or layout jump.
- An effect restores state that an event handler just cleared.

## What happened

In MuxMap, selecting a node opened its terminal. Clicking blank canvas then made the node shrink and expand again. The desired interaction was later clarified: the outside click should preserve the selected, expanded node.

## Diagnosis and approach

The blank-canvas handler cleared selection. A reactive effect observed the open terminal and reselected its node. Expansion followed selection, so the temporary clear became visible.

For a similar rebound, list every writer of selection or visibility, including handlers, effects, URL restoration, and background refreshes. Record their order across the event. A final-state assertion alone cannot reveal the conflicting writes.

## What did not work

The first patch, `a52ed10`, removed terminal-driven reselection. This addressed the rebound while still allowing outside clicks to collapse the node. The later requirement was to preserve expansion, so `1d932fd` removed blank-canvas deselection as well.

The first fix was incomplete for the clarified behavior, rather than evidence that selection and terminal visibility should always be coupled. A debounce is not documented as an attempted fix.

## What changed

Keep node selection and terminal visibility independent. Remove the effect that forcibly reselects the terminal node. For an outside click that should preserve selection, remove the clearing write as well. In the final MuxMap change, pointer release only ends panning. Selecting another node remains an explicit action.

## How to verify the improvement

1. Select a terminal node and record selection, expansion, and its bounding rectangle.
2. Click blank canvas and sample state across animation frames. There must be no collapsed frame.
3. Confirm the same terminal remains mounted and accepts input.
4. Repeat with floating and docked terminals, workspace updates, and a reload.
5. Confirm panning preserves selection and explicitly selecting another node still works.

## What to do next time

When state is cleared and immediately restored, resolve the competing writers before tuning animation. If an event should preserve a value, leave that value unchanged instead of repairing it later. Define whether outside clicks dismiss or preserve the surface, then assert that no unintended intermediate state occurs.

## Limits and exceptions

The general lesson is to avoid conflicting state writers and test the complete transition. Preserving selection on outside click is a MuxMap product requirement; other interfaces may intentionally dismiss. Decide the expected behavior first, then implement that behavior directly. A debounce or shorter animation would leave the underlying conflict intact.

## Commit evidence

- [syntaxskills/muxmap@a52ed10](https://github.com/syntaxskills/muxmap/commit/a52ed10e8cfd086d59f4d5dde39efcab42a41a05): Removed terminal-driven forced reselection and preserved independent selection in restored view state.
- [syntaxskills/muxmap@1d932fd](https://github.com/syntaxskills/muxmap/commit/1d932fd49870c6ca18283e7c8b1dba069a9a7dd9): Removed blank-canvas deselection so outside clicks preserve the selected, expanded node.
