Skip to content

Commit 4ca5b0c

Browse files
committed
Data driven sidebar component. Close #219
1 parent 2711499 commit 4ca5b0c

File tree

4 files changed

+303
-91
lines changed

4 files changed

+303
-91
lines changed
Lines changed: 76 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import React, { Component } from 'react';
2-
import { NavLink } from 'react-router-dom'
1+
import React, {Component} from 'react';
2+
import {NavLink} from 'react-router-dom';
3+
import {Badge, Nav, NavItem} from 'reactstrap';
4+
import classNames from 'classnames';
5+
import nav from './_nav'
36

47
class Sidebar extends Component {
58

@@ -8,97 +11,90 @@ class Sidebar extends Component {
811
e.target.parentElement.classList.toggle('open');
912
}
1013

11-
activeRoute(routeName) {
12-
return this.props.location.pathname.indexOf(routeName) > -1 ? 'nav-item nav-dropdown open' : 'nav-item nav-dropdown';
14+
activeRoute(routeName, props) {
15+
// return this.props.location.pathname.indexOf(routeName) > -1 ? 'nav-item nav-dropdown open' : 'nav-item nav-dropdown';
16+
return props.location.pathname.indexOf(routeName) > -1 ? 'nav-item nav-dropdown open' : 'nav-item nav-dropdown';
17+
1318
}
1419

20+
// todo Sidebar nav secondLevel
1521
// secondLevelActive(routeName) {
1622
// return this.props.location.pathname.indexOf(routeName) > -1 ? "nav nav-second-level collapse in" : "nav nav-second-level collapse";
1723
// }
1824

25+
1926
render() {
27+
28+
const props = this.props;
29+
const activeRoute = this.activeRoute;
30+
const handleClick = this.handleClick;
31+
32+
// badge addon to NavItem
33+
const badge = (badge) => {
34+
if (badge) {
35+
const classes = classNames( badge.class );
36+
return (<Badge className={ classes } color={ badge.variant }>{ badge.text }</Badge>)
37+
}
38+
};
39+
40+
// simple wrapper for nav-title item
41+
const wrapper = item => { return (!item.wrapper ? item.name : (React.createElement(item.wrapper.element, item.wrapper.attributes, item.name))) };
42+
43+
// nav list section title
44+
const title = (title, key) => {
45+
const classes = classNames( "nav-title", title.class);
46+
return (<li key={key} className={ classes }>{wrapper(title)} </li>);
47+
};
48+
49+
// nav list divider
50+
const divider = (divider, key) => (<li key={key} className="divider"></li>);
51+
52+
// nav item with nav link
53+
const navItem = (item, key) => {
54+
const classes = classNames( "nav-link", item.class);
55+
return (
56+
<NavItem key={key}>
57+
<NavLink to={item.url} className={ classes } activeClassName="active">
58+
<i className={item.icon}></i>{item.name}{badge(item.badge)}
59+
</NavLink>
60+
</NavItem>
61+
)
62+
};
63+
64+
// nav dropdown
65+
const navDropdown = (item, key) => {
66+
return (
67+
<li key={key} className={activeRoute(item.url, props)}>
68+
<a className="nav-link nav-dropdown-toggle" href="#" onClick={handleClick.bind(this)}><i className={item.icon}></i> {item.name}</a>
69+
<ul className="nav-dropdown-items">
70+
{navList(item.children)}
71+
</ul>
72+
</li>)
73+
};
74+
75+
// nav link
76+
const navLink = (item, idx) =>
77+
item.title ? title(item, idx) :
78+
item.divider ? divider(item, idx) :
79+
item.children ? navDropdown(item, idx)
80+
: navItem(item, idx) ;
81+
82+
// nav list
83+
const navList = (items) => {
84+
return items.map( (item, index) => navLink(item, index) );
85+
};
86+
87+
// sidebar-nav root
2088
return (
2189
<div className="sidebar">
2290
<nav className="sidebar-nav">
23-
<ul className="nav">
24-
<li className="nav-item">
25-
<NavLink to={'/dashboard'} className="nav-link" activeClassName="active"><i className="icon-speedometer"></i> Dashboard <span className="badge badge-info">NEW</span></NavLink>
26-
</li>
27-
<li className="nav-title">
28-
UI Elements
29-
</li>
30-
<li className={this.activeRoute("/components")}>
31-
<a className="nav-link nav-dropdown-toggle" href="#" onClick={this.handleClick.bind(this)}><i className="icon-puzzle"></i> Components</a>
32-
<ul className="nav-dropdown-items">
33-
<li className="nav-item">
34-
<NavLink to={'/components/buttons'} className="nav-link" activeClassName="active"><i className="icon-puzzle"></i> Buttons</NavLink>
35-
</li>
36-
<li className="nav-item">
37-
<NavLink to={'/components/social-buttons'} className="nav-link" activeClassName="active"><i className="icon-puzzle"></i> Social Buttons</NavLink>
38-
</li>
39-
<li className="nav-item">
40-
<NavLink to={'/components/cards'} className="nav-link" activeClassName="active"><i className="icon-puzzle"></i> Cards</NavLink>
41-
</li>
42-
<li className="nav-item">
43-
<NavLink to={'/components/forms'} className="nav-link" activeClassName="active"><i className="icon-puzzle"></i> Forms</NavLink>
44-
</li>
45-
<li className="nav-item">
46-
<NavLink to={'/components/modals'} className="nav-link" activeClassName="active"><i className="icon-puzzle"></i> Modals</NavLink>
47-
</li>
48-
<li className="nav-item">
49-
<NavLink to={'/components/switches'} className="nav-link" activeClassName="active"><i className="icon-puzzle"></i> Switches</NavLink>
50-
</li>
51-
<li className="nav-item">
52-
<NavLink to={'/components/tables'} className="nav-link" activeClassName="active"><i className="icon-puzzle"></i> Tables</NavLink>
53-
</li>
54-
<li className="nav-item">
55-
<NavLink to={'/components/tabs'} className="nav-link" activeClassName="active"><i className="icon-puzzle"></i> Tabs</NavLink>
56-
</li>
57-
</ul>
58-
</li>
59-
<li className={this.activeRoute("/icons")}>
60-
<a className="nav-link nav-dropdown-toggle" href="#" onClick={this.handleClick.bind(this)}><i className="icon-star"></i> Icons</a>
61-
<ul className="nav-dropdown-items">
62-
<li className="nav-item">
63-
<NavLink to={'/icons/font-awesome'} className="nav-link" activeClassName="active"><i className="icon-star"></i> Font Awesome</NavLink>
64-
</li>
65-
<li className="nav-item">
66-
<NavLink to={'/icons/simple-line-icons'} className="nav-link" activeClassName="active"><i className="icon-star"></i> Simple Line Icons</NavLink>
67-
</li>
68-
</ul>
69-
</li>
70-
<li className="nav-item">
71-
<NavLink to={'/widgets'} className="nav-link" activeClassName="active"><i className="icon-calculator"></i> Widgets <span className="badge badge-info">NEW</span></NavLink>
72-
</li>
73-
<li className="nav-item">
74-
<NavLink to={'/charts'} className="nav-link" activeClassName="active"><i className="icon-pie-chart"></i> Charts</NavLink>
75-
</li>
76-
<li className="divider"></li>
77-
<li className="nav-title">
78-
Extras
79-
</li>
80-
<li className="nav-item nav-dropdown">
81-
<a className="nav-link nav-dropdown-toggle" href="#" onClick={this.handleClick.bind(this)}><i className="icon-star"></i> Pages</a>
82-
<ul className="nav-dropdown-items">
83-
<li className="nav-item">
84-
<NavLink to={'/login'} className="nav-link" activeClassName="active"><i className="icon-star"></i> Login</NavLink>
85-
</li>
86-
<li className="nav-item">
87-
<NavLink to={'/register'} className="nav-link" activeClassName="active"><i className="icon-star"></i> Register</NavLink>
88-
</li>
89-
<li className="nav-item">
90-
<NavLink to={'/404'} className="nav-link" activeClassName="active"><i className="icon-star"></i> Error 404</NavLink>
91-
</li>
92-
<li className="nav-item">
93-
<NavLink to={'/500'} className="nav-link" activeClassName="active"><i className="icon-star"></i> Error 500</NavLink>
94-
</li>
95-
</ul>
96-
</li>
97-
</ul>
91+
<Nav>
92+
{navList(nav.items)}
93+
</Nav>
9894
</nav>
9995
</div>
10096
)
10197
}
10298
}
10399

104-
export default Sidebar;
100+
export default Sidebar;
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
export default {
2+
items: [
3+
{
4+
name: 'Dashboard',
5+
url: '/dashboard',
6+
icon: 'icon-speedometer',
7+
badge: {
8+
variant: 'info',
9+
text: 'NEW'
10+
}
11+
},
12+
{
13+
title: true,
14+
name: 'UI elements',
15+
wrapper: { // optional wrapper object
16+
element: "span", // required valid HTML5 element tag
17+
attributes: {} // optional valid JS object with JS API naming ex: { className: "my-class", style: { fontFamily: "Verdana" }, id: "my-id"}
18+
},
19+
class: "" // optional class names space delimited list for title item ex: "text-center"
20+
},
21+
{
22+
name: 'Components',
23+
url: '/components',
24+
icon: 'icon-puzzle',
25+
children: [
26+
{
27+
name: 'Buttons',
28+
url: '/components/buttons',
29+
icon: 'icon-puzzle'
30+
},
31+
{
32+
name: 'Social Buttons',
33+
url: '/components/social-buttons',
34+
icon: 'icon-puzzle'
35+
},
36+
{
37+
name: 'Cards',
38+
url: '/components/cards',
39+
icon: 'icon-puzzle'
40+
},
41+
{
42+
name: 'Forms',
43+
url: '/components/forms',
44+
icon: 'icon-puzzle'
45+
},
46+
{
47+
name: 'Modals',
48+
url: '/components/modals',
49+
icon: 'icon-puzzle'
50+
},
51+
{
52+
name: 'Switches',
53+
url: '/components/switches',
54+
icon: 'icon-puzzle'
55+
},
56+
{
57+
name: 'Tables',
58+
url: '/components/tables',
59+
icon: 'icon-puzzle'
60+
},
61+
{
62+
name: 'Tabs',
63+
url: '/components/tabs',
64+
icon: 'icon-puzzle'
65+
}
66+
]
67+
},
68+
{
69+
name: 'Icons',
70+
url: '/icons',
71+
icon: 'icon-star',
72+
children: [
73+
{
74+
name: 'Font Awesome',
75+
url: '/icons/font-awesome',
76+
icon: 'icon-star',
77+
badge: {
78+
variant: 'secondary',
79+
text: '4.7'
80+
}
81+
},
82+
{
83+
name: 'Simple Line Icons',
84+
url: '/icons/simple-line-icons',
85+
icon: 'icon-star'
86+
}
87+
]
88+
},
89+
{
90+
name: 'Widgets',
91+
url: '/widgets',
92+
icon: 'icon-calculator',
93+
badge: {
94+
variant: 'info',
95+
text: 'NEW'
96+
}
97+
},
98+
{
99+
name: 'Charts',
100+
url: '/charts',
101+
icon: 'icon-pie-chart'
102+
},
103+
{
104+
divider: true
105+
},
106+
{
107+
title: true,
108+
name: 'Extras'
109+
},
110+
{
111+
name: 'Pages',
112+
url: '/pages',
113+
icon: 'icon-star',
114+
children: [
115+
{
116+
name: 'Login',
117+
url: '/login',
118+
icon: 'icon-star'
119+
},
120+
{
121+
name: 'Register',
122+
url: '/register',
123+
icon: 'icon-star'
124+
},
125+
{
126+
name: 'Error 404',
127+
url: '/404',
128+
icon: 'icon-star'
129+
},
130+
{
131+
name: 'Error 500',
132+
url: '/500',
133+
icon: 'icon-star'
134+
}
135+
]
136+
}
137+
]
138+
};

0 commit comments

Comments
 (0)