]> BookStack Code Mirror - bookstack/blob - resources/js/components/tri-layout.js
Default OpenID display name set to standard value
[bookstack] / resources / js / components / tri-layout.js
1
2 class TriLayout {
3
4     constructor(elem) {
5         this.elem = elem;
6
7         this.lastLayoutType = 'none';
8         this.onDestroy = null;
9         this.scrollCache = {
10             'content': 0,
11             'info': 0,
12         };
13         this.lastTabShown = 'content';
14
15         // Bind any listeners
16         this.mobileTabClick = this.mobileTabClick.bind(this);
17
18         // Watch layout changes
19         this.updateLayout();
20         window.addEventListener('resize', event => {
21             this.updateLayout();
22         }, {passive: true});
23     }
24
25     updateLayout() {
26         let newLayout = 'tablet';
27         if (window.innerWidth <= 1000) newLayout =  'mobile';
28         if (window.innerWidth >= 1400) newLayout =  'desktop';
29         if (newLayout === this.lastLayoutType) return;
30
31         if (this.onDestroy) {
32             this.onDestroy();
33             this.onDestroy = null;
34         }
35
36         if (newLayout === 'desktop') {
37             this.setupDesktop();
38         } else if (newLayout === 'mobile') {
39             this.setupMobile();
40         }
41
42         this.lastLayoutType = newLayout;
43     }
44
45     setupMobile() {
46         const layoutTabs = document.querySelectorAll('[tri-layout-mobile-tab]');
47         for (let tab of layoutTabs) {
48             tab.addEventListener('click', this.mobileTabClick);
49         }
50
51         this.onDestroy = () => {
52             for (let tab of layoutTabs) {
53                 tab.removeEventListener('click', this.mobileTabClick);
54             }
55         }
56     }
57
58     setupDesktop() {
59         //
60     }
61
62
63     /**
64      * Action to run when the mobile info toggle bar is clicked/tapped
65      * @param event
66      */
67     mobileTabClick(event) {
68         const tab = event.target.getAttribute('tri-layout-mobile-tab');
69         this.showTab(tab);
70     }
71
72     /**
73      * Show the content tab.
74      * Used by the page-display component.
75      */
76     showContent() {
77         this.showTab('content', false);
78     }
79
80     /**
81      * Show the given tab
82      * @param tabName
83      */
84     showTab(tabName, scroll = true) {
85         this.scrollCache[this.lastTabShown] = document.documentElement.scrollTop;
86
87         // Set tab status
88         const tabs = document.querySelectorAll('.tri-layout-mobile-tab');
89         for (let tab of tabs) {
90             const isActive = (tab.getAttribute('tri-layout-mobile-tab') === tabName);
91             tab.classList.toggle('active', isActive);
92         }
93
94         // Toggle section
95         const showInfo = (tabName === 'info');
96         this.elem.classList.toggle('show-info', showInfo);
97
98         // Set the scroll position from cache
99         if (scroll) {
100             const pageHeader = document.querySelector('header');
101             const defaultScrollTop = pageHeader.getBoundingClientRect().bottom;
102             document.documentElement.scrollTop = this.scrollCache[tabName] || defaultScrollTop;
103             setTimeout(() => {
104                 document.documentElement.scrollTop = this.scrollCache[tabName] || defaultScrollTop;
105             }, 50);
106         }
107
108         this.lastTabShown = tabName;
109     }
110
111 }
112
113 export default TriLayout;