fix(client): simplify header component and styles, auto close menu

This commit is contained in:
Valeriy S
2019-01-23 17:23:06 +03:00
committed by Stuart Taylor
parent 4987f986a9
commit 271e7dd077
4 changed files with 88 additions and 86 deletions

View File

@ -15845,13 +15845,29 @@
} }
}, },
"react-media": { "react-media": {
"version": "1.8.0", "version": "1.9.2",
"resolved": "https://registry.npmjs.org/react-media/-/react-media-1.8.0.tgz", "resolved": "https://registry.npmjs.org/react-media/-/react-media-1.9.2.tgz",
"integrity": "sha512-XcfqkDQj5/hmJod/kXUAZljJyMVkWrBWOkzwynAR8BXOGlbFLGBwezM0jQHtp2BrSymhf14/XrQrb3gGBnGK4g==", "integrity": "sha512-JUYECMcJIm0V61LSVKd1e+II4ZTYO0GuR7xtlvKETlmThZ416BqZjZdJ1uGqgmMAGFeJ3TG4TX/3Kg4qbR3EJw==",
"requires": { "requires": {
"@babel/runtime": "^7.2.0",
"invariant": "^2.2.2", "invariant": "^2.2.2",
"json2mq": "^0.2.0", "json2mq": "^0.2.0",
"prop-types": "^15.5.10" "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": { "react-monaco-editor": {

View File

@ -45,7 +45,7 @@
"react-freecodecamp-search": "^2.0.2", "react-freecodecamp-search": "^2.0.2",
"react-ga": "^2.5.3", "react-ga": "^2.5.3",
"react-helmet": "^5.2.0", "react-helmet": "^5.2.0",
"react-media": "^1.8.0", "react-media": "^1.9.2",
"react-monaco-editor": "^0.18.0", "react-monaco-editor": "^0.18.0",
"react-redux": "^5.0.7", "react-redux": "^5.0.7",
"react-reflex": "^2.2.9", "react-reflex": "^2.2.9",

View File

@ -13,6 +13,7 @@ header {
border: none; border: none;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
padding: 0 15px; padding: 0 15px;
} }
@ -31,13 +32,15 @@ header {
display: flex; display: flex;
margin: 0; margin: 0;
list-style: none; list-style: none;
justify-content: space-around; justify-content: space-between;
align-items: center;
width: 290px;
background-color: #006400; background-color: #006400;
} }
#top-right-nav a, #top-right-nav a,
#top-right-nav img { #top-right-nav img {
max-height: 40px; max-height: 38px;
} }
#top-right-nav a.btn-cta { #top-right-nav a.btn-cta {
@ -51,12 +54,7 @@ header {
} }
#top-right-nav li { #top-right-nav li {
display: flex; margin: 0;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
margin: 0 5px;
} }
#top-right-nav li, #top-right-nav li,
@ -75,11 +73,6 @@ header {
color: #006400; color: #006400;
} }
li.user-state-link {
position: relative;
bottom: 0;
}
li.user-state-link, li.user-state-link,
li.user-state-link:hover, li.user-state-link:hover,
li.user-state-link:focus, li.user-state-link:focus,
@ -95,7 +88,7 @@ li.user-state-link > a:focus {
} }
.user-state-spinner { .user-state-spinner {
height: 40px; height: 38px;
} }
.user-state-spinner > div { .user-state-spinner > div {
@ -105,7 +98,7 @@ li.user-state-link > a:focus {
/* Search bar */ /* Search bar */
.fcc_searchBar { .fcc_searchBar {
flex-grow: 1; flex-grow: 1;
padding: 2px 10px 0; padding: 0 10px;
} }
.fcc_searchBar .ais-SearchBox-form { .fcc_searchBar .ais-SearchBox-form {
@ -154,25 +147,8 @@ li.user-state-link > a:focus {
} }
} }
.mobile-menu { #top-nav .menu-button {
display: flex; display: none;
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;
} }
@media (max-width: 734px) { @media (max-width: 734px) {
@ -180,37 +156,41 @@ li.user-state-link > a:focus {
padding: 0; 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 { .opened #top-right-nav {
transform: translate(0, 38px); top: 38px;
padding-bottom: 10px;
opacity: 1;
} }
#top-right-nav { #top-right-nav {
transform: translate(0, -300px); position: absolute;
top: -300px;
flex-direction: column; flex-direction: column;
width: 100%; width: 100vw;
height: min-content; height: min-content;
min-height: 180px; min-height: 160px;
margin: 0; padding: 10px 0;
opacity: 0;
} }
#top-right-nav li:last-child { #top-nav img {
margin-right: 0;
}
.mobile-menu img {
margin: 0 0 0 10px; margin: 0 0 0 10px;
} }
} }
@media (max-width: 420px) { @media (max-width: 420px) {
.mobile-menu img { #top-nav img {
margin: 0 0 0 5px; margin: 0 0 0 5px;
} }
.mobile-menu .menu-button { #top-nav .menu-button {
margin: 0 10px 0 4px; margin: 0 10px 0 4px;
} }
} }

View File

@ -1,4 +1,4 @@
import React, { Component, Fragment } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Link } from 'gatsby'; import { Link } from 'gatsby';
import Media from 'react-media'; import Media from 'react-media';
@ -15,33 +15,47 @@ class Header extends Component {
this.state = { this.state = {
isMenuOpened: false 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({ this.setState({
isMenuOpened: !this.state.isMenuOpened 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() { render() {
const { disableSettings } = this.props; const { disableSettings } = this.props;
return ( return (
<header className={this.state.isMenuOpened ? 'opened' : null}> <header className={this.state.isMenuOpened ? 'opened' : null}>
<nav id='top-nav'> <nav id='top-nav'>
<Media query='(min-width: 735px)'>
{matches =>
matches && (
<Fragment>
<Link className='home-link' to='/'> <Link className='home-link' to='/'>
<NavLogo /> <NavLogo />
</Link> </Link>
{disableSettings ? null : <FCCSearch />} {disableSettings ? null : <FCCSearch />}
</Fragment>
)
}
</Media>
<ul id='top-right-nav'> <ul id='top-right-nav'>
<li> <li>
<Link to='/learn'>Curriculum</Link> <Link to='/learn'>Curriculum</Link>
@ -60,23 +74,15 @@ class Header extends Component {
<UserState disableSettings={disableSettings} /> <UserState disableSettings={disableSettings} />
</li> </li>
</ul> </ul>
</nav> <span
className='menu-button'
<Media defaultMatches={false} query='(max-width: 734px)'> onClick={this.toggleClass}
{matches => ref={this.menuButtonRef}
matches && ( >
<div className='mobile-menu'>
<Link className='home-link' to='/'>
<NavLogo />
</Link>
{disableSettings ? null : <FCCSearch />}
<span className='menu-button' onClick={this.toggleClass}>
Menu Menu
</span> </span>
</div> <Media onChange={this.handleMediaChange} query='(max-width: 734px)' />
) </nav>
}
</Media>
</header> </header>
); );
} }