Skip to content

chore(desktop): extract useAutoCollapse hook, tidy sidebar logic#1652

Merged
esengine merged 1 commit into
mainfrom
chore/desktop-1585-tidy
May 24, 2026
Merged

chore(desktop): extract useAutoCollapse hook, tidy sidebar logic#1652
esengine merged 1 commit into
mainfrom
chore/desktop-1585-tidy

Conversation

@esengine

Copy link
Copy Markdown
Owner

What

Refactor of #1585's responsive sidebar logic. Same behavior, fewer moving parts.

Why

The merged version split each panel's "is this collapsed because the user asked, or because the layout forced it" across six refs:

```
autoSideCollapsedRef autoCtxCollapsedRef
suppressSidePersistRef suppressCtxPersistRef
sideCollapsedRef ctxCollapsedRef
```

Plus a 70-line resize `useEffect` that hand-coded all six stage-transition combinations. Hard to scan; easy to break a corner case (e.g. NARROW → COMPACT preserving the user's manual ctx-open) without noticing.

How

Extracted per-panel collapse into a hook:

```ts
const {
collapsed, toggle,
requireCollapsed, releaseCollapsed,
} = useAutoCollapse(persistKey);
```

  • `toggle` — user-driven flip; persists to localStorage.
  • `requireCollapsed` — layout asks for collapsed; claims as auto only if the panel wasn't already collapsed so we don't override a manual choice.
  • `releaseCollapsed` — layout asks for expanded; restores only if WE collapsed it (manual collapses stay).

The resize effect drops to one branch per stage:

```
WIDE → release both
COMPACT → require ctx (only when entering from WIDE — coming from NARROW we preserve a user's manual ctx-open); release side
NARROW → require both
```

Also fixed the one-line CSS indent slip on `.app[data-side-collapsed]`.

Behavior matrix (unchanged from #1585)

from → to ctx side
WIDE → COMPACT require
WIDE → NARROW require require
COMPACT → NARROW (stays) require
COMPACT → WIDE release if auto release if auto
NARROW → COMPACT (stays — user may have manually opened) release if auto
NARROW → WIDE release if auto release if auto

Diff stats

```
desktop/src/App.tsx | 140 +++++++++++--------------------------------------
desktop/src/styles.css | 2 +-
desktop/src/ui/useAutoCollapse.ts (new) | 47 +++++++++++
```

Net: -33 lines, hook isolated, fewer refs to keep in your head.

Checklist

  • `npm run verify` passes locally (pre-push gate)
  • No `Co-Authored-By: Claude` trailer
  • No edits to `CHANGELOG.md`

Follow-up to #1585. The responsive sidebar logic was split across six
refs (autoSideCollapsedRef / autoCtxCollapsedRef / suppressSide... /
suppressCtx... / sideCollapsedRef / ctxCollapsedRef) and a 70-line
useEffect that did everything inline. Each panel's "is this collapsed
because the user asked, or because the layout forced it" state was
encoded across two of those refs; the resize logic had to spell out
all 6 stage-transition combinations by hand.

Extracted the per-panel collapse into useAutoCollapse(persistKey):

  - collapsed: the boolean for CSS
  - toggle:    user-driven flip; persists to localStorage
  - requireCollapsed:  layout asks for collapsed — claims as auto if
                       the panel wasn't already collapsed
  - releaseCollapsed:  layout asks for expanded — restores only if WE
                       collapsed it (manual collapses stay)

The resize effect drops to one branch per stage:

  WIDE    → release both
  COMPACT → require ctx (only when entering from wider — coming from
            narrow we preserve a user's manual ctx-open); release side
  NARROW  → require both

Also: fixed the one-line CSS indent slip on .app[data-side-collapsed].

Behavior is unchanged — same five stage-transition outcomes that #1585
hand-coded, just expressed declaratively.
@esengine esengine merged commit bf77bba into main May 24, 2026
4 checks passed
@esengine esengine deleted the chore/desktop-1585-tidy branch May 24, 2026 05:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant