Skip to content

Cell-detail right-hand drawer: add horizontal resize #101

Description

@BorisTyshkevich

Part of #68 (Roadmap to 1.0.0), Phase 3 — Windows.

Problem. openCellDetail and openRowsViewer (src/ui/results.js:549, :259) both render into a shared .cd-backdrop/.cd-panel scaffold — already a right-anchored, full-height drawer (position: fixed; inset: 0; ... justify-content: flex-end, src/styles.css:1407) — but .cd-panel's width is hardcoded (width: min(560px, 92vw), src/styles.css:1408) with no resize handle at all. Users can't widen it to see long values/rows comfortably.

Scope.

  • Add a drag handle on the drawer's left edge, inside .cd-panel, for both openCellDetail() and openRowsViewer() — same width for both, one persisted value.
  • Reuse splitters.js's drag controller rather than write a third bespoke resize implementation (the app already has two: splitters.js for sidebar/editor/results splits, and an ad-hoc column-resize handler in the data grid). dragValue/startDrag (src/ui/splitters.js:16,24) currently hardcode three axes (col/sideRow/row) via if/else branches tied 1:1 to specific state fields — adding this drawer is a 4th axis, so either (a) add a drawer/rightDrawer branch the same way, or (b) refactor to a small per-axis descriptor (compute/apply/save) so a 5th consumer doesn't mean another if/else arm. Implementer's call — not a blocker, doesn't need to be settled before starting.
  • Geometry: this drawer is anchored to the right edge, unlike the existing axes (which anchor left/top), so the math is new: width = viewportWidth - ev.clientX, clamped to 320..min(0.92*viewportWidth, ...) (matching the existing 92vw cap).
  • Persist as cellDrawerPx (signal + app.savePref()), same pattern as sidebarPx/editorPct.
  • Correctness catch: dragging the handle and releasing the mouse outside .cd-panel (e.g. over .cd-backdrop, easy to do since dragging left grows the backdrop area) will fire the drawer closed. .cd-backdrop closes on onclick: close, and .cd-panel only stops that via its own onclick handler's stopPropagation() — but a click event fires on the nearest common ancestor of the mousedown and mouseup targets, not the mousedown target. If mouseup lands on the backdrop, that common ancestor is the backdrop, so click dispatches directly on it, and .cd-panel's stopPropagation() never runs (the panel isn't in the event's path at all). Net effect: finishing a resize drag can close the drawer. Fix by swallowing the one post-drag click (e.g. a one-shot capturing click listener installed at drag-start and removed after consuming exactly one event) rather than relying on .cd-panel's existing stopPropagation.

Acceptance.

  • Dragging the drawer's left edge resizes it (both openCellDetail and openRowsViewer); width persists across reopens/reloads via cellDrawerPx.
  • Width is clamped to 320px..92vw.
  • Finishing a resize drag — including when the mouse ends up outside .cd-panel — does not close the drawer.
  • A genuine click outside the drawer (no drag) still closes it, and Esc still closes it — unchanged.
  • Unit tests cover: persisted width read/write, handle presence, clamp bounds, and the no-close-after-drag behavior.
  • npm test green at the per-file coverage gate.

Reconciled (implementation notes). Went with option (a) — a fourth 'drawer'
axis added to dragValue/startDrag's existing if/else chains (src/ui/splitters.js),
matching the codebase's established style rather than refactoring to a descriptor
table for a 4th consumer. cellDrawerPx is a plain (non-signal) state field,
matching sidebarPx/editorPct's actual pattern. Code review surfaced one
additional correctness gap beyond the issue's own correctness catch: closing the
drawer mid-drag (e.g. Escape while the mouse button is still down, before the
drag's own mouseup/click ever fires) left the drag's listeners attached after the
panel was removed — a later unrelated mouseup would still persist a stale width,
and a later unrelated click would be silently swallowed. Fixed by having
startDrag return a cancel() and wiring it into both drawers' close().
A related-but-broader pattern (.cd-backdrop's onclick:close doesn't check
where the mousedown originated, so e.g. dragging a text selection past the panel
edge has the same failure mode, pre-existing and not specific to this resize
handle) is filed separately as inbox issue #110, deferred to the planned shared
Drawer primitive (#60) rather than patched per-instance here.

Note (out of scope): the schema-detail pane (src/ui/schema-detail.js) stays bottom-docked with its own vertical-resize logic — excluded from this issue (it's not a "right pane," and its own Expand-to-tab behavior is covered by #100).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions