1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-28 17:02:04 +03:00

Layout: Converted tri-layout component to ts

This commit is contained in:
Dan Brown
2025-06-30 15:36:27 +01:00
parent 9186e77d27
commit 0dcb2ec78c

View File

@ -1,20 +1,23 @@
import {Component} from './component'; import {Component} from './component';
export class TriLayout extends Component { export class TriLayout extends Component {
private container!: HTMLElement;
private tabs!: HTMLElement[];
private sidebarScrollContainers!: HTMLElement[];
setup() { private lastLayoutType = 'none';
private onDestroy: (()=>void)|null = null;
private scrollCache: Record<string, number> = {
content: 0,
info: 0,
};
private lastTabShown = 'content';
setup(): void {
this.container = this.$refs.container; this.container = this.$refs.container;
this.tabs = this.$manyRefs.tab; this.tabs = this.$manyRefs.tab;
this.sidebarScrollContainers = this.$manyRefs.sidebarScrollContainer; this.sidebarScrollContainers = this.$manyRefs.sidebarScrollContainer;
this.lastLayoutType = 'none';
this.onDestroy = null;
this.scrollCache = {
content: 0,
info: 0,
};
this.lastTabShown = 'content';
// Bind any listeners // Bind any listeners
this.mobileTabClick = this.mobileTabClick.bind(this); this.mobileTabClick = this.mobileTabClick.bind(this);
@ -27,7 +30,7 @@ export class TriLayout extends Component {
this.setupSidebarScrollHandlers(); this.setupSidebarScrollHandlers();
} }
updateLayout() { updateLayout(): void {
let newLayout = 'tablet'; let newLayout = 'tablet';
if (window.innerWidth <= 1000) newLayout = 'mobile'; if (window.innerWidth <= 1000) newLayout = 'mobile';
if (window.innerWidth > 1400) newLayout = 'desktop'; if (window.innerWidth > 1400) newLayout = 'desktop';
@ -59,16 +62,15 @@ export class TriLayout extends Component {
}; };
} }
setupDesktop() { setupDesktop(): void {
// //
} }
/** /**
* Action to run when the mobile info toggle bar is clicked/tapped * Action to run when the mobile info toggle bar is clicked/tapped
* @param event
*/ */
mobileTabClick(event) { mobileTabClick(event: MouseEvent): void {
const {tab} = event.target.dataset; const tab = (event.target as HTMLElement).dataset.tab || '';
this.showTab(tab); this.showTab(tab);
} }
@ -76,16 +78,14 @@ export class TriLayout extends Component {
* Show the content tab. * Show the content tab.
* Used by the page-display component. * Used by the page-display component.
*/ */
showContent() { showContent(): void {
this.showTab('content', false); this.showTab('content', false);
} }
/** /**
* Show the given tab * Show the given tab
* @param {String} tabName
* @param {Boolean }scroll
*/ */
showTab(tabName, scroll = true) { showTab(tabName: string, scroll: boolean = true): void {
this.scrollCache[this.lastTabShown] = document.documentElement.scrollTop; this.scrollCache[this.lastTabShown] = document.documentElement.scrollTop;
// Set tab status // Set tab status
@ -100,7 +100,7 @@ export class TriLayout extends Component {
// Set the scroll position from cache // Set the scroll position from cache
if (scroll) { if (scroll) {
const pageHeader = document.querySelector('header'); const pageHeader = document.querySelector('header') as HTMLElement;
const defaultScrollTop = pageHeader.getBoundingClientRect().bottom; const defaultScrollTop = pageHeader.getBoundingClientRect().bottom;
document.documentElement.scrollTop = this.scrollCache[tabName] || defaultScrollTop; document.documentElement.scrollTop = this.scrollCache[tabName] || defaultScrollTop;
setTimeout(() => { setTimeout(() => {
@ -111,7 +111,7 @@ export class TriLayout extends Component {
this.lastTabShown = tabName; this.lastTabShown = tabName;
} }
setupSidebarScrollHandlers() { setupSidebarScrollHandlers(): void {
for (const sidebar of this.sidebarScrollContainers) { for (const sidebar of this.sidebarScrollContainers) {
sidebar.addEventListener('scroll', () => this.handleSidebarScroll(sidebar), { sidebar.addEventListener('scroll', () => this.handleSidebarScroll(sidebar), {
passive: true, passive: true,
@ -126,13 +126,15 @@ export class TriLayout extends Component {
}); });
} }
handleSidebarScroll(sidebar) { handleSidebarScroll(sidebar: HTMLElement): void {
const scrollable = sidebar.clientHeight !== sidebar.scrollHeight; const scrollable = sidebar.clientHeight !== sidebar.scrollHeight;
const atTop = sidebar.scrollTop === 0; const atTop = sidebar.scrollTop === 0;
const atBottom = (sidebar.scrollTop + sidebar.clientHeight) === sidebar.scrollHeight; const atBottom = (sidebar.scrollTop + sidebar.clientHeight) === sidebar.scrollHeight;
sidebar.parentElement.classList.toggle('scroll-away-from-top', !atTop && scrollable); if (sidebar.parentElement) {
sidebar.parentElement.classList.toggle('scroll-away-from-bottom', !atBottom && scrollable); sidebar.parentElement.classList.toggle('scroll-away-from-top', !atTop && scrollable);
sidebar.parentElement.classList.toggle('scroll-away-from-bottom', !atBottom && scrollable);
}
} }
} }