1
0
mirror of https://github.com/kremalicious/blog.git synced 2025-01-02 18:13:10 +01:00

port over main menu

This commit is contained in:
Matthias Kretschmann 2018-07-21 22:21:00 +02:00
parent 3fa552016e
commit 8bb892a07d
Signed by: m
GPG Key ID: 606EEEF3C479A91F
12 changed files with 345 additions and 73 deletions

View File

@ -65,7 +65,7 @@
"prettier": "^1.13.7",
"prettier-stylelint": "^0.4.2",
"stylelint": "^9.2.1",
"stylelint-config-css-modules": "^1.2.0",
"stylelint-config-css-modules": "^1.3.0",
"stylelint-config-recommended-scss": "^3.2.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-scss": "^3.2.0"

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import { StaticQuery, graphql } from 'gatsby'
import Container from './atoms/Container'
import Head from './molecules/Head'
import Header from './molecules/Header'
import Header from './organisms/Header'
import styles from './Layout.module.scss'
const Layout = ({ children, location }) => {

View File

@ -9,7 +9,6 @@
}
.site__content,
.header__content,
.footer__content {
padding: 0 $spacer;
width: 100%;
@ -33,19 +32,19 @@
0 -1px 4px rgba($brand-main, .2);
transform: translate3d(0, 0, 0);
.has-menu-open & {
transform: translate3d(0, 0, 0);
:global(.has-menu-open) & {
transform: translate3d(0, ($spacer * 8), 0);
}
@media (min-width: $screen-sm) {
@include transition;
margin-top: $spacer * 3;
margin-top: $spacer * 2.65;
position: relative;
z-index: 2;
.has-menu-open & {
transform: translate3d(0, ($spacer * 8), 0);
:global(.has-menu-open) & {
transform: translate3d(0, ($spacer * 5), 0);
}
}
}

View File

@ -0,0 +1,14 @@
import React from 'react'
import styles from './Hamburger.module.scss'
const Hamburger = props => (
<button type="button" className={styles.hamburgerButton} {...props}>
<span className={styles.hamburger}>
<span className={styles.hamburgerLine} />
<span className={styles.hamburgerLine} />
<span className={styles.hamburgerLine} />
</span>
</button>
)
export default Hamburger

View File

@ -0,0 +1,77 @@
@import 'variables';
@import 'mixins';
.hamburgerLine {
@include transition;
display: block;
position: absolute;
height: 3px;
width: 100%;
background: $text-color-light;
border-radius: 20px;
opacity: 1;
left: 0;
transform: rotate(0deg);
&:nth-child(1) {
top: 0;
transform-origin: left center;
}
&:nth-child(2) {
top: 5px;
transform-origin: left center;
}
&:nth-child(3) {
top: 10px;
transform-origin: left center;
}
// open state
:global(.has-menu-open) & {
&:nth-child(1) {
transform: rotate(45deg);
top: -1px;
}
&:nth-child(2) {
width: 0%;
opacity: 0;
}
&:nth-child(3) {
transform: rotate(-45deg);
top: 12px;
}
}
}
.hamburgerButton {
padding: .65rem .85rem;
text-align: center;
line-height: 1;
vertical-align: middle;
display: inline-block;
margin: 0;
&:hover,
&:focus {
outline: 0;
.hamburgerLine {
background: $brand-cyan;
}
}
}
.hamburger {
width: 18px;
height: 18px;
display: block;
position: relative;
transform: rotate(0deg);
cursor: pointer;
margin-top: 6px;
}

View File

@ -1,60 +0,0 @@
import React from 'react'
// import PropTypes from 'prop-types'
import { Link } from 'gatsby'
import styles from './Header.module.scss'
import layout from '../Layout.module.scss'
const Header = () => {
return (
<header role="banner" className={styles.header}>
<div className={layout.header__content}>
<h1 className={styles.title}>
<Link className={styles.header__logo} to="/">
kremalicious
</Link>
</h1>
{/* <nav role="navigation" className="nav-main grid__col">
<button type="button" className="menu-btn">
<div className="hamburger">
<span />
<span />
<span />
</div>
</button>
</nav> */}
{/* <section class="site-search">
<button type="button" class="search-btn">
<svg class="icon icon-search" role="img" aria-labelledby="title">
<title id="title">Search</title>
<use xlink:href="/assets/img/sprite.svg#magnifying-glass"></use>
</svg>
</button>
<div class="search-area">
<input type="search" id="search-input" class="form-control input-search search-field" placeholder="Search everything">
<button class="close search-close">&times;</button>
</div>
</section> */}
{/* <ul class="nav-popover grid grid--half grid-medium--third">
<li class="grid__col">
<a class="nav-link" href="/{{ category | first }}/">
{{ category | first }}
</a>
</li>
</ul> */}
{/* <div id="search-popover" class="search-popover hide">
<div class="container">
<nav id="search-results" class="search-results"></nav>
</div>
</div> */}
</div>
</header>
)
}
Header.propTypes = {}
export default Header

View File

@ -0,0 +1,79 @@
import React, { PureComponent, Fragment } from 'react'
import Helmet from 'react-helmet'
import { Link, StaticQuery, graphql } from 'gatsby'
import Hamburger from '../atoms/Hamburger'
import styles from './Menu.module.scss'
class Menu extends PureComponent {
constructor() {
super()
this.state = {
menuOpen: false
}
}
toggleMenu = () => {
this.setState(prevState => ({
menuOpen: !prevState.menuOpen
}))
}
isMenuOpen = () => this.state.menuOpen === true
render() {
return (
<Fragment>
<Helmet>
<body className={this.isMenuOpen() ? 'has-menu-open' : null} />
</Helmet>
<StaticQuery
query={graphql`
query {
allMarkdownRemark(
sort: { fields: [fields___date], order: DESC }
) {
edges {
node {
frontmatter {
category
}
}
}
}
}
`}
render={data => {
const posts = data.allMarkdownRemark.edges
const categorySet = new Set()
posts.forEach(post => {
if (post.node.frontmatter.category) {
categorySet.add(post.node.frontmatter.category)
}
})
const categoryList = Array.from(categorySet)
const Categories = categoryList.map(category => (
<li key={category}>
<Link onClick={this.toggleMenu} to={`/${category}/`}>
{category}
</Link>
</li>
))
return (
<Fragment>
<Hamburger onClick={this.toggleMenu} />
<ul className={styles.menu}>{Categories}</ul>
</Fragment>
)
}}
/>
</Fragment>
)
}
}
export default Menu

View File

@ -0,0 +1,42 @@
@import 'variables';
@import 'mixins';
.menu {
position: absolute;
top: calc(100% + #{$spacer});
left: 0;
display: flex;
flex-wrap: wrap;
width: 100%;
li {
list-style: none;
flex: 0 0 100%;
@media (min-width: $screen-sm) {
flex-basis: 33%;
}
&::before {
display: none;
}
}
opacity: 0;
:global(.has-menu-open) & {
opacity: 1;
}
a {
color: $text-color;
line-height: 1;
text-transform: uppercase;
margin: 0;
font-size: $font-size-small;
text-shadow: 0 1px 0 rgba(#fff, .5);
padding: $padding-base-horizontal;
display: block;
text-align: center;
}
}

View File

@ -0,0 +1,58 @@
import React, { PureComponent } from 'react'
import { Link } from 'gatsby'
import Container from '../atoms/Container'
import Menu from '../molecules/Menu'
import Search from '../svg/MagnifyingGlass'
import styles from './Header.module.scss'
class Header extends PureComponent {
render() {
return (
<header role="banner" className={styles.header}>
<Container>
<div className={styles.header__content}>
<h1 className={styles.title}>
<Link className={styles.header__logo} to="/">
kremalicious
</Link>
</h1>
<nav role="navigation" className={styles.nav}>
<button type="button" className={styles.search}>
<Search />
</button>
<Menu />
</nav>
{/* <section class="site-search">
<div class="search-area">
<input type="search" id="search-input" class="form-control input-search search-field" placeholder="Search everything">
<button class="close search-close">&times;</button>
</div>
</section> */}
{/* <ul class="nav-popover grid grid--half grid-medium--third">
<li class="grid__col">
<a class="nav-link" href="/{{ category | first }}/">
{{ category | first }}
</a>
</li>
</ul> */}
{/* <div id="search-popover" class="search-popover hide">
<div class="container">
<nav id="search-results" class="search-results"></nav>
</div>
</div> */}
</div>
</Container>
</header>
)
}
}
Header.propTypes = {}
export default Header

View File

@ -6,8 +6,6 @@
margin-bottom: ($spacer/2);
@media (min-width: $screen-sm) {
margin-top: $spacer;
margin-bottom: $spacer;
position: fixed;
width: 100%;
z-index: 1;
@ -17,6 +15,19 @@
}
}
.header__content {
@include breakoutviewport;
position: relative;
display: flex;
justify-content: space-between;
padding: 0 $spacer;
@media (min-width: $screen-md) {
padding: 0;
}
}
// Logo
/////////////////////////////////////
@ -44,7 +55,8 @@
}
.title {
margin: 0;
margin-top: $spacer / 5;
margin-bottom: 0;
// display toned down logo
// by default
@extend .logo;
@ -71,3 +83,39 @@
box-shadow: none;
}
}
.nav {
display: inline-block;
}
.search {
padding: .65rem .85rem;
text-align: center;
line-height: 1;
vertical-align: middle;
display: inline-block;
margin-right: $spacer / 4;
&:focus {
outline: 0;
}
svg {
fill: $text-color-light;
width: 21px;
height: 21px;
}
&:hover,
&:focus {
svg {
fill: $brand-cyan;
}
}
&:active {
svg {
fill: darken($brand-cyan, 30%);
}
}
}

View File

@ -61,6 +61,20 @@ textarea {
line-height: inherit;
}
// Reset default button element
button {
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
&:active {
transition: none;
text-shadow: none;
}
}
// Headings
/////////////////////////////////////

View File

@ -2,7 +2,8 @@
@import 'mixins';
.archiveTitle {
font-size: $font-size-h3;
@include heading-band();
font-size: $font-size-h3;
margin-top: 0;
}