Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ce7d201

Browse filesBrowse files
committed
fix(SidebarNav): perfect scrollbar issue on sidebar minimized
1 parent 35eafef commit ce7d201
Copy full SHA for ce7d201

File tree

Expand file treeCollapse file tree

3 files changed

+135
-15
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+135
-15
lines changed

‎css/scrollbar.css

Copy file name to clipboard
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* rtl fix */
2+
.ps__rtl .ps__rail-y {
3+
left: 0px !important;
4+
right: unset;
5+
}
6+
*[dir="rtl"] .ps__rail-y {
7+
left: 0px !important;
8+
right: unset;
9+
}
10+
11+
.ps__rtl .ps__thumb-y {
12+
left: 2px;
13+
right: unset;
14+
}
15+
*[dir="rtl"] .ps__thumb-y {
16+
left: 2px;
17+
right: unset;
18+
}

‎src/Shared/layout/layout.js

Copy file name to clipboardExpand all lines: src/Shared/layout/layout.js
+54-3Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,58 @@ class LayoutHelper {
1010
}
1111

1212
static sidebarMinimize(force) {
13-
// return this.elClassList.toggle('sidebar-minimized', force);
1413
return this.toggleClass('sidebar-minimized', force);
1514
}
1615

1716
static brandMinimize(force) {
18-
// this.elClassList.toggle('brand-minimized', force);
1917
this.toggleClass('brand-minimized', force);
2018
}
2119

