diff --git a/package.json b/package.json index 7abff691..60ddf8d2 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dependencies": { "@fortawesome/fontawesome-free": "^5.15.3", "bootstrap": "^4.6.0", + "headroom.js": "^0.12.0", "instant.page": "^5.1.0", "jquery": "^3.6.0", "medium-zoom": "^1.0.6" diff --git a/wowchemy/assets/js/_vendor/headroom.min.js b/wowchemy/assets/js/_vendor/headroom.min.js new file mode 100644 index 00000000..58836a2d --- /dev/null +++ b/wowchemy/assets/js/_vendor/headroom.min.js @@ -0,0 +1,7 @@ +/*! + * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it + * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js + * License: MIT + */ + +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s}); \ No newline at end of file diff --git a/wowchemy/assets/js/wowchemy-headroom.js b/wowchemy/assets/js/wowchemy-headroom.js new file mode 100644 index 00000000..2fb16147 --- /dev/null +++ b/wowchemy/assets/js/wowchemy-headroom.js @@ -0,0 +1,22 @@ +/************************************************* + * Wowchemy + * https://github.com/wowchemy/wowchemy-hugo-themes + * + * Wowchemy Headroom + **************************************************/ + +import Headroom from './_vendor/headroom.min.js'; + +let pageData = JSON.parse(document.getElementById('page-data').textContent); +console.debug(`Use headroom on this page? ${pageData['use_headroom']}`); + +if (pageData['use_headroom'] === true) { + document.addEventListener('DOMContentLoaded', function () { + // Grab header element + let myElement = document.querySelector('header'); + // Construct an instance of Headroom, passing the header + let headroom = new Headroom(myElement); + // Initialise Headroom + headroom.init(); + }); +} diff --git a/wowchemy/assets/scss/wowchemy/components/_nav.scss b/wowchemy/assets/scss/wowchemy/components/_nav.scss index a85f7552..408d7ec6 100644 --- a/wowchemy/assets/scss/wowchemy/components/_nav.scss +++ b/wowchemy/assets/scss/wowchemy/components/_nav.scss @@ -2,6 +2,25 @@ * Navigation bar **************************************************/ +.headroom { + will-change: transform; + transition: transform 200ms linear; +} +.headroom--pinned { + transform: translateY(0%); +} +.headroom--unpinned { + transform: translateY(-100%); +} + +.header--fixed { + position: fixed; + z-index: 10; // previously, 1030 + right: 0; + left: 0; + top: 0; +} + .dropdown-menu { background-color: $sta-menu-primary !important; color: $sta-menu-text !important; @@ -13,11 +32,6 @@ background: $sta-menu-primary; box-shadow: 0 0.125rem 0.25rem 0 rgba(0, 0, 0, 0.11); font-size: #{$sta-font-size-small}px; - position: fixed; - top: 0; - right: 0; - left: 0; - z-index: 1030; // Remove Bootstrap's navbar v-padding and assign v-padding to logo separately to maximise logo size. // Otherwise, Bootstrap's navbar v-padding causes issue with logo fitting within fixed 50px height bar in md-lg sizes. diff --git a/wowchemy/layouts/index.json b/wowchemy/layouts/index.json index ef9d379d..d4cfc210 100644 --- a/wowchemy/layouts/index.json +++ b/wowchemy/layouts/index.json @@ -53,7 +53,7 @@ {{- end -}} {{- /* Add page to index. */ -}} - {{- $index = $index | append (dict "objectID" .File.UniqueID "date" .Date.UTC.Unix "publishdate" .PublishDate "lastmod" .Lastmod.UTC.Unix "expirydate" .ExpiryDate.UTC.Unix "lang" .Lang "permalink" $permalink "relpermalink" $rel_permalink "title" $title "summary" (plainify $desc) "content" .Plain "authors" $authors "kind" .Kind "type" .Type "section" .Section "tags" .Params.Tags "categories" .Params.Categories) -}} + {{- $index = $index | append (dict "objectID" .File.UniqueID "date" .Date.UTC.Unix "publishdate" .PublishDate "lastmod" .Lastmod.UTC.Unix "expirydate" .ExpiryDate.UTC.Unix "lang" .Lang "permalink" $permalink "relpermalink" $rel_permalink "title" $title "summary" (plainify $desc | htmlUnescape) "content" (.Plain | htmlUnescape | truncate 5000) "authors" $authors "kind" .Kind "type" .Type "section" .Section "tags" .Params.Tags "categories" .Params.Categories) -}} {{- end -}} {{- end -}} diff --git a/wowchemy/layouts/partials/components/breadcrumb.html b/wowchemy/layouts/partials/components/breadcrumb.html index 13fdcc30..82b1b005 100644 --- a/wowchemy/layouts/partials/components/breadcrumb.html +++ b/wowchemy/layouts/partials/components/breadcrumb.html @@ -1,10 +1,25 @@ {{ if not .IsHome }} {{ end }} + +{{ define "breadcrumb" }} + {{ with .Parent }} + {{ template "breadcrumb" . }} + + {{ end }} +{{ end }} diff --git a/wowchemy/layouts/partials/components/breadcrumb_child.html b/wowchemy/layouts/partials/components/breadcrumb_child.html deleted file mode 100644 index 742057c4..00000000 --- a/wowchemy/layouts/partials/components/breadcrumb_child.html +++ /dev/null @@ -1,12 +0,0 @@ -{{ with .Parent }} - {{ partial "components/breadcrumb_child" . }} - -{{ end }} diff --git a/wowchemy/layouts/partials/navbar.html b/wowchemy/layouts/partials/navbar.html index 453f9bc8..ed57353b 100644 --- a/wowchemy/layouts/partials/navbar.html +++ b/wowchemy/layouts/partials/navbar.html @@ -13,12 +13,34 @@ {{ $logo = (partial "functions/get_logo" (dict "constraint" "max_height" "size" 70)) }} {{ end }} - + {{end}}{{/* End show navbar. */}} diff --git a/wowchemy/layouts/partials/site_js.html b/wowchemy/layouts/partials/site_js.html index 7c3bfa01..8a06f2b8 100644 --- a/wowchemy/layouts/partials/site_js.html +++ b/wowchemy/layouts/partials/site_js.html @@ -131,6 +131,20 @@ {{ end }} + {{/* Page Data */}} + {{ $default_headroom := not (.IsHome | or (eq .Type "book")) }} + {{ $use_headroom := cond (isset $.Params "header.on_scroll") (eq $.Params.header.on_scroll "disappear") (default $default_headroom) }} + {{ printf "" (dict "use_headroom" $use_headroom | jsonify) | safeHTML}} + + {{/* Headroom */}} + {{ if $use_headroom }} + {{ $headroom := resources.Get "js/wowchemy-headroom.js" | js.Build (dict "format" "esm" "minify" true) }} + {{- if hugo.IsProduction -}} + {{- $headroom = $headroom | fingerprint "md5" -}} + {{- end -}} + + {{- end -}} + {{ $js_license := printf "/*! Wowchemy v%s | https://wowchemy.com/ */\n" site.Data.wowchemy.version }} {{ $js_license := $js_license | printf "%s/*! Copyright 2016-present George Cushen (https://georgecushen.com/) */\n" }} {{ $js_license := $js_license | printf "%s/*! License: https://github.com/wowchemy/wowchemy-hugo-themes/blob/main/LICENSE.md */\n" }} diff --git a/yarn.lock b/yarn.lock index 0486b97e..2791280b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -962,6 +962,11 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +headroom.js@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/headroom.js/-/headroom.js-0.12.0.tgz#e09b466b18d22457f2023fb946ff620e47a5c205" + integrity sha512-iXnAafUm3FdzfJ91uixLws2hkKI1jC8bAKK/pt7XYr8Ie1jO7xbK48Ycpl9tUPyBgkzuj1p/PhJS0fy4E/5anA== + hosted-git-info@^2.1.4: version "2.8.8" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"