I am started to build my UI using react-bootstrap
and now there is important task for me to create SideBar Accordion Menu using standard bootstrap
components. I found this example which uses panel-group
and table
, but I think that it is not the best way, because nav
is better in natural way for navigation components.
I want my SideBar menu code look like this (react-bootstrap
component):
<Nav bsStyle="pills" stacked>
<NavItem title="Item 1">
<Nav bsStyle="pills" stacked>
<NavItem title="Sub Item 1">Sub Item 1</NavItem>
<NavItem title="Sub Item 2">Sub Item 2</NavItem>
<NavItem title="Sub Item 3">Sub Item 3</NavItem>
</Nav>
</NavItem>
<NavItem title="Item 2">Item 2</NavItem>
<NavItem title="Item 3">Item 3</NavItem>
</Nav>
Any suggestions with react-bootstrap
or just bootstrap
will be useful.
We can use the following approach in ReactJS to use the react-bootstrap Accordion Component. Accordion Props: activeKey: It is the currently active key which corresponds to the expanded card which is currently active. as: It can be used as a custom element type for this component.
We can use the following approach in ReactJS to use the ReactJS Reactstrap Navbar Component. Navbar Props: light: It is used to indicate whether to apply the light color class to it or not. dark: It is used to indicate whether to apply the dark color class to it or not.
Just create a constant for the ref, apply it to the Accordion. Toggle , and call it from the onClick at the desired component (in this case, InternalComponent ). import { useRef } from 'react'; function App() { const accordionRef = useRef(null); function toggleAccordion () { accordionRef. current.
I found pure nav
solution. So maybe it can help someone else. The solution is to use a standard 'react-bootstrap' components, such as Navbar
, in combination with bootstrap
css customization.
Example code below:
SideBarMenu.jsx
import React from 'react';
import styles from './sideBarMenu.css';
import {Nav, NavItem, Navbar, NavDropdown, MenuItem, Glyphicon} from 'react-bootstrap';
export default React.createClass( {
render: function() {
return <div id="sidebar-menu" className={styles.sideBarMenuContainer}>
<Navbar fluid className={styles.sidebar} inverse >
<Navbar.Header>
<Navbar.Brand>
<a href="/">User Name</a>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Navbar.Text className={styles.userMenu}>
<Navbar.Link href="#"><Glyphicon glyph="home"/></Navbar.Link>
<Navbar.Link href="#"><Glyphicon glyph="log-out"/></Navbar.Link>
</Navbar.Text>
<Nav>
<NavDropdown eventKey={1} title="Item 1">
<MenuItem eventKey={1.1} href="#">Item 1.1</MenuItem>
</NavDropdown>
<NavItem eventKey={2}>Item 2</NavItem>
<NavItem eventKey={3}>Item 3</NavItem>
</Nav>
</Navbar.Collapse>
</Navbar>
</div>;
}
});
sideBarMenu.css
.sideBarMenuContainer {
position: fixed;
height: 100%;
}
.userMenu {
width: 100%;
text-align: center;
margin-right: 0px;
margin-left: 0px;
margin-top: 0px;
}
nav.sidebar :global(.navbar-brand) :global(.glyphicon) {
margin-right: 0px;
}
/*Remove rounded coners*/
nav.sidebar.:global(navbar) {
border-radius: 0px;
}
nav.sidebar {
-webkit-transition: margin 200ms ease-out;
-moz-transition: margin 200ms ease-out;
-o-transition: margin 200ms ease-out;
transition: margin 200ms ease-out;
}
/* .....NavBar: Icon only with coloring/layout.....*/
/*small/medium side display*/
@media ( min-width : 768px) {
/*Center Brand*/
nav.sidebar.:global(navbar).sidebar>.container :global(.navbar-brand), :global(.navbar)>:global(.container-fluid) :global(.navbar-brand)
{
margin-left: 0px;
}
/*Center Brand*/
nav.sidebar :global(.navbar-brand), nav.sidebar :global(.navbar-header) {
text-align: center;
width: 100%;
margin-left: 0px;
}
/*Center Icons*/
nav.sidebar a {
padding-right: 13px;
}
/*adds border top to first nav box */
nav.sidebar :global(.navbar-nav)>li:first-child {
border-top: 1px #e5e5e5 solid;
}
/*adds border to bottom nav boxes*/
nav.sidebar :global(.navbar-nav)>li {
border-bottom: 1px #e5e5e5 solid;
}
/* Colors/style dropdown box*/
nav.sidebar :global(.navbar-nav) :global(.open) :global(.dropdown-menu) {
position: static;
float: none;
width: auto;
margin-top: 0;
background-color: transparent;
border: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
/*allows nav box to use 100% width*/
nav.sidebar :global(.navbar-collapse), nav.sidebar :global(.container-fluid) {
padding: 0 0px 0 0px;
}
/*colors dropdown box text */
:global(.navbar-inverse) :global(.navbar-nav) :global(.open) :global(.dropdown-menu)>li>a {
color: #777;
}
/*gives sidebar width/height*/
nav.sidebar {
width: 200px;
height: 100%;
margin-left: -160px;
float: left;
z-index: 8000;
margin-bottom: 0px;
}
/*give sidebar 100% width;*/
nav.sidebar li {
width: 100%;
}
/* Move nav to full on mouse over*/
nav.sidebar:hover {
margin-left: 0px;
}
/*for hiden things when navbar hidden*/
:global(.forAnimate) {
opacity: 0;
}
}
/* .....NavBar: Fully showing nav bar..... */
@media ( min-width : 1330px) {
/*Show all nav*/
nav.sidebar {
margin-left: 0px;
float: left;
}
/*Show hidden items on nav*/
nav.sidebar :global(.forAnimate) {
opacity: 1;
}
}
nav.sidebar :global(.navbar-nav) :global(.open) :global(.dropdown-menu)>li>a:hover, nav.sidebar :global(.navbar-nav) :global(.open) :global(.dropdown-menu)>li>a:focus
{
color: #CCC;
background-color: transparent;
}
nav:hover :global(.forAnimate) {
opacity: 1;
}
section {
padding-left: 15px;
}
Note that I am using webpack
in combination with css-loader
modules scope, so :global
means bootstrap
css class name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With