From 086bc6dc529b3f6c5cd7c3be174b6c92a10e7468 Mon Sep 17 00:00:00 2001 From: ManuC Date: Tue, 7 Apr 2020 16:48:06 +0200 Subject: [PATCH] feat(ui): add burger nav to UI --- .../code-du-travail-frontend/package.json | 1 - .../src/layout/Header/BurgerNav.js | 146 ++++-------------- .../Header/__tests__/BurgerStyles.test.js | 11 -- packages/react-ui/package.json | 1 + packages/react-ui/rollup.config.js | 8 +- packages/react-ui/src/BurgerNav/index.js | 100 ++++++++++++ packages/react-ui/src/BurgerNav/story.js | 36 +++++ .../src/BurgerNav/styles.js} | 5 +- packages/react-ui/src/BurgerNav/test.js | 29 ++++ packages/react-ui/src/index.js | 6 + 10 files changed, 213 insertions(+), 130 deletions(-) delete mode 100644 packages/code-du-travail-frontend/src/layout/Header/__tests__/BurgerStyles.test.js create mode 100644 packages/react-ui/src/BurgerNav/index.js create mode 100644 packages/react-ui/src/BurgerNav/story.js rename packages/{code-du-travail-frontend/src/layout/Header/BurgerStyles.js => react-ui/src/BurgerNav/styles.js} (95%) create mode 100644 packages/react-ui/src/BurgerNav/test.js diff --git a/packages/code-du-travail-frontend/package.json b/packages/code-du-travail-frontend/package.json index 1fbb57c9cff..4f8c1fa6623 100644 --- a/packages/code-du-travail-frontend/package.json +++ b/packages/code-du-travail-frontend/package.json @@ -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", diff --git a/packages/code-du-travail-frontend/src/layout/Header/BurgerNav.js b/packages/code-du-travail-frontend/src/layout/Header/BurgerNav.js index 69feaf34315..00015d3cb55 100644 --- a/packages/code-du-travail-frontend/src/layout/Header/BurgerNav.js +++ b/packages/code-du-travail-frontend/src/layout/Header/BurgerNav.js @@ -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 }) => ( - - {children} - -); - -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 ( - - - } - customCrossIcon={} - > - - {(openModal) => ( - - Accessibilité - - )} - - {currentPage !== "tools" ? ( - - Boîte à outils - - ) : ( - Boîte à outils +export const BurgerNav = ({ currentPage }) => ( + + <> + + {(openModal) => ( + Accessibilité )} - {currentPage !== "themes" ? ( - - Thèmes - - ) : ( - Thèmes - )} - - - ); -}; - -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; - } -`; + + {currentPage !== "tools" ? ( + + Boîte à outils + + ) : ( + Boîte à outils + )} + {currentPage !== "themes" ? ( + + Thèmes + + ) : ( + Thèmes + )} + + +); diff --git a/packages/code-du-travail-frontend/src/layout/Header/__tests__/BurgerStyles.test.js b/packages/code-du-travail-frontend/src/layout/Header/__tests__/BurgerStyles.test.js deleted file mode 100644 index ad55e66d82a..00000000000 --- a/packages/code-du-travail-frontend/src/layout/Header/__tests__/BurgerStyles.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react"; -import { render } from "@testing-library/react"; -import { BurgerStyles } from "../BurgerStyles"; -import "jest-styled-components"; -describe("BurgerStyles", () => { - it("generates styles", () => { - render(); - const burgerStyles = document.head.getElementsByTagName("style"); - expect(burgerStyles).toMatchSnapshot(); - }); -}); diff --git a/packages/react-ui/package.json b/packages/react-ui/package.json index a42a6432b85..46225d0c4a2 100644 --- a/packages/react-ui/package.json +++ b/packages/react-ui/package.json @@ -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", diff --git a/packages/react-ui/rollup.config.js b/packages/react-ui/rollup.config.js index be1a18343fb..482c98ad021 100644 --- a/packages/react-ui/rollup.config.js +++ b/packages/react-ui/rollup.config.js @@ -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({ diff --git a/packages/react-ui/src/BurgerNav/index.js b/packages/react-ui/src/BurgerNav/index.js new file mode 100644 index 00000000000..194cc34a237 --- /dev/null +++ b/packages/react-ui/src/BurgerNav/index.js @@ -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 ( + + + } + customCrossIcon={} + > + {children} + + + ); +}; + +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; + } +`; diff --git a/packages/react-ui/src/BurgerNav/story.js b/packages/react-ui/src/BurgerNav/story.js new file mode 100644 index 00000000000..45ef14030e6 --- /dev/null +++ b/packages/react-ui/src/BurgerNav/story.js @@ -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 = () => ( + <> +
+

+ 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. +

+

+ You should use the provided nav items, even if you could do without (but + that would be hard). +

+
+
+ + + NavButton + + NavLink + + NavCurrent + + +
+ +); diff --git a/packages/code-du-travail-frontend/src/layout/Header/BurgerStyles.js b/packages/react-ui/src/BurgerNav/styles.js similarity index 95% rename from packages/code-du-travail-frontend/src/layout/Header/BurgerStyles.js rename to packages/react-ui/src/BurgerNav/styles.js index 6a73155aaea..b0b1d14db32 100644 --- a/packages/code-du-travail-frontend/src/layout/Header/BurgerStyles.js +++ b/packages/react-ui/src/BurgerNav/styles.js @@ -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 */ diff --git a/packages/react-ui/src/BurgerNav/test.js b/packages/react-ui/src/BurgerNav/test.js new file mode 100644 index 00000000000..2b0502395b4 --- /dev/null +++ b/packages/react-ui/src/BurgerNav/test.js @@ -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(); + const burgerStyles = document.head.getElementsByTagName("style"); + expect(burgerStyles).toMatchSnapshot(); + }); + it("renders", () => { + const { container } = render( + + ’Till it goes click + + ’Till it goes click + + You said it man + + ); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-ui/src/index.js b/packages/react-ui/src/index.js index bd42fca1030..62f7e5f7250 100644 --- a/packages/react-ui/src/index.js +++ b/packages/react-ui/src/index.js @@ -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";