How can I use Navbar.Collapse and Navbar.Offcanvas together? - reactjs

My goal is to have a standard topnav on large and greater breakpoints, then on smaller/mobile screens, to use an offcanvas instead while hiding the normal topnav links. However, when I use the two together, the hamburger button triggers both the collapse and the offcanvas, even though the aria-label is set to the offcanvas id (I understand this is just an accessibility label)
How can I tell it to only trigger the offcanvas and just ignore the collapse?
Alternatively, I want the collapse to come in from the side, like the offcanvas does, rather than the top.
Here's my code, as basic as it is:
import React from 'react'
import { Container, Nav, Navbar, NavDropdown, Offcanvas } from 'react-bootstrap';
const NavLinks = () => (
<Nav className="justify-content-end flex-grow-1 pe-3">
<Nav.Link href="#action1">Home</Nav.Link>
<Nav.Link href="#action2">Link</Nav.Link>
<NavDropdown title="Dropdown" id="offcanvasNavbarDropdown">
<NavDropdown.Item href="#action3">Action</NavDropdown.Item>
<NavDropdown.Item href="#action4">Another action</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action5">Something else here</NavDropdown.Item>
</NavDropdown>
</Nav>
);
const Header = () => {
return (
<Navbar bg="light" expand="lg">
<Container fluid>
<Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand>
<Navbar.Collapse>
<NavLinks />
</Navbar.Collapse>
<Navbar.Toggle aria-controls="offcanvasNavbar" />
<Navbar.Offcanvas
id="offcanvasNavbar"
aria-labelledby="offcanvasNavbarLabel"
placement="end">
<Offcanvas.Header closeButton>
<Offcanvas.Title id="offcanvasNavbarLabel">
Offcanvas
</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
<NavLinks />
</Offcanvas.Body>
</Navbar.Offcanvas>
</Container>
</Navbar>
);
}
export default Header

Related

React-Bootstrap Navbar issue

Can somebody help me align my navbar? Nothing I do makes the top part line up normally. I think the issue might be when navbar gets toggled whether the user is logged in and an admin or not. I'm wondering if is because of the divs and if I have to make a separate component now. It is also really big for no good reason.
<Navbar.Brand href="/homepage" className="logo">
<h2>BookShopper</h2>
{/* <img src = 'logo.png' height = '100px' width = '300px'/> */}
</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Form className="d-flex">
<FormControl
className = "justify-content-center"
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
/>
</Form>
{isLoggedIn ? (
<div>
<Nav className="me-auto">
<Nav.Link href="/edit">Profile</Nav.Link>
{/* The navbar will show these links after you log in */}
<Nav.Link href="#" onClick={handleClick}>
Logout
</Nav.Link>
<Nav.Link href="/cart">
<BsFillBasket3Fill />
</Nav.Link>
</Nav>
{isUserAdmin && (
<div>
<Nav className="me-auto">
<NavDropdown
title="Market Place"
id="collasible-nav-dropdown"
>
<NavDropdown.Item href="/stock">Stock</NavDropdown.Item>
<NavDropdown.Item href="/users">Users</NavDropdown.Item>
<NavDropdown.Item href="/add-book">
Add Book
</NavDropdown.Item>
</NavDropdown>
</Nav>
</div>
)}
</div>
) : (
<div>
{/* The navbar will show these links before you log in */}
<Nav>
<Nav.Link href="/login">Login</Nav.Link>
<Nav.Link href="/cart">
<BsFillBasket3Fill />
</Nav.Link>
</Nav>
</div>
)}
</Navbar.Collapse>
{/* </Container> */}
</Navbar>
I just want the elements to line up horizontally and look normal.
With your code you are creating two Navs (if logged in AND user admin). Move Nav outside of the ternary operator to create it only once and set navigation links according to your logic.
Basically you want:
When not logged in: Show "Login" and "Basket"
When logged in: Show "Profile", "Logout" and "Basket"
When logged in AND also having admin rights: Show "Profile", "Logout", "Basket" and "Market Place"
I've created a sandbox, fixed the problem with double Navs and tried to simplified your boolean logic as well: https://codesandbox.io/s/interesting-darkness-i0u64k?file=/src/App.js

