From d5a71c80f619430ca8ae63584eb9a2f625e8dbf7 Mon Sep 17 00:00:00 2001 From: Dalton Alexandre <166029845+dl-alexandre@users.noreply.github.com> Date: Mon, 23 Mar 2026 08:23:15 -0700 Subject: [PATCH] fix: prevent scroll jump when clicking on cell output Add scroll-margin CSS to data-el-cell-body to reduce scroll jumps when the cell body receives focus (e.g., when clicking on cell output). Add mousedown handler in cell.js to preserve scroll position when clicking on non-editor areas of the cell body. --- assets/css/js_interop.css | 6 ++++++ assets/js/hooks/cell.js | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/assets/css/js_interop.css b/assets/css/js_interop.css index 34d9992949e..82df88133cb 100644 --- a/assets/css/js_interop.css +++ b/assets/css/js_interop.css @@ -6,6 +6,12 @@ we hide/show certain elements. This way we don't have to engage the server in solely client-side operations. */ +/* Prevent scroll jump when cell body is focused (e.g., clicking on output) */ +[data-el-cell-body] { + scroll-margin-top: 50px; + scroll-margin-bottom: 50px; +} + /* Hooks */ [phx-hook="Dropzone"][data-js-dragging] { diff --git a/assets/js/hooks/cell.js b/assets/js/hooks/cell.js index 9699e455877..f438f668652 100644 --- a/assets/js/hooks/cell.js +++ b/assets/js/hooks/cell.js @@ -68,6 +68,26 @@ const Cell = { this.el.setAttribute("data-js-hover", ""); }); + // Prevent scroll jump when clicking on cell output by handling mousedown + // on the cell body. This ensures clicking on output doesn't trigger + // unwanted scroll behavior when the cell body receives focus. + const cellBody = this.el.querySelector(`[data-el-cell-body]`); + if (cellBody) { + cellBody.addEventListener("mousedown", (event) => { + // If clicking on output (not an editor), prevent default focus scroll + if (!event.target.closest(`[data-el-editor-container]`)) { + // Save scroll position before focus changes + const scrollX = window.scrollX; + const scrollY = window.scrollY; + + // After focus is applied, restore scroll position + requestAnimationFrame(() => { + window.scrollTo(scrollX, scrollY); + }); + } + }); + } + this.el.addEventListener("mouseleave", (event) => { this.el.removeAttribute("data-js-hover"); });