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": {
|
"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": {
|
||||||
|
@ -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",
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user