diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 345092a..2a6b0c5 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -216,7 +216,7 @@ gulp.task('serve', ['clean', 'hbs', 'styles', 'lint', 'scripts'], () => { $.watch([ './src/hbs/partials/**/*.hbs', './src/hbs/layouts/*.hbs', - './src/hbs/*.html' + './src/hbs/*.hbs' ], () => { gulp.start('hbs'); }); diff --git a/package.json b/package.json index 534c6e4..e6f78fe 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "devDependencies": { "babel-core": "^5.5.6", "babel-eslint": "^6.1.2", + "babel-polyfill": "^6.26.0", "babel-preset-es2015": "^6.18.0", "babel-preset-stage-0": "^6.16.0", "babelify": "^7.3.0", diff --git a/src/hbs/data.json b/src/hbs/data.json index 6da3ccd..0f0bd52 100644 --- a/src/hbs/data.json +++ b/src/hbs/data.json @@ -1,4 +1,37 @@ { + "rootUrl": "/", + "header": { + "links": [ + { + "url": "#introduction", + "title": "introduction" + }, + { + "url": "#project", + "title": "project" + }, + { + "url": "#structure", + "title": "structure" + }, + { + "url": "#team", + "title": "team" + }, + { + "url": "#get-involved", + "title": "get involved" + }, + { + "url": "#events", + "title": "events" + }, + { + "url": "#blog", + "title": "blog" + } + ] + }, "footer": { "links": [ { diff --git a/src/hbs/layouts/base.hbs b/src/hbs/layouts/base.hbs index d9536e9..7bcf421 100644 --- a/src/hbs/layouts/base.hbs +++ b/src/hbs/layouts/base.hbs @@ -17,7 +17,7 @@
- {{> header}} + {{> components/header}}
{{{ block "main"}}} diff --git a/src/hbs/partials/components/burger-button.hbs b/src/hbs/partials/components/burger-button.hbs new file mode 100644 index 0000000..7d7da08 --- /dev/null +++ b/src/hbs/partials/components/burger-button.hbs @@ -0,0 +1,5 @@ + diff --git a/src/hbs/partials/components/header.hbs b/src/hbs/partials/components/header.hbs new file mode 100644 index 0000000..eb70c80 --- /dev/null +++ b/src/hbs/partials/components/header.hbs @@ -0,0 +1,11 @@ +
+
+ + + {{> components/nav parentRouteName=parentRouteName}} + + {{> components/burger-button class="header__btn"}} +
+
diff --git a/src/hbs/partials/components/nav.hbs b/src/hbs/partials/components/nav.hbs new file mode 100644 index 0000000..88a5f4d --- /dev/null +++ b/src/hbs/partials/components/nav.hbs @@ -0,0 +1,11 @@ + diff --git a/src/hbs/partials/header.hbs b/src/hbs/partials/header.hbs deleted file mode 100644 index 22f5bd0..0000000 --- a/src/hbs/partials/header.hbs +++ /dev/null @@ -1,3 +0,0 @@ -
- This is header -
diff --git a/src/scripts/main.js b/src/scripts/main.js index ef212d6..565896c 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1 +1,6 @@ -console.log('Hello World!'); // eslint-disable-line no-console +import 'babel-polyfill'; +import nav from './nav'; + +document.addEventListener('DOMContentLoaded', () => { + nav(); +}); diff --git a/src/scripts/nav.js b/src/scripts/nav.js new file mode 100644 index 0000000..845693e --- /dev/null +++ b/src/scripts/nav.js @@ -0,0 +1,40 @@ +const ACTIVE_CLASS = 'is-active'; +const ACTIVATED_CLASS = 'is-activated'; + +class Nav { + constructor() { + this.$burger = document.querySelector('.js-burger'); + this.$nav = document.querySelector('.js-nav'); + } + + init() { + this.addEvents(); + } + + addEvents() { + const { $burger, $nav } = this; + + $burger.addEventListener('click', (e) => { + e.stopPropagation(); + + $nav.classList.toggle(ACTIVE_CLASS); + $burger.classList.toggle(ACTIVE_CLASS); + $nav.classList.add(ACTIVATED_CLASS); + }); + + $nav.addEventListener('transitionend', ({ target }) => { + if (target.classList.contains('js-nav-list')) { + this.$nav.classList.remove(ACTIVATED_CLASS); + } + }); + } + +} + +export default function init() { + const $menu = document.querySelector('.js-nav'); + + if ($menu) { + new Nav().init(); + } +} diff --git a/src/styles/components/_burger-button.scss b/src/styles/components/_burger-button.scss new file mode 100644 index 0000000..fe598cc --- /dev/null +++ b/src/styles/components/_burger-button.scss @@ -0,0 +1,81 @@ +$burger-layer-width: 25px; +$burger-layer-height: 2px; +$burger-layer-spacing: 5px; +$burger-layer-color: $color-white; +$burger-layer-border-radius: 4px; + +.burger { + display: inline-block; + padding: 15px; + overflow: visible; + font: inherit; + color: inherit; + text-transform: none; + cursor: pointer; + background-color: transparent; + border: 0; + + &.is-active { + .burger-inner { + transform: rotate(45deg); + transition-delay: .14s; + transition-timing-function: cubic-bezier(.215, .61, .355, 1); + } + + .burger-inner::before { + top: 0; + opacity: 0; + transition: top .1s ease, opacity .1s .14s ease; + } + + .burger-inner::after { + bottom: 0; + transform: rotate(-90deg); + transition: bottom .1s ease, transform .1s .14s cubic-bezier(.215, .61, .355, 1); + } + } +} + +.burger-box { + position: relative; + display: block; + width: $burger-layer-width; + height: $burger-layer-height * 3 + $burger-layer-spacing * 2; +} + +.burger-inner { + top: 50%; + display: block; + margin-top: $burger-layer-height / -2; + transition-duration: .1s; + transition-timing-function: cubic-bezier(.55, .055, .675, .19); + + &, + &::before, + &::after { + position: absolute; + width: $burger-layer-width; + height: $burger-layer-height; + background-color: $burger-layer-color; + border-radius: $burger-layer-border-radius; + transition-duration: .15s; + transition-property: transform; + transition-timing-function: ease; + } + + &::before, + &::after { + display: block; + content: ''; + } + + &::before { + top: ($burger-layer-spacing + $burger-layer-height) * -1; + transition: top .1s .14s ease, opacity .1s ease; + } + + &::after { + bottom: ($burger-layer-spacing + $burger-layer-height) * -1; + transition: bottom .1s .14s ease, transform .1s cubic-bezier(.55, .055, .675, .19); + } +} diff --git a/src/styles/components/_header.scss b/src/styles/components/_header.scss new file mode 100644 index 0000000..e0da880 --- /dev/null +++ b/src/styles/components/_header.scss @@ -0,0 +1,67 @@ +$header-height--mobile: 70px; +$header-height--desktop: 84px; + +.header { + position: fixed; + top: 0; + z-index: 10; + width: 100%; + height: $header-height--mobile; + background-color: $color-gray; + + &::after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + background: $color-gray; + content: ''; + } + + &__container { + @include container; + + display: flex; + align-items: center; + height: 100%; + } + + &__btn { + z-index: 1; + margin-left: auto; + } +} + +.header-logo { + position: relative; + z-index: 10; + display: block; + + &__img { + display: block; + width: 90px; + height: auto; + } +} + +@media #{$screen-sm} { + .header { + height: $header-height--desktop; + } + + .header-logo__img { + width: 110px; + height: 37px; + } +} + +@media #{$screen-md} { + .header { + &::after, + &__btn { + display: none !important; + } + } +} diff --git a/src/styles/components/_nav.scss b/src/styles/components/_nav.scss new file mode 100644 index 0000000..3599014 --- /dev/null +++ b/src/styles/components/_nav.scss @@ -0,0 +1,126 @@ +.nav { + height: 100%; + margin-left: auto; + + &.is-active { + display: block; + background-color: $color-gray; + + .nav__list { + transform: translate3d(0, 0, 0); + } + } + + &.is-activated { + .nav__list { + transition: $duration * 2 transform $ease-in-out-quint; + } + } + + &__list { + @include list-reset; + + position: absolute; + top: 60px; + left: 0; + display: flex; + flex-flow: column; + justify-content: center; + width: 100%; + height: calc(100vh - 60px); + font-size: 14px; + background-color: $color-gray; + transform: translate3d(0, -100%, 0); + box-shadow: 0 0 15px 0 rgba($color-black, .1); + } + + &__item { + position: relative; + display: flex; + align-items: center; + justify-content: center; + padding: 0 20px; + letter-spacing: 2px; + } + + &__link { + position: relative; + display: flex; + align-items: center; + height: 100%; + padding: 2.5vh 0; + font-family: Gilroy, sans-serif; + font-weight: 600; + color: $color-white; + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; + } + + &__link::after { + position: absolute; + bottom: 0; + left: 50%; + width: calc(100% + 20px); + height: 3px; + background-color: $color-white; + content: ''; + transform: translate(-50%, 0) scaleX(0); + transition: transform $duration $ease-out-cubic; + } + + &__link:hover::after, + &__link.is-active::after { + transform: translate(-50%, 0) scaleX(1); + } + + &__item--sub-nav { + flex-direction: column; + cursor: pointer; + } +} + +@media #{$screen-sm} { + .nav { + &__list { + top: 78px; + height: auto; + padding: 60px 0; + } + + &__link { + padding: 10px 0; + } + } +} + +@media #{$screen-md} { + .nav { + &__list { + position: relative; + top: auto; + display: flex; + flex-direction: row; + height: 100%; + padding: 0; + opacity: 1; + transform: translate3d(0, 0, 0); + box-shadow: none; + transition: 0s all ease; + } + + &__item:last-child { + padding-right: 0; + } + + &__link::after { + width: calc(100% - 20px); + } + + &__link { + position: static; + flex-direction: row; + } + } +} diff --git a/src/styles/main.scss b/src/styles/main.scss index 882759c..5fe6023 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -12,6 +12,9 @@ @import './base/core'; @import './base/typography'; +@import './components/header'; +@import './components/burger-button'; +@import './components/nav'; @import './components/section'; @import './components/get-involved'; @import './components/hero'; diff --git a/src/styles/utils/_ui.scss b/src/styles/utils/_ui.scss index 138c33f..20e169a 100644 --- a/src/styles/utils/_ui.scss +++ b/src/styles/utils/_ui.scss @@ -26,6 +26,12 @@ list-style: none; } +@mixin list-reset { + margin: 0; + padding: 0; + list-style: none; +} + //======================= // Scaling //=======================