From 26478b8427650ec2a8e508e32a42a1352a8076ed Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Sat, 26 Sep 2026 18:29:20 +0200 Subject: [PATCH] fix(update-modal): scroll long release notes inside the modal The release notes' max-height: 70% never resolved because the modal content has no definite height, so the notes grew the content instead of scrolling. With #1803 showing up to 100 releases, an upgrade from an old version pushed the Done footer ~122,000px down. Let the content shrink to the modal's bounded height and have the notes fill the remaining space so they scroll. --- src/styles.css | 5 +++- tests/e2e/update-modal-layout.test.ts | 37 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/update-modal-layout.test.ts diff --git a/src/styles.css b/src/styles.css index 4905594ab..32ab5ad6d 100644 --- a/src/styles.css +++ b/src/styles.css @@ -2328,12 +2328,15 @@ body:not(.is-mobile) flex-direction: column; align-items: center; justify-content: center; + /* The container is the modal's content element; let it shrink to the modal's + bounded height so the release notes scroll instead of growing it. */ + min-height: 0; } .quickadd-update-modal { min-width: 35%; max-width: 90%; - max-height: 70%; + flex: 1 1 auto; /* Let the scroll region shrink below its content height so the non-shrinking footer always fits inside the centered column — otherwise tall notes on a short viewport could overflow and clip the Done button out of view (#635). */ diff --git a/tests/e2e/update-modal-layout.test.ts b/tests/e2e/update-modal-layout.test.ts new file mode 100644 index 000000000..2861bc135 --- /dev/null +++ b/tests/e2e/update-modal-layout.test.ts @@ -0,0 +1,37 @@ +import { expect, it } from "vitest"; +import { createQuickAddE2EHarness } from "./e2eVault"; + +const getContext = createQuickAddE2EHarness("update-modal-layout"); + +// Upgrading from an old version fills the What's new modal with up to 100 +// releases. The notes must scroll inside the modal so the Done footer stays in +// view (#635). The DOM mirrors UpdateModal: its contentEl carries the container +// class, followed by the notes and the footer. +it("keeps the Done footer in view when the release notes are long", async () => { + const { obsidian } = getContext(); + const layout = await obsidian.dev.evalJson<{ + modalBottom: number; + footerBottom: number; + notesScrolls: boolean; + }>(`(() => { + const container = document.body.createDiv({ cls: "modal-container mod-dim" }); + try { + container.createDiv({ cls: "modal-bg" }); + const modal = container.createDiv({ cls: "modal" }); + const content = modal.createDiv({ cls: "modal-content quickadd-update-modal-container" }); + const notes = content.createDiv({ cls: "quickadd-update-modal" }); + for (let i = 0; i < 300; i++) notes.createEl("p", { text: "Release note " + i }); + const footer = content.createDiv({ cls: "quickadd-update-modal-footer" }); + footer.createEl("button", { text: "Done" }); + return { + modalBottom: modal.getBoundingClientRect().bottom, + footerBottom: footer.getBoundingClientRect().bottom, + notesScrolls: notes.scrollHeight > notes.clientHeight, + }; + } finally { + container.remove(); + } + })()`); + expect(layout.notesScrolls).toBe(true); + expect(layout.footerBottom).toBeLessThanOrEqual(layout.modalBottom); +});