Skip to content

Commit 7078dd5

Browse files
committed
feat(theme-default): sync code group status (close #541)
1 parent 88908d1 commit 7078dd5

File tree

1 file changed

+45
-14
lines changed
  • ecosystem/theme-default/src/client/components/global

1 file changed

+45
-14
lines changed

ecosystem/theme-default/src/client/components/global/CodeGroup.ts

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
import { defineComponent, h, onBeforeUpdate, ref } from 'vue'
1+
import { useStorage } from '@vueuse/core'
22
import type { Component, SlotsType, VNode } from 'vue'
3+
import {
4+
computed,
5+
defineComponent,
6+
h,
7+
onBeforeUpdate,
8+
onMounted,
9+
ref,
10+
watch,
11+
} from 'vue'
312

413
export const CodeGroup = defineComponent({
514
name: 'CodeGroup',
@@ -9,20 +18,45 @@ export const CodeGroup = defineComponent({
918
}>,
1019

1120
setup(_, { slots }) {
12-
// index of current active item
13-
const activeIndex = ref(-1)
14-
1521
// refs of the tab buttons
1622
const tabRefs = ref<HTMLButtonElement[]>([])
1723

1824
if (__VUEPRESS_DEV__) {
19-
// after removing a code-group-item, we need to clear the ref
20-
// of the removed item to avoid issues caused by HMR
25+
// in dev mode, we need to clear the tabs ref to avoid HMR issues
26+
// after removing a code-group-item
2127
onBeforeUpdate(() => {
2228
tabRefs.value = []
2329
})
2430
}
2531

32+
// index of current active item
33+
const activeIndex = ref(-1)
34+
const codeGroupStorage = useStorage<Record<string, number | undefined>>(
35+
'vuepress-code-group',
36+
{},
37+
)
38+
const codeGroupKey = computed(() =>
39+
tabRefs.value.map((tab) => tab.innerText).join(','),
40+
)
41+
onMounted(() => {
42+
watch(
43+
() => codeGroupStorage.value[codeGroupKey.value],
44+
(val = -1) => {
45+
if (activeIndex.value !== val) {
46+
console.log('codeGroupStorage -> activeIndex')
47+
activeIndex.value = val
48+
}
49+
},
50+
{ immediate: true },
51+
)
52+
watch(activeIndex, (val) => {
53+
if (codeGroupStorage.value[codeGroupKey.value] !== val) {
54+
console.log('activeIndex -> codeGroupStorage')
55+
codeGroupStorage.value[codeGroupKey.value] = val
56+
}
57+
})
58+
})
59+
2660
// activate next tab
2761
const activateNext = (i = activeIndex.value): void => {
2862
if (i < tabRefs.value.length - 1) {
@@ -58,11 +92,7 @@ export const CodeGroup = defineComponent({
5892
}
5993

6094
return () => {
61-
// NOTICE: here we put the `slots.default()` inside the render function to make
62-
// the slots reactive, otherwise the slot content won't be changed once the
63-
// `setup()` function of current component is called
64-
65-
// get children code-group-item
95+
// get children code-group-item from default slots
6696
const items = (slots.default?.() || [])
6797
.filter((vnode) => (vnode.type as Component).name === 'CodeGroupItem')
6898
.map((vnode) => {
@@ -77,9 +107,8 @@ export const CodeGroup = defineComponent({
77107
return null
78108
}
79109

110+
// if activeIndex is invalid
80111
if (activeIndex.value < 0 || activeIndex.value > items.length - 1) {
81-
// if `activeIndex` is invalid
82-
83112
// find the index of the code-group-item with `active` props
84113
activeIndex.value = items.findIndex(
85114
(vnode) => vnode.props.active === '' || vnode.props.active === true,
@@ -89,7 +118,9 @@ export const CodeGroup = defineComponent({
89118
if (activeIndex.value === -1) {
90119
activeIndex.value = 0
91120
}
92-
} else {
121+
}
122+
// if activeIndex is valid
123+
else {
93124
// set the active item
94125
items.forEach((vnode, i) => {
95126
vnode.props.active = i === activeIndex.value

0 commit comments

Comments
 (0)