fix(client): simplify header component and styles, auto close menu
This commit is contained in:
22
client/package-lock.json
generated
22
client/package-lock.json
generated
@ -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": {
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 (
|
||||
<header className={this.state.isMenuOpened ? 'opened' : null}>
|
||||
<nav id='top-nav'>
|
||||
<Media query='(min-width: 735px)'>
|
||||
{matches =>
|
||||
matches && (
|
||||
<Fragment>
|
||||
<Link className='home-link' to='/'>
|
||||
<NavLogo />
|
||||
</Link>
|
||||
{disableSettings ? null : <FCCSearch />}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
</Media>
|
||||
|
||||
<ul id='top-right-nav'>
|
||||
<li>
|
||||
<Link to='/learn'>Curriculum</Link>
|
||||
@ -60,23 +74,15 @@ class Header extends Component {
|
||||
<UserState disableSettings={disableSettings} />
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<Media defaultMatches={false} query='(max-width: 734px)'>
|
||||
{matches =>
|
||||
matches && (
|
||||
<div className='mobile-menu'>
|
||||
<Link className='home-link' to='/'>
|
||||
<NavLogo />
|
||||
</Link>
|
||||
{disableSettings ? null : <FCCSearch />}
|
||||
<span className='menu-button' onClick={this.toggleClass}>
|
||||
<span
|
||||
className='menu-button'
|
||||
onClick={this.toggleClass}
|
||||
ref={this.menuButtonRef}
|
||||
>
|
||||
Menu
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</Media>
|
||||
<Media onChange={this.handleMediaChange} query='(max-width: 734px)' />
|
||||
</nav>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user