fix(zoom): bridge html{zoom} in full-view panel + drag/popover coordinates#62
Merged
Merged
Conversation
…ordinates
The page ships `html { zoom: 1.2 }`, but `zoom` does not divide viewport units,
and getBoundingClientRect returns post-zoom px while layout values (style.width,
flexBasis, fixed top/right) are pre-zoom. Several spots mixed the two:
- Schema full-view panel rendered 1.2× tall (100vh × zoom), pushing the detail
pane's CREATE TABLE DDL below the viewport with no way to scroll to it.
- Sidebar splitter and the detail-pane resize handle drifted ~20% ahead of the
cursor (visual-px delta applied as layout px).
- Save popover / user menu mis-anchored (fixed top/right re-scaled by zoom).
Fixes:
- Introduce a `--zoom` CSS variable; size the full-viewport graph panels (overlay,
schema tab, and the tab body) as `calc(... / var(--zoom))` so they fit exactly.
- Bridge the splitter ('col' axis), the detail-pane resize handle, and the
anchored popovers through the existing `zoomScale()` helper; measure the zoom
once per drag, not per mousemove.
- Harden `zoomScale()` to fall back to 1 for Infinity/0/negative ratios, not just
NaN (its docstring already promised this), since three new callers rely on it.
`dragValue` stays pure (injected `scale` param). Tests added for every new path;
splitters/schema-detail/dom remain at 100% coverage. All 1010 tests pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019kE9qbgBNBrfNgwg9fRsMJ
BorisTyshkevich
added a commit
that referenced
this pull request
Jun 28, 2026
Coordinate-system release: bridges the shipped `html{zoom:1.2}` across the
schema full-view panel and the splitter/resize-handle/popover math (#62), so the
full view fits one screen (detail-pane DDL no longer hidden) and drags/popovers
track the cursor. No new runtime deps.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019kE9qbgBNBrfNgwg9fRsMJ
BorisTyshkevich
added a commit
that referenced
this pull request
Jun 28, 2026
Code-review follow-ups for the zoom-bridge (#62) and schema-graph (#63) PRs. Correctness / behavior: - ch-client: the transitive-lineage nodeCap now counts only *linked* nodes, not every standalone table — so a single large DB of mostly-unrelated tables no longer truncates on round 1 and skips its cross-DB lineage walk (#63 review). - schema-graph: guard the db-prefix label strip with `&& n.name` so a node with an empty name can't be rewritten to a blank title (#63 review). Altitude / cleanup: - dot-layout: split the schema-specific "lineage first, singles gridded below" policy out of the generic dagre wrapper into a dedicated `schemaLayout()`; `dagreLayout` reverts to its plain generic form (no opts). Drops the dead `usedCols` (== cols) term and the always-built `connected` set on the pipeline path (#62/#63 review). - dom: extract the fixed-popover anchor recipe (divide client coords by the zoom) into a pure, 100%-covered `fixedAnchor()` helper; the File menu and the Save/user popover now share it instead of hand-transcribing the math — which also moves the previously-untested anchoredPopover arithmetic under test (#62). - app: simplify `dragCtx.scale` to report the page zoom without the redundant per-axis ternary (dragValue already ignores scale for the % axes) (#62). - dom: note in zoomScale that the measured element is immaterial (page-global) (#62). Tests added for schemaLayout (grid extent + no-lineage + no-singles + empty), fixedAnchor (both corners + floors), the ·inner label-skip, and the linked-only nodeCap. All 1020 tests pass; dot-layout/dom back to 100% coverage. Claude-Session: https://claude.ai/code/session_019kE9qbgBNBrfNgwg9fRsMJ Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The app ships
html { zoom: 1.2 }to upscale a deliberately pixel-dense UI. But CSSzoomhas two quirks that several spots got wrong:100vh-tall element lays out against the unzoomed viewport (800px) and is then scaled ×1.2 → 960px, overflowing the window by 20%.getBoundingClientRect()is post-zoom px, while values written tostyle.width/flexBasis/ fixedtop/rightare pre-zoom layout px.Symptoms found:
CREATE TABLEDDL below the viewport with no way to scroll to it (the reported bug).top/rightre-scaled by zoom; the gap read 15px instead of 6px).Fix
--zoomCSS variable; size the full-viewport graph panels (in-app overlay, schema tab, and the tabbody) ascalc(... / var(--zoom))so they fit exactly one screen.'col'axis, the detail-pane resize handle, and the anchored popovers through the existingzoomScale()helper — measured once per drag, not permousemove.dragValuestays pure (injectedscaleparam).zoomScale()to fall back to1forInfinity/0/negative ratios, not justNaN(its docstring already promised this), since three new callers now rely on it.The
'%'-based splitter axes are intentionally left alone — they derive from a(clientY-top)/heightratio where zoom cancels.Tests
New unit tests for every path (splitter scale, resize-handle scale,
zoomScalefallbacks).splitters.js,schema-detail.js, anddom.jsstay at 100% coverage; full suite 1010 passing, coverage gate green.Verification
Built and deployed to antalya (
play-sql.html), then drove the live cluster in-browser:shop→ clickevents_raw→ pane overflows, scrolls to bottom, full DDL visible at y=775 within the 800px viewport. ✅🤖 Generated with Claude Code
https://claude.ai/code/session_019kE9qbgBNBrfNgwg9fRsMJ