Skip to content

Commit

Permalink
feat(ui): add burger nav to UI
Browse files Browse the repository at this point in the history
  • Loading branch information
UnbearableBear committed Apr 7, 2020
1 parent 304c9bf commit 086bc6d
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 130 deletions.
1 change: 0 additions & 1 deletion packages/code-du-travail-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
"next-transpile-modules": "^3.1.0",
"react": "^16.13.1",
"react-autosuggest": "9.4.3",
"react-burger-menu": "^2.6.13",
"react-delay": "^0.1.0",
"react-dom": "^16.13.1",
"react-feather": "2.0.3",
Expand Down
146 changes: 31 additions & 115 deletions packages/code-du-travail-frontend/src/layout/Header/BurgerNav.js
Original file line number Diff line number Diff line change
@@ -1,120 +1,36 @@
import React, { useState, useEffect } from "react";
import React from "react";
import Link from "next/link";
import styled from "styled-components";
import { slide as Menu } from "react-burger-menu";
import { Button, icons, theme } from "@socialgouv/react-ui";
import {
BurgerNav as RootBurgerNav,
BurgerNavButton as NavButton,
BurgerNavLink as NavAnchor,
BurgerNavCurrent as NavCurrent,
} from "@socialgouv/react-ui";

import { AccessibilityModal } from "../../common/AccessibilityModal";
import { BurgerStyles } from "./BurgerStyles";

const { Burger: BurgerIcon, Close: CloseIcon } = icons;

const TabIndexedLink = ({ href, children, ...props }) => (
<Link href={href} passHref>
<LinkItem {...props}>{children}</LinkItem>
</Link>
);

