Skip to content

Commit

Permalink
Improve code switcher in docs
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalbaljet committed Dec 4, 2024
1 parent 112b234 commit 323496f
Show file tree
Hide file tree
Showing 2 changed files with 562 additions and 608 deletions.
85 changes: 52 additions & 33 deletions docs/.vitepress/theme/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ export default {
if (inBrowser) {
const route = useRoute()

// Click on the tab with the given label text
function showCodeWithLabel(labelText) {
document.querySelectorAll(`.vp-code-group .tabs label`).forEach((label) => {
if (label.innerText === labelText) {
const input = document.getElementById(label.getAttribute('for'))

if(! input.checked) {
if (!input.checked) {
label.click()
}
}
Expand All @@ -23,19 +24,24 @@ export default {

let preventScroll = false

function bindClickEvent() {
document.querySelectorAll('.vp-code-group .tabs label').forEach((label) => {
function bindClickEvents() {
// Find all the labels
const labels = document.querySelectorAll('.vp-code-group .tabs label')

labels.forEach((label) => {
label.addEventListener('click', ($event) => {
const labelFor = label.getAttribute('for')
const initialRect = label.getBoundingClientRect()
const initialScrollY = window.scrollY

// Save the selected tab
localStorage.setItem('codeGroupTab', label.innerText)

// Show the code
// Show the selected tab on each code group
showCodeWithLabel(label.innerText)

// Use nextTick to ensure DOM is updated
// Use nextTick to ensure DOM is updated and scroll to the position
// so that the clicked label is at the same position as before
nextTick(() => {
if (preventScroll || !$event.isTrusted) {
return
Expand All @@ -46,44 +52,57 @@ export default {
const newRect = labelNew.getBoundingClientRect()

// Calculate the difference in position relative to the document
const yDiff = (newRect.top + window.scrollY) - (initialRect.top + initialScrollY)
const yDiff = newRect.top + window.scrollY - (initialRect.top + initialScrollY)

// Scroll to maintain the label's position
window.scrollTo({
top: initialScrollY + yDiff,
behavior: 'instant'
})
scrollToY(initialScrollY + yDiff)
})
})
});
})
}

// Scroll to the given Y position without animation
function scrollToY(y) {
window.scrollTo({
top: y,
behavior: 'instant',
})
}

// Select the given tab and scroll to the top of the page
function selectTabAndScrollToTop(tab) {
if (!tab) {
return
}

// Restore the last selected tab and scroll back to to top
// Enable 'preventScroll' to avoid scrolling to all the tabs
preventScroll = true
showCodeWithLabel(tab)
nextTick(() => {
preventScroll = false
scrollToY(0)
})
}

onMounted(() => nextTick(() => bindClickEvent()))
// Bind click event on initial page and restore the last selected tab
onMounted(() =>
nextTick(() => {
bindClickEvents()
selectTabAndScrollToTop(localStorage.getItem('codeGroupTab'))
}),
)

watch(
() => route.path,
() => {
// Restore tab from local storage
const tab = localStorage.getItem('codeGroupTab')
if (tab) {
preventScroll = true

nextTick(() => {
bindClickEvent()

showCodeWithLabel(tab)
nextTick(() => {
preventScroll = false
window.scrollTo({
top: 0,
behavior: 'instant'
})
})
})
}
nextTick(() => {
// Bind click event on new page
bindClickEvents()
selectTabAndScrollToTop(localStorage.getItem('codeGroupTab'))
})
},
{ immediate: true }
)
}
}
}
},
}
Loading

0 comments on commit 323496f

Please sign in to comment.