22-
// sidebar perfect scrollbar
20+
// sidebar perfect scrollbar ugly hack
2321
static sidebarPSToggle(toggle) {
22+
23+
if (this.isOnMobile()) {
24+
toggle = true
25+
} else {
26+
const isSidebarMinimized = document.body.classList.contains('sidebar-minimized') || false
27+
toggle = !isSidebarMinimized
28+
}
29+
30+
const ps = { y: { rail: {}, thumb: {} } };
31+
const isRtl = getComputedStyle(document.documentElement).direction === 'rtl'
2432
const sidebar = document.querySelector('.sidebar-nav');
33+
ps.y.rail.on = document.querySelector('.sidebar-nav .ps__rail-y');
34+
ps.y.rail.off = document.querySelector('.sidebar-nav .ps__rail-y-off');
35+
ps.y.thumb.on = document.querySelector('.sidebar-nav .ps__thumb-y');
36+
ps.y.thumb.off = document.querySelector('.sidebar-nav .ps__thumb-y-off');
2537
if (sidebar) {
2638
if (toggle) {
2739
sidebar.classList.add('ps');
2840
sidebar.classList.add('ps-container');
2941
sidebar.classList.add('ps--active-y');
42+
if (ps.y.rail.off) {
43+
ps.y.rail.off.classList.add('ps__rail-y');
44+
ps.y.rail.off.removeAttribute('style');
45+
ps.y.rail.off.style.left = isRtl ? '0px' : 'unset';
46+
ps.y.rail.off.style.right = isRtl ? 'unset' : '0px';
47+
ps.y.rail.off.classList.remove('ps__rail-y-off');
48+
}
49+
if (ps.y.thumb.off) {
50+
ps.y.thumb.off.removeAttribute('style');
51+
ps.y.thumb.off.classList.add('ps__thumb-y');
52+
ps.y.thumb.off.classList.remove('ps__thumb-y-off');
53+
}
3054
} else {
55+
if (ps.y.rail.on) {
56+
ps.y.rail.on.classList.add('ps__rail-y-off');
57+
ps.y.rail.on.removeAttribute('style');
58+
ps.y.rail.on.classList.remove('ps__rail-y');
59+
}
60+
if (ps.y.thumb.on) {
61+
ps.y.thumb.on.classList.add('ps__thumb-y-off');
62+
ps.y.thumb.on.removeAttribute('style');
63+
ps.y.thumb.on.classList.remove('ps__thumb-y');
64+
}
3165
sidebar.classList.remove('ps');
3266
sidebar.classList.remove('ps-container');
3367
sidebar.classList.remove('ps--active-y');
@@ -46,6 +80,23 @@ class LayoutHelper {
4680
}
4781
return this.elClassList.contains(className);
4882
}
83+
84+
static isOnMobile() {
85+
let onMobile = false;
86+
try {
87+
const minimizerElement = document.querySelector('.sidebar-minimizer');
88+
if (minimizerElement) {
89+
onMobile = getComputedStyle(minimizerElement).getPropertyValue('display') === 'none';
90+
} else {
91+
const sidebarElement = document.querySelector('.sidebar .sidebar-nav');
92+
sidebarElement && (onMobile = getComputedStyle(sidebarElement).getPropertyValue('overflow-y') === 'auto');
93+
}
94+
} catch (ignore) {
95+
// eslint-disable-next-line
96+
console.warn('CoreUI isOnMobile failed to getComputedStyle', ignore)
97+
}
98+
return onMobile
99+
}
49100
}
50101

51102
export default LayoutHelper;

‎src/SidebarNav2.js

Copy file name to clipboardExpand all lines: src/SidebarNav2.js
+63-12Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import classNames from 'classnames';
44
import PropTypes from 'prop-types';
55
import PerfectScrollbar from 'react-perfect-scrollbar';
66
import 'react-perfect-scrollbar/dist/css/styles.css';
7+
import '../css/scrollbar.css';
8+
9+
import LayoutHelper from './Shared/layout/layout'
710

811
const propTypes = {
912
children: PropTypes.node,
@@ -39,17 +42,26 @@ class AppSidebarNav2 extends Component {
3942
this.handleClick = this.handleClick.bind(this);
4043
this.activeRoute = this.activeRoute.bind(this);
4144
this.hideMobile = this.hideMobile.bind(this);
45+
46+
this.changes = null;
47+
this.state = { sidebarMinimized: false }
4248
}
4349

50+
_scrollBarRef = null;
51+
4452
handleClick(e) {
4553
e.preventDefault();
4654
e.currentTarget.parentElement.classList.toggle('open');
4755
}
4856

49-
activeRoute(routeName, props) {
57+
isActiveRoute(routeName, props) {
5058
return props.location.pathname.indexOf(routeName) > -1
51-
? 'nav-item nav-dropdown open'
52-
: 'nav-item nav-dropdown';
59+
}
60+
61+
activeRoute(routeName, props) {
62+
return this.isActiveRoute(routeName, props) ?
63+
'nav-item nav-dropdown open' :
64+
'nav-item nav-dropdown';
5365
}
5466

5567
hideMobile() {
@@ -148,6 +160,7 @@ class AppSidebarNav2 extends Component {
148160

149161
// nav link
150162
navLink(item, key, classes) {
163+
const ref = React.createRef();
151164
const url = item.url || '';
152165
const itemIcon = <i className={classes.icon} />
153166
const itemBadge = this.navBadge(item.badge)
@@ -171,7 +184,7 @@ class AppSidebarNav2 extends Component {
171184
<RsNavLink href={url} className={classes.link} active {...attributes}>
172185
{itemIcon}{item.name}{itemBadge}
173186
</RsNavLink> :
174-
<NavLink to={url} className={classes.link} activeClassName="active" onClick={this.hideMobile} {...attributes}>
187+
<NavLink to={url} className={classes.link} activeClassName="active" onClick={() => this.hideMobile(ref)} ref={ref} {...attributes}>
175188
{itemIcon}{item.name}{itemBadge}
176189
</NavLink>
177190
}
@@ -200,6 +213,45 @@ class AppSidebarNav2 extends Component {
200213
return link.substring(0, 4) === 'http';
201214
}
202215

216+
observeDomMutations() {
217+
if (window.MutationObserver) {
218+
219+
// eslint-disable-next-line
220+
this.changes = new MutationObserver((mutations) => {
221+
222+
const isSidebarMinimized = document.body.classList.contains('sidebar-minimized') || false
223+
this.setState({ sidebarMinimized: isSidebarMinimized })
224+
225+
LayoutHelper.sidebarPSToggle(!isSidebarMinimized)
226+
227+
});
228+
const element = document.body;
229+
this.changes.observe(element, {
230+
attributes: true,
231+
attributeFilter: ['class']
232+
});
233+
}
234+
window.addEventListener('resize', this.onResize);
235+
}
236+
237+
onResize() {
238+
LayoutHelper.sidebarPSToggle(true)
239+
}
240+
241+
componentDidMount() {
242+
this.observeDomMutations()
243+
}
244+
245+
componentWillUnmount() {
246+
try {
247+
this.changes.disconnect()
248+
window.removeEventListener('resize', this.onResize);
249+
} catch (ignore) {
250+
// eslint-disable-next-line
251+
console.warn('CoreUI SidebarNav failed to disconnect from MutationObserver', ignore)
252+
}
253+
}
254+
203255
render() {
204256
const { className, children, navConfig, ...attributes } = this.props;
205257

@@ -208,18 +260,17 @@ class AppSidebarNav2 extends Component {
208260
delete attributes.Tag
209261
delete attributes.router
210262

211-
const navClasses = classNames(className, 'sidebar-nav');
263+
const navClasses = classNames(className, 'sidebar-nav')
212264

213-
// ToDo: find better rtl fix
214-
const isRtl = getComputedStyle(document.documentElement).direction === 'rtl'
265+
const options = Object.assign({}, { suppressScrollX: true, suppressScrollY: this.state.sidebarMinimized })
215266

216267
// sidebar-nav root
217268
return (
218-
<PerfectScrollbar className={navClasses} {...attributes} options={{ suppressScrollX: !isRtl }} >
219-
<Nav>
220-
{children || this.navList(navConfig.items)}
221-
</Nav>
222-
</PerfectScrollbar>
269+
<PerfectScrollbar className={navClasses} {...attributes} options={options} ref = {(ref) => { this._scrollBarRef = ref; }} >
270+
<Nav>
271+
{children || this.navList(navConfig.items)}
272+
</Nav>
273+
</PerfectScrollbar>
223274
);
224275
}
225276
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.