From 271e7dd0776b66df0b909403ce32c7029be20c27 Mon Sep 17 00:00:00 2001 From: Valeriy S Date: Wed, 23 Jan 2019 17:23:06 +0300 Subject: [PATCH] fix(client): simplify header component and styles, auto close menu --- client/package-lock.json | 22 ++++++- client/package.json | 2 +- client/src/components/Header/header.css | 78 +++++++++---------------- client/src/components/Header/index.js | 72 ++++++++++++----------- 4 files changed, 88 insertions(+), 86 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 4833345fe6..4d6d756dbb 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -15845,13 +15845,29 @@ } }, "react-media": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/react-media/-/react-media-1.8.0.tgz", - "integrity": "sha512-XcfqkDQj5/hmJod/kXUAZljJyMVkWrBWOkzwynAR8BXOGlbFLGBwezM0jQHtp2BrSymhf14/XrQrb3gGBnGK4g==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/react-media/-/react-media-1.9.2.tgz", + "integrity": "sha512-JUYECMcJIm0V61LSVKd1e+II4ZTYO0GuR7xtlvKETlmThZ416BqZjZdJ1uGqgmMAGFeJ3TG4TX/3Kg4qbR3EJw==", "requires": { + "@babel/runtime": "^7.2.0", "invariant": "^2.2.2", "json2mq": "^0.2.0", "prop-types": "^15.5.10" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz", + "integrity": "sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==", + "requires": { + "regenerator-runtime": "^0.12.0" + } + }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + } } }, "react-monaco-editor": { diff --git a/client/package.json b/client/package.json index 3fdd37d5f3..c46bb4248c 100644 --- a/client/package.json +++ b/client/package.json @@ -45,7 +45,7 @@ "react-freecodecamp-search": "^2.0.2", "react-ga": "^2.5.3", "react-helmet": "^5.2.0", - "react-media": "^1.8.0", + "react-media": "^1.9.2", "react-monaco-editor": "^0.18.0", "react-redux": "^5.0.7", "react-reflex": "^2.2.9", diff --git a/client/src/components/Header/header.css b/client/src/components/Header/header.css index 60bf19a786..300274214b 100644 --- a/client/src/components/Header/header.css +++ b/client/src/components/Header/header.css @@ -13,6 +13,7 @@ header { border: none; display: flex; justify-content: space-between; + align-items: center; padding: 0 15px; } @@ -31,13 +32,15 @@ header { display: flex; margin: 0; list-style: none; - justify-content: space-around; + justify-content: space-between; + align-items: center; + width: 290px; background-color: #006400; } #top-right-nav a, #top-right-nav img { - max-height: 40px; + max-height: 38px; } #top-right-nav a.btn-cta { @@ -51,12 +54,7 @@ header { } #top-right-nav li { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - height: 100%; - margin: 0 5px; + margin: 0; } #top-right-nav li, @@ -75,11 +73,6 @@ header { color: #006400; } -li.user-state-link { - position: relative; - bottom: 0; -} - li.user-state-link, li.user-state-link:hover, li.user-state-link:focus, @@ -95,7 +88,7 @@ li.user-state-link > a:focus { } .user-state-spinner { - height: 40px; + height: 38px; } .user-state-spinner > div { @@ -105,7 +98,7 @@ li.user-state-link > a:focus { /* Search bar */ .fcc_searchBar { flex-grow: 1; - padding: 2px 10px 0; + padding: 0 10px; } .fcc_searchBar .ais-SearchBox-form { @@ -154,25 +147,8 @@ li.user-state-link > a:focus { } } -.mobile-menu { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - background-color: #006400; - color: #fff; - margin-top: -38px; - height: 38px; - z-index: 300; -} - -.mobile-menu .menu-button { - margin: 0 20px 0 12px; - padding: 2px 14px; - border: 1px solid #fff; - border-radius: 3px; - cursor: pointer; - justify-self: flex-end; +#top-nav .menu-button { + display: none; } @media (max-width: 734px) { @@ -180,37 +156,41 @@ li.user-state-link > a:focus { padding: 0; } + #top-nav .menu-button { + display: block; + margin: 0 20px 0 12px; + padding: 2px 14px; + border: 1px solid #fff; + border-radius: 3px; + cursor: pointer; + color: #fff; + } + .opened #top-right-nav { - transform: translate(0, 38px); - padding-bottom: 10px; - opacity: 1; + top: 38px; } #top-right-nav { - transform: translate(0, -300px); + position: absolute; + top: -300px; flex-direction: column; - width: 100%; + width: 100vw; height: min-content; - min-height: 180px; - margin: 0; - opacity: 0; + min-height: 160px; + padding: 10px 0; } - #top-right-nav li:last-child { - margin-right: 0; - } - - .mobile-menu img { + #top-nav img { margin: 0 0 0 10px; } } @media (max-width: 420px) { - .mobile-menu img { + #top-nav img { margin: 0 0 0 5px; } - .mobile-menu .menu-button { + #top-nav .menu-button { margin: 0 10px 0 4px; } } diff --git a/client/src/components/Header/index.js b/client/src/components/Header/index.js index 8565b09a0d..9b95c3024e 100644 --- a/client/src/components/Header/index.js +++ b/client/src/components/Header/index.js @@ -1,4 +1,4 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { Link } from 'gatsby'; import Media from 'react-media'; @@ -15,33 +15,47 @@ class Header extends Component { this.state = { isMenuOpened: false }; - this.toggleClass = this.toggleClass.bind(this); + this.menuButtonRef = React.createRef(); } - toggleClass() { + componentDidMount() { + document.addEventListener('click', this.handleClickOutside); + } + + componentWillUnmount() { + document.removeEventListener('click', this.handleClickOutside); + } + + toggleClass = () => { this.setState({ isMenuOpened: !this.state.isMenuOpened }); - } + }; + + handleClickOutside = event => { + if ( + this.state.isMenuOpened && + !this.menuButtonRef.current.contains(event.target) + ) { + this.toggleClass(); + } + }; + + handleMediaChange = matches => { + if (!matches && this.state.isMenuOpened) { + this.toggleClass(); + } + }; render() { const { disableSettings } = this.props; return (
- - - {matches => - matches && ( -
- - - - {disableSettings ? null : } - - Menu - -
- ) - } -
); }