Skip to content

Commit

Permalink
fix(NavbarOffcanvas): fix rendering of nav items when expand is used (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
kyletsang committed Apr 27, 2022
1 parent ff08942 commit 63869f9
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 42 deletions.
3 changes: 2 additions & 1 deletion src/Navbar.tsx
Expand Up @@ -190,8 +190,9 @@ const Navbar: BsPrefixRefForwardingComponent<'nav', NavbarProps> =
onToggle: () => onToggle?.(!expanded),
bsPrefix,
expanded: !!expanded,
expand,
}),
[bsPrefix, expanded, onToggle],
[bsPrefix, expanded, expand, onToggle],
);

return (
Expand Down
1 change: 1 addition & 0 deletions src/NavbarContext.tsx
Expand Up @@ -5,6 +5,7 @@ export interface NavbarContextType {
onToggle: () => void;
bsPrefix?: string;
expanded: boolean;
expand?: boolean | string | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
}

const context = React.createContext<NavbarContextType | null>(null);
Expand Down
73 changes: 70 additions & 3 deletions src/NavbarOffcanvas.tsx
@@ -1,13 +1,80 @@
import * as React from 'react';
import { useContext } from 'react';
import useBreakpoint from '@restart/hooks/useBreakpoint';
import classNames from 'classnames';
import { useBootstrapPrefix } from './ThemeProvider';
import Offcanvas, { OffcanvasProps } from './Offcanvas';
import NavbarContext from './NavbarContext';

const NavbarOffcanvas = React.forwardRef<HTMLDivElement, OffcanvasProps>(
(props, ref) => {
export type NavbarOffcanvasProps = Omit<OffcanvasProps, 'show'>;

const NavbarOffcanvas = React.forwardRef<HTMLDivElement, NavbarOffcanvasProps>(
(
{
className,
bsPrefix,
backdrop,
backdropClassName,
keyboard,
scroll,
placement,
autoFocus,
enforceFocus,
restoreFocus,
restoreFocusOptions,
onShow,
onHide,
onEscapeKeyDown,
onEnter,
onEntering,
onEntered,
onExit,
onExiting,
onExited,
...props
},
ref,
) => {
const context = useContext(NavbarContext);
bsPrefix = useBootstrapPrefix(bsPrefix, 'offcanvas');
const hasExpandProp = typeof context?.expand === 'string';
const shouldExpand = useBreakpoint(
(hasExpandProp ? context.expand : 'xs') as any,
'up',
);

return <Offcanvas ref={ref} show={!!context?.expanded} {...props} />;
return hasExpandProp && shouldExpand ? (
<div
ref={ref}
{...props}
className={classNames(className, bsPrefix, `${bsPrefix}-${placement}`)}
/>
) : (
<Offcanvas
ref={ref}
show={!!context?.expanded}
bsPrefix={bsPrefix}
backdrop={backdrop}
backdropClassName={backdropClassName}
keyboard={keyboard}
scroll={scroll}
placement={placement}
autoFocus={autoFocus}
enforceFocus={enforceFocus}
restoreFocus={restoreFocus}
restoreFocusOptions={restoreFocusOptions}
onShow={onShow}
onHide={onHide}
onEscapeKeyDown={onEscapeKeyDown}
onEnter={onEnter}
onEntering={onEntering}
onEntered={onEntered}
onExit={onExit}
onExiting={onExiting}
onExited={onExited}
{...props}
/>
);
},
);

Expand Down
11 changes: 11 additions & 0 deletions test/NavbarOffcanvasSpec.tsx
Expand Up @@ -31,4 +31,15 @@ describe('<NavbarOffcanvas>', () => {
fireEvent.click(getByLabelText('Close'));
onToggleSpy.should.have.been.calledWith(false);
});

it('should render nav items with expand prop', () => {
const { getByText } = render(
<Navbar expand="sm">
<Navbar.Toggle data-testid="toggle" />
<Navbar.Offcanvas data-testid="offcanvas">hello</Navbar.Offcanvas>
</Navbar>,
);

getByText('hello').should.exist;
});
});
87 changes: 49 additions & 38 deletions www/src/examples/Navbar/Offcanvas.js
@@ -1,38 +1,49 @@
<Navbar bg="light" expand={false}>
<Container fluid>
<Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand>
<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>
<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>
</Container>
</Navbar>;
<>
{[false, 'sm', 'md', 'lg', 'xl', 'xxl'].map((expand) => (
<Navbar key={expand} bg="light" expand={expand} className="mb-3">
<Container fluid>
<Navbar.Brand href="#">Navbar Offcanvas</Navbar.Brand>
<Navbar.Toggle aria-controls={`offcanvasNavbar-expand-${expand}`} />
<Navbar.Offcanvas
id={`offcanvasNavbar-expand-${expand}`}
aria-labelledby={`offcanvasNavbarLabel-expand-${expand}`}
placement="end"
>
<Offcanvas.Header closeButton>
<Offcanvas.Title id={`offcanvasNavbarLabel-expand-${expand}`}>
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-expand-${expand}`}
>
<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>
</Container>
</Navbar>
))}
</>;

0 comments on commit 63869f9

Please sign in to comment.