From: Dan Brown Date: Mon, 30 Jun 2025 12:19:45 +0000 (+0100) Subject: Layout: Improved sidebar sizing, and dropdown consideration X-Git-Url: http://source.bookstackapp.com/bookstack/commitdiff_plain/6045aff33a3c57f03b380bd10919bb47a55440c6?ds=inline Layout: Improved sidebar sizing, and dropdown consideration - 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. --- diff --git a/resources/js/components/dropdown.js b/resources/js/components/dropdown.js index 5dd5dd93b..d2b044ee1 100644 --- a/resources/js/components/dropdown.js +++ b/resources/js/components/dropdown.js @@ -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 diff --git a/resources/js/services/dom.ts b/resources/js/services/dom.ts index c3817536c..8696fe816 100644 --- a/resources/js/services/dom.ts +++ b/resources/js/services/dom.ts @@ -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 diff --git a/resources/sass/_layout.scss b/resources/sass/_layout.scss index 8175db948..58c06f4ac 100644 --- a/resources/sass/_layout.scss +++ b/resources/sass/_layout.scss @@ -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; }