]> BookStack Code Mirror - bookstack/commitdiff
Layout: Improved sidebar sizing, and dropdown consideration
authorDan Brown <redacted>
Mon, 30 Jun 2025 12:19:45 +0000 (13:19 +0100)
committerDan Brown <redacted>
Mon, 30 Jun 2025 12:19:45 +0000 (13:19 +0100)
- Updated tri-layout sidebars to have less padding and to avoid cutting
  off content when in single-sidebar mode.
- Updated dropdown handling to consider the parent scroll container when
  deciding to drop upwards, to help prevent cut-off.

resources/js/components/dropdown.js
resources/js/services/dom.ts
resources/sass/_layout.scss

index 5dd5dd93b013023ebf466ef021e9237dd1b57ce7..d2b044ee1ca871a96136415442b8e74add02c817 100644 (file)
@@ -1,4 +1,4 @@
-import {onSelect} from '../services/dom.ts';
+import {findClosestScrollContainer, onSelect} from '../services/dom.ts';
 import {KeyboardNavigationHandler} from '../services/keyboard-navigation.ts';
 import {Component} from './component';
 
@@ -33,7 +33,8 @@ export class Dropdown extends Component {
         const menuOriginalRect = this.menu.getBoundingClientRect();
         let heightOffset = 0;
         const toggleHeight = this.toggle.getBoundingClientRect().height;
-        const dropUpwards = menuOriginalRect.bottom > window.innerHeight;
+        const containerBounds = findClosestScrollContainer(this.menu).getBoundingClientRect();
+        const dropUpwards = menuOriginalRect.bottom > containerBounds.bottom;
         const containerRect = this.container.getBoundingClientRect();
 
         // If enabled, Move to body to prevent being trapped within scrollable sections
index c3817536c85422c8d0e480cbd05f267be3f6633f..8696fe81639c84aea40294dc9b3c1db376ca129f 100644 (file)
@@ -256,4 +256,22 @@ export function findTargetNodeAndOffset(parentNode: HTMLElement, offset: number)
 export function hashElement(element: HTMLElement): string {
     const normalisedElemText = (element.textContent || '').replace(/\s{2,}/g, '');
     return cyrb53(normalisedElemText);
+}
+
+/**
+ * Find the closest scroll container parent for the given element
+ * otherwise will default to the body element.
+ */
+export function findClosestScrollContainer(start: HTMLElement): HTMLElement {
+    let el: HTMLElement|null = start;
+    do {
+        const computed = window.getComputedStyle(el);
+        if (computed.overflowY === 'scroll') {
+            return el;
+        }
+
+        el = el.parentElement;
+    } while (el);
+
+    return document.body;
 }
\ No newline at end of file
index 8175db948a5c6617522d57c980a26706503b00d8..58c06f4ac99fa276a56129ae262a8be1293901da 100644 (file)
@@ -431,7 +431,8 @@ body.flexbox {
     grid-template-areas:  "a b b";
     grid-template-columns: 1fr 3fr;
     grid-template-rows: min-content min-content 1fr;
-    padding-inline-end: vars.$l;
+    margin-inline-start: (vars.$m + vars.$xxs);
+    margin-inline-end: (vars.$m + vars.$xxs);
   }
   .tri-layout-sides {
     grid-column-start: a;
@@ -452,6 +453,8 @@ body.flexbox {
     height: 100%;
     scrollbar-width: none;
     -ms-overflow-style: none;
+    padding-inline: vars.$m;
+    margin-inline: -(vars.$m);
     &::-webkit-scrollbar {
       display: none;
     }