export const BurgerNav = ({ currentPage }) => {
const [isDesktop, setIsDesktop] = useState(false);
useEffect(() => {
if (window.innerWidth > theme.breakpoints.intTablet) {
// make sure the nav is focusable
setIsDesktop(true);
}
}, []);
return (
<BurgerWrapper>
<BurgerStyles />
<Menu
isOpen={isDesktop ? true : false}
disableAutoFocus={isDesktop ? true : false}
customBurgerIcon={<BurgerIcon />}
customCrossIcon={<CloseIcon />}
>
<AccessibilityModal>
{(openModal) => (
<BaseNavItem variant="navLink" onClick={openModal}>
Accessibilité
</BaseNavItem>
)}
</AccessibilityModal>
{currentPage !== "tools" ? (
<TabIndexedLink href="/outils" passHref>
Boîte à outils
</TabIndexedLink>
) : (
<CurrentPageItem>Boîte à outils</CurrentPageItem>
export const BurgerNav = ({ currentPage }) => (
<RootBurgerNav>
<>
<AccessibilityModal>
{(openModal) => (
<NavButton onClick={openModal}>Accessibilité</NavButton>
)}
{currentPage !== "themes" ? (
<TabIndexedLink href="/themes" passHref>
Thèmes
</TabIndexedLink>
) : (
<CurrentPageItem>Thèmes</CurrentPageItem>
)}
</Menu>
</BurgerWrapper>
);
};

const { box, breakpoints, fonts, spacings } = theme;

const BaseNavItem = styled(Button)`
position: relative;
display: flex !important;
align-items: center;
height: 100%;
padding: 0 ${spacings.base};
font-weight: normal;
font-size: ${fonts.sizes.default};
font-family: "Open Sans", sans-serif;
border: none;
@media (max-width: ${breakpoints.tablet}) {
justify-content: center;
width: 100%;
height: 5.4rem;
padding: 0;
font-weight: 600;
font-size: ${fonts.sizes.headings.small};
}
`;

const LinkItem = styled(BaseNavItem).attrs(() => ({ as: "a" }))`
text-decoration: none;
`;

const CurrentPageItem = styled(BaseNavItem).attrs(() => ({ as: "span" }))`
cursor: inherit;
&:after {
position: absolute;
bottom: 0;
left: 50%;
width: 90%;
height: 3px;
background-color: ${({ theme }) => theme.primary};
border-radius: ${box.borderRadius};
transform: translateX(-50%);
content: "";
}
@media (max-width: ${breakpoints.tablet}) {
&:after {
bottom: auto;
left: 0;
width: 3px;
height: 100%;
transform: none;
}
}
`;

const BurgerWrapper = styled.div`
order: 2;
height: 100%;
& > div {
height: 100%;
}
@media (max-width: ${breakpoints.tablet}) {
height: auto;
}
`;
</AccessibilityModal>
{currentPage !== "tools" ? (
<Link href="/outils" passHref>
<NavAnchor>Boîte à outils</NavAnchor>
</Link>
) : (
<NavCurrent>Boîte à outils</NavCurrent>
)}
{currentPage !== "themes" ? (
<Link href="/themes" passHref>
<NavAnchor>Thèmes</NavAnchor>
</Link>
) : (
<NavCurrent>Thèmes</NavCurrent>
)}
</>
</RootBurgerNav>
);

This file was deleted.

1 change: 1 addition & 0 deletions packages/react-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"prettier": "^2.0.2",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-burger-menu": "^2.6.13",
"react-dom": "^16.13.1",
"rollup": "^2.2.0",
"rollup-plugin-babel": "^4.4.0",
Expand Down
8 changes: 7 additions & 1 deletion packages/react-ui/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ export default {
format: "esm",
},
],
external: ["prop-types", "react", "react-dom", "styled-components"],
external: [
"prop-types",
"react",
"react-burger-menu",
"react-dom",
"styled-components",
],
plugins: [
babel(),
resolve({
Expand Down
100 changes: 100 additions & 0 deletions packages/react-ui/src/BurgerNav/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { slide as Menu } from "react-burger-menu";

import { Button } from "../Button";
import { Burger as BurgerIcon, Close as CloseIcon } from "../icons";
import { box, breakpoints, fonts, spacings } from "../theme";

import { BurgerStyles } from "./styles";

export const BurgerNav = ({ children, ...props }) => {
const [isDesktop, setIsDesktop] = useState(false);
useEffect(() => {
if (window.innerWidth > breakpoints.intTablet) {
// make sure the nav is focusable
setIsDesktop(true);
}
}, []);
return (
<BurgerWrapper {...props}>
<BurgerStyles />
<Menu
isOpen={isDesktop ? true : false}
disableAutoFocus={isDesktop ? true : false}
customBurgerIcon={<BurgerIcon />}
customCrossIcon={<CloseIcon />}
>
{children}
</Menu>
</BurgerWrapper>
);
};

BurgerNav.propTypes = {
children: PropTypes.node.isRequired,
};

export const BurgerNavButton = styled(Button).attrs(() => ({
variant: "navLink",
}))`
position: relative;
display: flex !important;
align-items: center;
height: 100%;
padding: 0 ${spacings.base};
font-weight: normal;
font-size: ${fonts.sizes.default};
font-family: "Open Sans", sans-serif;
border: none;
@media (max-width: ${breakpoints.tablet}) {
justify-content: center;
width: 100%;
height: 5.4rem;
padding: 0;
font-weight: 600;
font-size: ${fonts.sizes.headings.small};
}
`;

export const BurgerNavLink = styled(BurgerNavButton).attrs(() => ({ as: "a" }))`
text-decoration: none;
`;

export const BurgerNavCurrent = styled(BurgerNavButton).attrs(() => ({
as: "span",
}))`
cursor: inherit;
&:after {
position: absolute;
bottom: 0;
left: 50%;
width: 90%;
height: 3px;
background-color: ${({ theme }) => theme.primary};
border-radius: ${box.borderRadius};
transform: translateX(-50%);
content: "";
}
@media (max-width: ${breakpoints.tablet}) {
&:after {
bottom: auto;
left: 0;
width: 3px;
height: 100%;
transform: none;
}
}
`;

const BurgerWrapper = styled.div`
order: 2;
height: 100%;
& > div {
height: 100%;
}
@media (max-width: ${breakpoints.tablet}) {
height: auto;
}
`;
36 changes: 36 additions & 0 deletions packages/react-ui/src/BurgerNav/story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";

import { Section } from "../layout/Section";
import { Wrapper } from "../layout/Wrapper";
import { BurgerNav, BurgerNavButton, BurgerNavLink, BurgerNavCurrent } from ".";

export default {
component: BurgerNav,
title: "Components|BurgerNav",
};

export const base = () => (
<>
<Section>
<p>
The burger nav is only a burger on tablet / mobile. Otherwise it’s
nothing else than a div taking all the height of its container.
</p>
<p>
You should use the provided nav items, even if you could do without (but
that would be hard).
</p>
</Section>
<Section>
<Wrapper variant="dark" style={{ padding: 0, height: "10rem" }}>
<BurgerNav>
<BurgerNavButton>NavButton</BurgerNavButton>
<BurgerNavLink href="https://www.youtube.com/watch?v=8xTqP58o1iw&feature=youtu.be&t=20">
NavLink
</BurgerNavLink>
<BurgerNavCurrent>NavCurrent</BurgerNavCurrent>
</BurgerNav>
</Wrapper>
</Section>
</>
);
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/* eslint-disable import/namespace */
import { createGlobalStyle } from "styled-components";
import { theme } from "@socialgouv/react-ui";
import { theme } from "../";

const { box, breakpoints, spacings } = theme;

const BURGER_BREAKPOINT = `${theme.breakpoints.intTablet + 1}px`;
const BURGER_BREAKPOINT = `${breakpoints.intTablet + 1}px`;

export const BurgerStyles = createGlobalStyle`
/* Position and sizing of burger button */
Expand Down
29 changes: 29 additions & 0 deletions packages/react-ui/src/BurgerNav/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from "react";
import { render } from "@testing-library/react";
import { BurgerStyles } from "./styles";
import {
BurgerNav,
BurgerNavButton,
BurgerNavCurrent,
BurgerNavLink,
} from "./index";
import "jest-styled-components";
describe("BurgerStyles", () => {
it("generates styles", () => {
render(<BurgerStyles />);
const burgerStyles = document.head.getElementsByTagName("style");
expect(burgerStyles).toMatchSnapshot();
});
it("renders", () => {
const { container } = render(
<BurgerNav>
<BurgerNavButton>’Till it goes click</BurgerNavButton>
<BurgerNavLink href="https://www.youtube.com/watch?v=8xTqP58o1iw&feature=youtu.be&t=20">
’Till it goes click
</BurgerNavLink>
<BurgerNavCurrent>You said it man</BurgerNavCurrent>
</BurgerNav>
);
expect(container).toMatchSnapshot();
});
});
6 changes: 6 additions & 0 deletions packages/react-ui/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import * as icons from "./icons";
export { Accordion } from "./Accordion";
export { ArrowLink } from "./ArrowLink";
export { Badge } from "./Badge";
export {
BurgerNav,
BurgerNavButton,
BurgerNavLink,
BurgerNavCurrent,
} from "./BurgerNav";
export { Alert } from "./Alert";
export { Button } from "./Button";
export { GlobalStyles } from "./GlobalStyles";
Expand Down

0 comments on commit 086bc6d

Please sign in to comment.