enhanced ControlSidebar

- moved control sidebar related functions from Layout.js to ControlSidebar.js
- added own scrollbar options
- added ability to set control sidebar height while scrolling
- fixed overlapping with fixed footer/navbar
pull/2220/head
REJack 2019-08-30 11:45:07 +02:00
parent 05e0de2291
commit eeeee1fbbf
No known key found for this signature in database
GPG Key ID: 9F3976CC630CC888
6 changed files with 183 additions and 24 deletions

View File

@ -19,23 +19,39 @@ const ControlSidebar = (($) => {
const Event = { const Event = {
COLLAPSED: `collapsed${EVENT_KEY}`, COLLAPSED: `collapsed${EVENT_KEY}`,
EXPANDED: `expanded${EVENT_KEY}` EXPANDED: `expanded${EVENT_KEY}`,
} }
const Selector = { const Selector = {
CONTROL_SIDEBAR: '.control-sidebar', CONTROL_SIDEBAR: '.control-sidebar',
DATA_TOGGLE : '[data-widget="control-sidebar"]', CONTROL_SIDEBAR_CONTENT: '.control-sidebar-content',
MAIN_HEADER : '.main-header' DATA_TOGGLE: '[data-widget="control-sidebar"]',
CONTENT: '.content-wrapper',
HEADER: '.main-header',
FOOTER: '.main-footer',
} }
const ClassName = { const ClassName = {
CONTROL_SIDEBAR_ANIMATE: 'control-sidebar-animate', CONTROL_SIDEBAR_ANIMATE: 'control-sidebar-animate',
CONTROL_SIDEBAR_OPEN: 'control-sidebar-open', CONTROL_SIDEBAR_OPEN: 'control-sidebar-open',
CONTROL_SIDEBAR_SLIDE: 'control-sidebar-slide-open' CONTROL_SIDEBAR_SLIDE: 'control-sidebar-slide-open',
LAYOUT_FIXED: 'layout-fixed',
NAVBAR_FIXED: 'layout-navbar-fixed',
NAVBAR_SM_FIXED: 'layout-sm-navbar-fixed',
NAVBAR_MD_FIXED: 'layout-md-navbar-fixed',
NAVBAR_LG_FIXED: 'layout-lg-navbar-fixed',
NAVBAR_XL_FIXED: 'layout-xl-navbar-fixed',
FOOTER_FIXED: 'layout-footer-fixed',
FOOTER_SM_FIXED: 'layout-sm-footer-fixed',
FOOTER_MD_FIXED: 'layout-md-footer-fixed',
FOOTER_LG_FIXED: 'layout-lg-footer-fixed',
FOOTER_XL_FIXED: 'layout-xl-footer-fixed',
} }
const Default = { const Default = {
controlsidebarSlide: true controlsidebarSlide: true,
scrollbarTheme : 'os-theme-light',
scrollbarAutoHide: 'l',
} }
/** /**
@ -46,7 +62,9 @@ const ControlSidebar = (($) => {
class ControlSidebar { class ControlSidebar {
constructor(element, config) { constructor(element, config) {
this._element = element this._element = element
this._config = this._getConfig(config) this._config = config
this._init()
} }
// Public // Public
@ -101,10 +119,128 @@ const ControlSidebar = (($) => {
// Private // Private
_getConfig(config) { _init() {
return $.extend({}, Default, config) this._fixHeight()
this._fixScrollHeight()
$(window).resize(() => {
this._fixHeight()
this._fixScrollHeight()
})
$(window).scroll(() => {
if ($('body').hasClass(ClassName.CONTROL_SIDEBAR_OPEN) || $('body').hasClass(ClassName.CONTROL_SIDEBAR_SLIDE)) {
this._fixScrollHeight()
}
})
} }
_fixScrollHeight() {
const heights = {
scroll: $(document).height(),
window: $(window).height(),
header: $(Selector.HEADER).outerHeight(),
footer: $(Selector.FOOTER).outerHeight(),
}
const positions = {
bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll),
top: $(window).scrollTop(),
}
let navbarFixed = false;
let footerFixed = false;
if ($('body').hasClass(ClassName.LAYOUT_FIXED)) {
if (
$('body').hasClass(ClassName.NAVBAR_FIXED)
|| $('body').hasClass(ClassName.NAVBAR_SM_FIXED)
|| $('body').hasClass(ClassName.NAVBAR_MD_FIXED)
|| $('body').hasClass(ClassName.NAVBAR_LG_FIXED)
|| $('body').hasClass(ClassName.NAVBAR_XL_FIXED)
) {
if ($(Selector.HEADER).css("position") === "fixed") {
navbarFixed = true;
}
}
if (
$('body').hasClass(ClassName.FOOTER_FIXED)
|| $('body').hasClass(ClassName.FOOTER_SM_FIXED)
|| $('body').hasClass(ClassName.FOOTER_MD_FIXED)
|| $('body').hasClass(ClassName.FOOTER_LG_FIXED)
|| $('body').hasClass(ClassName.FOOTER_XL_FIXED)
) {
if ($(Selector.FOOTER).css("position") === "fixed") {
footerFixed = true;
}
}
if (positions.top === 0 && positions.bottom === 0) {
$(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer);
$(Selector.CONTROL_SIDEBAR).css('top', heights.header);
$(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.header + heights.footer))
} else if (positions.bottom <= heights.footer) {
if (footerFixed === false) {
$(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer - positions.bottom);
$(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.footer - positions.bottom))
} else {
$(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer);
}
} else if (positions.top <= heights.header) {
if (navbarFixed === false) {
$(Selector.CONTROL_SIDEBAR).css('top', heights.header - positions.top);
$(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.header - positions.top))
} else {
$(Selector.CONTROL_SIDEBAR).css('top', heights.header);
}
} else {
if (navbarFixed === false) {
$(Selector.CONTROL_SIDEBAR).css('top', 0);
$(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window)
} else {
$(Selector.CONTROL_SIDEBAR).css('top', heights.header);
}
}
}
}
_fixHeight() {
const heights = {
window: $(window).height(),
header: $(Selector.HEADER).outerHeight(),
footer: $(Selector.FOOTER).outerHeight(),
}
if ($('body').hasClass(ClassName.LAYOUT_FIXED)) {
let sidebarHeight = heights.window - heights.header;
if (
$('body').hasClass(ClassName.FOOTER_FIXED)
|| $('body').hasClass(ClassName.FOOTER_SM_FIXED)
|| $('body').hasClass(ClassName.FOOTER_MD_FIXED)
|| $('body').hasClass(ClassName.FOOTER_LG_FIXED)
|| $('body').hasClass(ClassName.FOOTER_XL_FIXED)
) {
if ($(Selector.FOOTER).css("position") === "fixed") {
sidebarHeight = heights.window - heights.header - heights.footer;
}
}
$(Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', sidebarHeight)
if (typeof $.fn.overlayScrollbars !== 'undefined') {
$(Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).overlayScrollbars({
className : this._config.scrollbarTheme,
sizeAutoCapable : true,
scrollbars : {
autoHide: this._config.scrollbarAutoHide,
clickScrolling : true
}
})
}
}
}
// Static // Static
static _jQueryInterface(operation) { static _jQueryInterface(operation) {

View File

@ -77,7 +77,6 @@ const Layout = (($) => {
if ($('body').hasClass(ClassName.LAYOUT_FIXED)) { if ($('body').hasClass(ClassName.LAYOUT_FIXED)) {
$(Selector.CONTENT).css('min-height', max - heights.header - heights.footer) $(Selector.CONTENT).css('min-height', max - heights.header - heights.footer)
// $(Selector.SIDEBAR).css('min-height', max - heights.header) // $(Selector.SIDEBAR).css('min-height', max - heights.header)
$(Selector.CONTROL_SIDEBAR + ' .control-sidebar-content').css('height', max - heights.header)
if (typeof $.fn.overlayScrollbars !== 'undefined') { if (typeof $.fn.overlayScrollbars !== 'undefined') {
$(Selector.SIDEBAR).overlayScrollbars({ $(Selector.SIDEBAR).overlayScrollbars({
@ -88,14 +87,6 @@ const Layout = (($) => {
clickScrolling : true clickScrolling : true
} }
}) })
$(Selector.CONTROL_SIDEBAR + ' .control-sidebar-content').overlayScrollbars({
className : this._config.scrollbarTheme,
sizeAutoCapable : true,
scrollbars : {
autoHide: this._config.scrollbarAutoHide,
clickScrolling : true
}
})
} }
} else { } else {
if (heights.window > heights.sidebar) { if (heights.window > heights.sidebar) {

View File

@ -7,13 +7,14 @@ html.control-sidebar-animate {
} }
.control-sidebar { .control-sidebar {
bottom: $main-footer-height;
position: absolute; position: absolute;
top: $main-header-height; top: $main-header-height;
z-index: $zindex-control-sidebar; z-index: $zindex-control-sidebar;
&, &,
&::before { &::before {
bottom: 0; bottom: $main-footer-height;
display: none; display: none;
right: -$control-sidebar-width; right: -$control-sidebar-width;
width: $control-sidebar-width; width: $control-sidebar-width;

View File

@ -16,7 +16,7 @@ body,
position: relative; position: relative;
& .content-wrapper { & .content-wrapper {
min-height: calc(100vh - 112px); min-height: calc(100vh - #{$main-header-height} - #{$main-footer-height});
} }
.layout-boxed & { .layout-boxed & {
@ -34,6 +34,9 @@ body,
} }
.layout-navbar-fixed.layout-fixed & { .layout-navbar-fixed.layout-fixed & {
.control-sidebar {
top: $main-header-height;
}
.sidebar { .sidebar {
margin-top: $main-header-height; margin-top: $main-header-height;
} }
@ -117,6 +120,9 @@ body,
$infix: breakpoint-infix($breakpoint, $grid-breakpoints); $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.layout#{$infix}-navbar-fixed.layout-fixed & { .layout#{$infix}-navbar-fixed.layout-fixed & {
.control-sidebar {
top: $main-header-height;
}
.sidebar { .sidebar {
margin-top: $main-header-height; margin-top: $main-header-height;
} }
@ -199,6 +205,12 @@ body,
} }
} }
.layout-footer-fixed & {
.control-sidebar {
bottom: 0;
}
}
.layout-footer-fixed & { .layout-footer-fixed & {
.main-footer { .main-footer {
bottom: 0; bottom: 0;
@ -222,6 +234,11 @@ body,
@each $breakpoint in map-keys($grid-breakpoints) { @each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) { @include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints); $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.layout#{$infix}-footer-fixed & {
.control-sidebar {
bottom: 0;
}
}
.layout#{$infix}-footer-fixed & { .layout#{$infix}-footer-fixed & {
.main-footer { .main-footer {
@ -357,6 +374,18 @@ body,
position: fixed; position: fixed;
top: 0; top: 0;
} }
.control-sidebar {
bottom: 0;
float: none;
height: 100vh;
position: fixed;
top: 0;
.control-sidebar-content {
height: calc(100vh - #{$main-header-height});
}
}
} }
.main-footer { .main-footer {

View File

@ -154,8 +154,8 @@ $attachment-border-radius: 3px !default;
// -------------------------------------------------------- // --------------------------------------------------------
$zindex-main-header: $zindex-fixed + 4 !default; $zindex-main-header: $zindex-fixed + 4 !default;
$zindex-main-sidebar: $zindex-fixed + 8 !default; $zindex-main-sidebar: $zindex-fixed + 8 !default;
$zindex-main-footer: $zindex-fixed + 1 !default; $zindex-main-footer: $zindex-fixed + 2 !default;
$zindex-control-sidebar: $zindex-fixed + 2 !default; $zindex-control-sidebar: $zindex-fixed + 1 !default;
$zindex-sidebar-mini-links: 010 !default; $zindex-sidebar-mini-links: 010 !default;
// TRANSITIONS SETTINGS // TRANSITIONS SETTINGS

View File

@ -38,13 +38,15 @@ $("#my-toggle-button").ControlSidebar('toggle');
|--- |---
| Name | Type | Default | Description | Name | Type | Default | Description
|-|-|-|- |-|-|-|-
|slide | Boolean | TRUE | Whether the sidebar should slide over the content or push the content to make space for itself. |controlsidebarSlide | Boolean | TRUE | Whether the sidebar should slide over the content or push the content to make space for itself.
|scrollbarTheme | Boolean | `os-theme-light` | Scrollbar Theme used while SideBar Fixed
|scrollbarAutoHide | Boolean | `l` | Scrollbar auto-hide trigger
{: .table .table-bordered .bg-light} {: .table .table-bordered .bg-light}
> ##### Tip! > ##### Tip!
> You can use any option via the data-attributes like this to enable auto collapse sidebar on 768 pixels width. > You can use any option via the data-attributes like this to enable auto collapse sidebar on 768 pixels width.
> ```html > ```html
> <a href="#" data-widget="control-sidebar" data-slide="false">Toggle Control Sidebar</a> > <a href="#" data-widget="control-sidebar" data-controlsidebar-slide="false">Toggle Control Sidebar</a>
> ``` > ```
{: .quote-info} {: .quote-info}