1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2024-11-23 19:32:29 +01:00

Updated tri-layout on mobile to be tab based

This commit is contained in:
Dan Brown 2019-04-13 17:36:27 +01:00
parent f797d2da20
commit 8d358e4894
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
5 changed files with 119 additions and 37 deletions

View File

@ -3,18 +3,23 @@ class TriLayout {
constructor(elem) {
this.elem = elem;
this.middle = elem.querySelector('.tri-layout-middle');
this.right = elem.querySelector('.tri-layout-right');
this.left = elem.querySelector('.tri-layout-left');
this.lastLayoutType = 'none';
this.onDestroy = null;
this.scrollCache = {
'content': 0,
'info': 0,
};
this.lastTabShown = 'content';
// Bind any listeners
this.mobileTabClick = this.mobileTabClick.bind(this);
// Watch layout changes
this.updateLayout();
window.addEventListener('resize', event => {
this.updateLayout();
});
}, {passive: true});
}
updateLayout() {
@ -38,16 +43,15 @@ class TriLayout {
}
setupMobile() {
const mobileSidebarClickBound = this.mobileSidebarClick.bind(this);
const mobileContentClickBound = this.mobileContentClick.bind(this);
this.left.addEventListener('click', mobileSidebarClickBound);
this.right.addEventListener('click', mobileSidebarClickBound);
this.middle.addEventListener('click', mobileContentClickBound);
const layoutTabs = document.querySelectorAll('[tri-layout-mobile-tab]');
for (let tab of layoutTabs) {
tab.addEventListener('click', this.mobileTabClick);
}
this.onDestroy = () => {
this.left.removeEventListener('click', mobileSidebarClickBound);
this.right.removeEventListener('click', mobileSidebarClickBound);
this.middle.removeEventListener('click', mobileContentClickBound);
for (let tab of layoutTabs) {
tab.removeEventListener('click', this.mobileTabClick);
}
}
}
@ -55,27 +59,35 @@ class TriLayout {
//
}
/**
* Slide the main content back into view if clicked and
* currently slid out of view.
* @param event
*/
mobileContentClick(event) {
this.elem.classList.remove('mobile-open');
}
/**
* On sidebar click, Show the content by sliding the main content out.
* Action to run when the mobile info toggle bar is clicked/tapped
* @param event
*/
mobileSidebarClick(event) {
if (this.elem.classList.contains('mobile-open')) {
this.elem.classList.remove('mobile-open');
} else {
event.preventDefault();
event.stopPropagation();
this.elem.classList.add('mobile-open');
mobileTabClick(event) {
const tab = event.target.getAttribute('tri-layout-mobile-tab');
this.scrollCache[this.lastTabShown] = document.documentElement.scrollTop;
// Set tab status
const activeTabs = document.querySelectorAll('.tri-layout-mobile-tab.active');
for (let tab of activeTabs) {
tab.classList.remove('active');
}
event.target.classList.add('active');
// Toggle section
const showInfo = (tab === 'info');
this.elem.classList.toggle('show-info', showInfo);
// Set the scroll position from cache
const pageHeader = document.querySelector('header');
const defaultScrollTop = pageHeader.getBoundingClientRect().bottom;
document.documentElement.scrollTop = this.scrollCache[tab] || defaultScrollTop;
setTimeout(() => {
document.documentElement.scrollTop = this.scrollCache[tab] || defaultScrollTop;
}, 50);
this.lastTabShown = tab;
}
}

View File

@ -9,13 +9,14 @@ header .grid {
@include smaller-than($l) {
header .grid {
grid-template-columns: 1fr;
grid-row-gap: 0;
}
}
header {
position: relative;
display: block;
z-index: 2;
z-index: 6;
top: 0;
background-color: $primary-dark;
color: #fff;
@ -202,6 +203,25 @@ header .search-box {
}
}
.tri-layout-mobile-tabs {
position: sticky;
top: 0;
z-index: 5;
background-color: #FFF;
border-bottom: 1px solid #DDD;
box-shadow: $bs-card;
}
.tri-layout-mobile-tab {
text-align: center;
border-bottom: 3px solid #BBB;
&:first-child {
border-right: 1px solid #DDD;
}
&.active {
border-bottom-color: currentColor;
}
}
.breadcrumbs {
display: flex;
flex-direction: row;
@ -226,6 +246,18 @@ header .search-box {
}
}
@include smaller-than($l) {
.breadcrumbs .icon-list-item {
padding: $-xs;
> span + span {
display: none;
}
> span:first-child {
margin-right: 0;
}
}
}
.breadcrumb-listing {
position: relative;
.breadcrumb-listing-toggle {

View File

@ -49,13 +49,17 @@
&.v-center {
align-items: center;
}
&.no-gap {
grid-row-gap: 0;
grid-column-gap: 0;
}
}
@include smaller-than($m) {
.grid.third {
grid-template-columns: 1fr 1fr;
}
.grid.half, .grid.left-focus, .grid.right-focus {
.grid.half:not(.no-break), .grid.left-focus:not(.no-break), .grid.right-focus:not(.no-break) {
grid-template-columns: 1fr;
}
.grid.half.collapse-xs {
@ -241,8 +245,10 @@ body.flexbox {
@include smaller-than($l) {
.tri-layout-container {
grid-template-areas: none;
grid-template-columns: 10% 90%;
grid-template-columns: 1fr;
grid-column-gap: 0;
padding-right: $-xs;
padding-left: $-xs;
.tri-layout-left-contents, .tri-layout-right-contents {
padding-left: $-m;
padding-right: $-m;
@ -252,33 +258,50 @@ body.flexbox {
z-index: 0;
}
.tri-layout-left > *, .tri-layout-right > * {
display: none;
pointer-events: none;
}
.tri-layout-right, .tri-layout-left, .tri-layout-middle {
.tri-layout-left, .tri-layout-right {
grid-area: none;
grid-column: 1/3;
grid-column: 1/1;
grid-row: 1;
padding-top: 0 !important;
}
.tri-layout-middle {
grid-row: 1/3;
grid-column: 2/3;
grid-area: none;
grid-row: 3;
grid-column: 1/1;
z-index: 1;
overflow: hidden;
transition: transform ease-in-out 240ms;
}
.tri-layout-left {
grid-row: 2;
}
&.mobile-open {
&.show-info {
overflow: hidden;
.tri-layout-middle {
transform: translateX(90%);
display: none;
}
.tri-layout-right > *, .tri-layout-left > * {
display: block;
pointer-events: auto;
}
}
}
}
@include larger-than($l) {
.tri-layout-mobile-tabs {
display: none;
}
}
@include smaller-than($m) {
.tri-layout-container {
margin-left: 0;
margin-right: 0;
}
}
.tri-layout-left-contents > div, .tri-layout-right-contents > div {
opacity: 0.6;

View File

@ -60,6 +60,10 @@ return [
'view_profile' => 'View Profile',
'edit_profile' => 'Edit Profile',
// Layout tabs
'tab_info' => 'Info',
'tab_content' => 'Content',
// Email Content
'email_action_help' => 'If youre having trouble clicking the ":actionText" button, copy and paste the URL below into your web browser:',
'email_rights' => 'All rights reserved',

View File

@ -4,6 +4,17 @@
@section('content')
<div class="tri-layout-mobile-tabs text-primary" >
<div class="grid half no-break no-gap">
<div class="tri-layout-mobile-tab px-m py-s" tri-layout-mobile-tab="info">
{{ trans('common.tab_info') }}
</div>
<div class="tri-layout-mobile-tab px-m py-s active" tri-layout-mobile-tab="content">
{{ trans('common.tab_content') }}
</div>
</div>
</div>
<div class="tri-layout-container" tri-layout @yield('container-attrs') >
<div class="tri-layout-left print-hidden pt-m" id="sidebar">