-
-
Notifications
You must be signed in to change notification settings - Fork 600
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
755eb3f
commit 5187b73
Showing
70 changed files
with
4,336 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
import $ from 'jquery' | ||
import slick from 'slick-carousel' | ||
import tippy from 'tippy.js' | ||
import AOS from 'aos' | ||
import GhostContentAPI from '@tryghost/content-api' | ||
import Fuse from 'fuse.js' | ||
|
||
$(document).ready(() => { | ||
const $body = $('body') | ||
const $header = $('.js-header') | ||
const $openMenu = $('.js-open-menu') | ||
const $closeMenu = $('.js-close-menu') | ||
const $menu = $('.js-menu') | ||
const $toggleSubmenu = $('.js-toggle-submenu') | ||
const $submenuOption = $('.js-submenu-option')[0] | ||
const $submenu = $('.js-submenu') | ||
const $recentArticles = $('.js-recent-articles') | ||
const $openSearch = $('.js-open-search') | ||
const $closeSearch = $('.js-close-search') | ||
const $search = $('.js-search') | ||
const $inputSearch = $('.js-input-search') | ||
const $searchResults = $('.js-search-results') | ||
|
||
const headerHeight = $header.outerHeight() | ||
|
||
let fuse = null | ||
let lastScrollY = window.pageYOffset | ||
let ticking = false | ||
let submenuIsOpen = false | ||
|
||
function onScroll() { | ||
requestTick() | ||
} | ||
|
||
function requestTick() { | ||
if (!ticking) { | ||
requestAnimationFrame(toggleHeader) | ||
} | ||
|
||
ticking = true | ||
} | ||
|
||
function toggleHeader() { | ||
const scrollTop = window.pageYOffset | ||
|
||
if (scrollTop >= headerHeight) { | ||
$header.addClass('fixed') | ||
|
||
if (submenuIsOpen) { | ||
$header.addClass('fixed-active') | ||
} | ||
|
||
if (scrollTop >= lastScrollY) { | ||
if (!submenuIsOpen) { | ||
$header.removeClass('fixed-active') | ||
} | ||
} else { | ||
$header.addClass('fixed-active') | ||
} | ||
} else { | ||
if (!submenuIsOpen) { | ||
$header.removeClass('fixed-active') | ||
} | ||
|
||
$header.removeClass('fixed') | ||
} | ||
|
||
lastScrollY = scrollTop | ||
ticking = false | ||
} | ||
|
||
function showSubmenu() { | ||
$header.addClass('submenu-is-active') | ||
$toggleSubmenu.addClass('active') | ||
$submenu.removeClass('closed').addClass('opened') | ||
} | ||
|
||
function hideSubmenu() { | ||
$header.removeClass('submenu-is-active') | ||
$toggleSubmenu.removeClass('active') | ||
$submenu.removeClass('opened').addClass('closed') | ||
} | ||
|
||
function toggleScrollVertical() { | ||
$body.toggleClass('no-scroll-y') | ||
} | ||
|
||
function trySearchFeature() { | ||
if (typeof ghostSearchApiKey !== 'undefined') { | ||
getAllPosts(ghostHost, ghostSearchApiKey) | ||
} else { | ||
$openSearch.remove() | ||
$closeSearch.remove() | ||
$search.remove() | ||
} | ||
} | ||
|
||
function getAllPosts(host, key) { | ||
const api = new GhostContentAPI({ | ||
host, | ||
key, | ||
version: 'v2' | ||
}) | ||
const allPosts = [] | ||
const fuseOptions = { | ||
shouldSort: true, | ||
threshold: 0, | ||
location: 0, | ||
distance: 100, | ||
tokenize: true, | ||
matchAllTokens: true, | ||
maxPatternLength: 32, | ||
minMatchCharLength: 1, | ||
keys: ['title'] | ||
} | ||
|
||
api.posts.browse({ | ||
limit: 'all', | ||
fields: 'id, title, url, published_at' | ||
}) | ||
.then((posts) => { | ||
for (var i = 0, len = posts.length; i < len; i++) { | ||
allPosts.push(posts[i]) | ||
} | ||
|
||
fuse = new Fuse(allPosts, fuseOptions) | ||
}) | ||
.catch((err) => { | ||
console.log(err) | ||
}) | ||
} | ||
|
||
function formatDate(date) { | ||
if (date) { | ||
return new Date(date).toLocaleDateString( | ||
document.documentElement.lang, | ||
{ | ||
year: 'numeric', | ||
month: 'long', | ||
day: 'numeric' | ||
} | ||
) | ||
} | ||
|
||
return '' | ||
} | ||
|
||
$openMenu.click(() => { | ||
$menu.addClass('opened') | ||
toggleScrollVertical() | ||
}) | ||
|
||
$closeMenu.click(() => { | ||
$menu.removeClass('opened') | ||
toggleScrollVertical() | ||
}) | ||
|
||
$toggleSubmenu.click(() => { | ||
submenuIsOpen = !submenuIsOpen | ||
|
||
if (submenuIsOpen) { | ||
showSubmenu() | ||
} else { | ||
hideSubmenu() | ||
} | ||
}) | ||
|
||
$openSearch.click(() => { | ||
$search.addClass('opened') | ||
setTimeout(() => { | ||
$inputSearch.focus() | ||
}, 400); | ||
toggleScrollVertical() | ||
}) | ||
|
||
$closeSearch.click(() => { | ||
$inputSearch.blur() | ||
$search.removeClass('opened') | ||
toggleScrollVertical() | ||
}) | ||
|
||
$inputSearch.keyup(() => { | ||
if ($inputSearch.val().length > 0 && fuse) { | ||
const results = fuse.search($inputSearch.val()) | ||
|
||
if (results.length > 0) { | ||
for (var i = 0, len = results.length; i < len; i++) { | ||
$searchResults.html(` | ||
<article class="m-result">\ | ||
<a href="${results[i].url}" class="m-result__link">\ | ||
<h3 class="m-result__title">${results[i].title}</h3>\ | ||
<span class="m-result__date">${formatDate(results[i].published_at)}</span>\ | ||
</a>\ | ||
</article> | ||
`) | ||
} | ||
} else { | ||
$searchResults.html('<p class="m-no-found align-center">0 results for your search, try something different.</>') | ||
} | ||
} else { | ||
$searchResults.html('') | ||
} | ||
}) | ||
|
||
$(window).click((e) => { | ||
if (submenuIsOpen) { | ||
if ($submenuOption && !$submenuOption.contains(e.target)) { | ||
submenuIsOpen = false | ||
hideSubmenu() | ||
} | ||
} | ||
}) | ||
|
||
if ($recentArticles.length > 0) { | ||
$recentArticles.slick({ | ||
adaptiveHeight: true, | ||
arrows: false, | ||
infinite: false, | ||
mobileFirst: true, | ||
variableWidth: true | ||
}) | ||
} | ||
|
||
AOS.init({ | ||
once: true, | ||
startEvent: 'DOMContentLoaded', | ||
}) | ||
|
||
tippy('.js-tooltip') | ||
|
||
trySearchFeature() | ||
|
||
window.addEventListener('scroll', onScroll, { passive: true }) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import $ from 'jquery' | ||
import slick from 'slick-carousel' | ||
|
||
$(document).ready(() => { | ||
const $featuredArticles = $('.js-featured-articles') | ||
|
||
if ($featuredArticles.length > 0) { | ||
$featuredArticles.slick({ | ||
arrows: true, | ||
infinite: true, | ||
prevArrow: '<button class="m-icon-button in-featured-articles slick-prev" aria-label="Previous"><span class="icon-arrow-left"></span></button>', | ||
nextArrow: '<button class="m-icon-button in-featured-articles slick-next" aria-label="Next"><span class="icon-arrow-right"></span></button>', | ||
mobileFirst: true | ||
}) | ||
|
||
setTimeout(() => { | ||
$featuredArticles.slick('setPosition') | ||
}, 350) | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import $ from 'jquery' | ||
import mediumZoom from 'medium-zoom' | ||
import fitvids from 'fitvids' | ||
|
||
$(document).ready(() => { | ||
fitvids('.js-post-content') | ||
|
||
function adjustImageGallery() { | ||
const images = document.querySelectorAll('.kg-gallery-image img') | ||
|
||
for (var i = 0, len = images.length; i < len; i++) { | ||
const container = images[i].closest('.kg-gallery-image') | ||
const width = images[i].attributes.width.value | ||
const height = images[i].attributes.height.value | ||
const ratio = width / height | ||
container.style.flex = `${ratio} 1 0%` | ||
} | ||
} | ||
|
||
adjustImageGallery() | ||
|
||
$('.js-post-content').find('figure img').each(function() { | ||
$(this).addClass('js-zoomable') | ||
|
||
const $figcaption = $(this).parent().find('figcaption') | ||
if ($figcaption) { | ||
$(this).attr('alt', $figcaption.text()) | ||
} else { | ||
$this.attr('alt', '') | ||
} | ||
}) | ||
|
||
mediumZoom('.js-zoomable') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import 'promise-polyfill/src/polyfill'; | ||
|
||
if (!Array.prototype.includes) { | ||
Object.defineProperty(Array.prototype, 'includes', { | ||
value: function (searchElement, fromIndex) { | ||
|
||
if (this == null) { | ||
throw new TypeError('"this" is null or is not defined'); | ||
} | ||
|
||
var o = Object(this); | ||
var len = o.length >>> 0; | ||
|
||
if (len === 0) { | ||
return false; | ||
} | ||
|
||
var n = fromIndex | 0; | ||
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); | ||
|
||
function sameValueZero(x, y) { | ||
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y)); | ||
} | ||
|
||
while (k < len) { | ||
if (sameValueZero(o[k], searchElement)) { | ||
return true; | ||
} | ||
k++; | ||
} | ||
|
||
return false; | ||
} | ||
}); | ||
} | ||
|
||
if (!String.prototype.endsWith) { | ||
String.prototype.endsWith = function (search, this_len) { | ||
if (this_len === undefined || this_len > this.length) { | ||
this_len = this.length; | ||
} | ||
return this.substring(this_len - search.length, this_len) === search; | ||
}; | ||
} | ||
|
||
if (!String.prototype.startsWith) { | ||
Object.defineProperty(String.prototype, 'startsWith', { | ||
value: function (search, pos) { | ||
pos = !pos || pos < 0 ? 0 : +pos; | ||
return this.substring(pos, pos + search.length) === search; | ||
} | ||
}); | ||
} | ||
|
||
if (typeof Object.assign != 'function') { | ||
Object.defineProperty(Object, "assign", { | ||
value: function assign(target, varArgs) { | ||
'use strict'; | ||
if (target == null) { | ||
throw new TypeError('Cannot convert undefined or null to object'); | ||
} | ||
|
||
var to = Object(target); | ||
|
||
for (var index = 1; index < arguments.length; index++) { | ||
var nextSource = arguments[index]; | ||
|
||
if (nextSource != null) { | ||
for (var nextKey in nextSource) { | ||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { | ||
to[nextKey] = nextSource[nextKey]; | ||
} | ||
} | ||
} | ||
} | ||
return to; | ||
}, | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
|
||
if (window.NodeList && !NodeList.prototype.forEach) { | ||
NodeList.prototype.forEach = function (callback, thisArg) { | ||
thisArg = thisArg || window; | ||
for (var i = 0; i < this.length; i++) { | ||
callback.call(thisArg, this[i], i, this); | ||
} | ||
}; | ||
} |
Oops, something went wrong.