Issue with React-Boostrap's Offcanvas and breakpoints

I'm currently trying to implement an offcanvas style navbar using react-boostrap, and am trying to make it responsive so that menu icon disappears and the contents are displayed on the nav bar itself when the screen reaches above a certain size.
I used the example from their site but have changed the value of the expand property and added a collapse component: https://react-bootstrap.netlify.app/components/navbar/#navbar-offcanvas
import {
Navbar,
Container,
Offcanvas,
NavDropdown,
Form,
FormControl,
Button,
Nav,
} from "react-bootstrap";
const Navigation = () => {
return (
<Navbar bg="light" expand="1g" collapseOnSelect>
<Container fluid>
<Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand>
<Navbar.Toggle aria-controls="offcanvasNavbar" />
<Navbar.Collapse id="offcanvasNavbar">
<Navbar.Offcanvas
id="offcanvasNavbar"
aria-labelledby="offcanvasNavbarLabel"
placement="end"
>
<Offcanvas.Header closeButton>
<Offcanvas.Title id="offcanvasNavbarLabel">
Offcanvas
</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
<Nav className="justify-content-end flex-grow-1 pe-3">
<Nav.Link href="#action1">Home</Nav.Link>
<Nav.Link href="#action2">Link</Nav.Link>
<NavDropdown title="Dropdown" id="offcanvasNavbarDropdown">
<NavDropdown.Item href="#action3">Action</NavDropdown.Item>
<NavDropdown.Item href="#action4">
Another action
</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action5">
Something else here
</NavDropdown.Item>
</NavDropdown>
</Nav>
<Form className="d-flex">
<FormControl
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-success">Search</Button>
</Form>
</Offcanvas.Body>
</Navbar.Offcanvas>
</Navbar.Collapse>
</Container>
</Navbar>
);
};
The menu icon should disappear and the contents expand onto the navbar at 992 horizontal res, but nothing changes.
I also tried to use a normal navbar from their examples, but then replace the body with an offcanvas body like so:
<Navbar collapseOnSelect expand="lg" bg="light">
<Container>
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Navbar.Offcanvas
id="offcanvasNavbar"
aria-labelledby="offcanvasNavbarLabel"
placement="end"
>
<Offcanvas.Header closeButton>
<Offcanvas.Title id="offcanvasNavbarLabel">
Offcanvas
</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
<Nav className="justify-content-end flex-grow-1 pe-3">
<Nav.Link href="#action1">Home</Nav.Link>
<Nav.Link href="#action2">Link</Nav.Link>
<NavDropdown title="Dropdown" id="offcanvasNavbarDropdown">
<NavDropdown.Item href="#action3">Action</NavDropdown.Item>
<NavDropdown.Item href="#action4">
Another action
</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action5">
Something else here
</NavDropdown.Item>
</NavDropdown>
</Nav>
<Form className="d-flex">
<FormControl
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
/>
<Button variant="outline-success">Search</Button>
</Form>
</Offcanvas.Body>
</Navbar.Offcanvas>
</Navbar.Collapse>
</Container>
</Navbar>
And while this did actually make the icon disappear correctly, none of the menu's contents would appear onto the bar as they are supposed to.
I've been taking bits out and putting bits in for long enough now that I could have probably created my own by now haha, but I really want to figure out what it is I'm missing.
Any help would be amazing!

React-Bootsrap navbar dropdown not closing

I'm using React-bootstrap package on my react project.
I tried to use simple navbar with dropdown example from react-bootsrap offical demo page.
Here is the example. Dropdown opening when click to 'dropdown' link but it's not closing when trying to click anywhere outside of dropdown. So it's not behave like on example on demo. What can be problem with that?
<Navbar bg="light" expand="lg">
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link href="#home">Home</Nav.Link>
<Nav.Link href="#link">Link</Nav.Link>
<NavDropdown title="Dropdown" id="basic-nav-dropdown">
<NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
<NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
<NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
</NavDropdown>
</Nav>
<Form inline>
<FormControl type="text" placeholder="Search" className="mr-sm-2" />
<Button variant="outline-success">Search</Button>
</Form>
</Navbar.Collapse>
</Navbar>
It's probably a little late for this but I had the same issue. What I finally ended up doing was adding this:
componentDidUpdate() {
document.getElementById("root").click();
}
This forced a closure as soon as the page was loaded. This was put into my main component, or app.js if you so choose.
HTH

