diff --git a/CHANGELOG.md b/CHANGELOG.md index 91943d6a..79c5d5f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,40 @@ auto-generated per-PR notes; this file is the curated, human-readable history. ## [Unreleased] ### Added +- **The foldable left navigation is reachable in the UI** (#487, phase 3 of 4 — + the phase's own most complex wiring step). `app-shell.ts` composes phase 1's + pure mode/resize-session core and phase 2's section registry with a new + controller seam this phase adds (`application/left-nav.ts`'s + `openFocusedSection`/`toggleFocusedSection`) and two new standalone UI + modules that had no consumer yet — `ui/left-rail.ts` (the compact icon + rail) and `ui/left-nav-separator.ts` (the resize/mode-changing separator) — + into one working feature: the sidebar's previously-always-wide presentation + now renders wide, a bare rail, or a rail-plus-focused-drawer, driven by the + `leftNavMode` preference and the `leftNavSection` session-only state phase 1 + added (the state field is session-only by design — #487 specifies the + focused drawer need not reopen automatically after reload — unlike + `leftNavMode`, which IS a persisted browser preference). `.sidebar` is + RE-PRESENTED through a new + `data-nav-mode` attribute (`wide` | `rail` | `drawer`) rather than moved or + rebuilt — the four navigation-section hosts phase 2 built stay exactly where + they are, and only which one is exposed, plus the sidebar's own + width/visibility, changes, which is what makes "wide and focused + presentations share and preserve all navigation state" true by construction. + The old `.col-resize` handle keeps its class (the existing mobile CSS and + e2e assertions key off it) but no longer drives `splitters.ts`'s bare + `'col'` width clamp — that axis is deleted outright (see Changed below), and + the handle's mousedown/keydown belong entirely to `mountLeftNavSeparator` + now, which reports a mode/drawer-open-or-closed transition it itself + commits (a pointer drag, or a keyboard Home/End/Arrow operation) through a + new visually-hidden `role="status"` live region — a rail-icon click or + Escape write `state` directly through `application/left-nav.ts`'s own seam + and are not announced through it. The presentation also re-derives on a + live browser-window resize via a new optional injected `observeElementWidth` + seam on `mountAppShell`, which the production `app.ts` call site wires to a + real `ResizeObserver` when the platform has one (omitted in production when + it does not, in which case the shell simply runs without live-resize + reclamping; several unit tests inject a fake implementation directly to + cover the callback regardless). - **A navigation section registry behind the left sidebar** (#487, phase 2 of 4). Each of the four navigation sections — Databases, Dashboards, Library, History — is now addressable through one registry (`src/ui/nav-sections.ts`) that owns its @@ -62,10 +96,64 @@ auto-generated per-PR notes; this file is the curated, human-readable history. focused drawer and the resize separator arrive in phase 3. ### Changed -- The sidebar's `'col'` drag axis now clamps through the same - `LEFT_PANEL_MIN_PX`/`LEFT_PANEL_MAX_PX` constants as the load path, instead of - repeating `180`/`420` as literals (#487). Behaviour is unchanged; it removes - the second owner of a range whose whole point is having one. +- **The wide sidebar's resize range gained a viewport-aware upper bound** + (#487, phase 3 of 4). The documented `[180, 420]` px drag range is + unchanged at the constant level, but on a viewport narrower than roughly + 907px (down to the 768px mobile breakpoint, below which the desktop rail/ + drawer does not render at all), the separator and the keyboard path now + additionally clamp the reachable maximum so the centre SQL/results surface + never drops below its own documented 480px minimum + (`LEFT_CENTRE_MIN_PX`, `core/left-nav-layout.ts`) — the "new central + layout constraint" issue #487 explicitly allows for. A drag or an Arrow/End + keypress that would otherwise cross that floor stops at it instead of + shrinking the centre surface arbitrarily thin; the full stored preference + is never downgraded by the clamp and is restored in full the moment the + viewport allows it again, the same rule phase 3's resize-session design + already guarantees for the focused drawer's own band. This "never" is + scoped to phase 3's own budget (viewport width minus the separator minus + the centre minimum) — phase 4's optional right inspector is not yet a term + in that budget, so the guarantee will need re-verifying once it is. +- The `.col-resize` handle no longer drives `splitters.ts`'s `'col'` drag + axis at all (#487, phase 3 of 4) — that axis is deleted outright: the + sidebar's own resize gesture now belongs entirely to + `ui/left-nav-separator.ts`'s mode reducer (see Added above), which folds + to a rail, opens/closes a focused drawer, and restores the wide sidebar, + none of which a bare width clamp on one axis could express. +- **Switching between Library and History no longer clears the search box** + (#487, phase 3 of 4). Each lower-navigation section now keeps its own filter + text (`state.lowerNavigationFilters`, replacing the single shared + `state.libraryFilter`), preserved across every switch between them — a + deliberate, user-visible behavior change from phase 2's "a section switch + still clears the search exactly as before," required by phase 3's own + acceptance bullet that wide and focused presentations share and preserve all + navigation state. Both sections' own search box and list now also render + unconditionally, independently of which section is currently exposed + (mirroring the upper pane's `renderSchema`/`renderDashboardTree`), which + fixes two latent bugs: the section that wasn't active at mount never painted + until the first switch to it, and the section that wasn't active when its own + data changed (e.g. a query recorded to History while Library was shown) went + stale. +- **The focused drawer's minimum resizable width is now 180px, not 140px** + (#487, phase 3 of 4) — a deliberate, user-visible behavior change from the + placeholder value phase 1 shipped, settled by a real-browser check rather + than left as-is. Phase 1 flagged the drawer's `[140, 260]` resize band as an + explicit open question, noting a 140px drawer has to hold a title, a search + box, tree indentation and action controls, and might be too narrow to do it + legibly. It was: at 140px the Dashboards section's three titles rendered as + "Sa...", "O...", "A..." — unreadable and indistinguishable from one another — + while at 180px they read as "Sales re...", "Ops late...", "A very lo..." — + still ellipsized, but genuinely readable and distinguishable. The drawer's + floor now reuses `LEFT_PANEL_MIN_PX`, the wide sidebar's own floor constant, + rather than a second "180" value, which also gives the drawer the wide + sidebar's own dead-zone behavior for free: a resize proposal between 140 and + 180 now holds the drawer open at the 180 floor instead of folding it or + clipping it to the raw proposed width, exactly mirroring how the wide + sidebar already holds at its own 180 floor between the fold threshold and + 180. The keyboard path gained the equivalent of the wide sidebar's own + at-the-floor boundary check for the same reason: once the drawer's floor + no longer coincided with the fold threshold, a plain `ArrowLeft` from the + floor could otherwise land in that same dead zone and get stranded there + rather than folding. - **`VariableBarApp`'s shared activation port is now caller-neutral** (#478). `state.filterActive`/`params.saveFilterActive` — named after Workbench persistence even though Dashboard's own caller uses them for an unpersisted @@ -104,6 +192,102 @@ auto-generated per-PR notes; this file is the curated, human-readable history. reaching it takes a hand-edited or foreign-origin `localStorage` entry. The same NaN hole in `editorPct`/`sideSplitPct`/`cellDrawerPx`/`docPanePx` is tracked separately in #570. +- **Closing a rail-launched drawer by clicking its own icon now returns focus + to that icon on WebKit/Safari too** (#487, phase 3 of 4). Chromium and + Firefox focus a clicked `