react-side-nav
v1.1.1
Published
A side bar react component that supports custom styles, icons and works with react-router
Downloads
38
Maintainers
Readme
react-side-nav ·
react-side-nav is a JavaScript react UI component that displays a navigation side bar. It supports custom styling, custom icons & chevrons and works with react-router. Add-on components are provided to support Font Awesome for the icons & chevrons.
New version
- react-side-nav was updated to the newest dependencies using webpack 4 and react 16 (These changes may cause code to break for some users still using the old versions)
- The default theme is no longer included in the js bundle and has to be included separately (see style guide below)
- New animation function is included to animate the click on a parent node
- Update for FontAwesome 5 - Icon properties must now specify icon style, Chevron add-on uses solid style
- Fixed bug that caused a side nav that gets a activeItem prop passed in to not activate that item when mounting
Installation
To get started with react-side-nav, simply install it with npm:
npm i react-side-nav -S
Usage
Include the main component and add-on icon components (optional) as well as the default theme (optional)
import { SideNav, Chevron, Icon } from 'react-side-nav';
The actual nav menu structure is defined via a JavaScript array / JSON (support for direct definition in a render method not included yet); each entry in the menu tree can either be a "leaf", meaning an object that has a routing link or a "branch" that is parent to multiple other branches or leaves. A leaf can also be on the top level, i.e. be parentless. A more detailed explanation about the possible fields of the nav menu tree can be found below. See the following array definition to illustrate this concept:
const menuItems = [
{ id: 1,
label: 'Item 1',
icon: 'fas fa-battery-half',
items: [
{ id: 11,
label: 'Item 1.1',
icon: 'fas fa-car',
link: '/item11',
},
{ id: 12,
label: 'Item 1.2',
icon: 'fas fa-bullhorn',
link: '/item12',
},
],
},
];
The component must be passed a "link" component so it knows how to render the leaves; to support react-router and Font Awesome icons, the following component could be used:
const NavLink = props => (<Link to={props.to} {...props}><i className={`fa ${props.icon}`} />{props.label}</Link>);
Alternatively, for non react-router links:
const NavLink = props => (<a href={props.to} {...props}><i className={`fa ${props.icon}`} />{props.label}</a>);
With the nav menu tree and the link component defined, the side nav is ready for use:
<SideNav
items={menuItems}
linkComponent={NavLink}
chevronComponent={Chevron}
iconComponent={Icon}
/>
All SideNav menu items have an expanded
and an active
state; the expanded
state indicates whether a branch item is expanded (showing all its children) or not; the expanded
state is automatically toggled by the user clicking "branch" items. The active
state can be used to indicate the currently active route (if some kind of routing, e.g. react-router is used); by passing in a valid link using the activeItem
prop of SideNav, the targeted leaf that matches this link will be marked active and all its parent elements will be expanded. Elements expanded because of the active
state cannot be collapsed to always indicate the active route. The link to be passed in as a prop can be gotten from the routing component if this functionality is supported by it; alternatively, the user can access the history API of the browser to extract that information if required.
To do
- Better documentation
- Allow direct definition of the nav menu by the user by placing SideNavItem instances as children of the SideNav instance (currently only JSON definition possible)
- Include example as well as more options for animation function
Developers guide
SideNav has the following props:
| Prop | Default | Description |
| --------- | ---------- | ---------------------------------------------------- |
| className | null | CSS class
that is to be applied for styling the SideNav; if not specified, the default theme will be used (see style guide below ) |
| items | null | Nav menu tree object, see below for structure of this object |
| linkComponent | null | React component used to render the leaves of the nav tree that contain actual navigation links; If no link component is passed to the SideNav, leaves will not render. See below for props passed to link component |
| iconComponent | null | React component used to render the icons of the nav menu items; if no icon component is supplied, nav menu items will have no icons; See below for props passed to icon component |
| chevronComponent | null | React component used to render the chevrons (expanded / closed indicator) of the nav menu; if no chevron component is supplied, there will be no expanded / closed indicator for the nav menu items. See below for props passed to chevron component |
| activeItem | null | Link (string) that matches the link of a leaf element of the nav menu tree; if a match is found, the corresponding node is marked active
and expanded |
SideNav items are defined using a JavaScript array; this array contains item
objects that can have multiple children item
elements. Actual navigation links have the link
property and are called "leaves" in this documentation. A leaf (with a link) cannot have children elements, as this would cause conflicts with clicks on the respective entry. Each entry of the SideNav items array can have the following fields:
| Field | Type | Description |
| ------------ | --------------- | ------------------------------------------- |
| id | String or Number | ID if the element; used to identify elements, must be unique |
| label | String | Label to be displayed by the nav menu for the corresponding entry |
| icon | String | (optional) CSS class
passed to the icon component (if provided) to render an icon for the corresponding entry |
| link | String | (only leaf entries) Link used for routing and passed to the Link component; depending on the application, this can be a full URL, a URL fragment or a hashtag anchor-link |
| animationTime| Number | (only branch entries) Time (in ms) for running the click animation; if animation is not used, do not define this field|
| items | Array | (only for branch entries) Array of children item
elements |
To better understand how to use the chevron and icon components, the following table shows the props and definitions of the provided icon and chevron components; the user is of course free to use their own components, provided they support the props passed to them by the SideNav:
| Chevron props | Type | Description |
| ------------- | ---- | ----------- |
| className | String | CSS class
passed to the chevron for additional styling; SideNav will pass the class side-nav-chevron
to the chevron |
| expanded | Boolean | Value declares if the chevron should indicate and expanded or collapsed nav element |
This is the default chevron implementation (using the className
package to compose CSS class names):
const Chevron = props => (<i className={classNames('fa', props.className, { 'fa-chevron-left': !props.expanded, 'fa-chevron-down': props.expanded })}/>);
For the icon component:
| Icon props | Type | Description |
| ---------- | ---- | ----------- |
| className | String | CSS class
passed to the icon for styling; SideNav will pass the class name given by the icon
field defined for the respective element; This implementation of the icon component is geared towards support of Font Awesome, which defines its icons by the CSS class
on the <i />
element |
Default implementation of the icon component:
const Icon = props => (<i className={classNames('fa', props.className)} />);
For the animation function:
If a branch item has the property "animationTime" defined, a click on it will not only expand / collapse it, but also add the class "animateIn" to the node; after "animationTime" milliseconds, the class "animateOut" will be added as well. After another "animationTime" milliseconds both classes "animateIn" and "animateOut" will be removed from the node
Style guide
The component has a few styles inlined that are required for it to work; the default theme is no longer inlined from version 1.0.0 onwards to reduce the size of the component. If you want to use the default theme, please require / import it in your application:
import './node_modules/react-side-nav/dist/themes.css';
Please also see default-theme for the default style definitions.
Example
A small sample application is included and can be found here. To run the sample, clone the repository, install the dependencies and run the example:
git clone https://github.com/ahauser31/react-side-nav.git
cd react-side-nav
npm i
npm start
Credits
This small component was inspired by Banomaster and his very nice component react-sidemenu that unfortunately proved unsuited to what I had in mind; To improve my own skills and as a programming exercise, I wrote SideNav instead of forking & fiddling with SideMenu. Thank you @Banomaster for the excellent work!