import homepageControl from "./homepage-control";
import headerMobileToggle from "./header-mobile-toggle";
import listSortControl from "./list-sort-control";
+import triLayout from "./tri-layout";
const componentMapping = {
'homepage-control': homepageControl,
'header-mobile-toggle': headerMobileToggle,
'list-sort-control': listSortControl,
+ 'tri-layout': triLayout,
};
window.components = {};
--- /dev/null
+
+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.updateLayout();
+ window.addEventListener('resize', event => {
+ this.updateLayout();
+ });
+ }
+
+ updateLayout() {
+ const newLayout = (window.innerWidth <= 1000) ? 'mobile' : 'desktop';
+ if (newLayout === this.lastLayoutType) return;
+
+ if (this.onDestroy) {
+ this.onDestroy();
+ this.onDestroy = null;
+ }
+
+ if (newLayout === 'desktop') {
+ this.setupDesktop();
+ } else {
+ this.setupMobile();
+ }
+
+ this.lastLayoutType = newLayout;
+ }
+
+ 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);
+
+ this.onDestroy = () => {
+ this.left.removeEventListener('click', mobileSidebarClickBound);
+ this.right.removeEventListener('click', mobileSidebarClickBound);
+ this.middle.removeEventListener('click', mobileContentClickBound);
+ }
+ }
+
+ setupDesktop() {
+ // TODO
+ }
+
+ /**
+ * 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.
+ * @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');
+ }
+ }
+
+}
+
+export default TriLayout;
\ No newline at end of file
flex: 1;
}
-.flex.sidebar {
- flex: 1;
- background-color: #F2F2F2;
- max-width: 420px;
- min-height: 90vh;
- section {
- margin: $-m;
+
+.tri-layout-container {
+ display: grid;
+ grid-template-columns: 1fr minmax(auto, 940px) 1fr;
+ grid-template-areas: "a b c";
+ grid-column-gap: $-xl;
+ padding-right: $-xl;
+ padding-left: $-xl;
+ .tri-layout-right {
+ grid-area: c;
+ }
+ .tri-layout-left {
+ grid-area: a;
+ }
+ .tri-layout-middle {
+ grid-area: b;
+ }
+ .content-wrap.card {
+ padding: $-l $-xxl;
+ margin-left: auto;
+ margin-right: auto;
+ margin-bottom: $-xl;
+ overflow: auto;
+ &.thin {
+ width: 940px;
+ max-width: 100%;
+ }
}
}
-.flex.sidebar + .flex {
- flex: 3;
- max-width: 100%;
-}
-.flex.sidebar + .flex .content-wrap {
- padding: $-l $-xxl;
- margin-left: auto;
- margin-right: auto;
- margin-bottom: $-xl;
- overflow: auto;
- &.thin {
- width: 940px;
- max-width: 100%;
+@include smaller-than($xxl) {
+ .tri-layout-container {
+ grid-template-areas: "c b b"
+ "a b b";
+ grid-template-columns: 1fr 3fr;
+ grid-template-rows: max-content min-content;
+ .content-wrap.card {
+ padding: $-l $-l;
+ }
}
}
-.flex.sidebar .sidebar-toggle {
- display: none;
-}
-
-@include smaller-than($xl) {
- body.sidebar-layout {
- padding-left: 30px;
- }
- .flex.sidebar {
- position: fixed;
- top: 0;
- left: 0;
- bottom: 0;
- z-index: 100;
- padding-right: 30px;
- width: 360px;
- box-shadow: none;
- transform: translate3d(-330px, 0, 0);
- transition: transform ease-in-out 120ms;
- display: flex;
- flex-direction: column;
- }
- .flex.sidebar.open {
- box-shadow: 1px 2px 2px 1px rgba(0,0,0,.10);
- transform: translate3d(0, 0, 0);
- .sidebar-toggle i {
- transform: rotate(180deg);
+@include smaller-than($l) {
+ .tri-layout-container {
+ grid-template-areas: none;
+ grid-template-columns: 10% 90%;
+ grid-column-gap: 0;
+ padding-right: $-l;
+ padding-left: $-l;
+ .tri-layout-right, .tri-layout-left {
+ opacity: 0.6;
+ z-index: 0;
}
- }
- .flex.sidebar .sidebar-toggle {
- display: block;
- position: absolute;
- opacity: 0.9;
- right: 0;
- top: 0;
- bottom: 0;
- width: 30px;
- fill: #666;
- font-size: 20px;
- vertical-align: middle;
- text-align: center;
- border: 1px solid #DDD;
- border-top: 1px solid #BBB;
- padding-top: $-m;
- cursor: pointer;
- svg {
- opacity: 0.5;
- transition: all ease-in-out 120ms;
- margin: 0;
+ .tri-layout-left > *, .tri-layout-right > * {
+ pointer-events: none;
}
- &:hover i {
- opacity: 1;
+ .tri-layout-right, .tri-layout-left, .tri-layout-middle {
+ grid-area: none;
+ grid-column: 1/3;
+ grid-row: 1;
+ }
+ .tri-layout-middle {
+ grid-row: 1/3;
+ grid-column: 2/3;
+ z-index: 1;
+ transition: transform ease-in-out 240ms;
+ }
+ .tri-layout-left {
+ grid-row: 2;
+ }
+ &.mobile-open {
+ overflow: hidden;
+ .tri-layout-middle {
+ transform: translateX(90%);
+ }
+ .tri-layout-right > *, .tri-layout-left > * {
+ pointer-events: auto;
+ }
}
- }
- .sidebar .scroll-body {
- flex: 1;
- overflow-y: scroll;
- }
- #sidebar .scroll-body.fixed {
- width: auto !important;
- }
-}
-
-@include larger-than($xl) {
- #sidebar .scroll-body.fixed {
- z-index: 5;
- position: fixed;
- top: 0;
- padding-top: $-m;
- width: 30%;
- left: 0;
- height: 100%;
- overflow-y: auto;
- -ms-overflow-style: none;
- //background-color: $primary-faded;
- border-left: 1px solid #DDD;
- &::-webkit-scrollbar { width: 0 !important }
}
}
}
.container {
- max-width: $max-width;
+ max-width: $xxl;
margin-left: auto;
margin-right: auto;
padding-left: $-m;
grid-column-gap: $-m;
grid-row-gap: 0;
&.contained {
- max-width: $max-width;
+ max-width: $xxl;
padding-left: $-m;
padding-right: $-m;
margin-left: auto;
background-size: cover;
background-position: 50% 50%;
border-radius: 3px;
+ @include smaller-than($m) {
+ width: 80px;
+ }
}
.entity-list.compact {
// Variables
///////////////
-// Sizes
-$max-width: 1400px;
-
// Screen breakpoints
+$xxl: 1400px;
$xl: 1100px;
$ipad-width: 1028px; // Is actually 1024 but we go over to ensure functionality.
$l: 1000px;
@section('right')
- <div class="actions mb-xl px-xl">
+ <div class="actions mb-xl">
<h5>Actions</h5>
<div class="icon-list text-primary">
@if($currentUser->can('book-create-all'))
@yield('toolbar')
</div>
- <div class="flex-fill flex" @yield('container-attrs') >
-
- <div sidebar class="sidebar flex print-hidden tri-layout-left" id="sidebar">
- <div class="sidebar-toggle primary-background-light">@icon('caret-right-circle')
- </div>
- <div class="scroll-body px-xl">
- @yield('left')
- </div>
+ <div class="tri-layout-container" tri-layout @yield('container-attrs') >
+
+ <div class="tri-layout-left print-hidden " id="sidebar">
+ @yield('left')
</div>
- <div class="flex @yield('body-wrap-classes')">
+ <div class="@yield('body-wrap-classes') tri-layout-middle">
@yield('body')
</div>
- <div class="flex tri-layout-right">
+ <div class="tri-layout-right print-hidden">
@yield('right')
</div>
</div>
-
@stop