-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Sync code group selection #2954
Comments
Can you elaborate more on this point. |
+1 from me. I was excited to use code groups, but find them useless without synchronisation. @re-ovo FYI: I added the following styles to make tabs look more like code groups: .plugin-tabs--content {
padding: 0px !important;
}
.plugin-tabs--content div[class*='language-'] {
background-color: var(--vp-code-block-bg) !important;
border-radius: 0 !important;
} |
+1, It would be great to have code group syncing as a core feature, like it is in docusaurus. |
Came here looking for this, would love to see it added! |
+1 for this feature, much needed for documentation pages! |
Here's how I did it ( import { onMounted, nextTick, watch } from 'vue'
import { inBrowser, useRoute } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
setup() {
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) {
label.click()
}
}
})
}
let preventScroll = false
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 selected tab on each code group
showCodeWithLabel(label.innerText)
// 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
}
// Find the new position of the label
const labelNew = document.querySelector(`label[for="${labelFor}"]`)
const newRect = labelNew.getBoundingClientRect()
// Calculate the difference in position relative to the document
const yDiff = newRect.top + window.scrollY - (initialRect.top + initialScrollY)
// Scroll to maintain the label's position
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)
})
}
// Bind click event on initial page and restore the last selected tab
onMounted(() =>
nextTick(() => {
bindClickEvents()
selectTabAndScrollToTop(localStorage.getItem('codeGroupTab'))
}),
)
watch(
() => route.path,
() => {
nextTick(() => {
// Bind click event on new page
bindClickEvents()
selectTabAndScrollToTop(localStorage.getItem('codeGroupTab'))
})
},
)
}
},
} |
Is your feature request related to a problem? Please describe.
In many cases, developers will provide code groups for multiple programming languages at the same time. I hope that after the user switches one, other code groups can automatically follow, and it is best to be persistent.
#2773, a solution is proposed here, but I don't think it's good enough
Describe the solution you'd like
::: code-group
```js [config.js] :js <-- key
const config = {
// ...
}
export default config
```
```ts [config.ts] :ts
import type { UserConfig } from 'vitepress'
const config: UserConfig = {
// ...
}
export default config
```
:::
Describe alternatives you've considered
No response
Additional context
No response
Validations
The text was updated successfully, but these errors were encountered: