1
- import { defineComponent , h , onBeforeUpdate , ref } from 'vue '
1
+ import { useStorage } from '@vueuse/core '
2
2
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'
3
12
4
13
export const CodeGroup = defineComponent ( {
5
14
name : 'CodeGroup' ,
@@ -9,20 +18,45 @@ export const CodeGroup = defineComponent({
9
18
} > ,
10
19
11
20
setup ( _ , { slots } ) {
12
- // index of current active item
13
- const activeIndex = ref ( - 1 )
14
-
15
21
// refs of the tab buttons
16
22
const tabRefs = ref < HTMLButtonElement [ ] > ( [ ] )
17
23
18
24
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
21
27
onBeforeUpdate ( ( ) => {
22
28
tabRefs . value = [ ]
23
29
} )
24
30
}
25
31
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
+
26
60
// activate next tab
27
61
const activateNext = ( i = activeIndex . value ) : void => {
28
62
if ( i < tabRefs . value . length - 1 ) {
@@ -58,11 +92,7 @@ export const CodeGroup = defineComponent({
58
92
}
59
93
60
94
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
66
96
const items = ( slots . default ?.( ) || [ ] )
67
97
. filter ( ( vnode ) => ( vnode . type as Component ) . name === 'CodeGroupItem' )
68
98
. map ( ( vnode ) => {
@@ -77,9 +107,8 @@ export const CodeGroup = defineComponent({
77
107
return null
78
108
}
79
109
110
+ // if activeIndex is invalid
80
111
if ( activeIndex . value < 0 || activeIndex . value > items . length - 1 ) {
81
- // if `activeIndex` is invalid
82
-
83
112
// find the index of the code-group-item with `active` props
84
113
activeIndex . value = items . findIndex (
85
114
( vnode ) => vnode . props . active === '' || vnode . props . active === true ,
@@ -89,7 +118,9 @@ export const CodeGroup = defineComponent({
89
118
if ( activeIndex . value === - 1 ) {
90
119
activeIndex . value = 0
91
120
}
92
- } else {
121
+ }
122
+ // if activeIndex is valid
123
+ else {
93
124
// set the active item
94
125
items . forEach ( ( vnode , i ) => {
95
126
vnode . props . active = i === activeIndex . value
0 commit comments