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 = {
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) {

View File

@ -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) {

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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
> <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}