diff --git a/build/js/ControlSidebar.js b/build/js/ControlSidebar.js index 15f023720..1356987d1 100644 --- a/build/js/ControlSidebar.js +++ b/build/js/ControlSidebar.js @@ -19,23 +19,39 @@ const ControlSidebar = (($) => { const Event = { COLLAPSED: `collapsed${EVENT_KEY}`, - EXPANDED: `expanded${EVENT_KEY}` + EXPANDED: `expanded${EVENT_KEY}`, } const Selector = { CONTROL_SIDEBAR: '.control-sidebar', - DATA_TOGGLE : '[data-widget="control-sidebar"]', - MAIN_HEADER : '.main-header' + CONTROL_SIDEBAR_CONTENT: '.control-sidebar-content', + DATA_TOGGLE: '[data-widget="control-sidebar"]', + CONTENT: '.content-wrapper', + HEADER: '.main-header', + FOOTER: '.main-footer', } const ClassName = { CONTROL_SIDEBAR_ANIMATE: 'control-sidebar-animate', 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 = { - controlsidebarSlide: true + controlsidebarSlide: true, + scrollbarTheme : 'os-theme-light', + scrollbarAutoHide: 'l', } /** @@ -46,7 +62,9 @@ const ControlSidebar = (($) => { class ControlSidebar { constructor(element, config) { this._element = element - this._config = this._getConfig(config) + this._config = config + + this._init() } // Public @@ -101,10 +119,128 @@ const ControlSidebar = (($) => { // Private - _getConfig(config) { - return $.extend({}, Default, config) + _init() { + 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 _jQueryInterface(operation) { diff --git a/build/js/Layout.js b/build/js/Layout.js index 063eb8931..eced4ff1e 100644 --- a/build/js/Layout.js +++ b/build/js/Layout.js @@ -77,7 +77,6 @@ const Layout = (($) => { if ($('body').hasClass(ClassName.LAYOUT_FIXED)) { $(Selector.CONTENT).css('min-height', max - heights.header - heights.footer) // $(Selector.SIDEBAR).css('min-height', max - heights.header) - $(Selector.CONTROL_SIDEBAR + ' .control-sidebar-content').css('height', max - heights.header) if (typeof $.fn.overlayScrollbars !== 'undefined') { $(Selector.SIDEBAR).overlayScrollbars({ @@ -88,14 +87,6 @@ const Layout = (($) => { clickScrolling : true } }) - $(Selector.CONTROL_SIDEBAR + ' .control-sidebar-content').overlayScrollbars({ - className : this._config.scrollbarTheme, - sizeAutoCapable : true, - scrollbars : { - autoHide: this._config.scrollbarAutoHide, - clickScrolling : true - } - }) } } else { if (heights.window > heights.sidebar) { diff --git a/build/scss/_control-sidebar.scss b/build/scss/_control-sidebar.scss index 7e5ce2afc..e38cc36b7 100644 --- a/build/scss/_control-sidebar.scss +++ b/build/scss/_control-sidebar.scss @@ -7,13 +7,14 @@ html.control-sidebar-animate { } .control-sidebar { + bottom: $main-footer-height; position: absolute; top: $main-header-height; z-index: $zindex-control-sidebar; - + &, &::before { - bottom: 0; + bottom: $main-footer-height; display: none; right: -$control-sidebar-width; width: $control-sidebar-width; diff --git a/build/scss/_layout.scss b/build/scss/_layout.scss index 736fe6ccc..6b27b4e90 100644 --- a/build/scss/_layout.scss +++ b/build/scss/_layout.scss @@ -16,7 +16,7 @@ body, position: relative; & .content-wrapper { - min-height: calc(100vh - 112px); + min-height: calc(100vh - #{$main-header-height} - #{$main-footer-height}); } .layout-boxed & { @@ -34,6 +34,9 @@ body, } .layout-navbar-fixed.layout-fixed & { + .control-sidebar { + top: $main-header-height; + } .sidebar { margin-top: $main-header-height; } @@ -117,6 +120,9 @@ body, $infix: breakpoint-infix($breakpoint, $grid-breakpoints); .layout#{$infix}-navbar-fixed.layout-fixed & { + .control-sidebar { + top: $main-header-height; + } .sidebar { margin-top: $main-header-height; } @@ -199,6 +205,12 @@ body, } } + .layout-footer-fixed & { + .control-sidebar { + bottom: 0; + } + } + .layout-footer-fixed & { .main-footer { bottom: 0; @@ -222,6 +234,11 @@ body, @each $breakpoint in map-keys($grid-breakpoints) { @include media-breakpoint-up($breakpoint) { $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + .layout#{$infix}-footer-fixed & { + .control-sidebar { + bottom: 0; + } + } .layout#{$infix}-footer-fixed & { .main-footer { @@ -357,6 +374,18 @@ body, position: fixed; 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 { diff --git a/build/scss/_variables.scss b/build/scss/_variables.scss index db23d3b14..a22c94d96 100644 --- a/build/scss/_variables.scss +++ b/build/scss/_variables.scss @@ -154,8 +154,8 @@ $attachment-border-radius: 3px !default; // -------------------------------------------------------- $zindex-main-header: $zindex-fixed + 4 !default; $zindex-main-sidebar: $zindex-fixed + 8 !default; -$zindex-main-footer: $zindex-fixed + 1 !default; -$zindex-control-sidebar: $zindex-fixed + 2 !default; +$zindex-main-footer: $zindex-fixed + 2 !default; +$zindex-control-sidebar: $zindex-fixed + 1 !default; $zindex-sidebar-mini-links: 010 !default; // TRANSITIONS SETTINGS diff --git a/docs/javascript/control-sidebar.md b/docs/javascript/control-sidebar.md index 516d74318..718c66a7c 100644 --- a/docs/javascript/control-sidebar.md +++ b/docs/javascript/control-sidebar.md @@ -38,13 +38,15 @@ $("#my-toggle-button").ControlSidebar('toggle'); |--- | 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} > ##### Tip! > You can use any option via the data-attributes like this to enable auto collapse sidebar on 768 pixels width. > ```html -> Toggle Control Sidebar +> Toggle Control Sidebar > ``` {: .quote-info}