Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature layout #48

Merged
merged 2 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 58 additions & 44 deletions docs/assets/script/main.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// Theme switching
const storageKey = 'theme-preference'
const theme = { value: getColorPreference() }
let currentTheme = getColorPreference()

reflectPreference()

document.querySelector('#theme').addEventListener('click', () => {
theme.value = theme.value === 'light' ? 'dark' : 'light'
document.querySelector('button#theme').addEventListener('click', () => {
currentTheme = currentTheme === 'light' ? 'dark' : 'light'
setPreference()
})

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ({ matches: isDark }) => {
theme.value = isDark ? 'dark' : 'light'
currentTheme = isDark ? 'dark' : 'light'
setPreference()
})

Expand All @@ -19,60 +20,73 @@ function getColorPreference() {
}

function reflectPreference() {
document.firstElementChild.setAttribute('data-theme', theme.value)
document.querySelector('#theme')?.setAttribute('aria-label', theme.value)
document.firstElementChild.setAttribute('data-theme', currentTheme)
document.querySelector('button#theme')?.setAttribute('aria-label', currentTheme)
}

function setPreference() {
localStorage.setItem(storageKey, theme.value)
localStorage.setItem(storageKey, currentTheme)
reflectPreference()
}

// Scrolling functions
const paragraphItems = Array.from(document.querySelectorAll('#paragraph-dropdown a'))
const articleParagraphs = paragraphItems.map((item) => document.getElementById(decodeURI(item.hash).replace('#', '')))
// Scroll functions
const paragraphButton = document.querySelector('#paragraph-button > span'),
subnavLinks = Array.from(document.querySelectorAll('.subnav a')),
articleHeadings = subnavLinks.map((link) => document.getElementById(decodeURI(link.hash).replace('#', '')))

const subnavItems = Array.from(document.querySelectorAll('.subnav a'))
const articleItems = subnavItems.map((item) => document.getElementById(decodeURI(item.hash).replace('#', '')))
let currentParagraph = null,
currentHeading = null,
ticking = false

const delta = 5
document.addEventListener('scroll', scrollHandler)

let scrolled
let lastItem
let lastParagraph
let lastScrollTop = 0
function scrollHandler(event) {
if (!ticking) {
ticking = true
window.requestAnimationFrame(() => {
checkScrollPosition(window.scrollY)
ticking = false
})
}
}

window.addEventListener('scroll', () => {
scrolled = true
})
function checkScrollPosition(scrollPosition) {
const headings = getElementsAbove(articleHeadings, scrollPosition)
if (changeCurrentParagraph(getNearestElement(headings, 'H3'))) updateParagraphButton()
if (changeCurrentHeading(getLast(headings))) updateSubnav()
}

setInterval(() => {
if (scrolled) {
scrollHandler()
scrolled = false
}
}, 200)
function getElementsAbove(elements, scrollPosition) {
return elements.filter((element) => element.offsetParent.offsetTop < scrollPosition)
}

function changeCurrentParagraph(newParagraph) {
if (currentParagraph == newParagraph) return false
currentParagraph = newParagraph
return true
}

function scrollHandler() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
function getNearestElement(elements, tagName) {
return elements.findLast((element) => element.tagName === tagName)
}

// set text on paragraph button
const passedParagraph = articleParagraphs.filter((item) => item.offsetParent.offsetTop < scrollTop)
const currentParagraph = passedParagraph[passedParagraph.length - 1]?.id
function updateParagraphButton() {
paragraphButton.innerHTML = currentParagraph?.firstChild.textContent || 'Paragraaf'
}

if (currentParagraph !== undefined && currentParagraph !== lastParagraph) {
document.getElementById('paragraph-button').firstChild.innerHTML =
document.getElementById(currentParagraph).firstChild.textContent
lastParagraph = currentParagraph
}
function changeCurrentHeading(newHeading) {
if (currentHeading == newHeading) return false
currentHeading = newHeading
return true
}

// highlight the correct toc item
const passedItems = articleItems.filter((item) => item.offsetParent.offsetTop < scrollTop)
const currentItem = passedItems[passedItems.length - 1]?.id
function getLast(elements) {
return elements.at(-1)
}

if (currentItem !== undefined && currentItem !== lastItem) {
document.querySelector(`.subnav a[href$='#${lastItem}']`)?.classList.remove('active')
document.querySelector(`.subnav a[href$='#${currentItem}']`)?.classList.add('active')
lastItem = currentItem
}
function updateSubnav() {
subnavLinks.forEach((link) => {
link.classList.remove('active')
if (decodeURI(link.hash).replace('#', '') === currentHeading?.id) link.classList.add('active')
})
}
111 changes: 0 additions & 111 deletions docs/assets/script/main_old.js

This file was deleted.

Loading
Loading