From 39a5cf7aff31088f05db4eb132fe0337772f13a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Thu, 30 Nov 2023 20:45:33 +0100 Subject: [PATCH] Always scroll menu into view (#2377) --- assets/js/events.js | 15 +++++++++++++++ assets/js/lib/utils.js | 18 ++++++++++++++++++ lib/livebook_web/components/core_components.ex | 1 + 3 files changed, 34 insertions(+) diff --git a/assets/js/events.js b/assets/js/events.js index 2bb820ad4..1e3d36538 100644 --- a/assets/js/events.js +++ b/assets/js/events.js @@ -1,4 +1,7 @@ import topbar from "topbar"; +import scrollIntoView from "scroll-into-view-if-needed"; + +import { waitUntilVisible } from "./lib/utils"; export function registerTopbar() { topbar.config({ @@ -57,6 +60,18 @@ export function registerGlobalEventHandlers() { } }); + window.addEventListener("lb:scroll_into_view", (event) => { + // If the element is going to be shown, we want to wait for that + waitUntilVisible(event.target).then(() => { + scrollIntoView(event.target, { + scrollMode: "if-needed", + behavior: "smooth", + block: "nearest", + inline: "nearest", + }); + }); + }); + window.addEventListener("phx:lb:exec_js", (event) => { const selector = event.detail.to || "body"; diff --git a/assets/js/lib/utils.js b/assets/js/lib/utils.js index 295b98ea9..a89a36729 100644 --- a/assets/js/lib/utils.js +++ b/assets/js/lib/utils.js @@ -21,6 +21,24 @@ export function isElementHidden(element) { return element.offsetParent === null; } +export function waitUntilVisible(element) { + let viewportIntersectionObserver = null; + + return new Promise((resolve, reject) => { + if (isElementHidden(element)) { + viewportIntersectionObserver = new ResizeObserver((entries) => { + if (!isElementHidden(element)) { + viewportIntersectionObserver.disconnect(); + resolve(); + } + }); + viewportIntersectionObserver.observe(element); + } else { + resolve(); + } + }); +} + export function isElementVisibleInViewport(element) { return !isElementHidden(element) && isElementInViewport(element); } diff --git a/lib/livebook_web/components/core_components.ex b/lib/livebook_web/components/core_components.ex index 2be466bae..9e132c12f 100644 --- a/lib/livebook_web/components/core_components.ex +++ b/lib/livebook_web/components/core_components.ex @@ -326,6 +326,7 @@ defmodule LivebookWeb.CoreComponents do defp show_menu(id) do JS.show(to: "##{id}-overlay") |> JS.show(to: "##{id}-content", display: "flex") + |> JS.dispatch("lb:scroll_into_view", to: "##{id}-content") end defp hide_menu(id) do