From d3bb0e936c2de587aea0a4b4698bb9b47364bf7f Mon Sep 17 00:00:00 2001 From: xidedix Date: Fri, 20 Jul 2018 19:03:22 +0200 Subject: [PATCH 1/5] refactor: toggle-classes force --- src/Shared/toggle-classes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Shared/toggle-classes.js b/src/Shared/toggle-classes.js index 6f6205f7..feac9832 100644 --- a/src/Shared/toggle-classes.js +++ b/src/Shared/toggle-classes.js @@ -1,6 +1,6 @@ -export default function toggleClasses (toggleClass, classList) { +export default function toggleClasses (toggleClass, classList, force) { const level = classList.indexOf(toggleClass) const removeClassList = classList.slice(0, level) removeClassList.map((className) => document.body.classList.remove(className)) - document.body.classList.toggle(toggleClass) + document.body.classList.toggle(toggleClass, force) } From a7caae1029aff156070fc55c516c02abab5d4e92 Mon Sep 17 00:00:00 2001 From: xidedix Date: Fri, 20 Jul 2018 19:04:45 +0200 Subject: [PATCH 2/5] refactor: Shared/classes.js *Breakpoints --- src/Shared/classes.js | 6 ++++++ src/Shared/index.js | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Shared/classes.js b/src/Shared/classes.js index aad4137c..6fc0420b 100644 --- a/src/Shared/classes.js +++ b/src/Shared/classes.js @@ -13,3 +13,9 @@ export const asideMenuCssClasses = [ 'aside-menu-lg-show', 'aside-menu-xl-show' ]; + +export const validBreakpoints = [ 'sm', 'md', 'lg', 'xl' ] + +export function checkBreakpoint (breakpoint, list) { + return list.indexOf(breakpoint) > -1 +} diff --git a/src/Shared/index.js b/src/Shared/index.js index f2e9f298..517f2787 100644 --- a/src/Shared/index.js +++ b/src/Shared/index.js @@ -1,3 +1,3 @@ -import { sidebarCssClasses, asideMenuCssClasses } from './classes'; +import { sidebarCssClasses, asideMenuCssClasses, validBreakpoints, checkBreakpoint } from './classes'; -export { sidebarCssClasses, asideMenuCssClasses }; +export { sidebarCssClasses, asideMenuCssClasses, validBreakpoints, checkBreakpoint }; From 61ff624930bb65bb64d468bd10506ca2bd442601 Mon Sep 17 00:00:00 2001 From: xidedix Date: Fri, 20 Jul 2018 19:06:59 +0200 Subject: [PATCH 3/5] feat: hide onclick outside mobile sidebar --- demo/src/polyfill.js | 2 ++ package.json | 6 ++++-- src/Sidebar.js | 24 +++++++++++++++++++++--- src/SidebarToggler.js | 22 ++++++++++------------ 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/demo/src/polyfill.js b/demo/src/polyfill.js index 4826bf56..d09b4a21 100644 --- a/demo/src/polyfill.js +++ b/demo/src/polyfill.js @@ -26,6 +26,8 @@ import 'core-js/es7/object' // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. // import 'core-js/es7/reflect' +import 'element-closest' + // CustomEvent() constructor functionality in IE9, IE10, IE11 (function () { diff --git a/package.json b/package.json index 5f8aecee..4af20433 100644 --- a/package.json +++ b/package.json @@ -38,17 +38,19 @@ "@coreui/icons": "0.2.0", "classnames": "^2.2.6", "core-js": "^2.5.7", + "element-closest": "^2.0.2", "prop-types": "^15.6.2", + "react-onclickout": "^2.0.8", "react-perfect-scrollbar": "^1.1.1", "react-router-dom": "^4.3.1", - "reactstrap": "^6.1.0" + "reactstrap": "^6.3.0" }, "peerDependencies": { "@coreui/coreui": "^2.0.2", "react": "16.x" }, "devDependencies": { - "babel-eslint": "^8.2.5", + "babel-eslint": "^8.2.6", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "eslint": "^4.19.1", diff --git a/src/Sidebar.js b/src/Sidebar.js index 6896522f..5263bb90 100644 --- a/src/Sidebar.js +++ b/src/Sidebar.js @@ -2,6 +2,8 @@ import React, { Component } from 'react'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import { sidebarCssClasses } from './Shared'; +import ClickOutHandler from 'react-onclickout' +import 'element-closest' const propTypes = { children: PropTypes.node, @@ -35,6 +37,7 @@ class AppSidebar extends Component { this.isMinimized = this.isMinimized.bind(this); this.isOffCanvas = this.isOffCanvas.bind(this); this.displayBreakpoint = this.displayBreakpoint.bind(this); + this.hideMobile = this.hideMobile.bind(this); } componentDidMount() { @@ -70,6 +73,19 @@ class AppSidebar extends Component { document.body.classList.add(cssClass); } + hideMobile() { + if (document.body.classList.contains('sidebar-show')) { + document.body.classList.remove('sidebar-show'); + } + } + + onClickOut(e) { + if (!e.target.closest('[data-sidebar-toggler]')) { + this.hideMobile(); + } + + } + render() { const { className, children, tag: Tag, ...attributes } = this.props; @@ -85,9 +101,11 @@ class AppSidebar extends Component { // sidebar-nav root return ( - - {children} - + {this.onClickOut(e)}}> + + {children} + + ); } } diff --git a/src/SidebarToggler.js b/src/SidebarToggler.js index 3d8f74b7..c0e5497b 100644 --- a/src/SidebarToggler.js +++ b/src/SidebarToggler.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import { sidebarCssClasses } from './Shared/index'; +import { sidebarCssClasses, validBreakpoints, checkBreakpoint } from './Shared/index'; import toggleClasses from './Shared/toggle-classes'; const propTypes = { @@ -28,18 +28,16 @@ class AppSidebarToggler extends Component { sidebarToggle(e) { e.preventDefault(); + this.toggle(); + } - if (this.props.mobile) { - document.body.classList.toggle('sidebar-show'); - } else { - const display = this.props.display; - const cssTemplate = `sidebar-${display}-show`; - let [cssClass] = sidebarCssClasses[0]; - if (display && sidebarCssClasses.indexOf(cssTemplate) > -1) { - cssClass = cssTemplate; - } - toggleClasses(cssClass, sidebarCssClasses); + toggle(force) { + const [display, mobile] = [this.props.display, this.props.mobile] + let cssClass = sidebarCssClasses[0] + if (!mobile && display && checkBreakpoint(display, validBreakpoints)) { + cssClass = `sidebar-${display}-show` } + toggleClasses(cssClass, sidebarCssClasses, force) } render() { @@ -51,7 +49,7 @@ class AppSidebarToggler extends Component { const classes = classNames(className, 'navbar-toggler'); return ( - this.sidebarToggle(event)}> + this.sidebarToggle(event)} data-sidebar-toggler> {children || } ); From e6f127fe0fb14cc9ac40d2fafb08f1ed5243a900 Mon Sep 17 00:00:00 2001 From: xidedix Date: Fri, 20 Jul 2018 19:09:29 +0200 Subject: [PATCH 4/5] chore(ship): v2.0.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4af20433..92489a59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@coreui/react", - "version": "2.0.4", + "version": "2.0.5", "description": "CoreUI React Bootstrap 4 components", "license": "MIT", "author": { From df2c8cda8befaba469c0d403577e37114f81afc9 Mon Sep 17 00:00:00 2001 From: xidedix Date: Fri, 20 Jul 2018 19:14:39 +0200 Subject: [PATCH 5/5] test: adjust SidebarToggler.test --- tests/SidebarToggler.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SidebarToggler.test.js b/tests/SidebarToggler.test.js index 53e1662e..8d673f9f 100644 --- a/tests/SidebarToggler.test.js +++ b/tests/SidebarToggler.test.js @@ -13,7 +13,7 @@ configure({ adapter: new Adapter() }); describe('AppSidebarToggler', () => { it('renders button with class="navbar-toggler"', () => { expect(render()) - .toContain('') + .toContain('') }) it('should call sidebarToggle', () => { let component = mount();