Skip to content

Commit 569a93d

Browse files
authored
Merge pull request #101 from coreui/dev-v2.5.5-fix
v2.5.5 fix
2 parents 35eafef + 36461f6 commit 569a93d

File tree

7 files changed

+158
-32
lines changed

7 files changed

+158
-32
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# See https://help.github.com/ignore-files/ for more about ignoring files.
22

33
# dependencies
4+
node_modules
45
/node_modules
56
package-lock.json
67

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
### [@coreui/react](https://coreui.io/) changelog
22

3+
##### `v2.5.5`
4+
- fix(SidebarNav): perfect scrollbar issue on sidebar minimized / rtl
5+
- chore: dependencies update and config refactor
6+
37
##### `v2.5.4`
48
- fix(SidebarNav): allow location object as navConfig item url parameter
59

css/scrollbar.css

+18
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+
}

nwb.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module.exports = {
55
umd: {
66
global: 'CoreUIReact',
77
externals: {
8-
react: 'React'
8+
react: 'React',
9+
'react-router': 'ReactRouter'
910
}
1011
}
1112
}

package.json

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@coreui/react",
3-
"version": "2.5.4",
3+
"version": "2.5.5",
44
"description": "CoreUI React Bootstrap 4 components",
55
"license": "MIT",
66
"author": {
@@ -35,32 +35,32 @@
3535
"lint": "eslint src"
3636
},
3737
"dependencies": {
38-
"@coreui/icons": "0.3.0",
3938
"classnames": "^2.2.6",
40-
"core-js": "^2.6.9",
39+
"core-js": "^2.6.11",
4140
"prop-types": "^15.7.2",
4241
"react-onclickout": "^2.0.8",
43-
"react-perfect-scrollbar": "^1.5.3",
44-
"reactstrap": "^8.0.1"
42+
"react-perfect-scrollbar": "~1.5.8"
4543
},
4644
"peerDependencies": {
47-
"@coreui/coreui": "^2.1.12",
48-
"react": "^16.10.1",
49-
"react-router-dom": "^5.1.2"
45+
"@coreui/coreui": "^2.1.16",
46+
"react": "^16.12.0",
47+
"react-router-dom": "^5.1.2",
48+
"mutationobserver-shim": "^0.3.3"
5049
},
5150
"devDependencies": {
51+
"@coreui/icons": "~0.3.0",
5252
"babel-eslint": "^10.0.3",
53-
"enzyme": "^3.10.0",
54-
"enzyme-adapter-react-16": "^1.14.0",
53+
"enzyme": "^3.11.0",
54+
"enzyme-adapter-react-16": "^1.15.2",
5555
"eslint": "^5.16.0",
56-
"eslint-plugin-import": "^2.18.2",
57-
"eslint-plugin-react": "^7.15.1",
56+
"eslint-plugin-import": "^2.20.1",
57+
"eslint-plugin-react": "^7.18.3",
5858
"nwb": "^0.23.0",
59-
"react": "^16.10.1",
60-
"react-dom": "^16.10.1",
59+
"react": "^16.12.0",
60+
"react-dom": "^16.12.0",
6161
"react-router-dom": "^5.1.2",
62-
"sinon": "^5.1.1",
63-
"webpack-dev-server": "^3.8.1"
62+
"reactstrap": "^8.4.1",
63+
"sinon": "^5.1.1"
6464
},
6565
"repository": {
6666
"type": "git",

src/Shared/layout/layout.js

+54-3
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

+63-12
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)