Add a image to React Bootstrap dropdown

I'm using React Bootstrap and React Router Bootstrap for my Navbar, and I am making a user profile dropdown menu list.
I'd like to be able to have an user's avatar show up in place of the 'title' property. (The same idea as the user profile dropdown on Github)
Is this possible? I don't see any options to use an image instead of title for NavDropdown
<Navbar inverse>
<Navbar.Header>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav pullRight>
<NavDropdown eventKey={ 3 } id="profile-dropdown" >
<LinkContainer to="/profile/edit" >
<NavItem eventKey={ 3.4 } > Edit </NavItem>
</LinkContainer>
<LinkContainer to="/logout">
<Logout eventKey={ 3.5 } />
</LinkContainer>
</NavDropdown>
</Nav>
</Navbar.Collapse>
</Navbar>
Would a SplitButton or straight Dropdown be a better option? I don't really see much that the "NavDropdown" is adding to the HTML.
The NavDropdown's title property can take any React element as a value. This is what I did:
<Nav pullRight>
<NavDropdown eventKey={1}
title={
<div className="pull-left">
<img className="thumbnail-image"
src={src}
alt="user pic"
/>
{user.username}
</div>
}
id="basic-nav-dropdown">
<MenuItem eventKey={1.1} href="/profile">Profile</MenuItem>
<MenuItem divider />
<MenuItem eventKey={1.3}>
<i className="fa fa-sign-out"></i> Logout
</MenuItem>
</NavDropdown>
</Nav>
You'll probably need to adjust the css a little bit.
You can also use the <Image /> component, e.g.
const UserMenu = (
<Image
src={'https://github.com/mshaaban0.png'}
alt="UserName profile image"
roundedCircle
style={{ width: '40px' }}
/>
)
<NavDropdown id="nav-dropdown-dark-example" title={UserMenu}>
//....
</NavDropdown>

Hide collapse navbar after link click, react-redux, react-bootstrap

I'm beginner in react, so, need your help.
I used collapsible bootstrap navbar, have no ideas how to make it collapse after link click on mobile. Native bootsrap property collapseOnSelect not working, or i did something wrong.
const AppBar = () => (
<Navbar collapseOnSelect>
<Navbar.Header>
<Navbar.Brand>
<div className="logo-wrap">
<Link to="define">
<img height='50' src='./../assets/img/logo.png' className="logo"/>
</Link>
</div>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav>
<LinkContainer to="define" className="nav-link"><NavItem eventKey={1}>Home</NavItem></LinkContainer>
<LinkContainer to="about" className="nav-link"><NavItem eventKey={1}>About</NavItem></LinkContainer>
<LinkContainer to="features" className="nav-link"><NavItem eventKey={1}>Features</NavItem></LinkContainer>
<LinkContainer to="pricing" className="nav-link"><NavItem eventKey={1}>Pricing</NavItem></LinkContainer>
<LinkContainer to="areaMap" className="nav-link"><NavItem eventKey={1}>Area Map</NavItem></LinkContainer>
</Nav>
<Nav pullRight>
<LinkContainer to="login" className="nav-link"><NavItem eventKey={2}>Log In</NavItem></LinkContainer>
<LinkContainer to="registration"><NavItem eventKey={2}><Button className="sign-up">Sign Up</Button></NavItem></LinkContainer>
</Nav>
</Navbar.Collapse>
</Navbar>
);
export default AppBar;
const [expanded, setExpanded] = useState(false);
Second in the Navbar we add this prop:
<Navbar expanded={expanded}>
Third, we add an onClick event to the toggle handler that changes the menu visibility status:
<Navbar.Toggle onClick={() => setExpanded(expanded ? false : "expanded")} />
Fourth we add the prop
<Link to="/" onClick={() => setExpanded(false)}>Menu</Link>

Resources