@sugarat/theme 0.5.11 → 0.5.12-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,397 @@
1
+ <script lang="ts" setup>
2
+ import { computed, ref, watch } from 'vue'
3
+
4
+ const props = defineProps({
5
+ total: {
6
+ type: Number,
7
+ default: 0,
8
+ },
9
+ pageSize: {
10
+ type: Number,
11
+ default: 10,
12
+ },
13
+ currentPage: {
14
+ type: Number,
15
+ default: 1,
16
+ },
17
+ layout: {
18
+ type: String,
19
+ default: 'prev, pager, next, jumper',
20
+ },
21
+ background: {
22
+ type: Boolean,
23
+ default: false,
24
+ },
25
+ small: {
26
+ type: Boolean,
27
+ default: false,
28
+ },
29
+ })
30
+
31
+ const emit = defineEmits(['update:current-page', 'currentChange'])
32
+
33
+ const innerCurrentPage = ref(props.currentPage)
34
+
35
+ watch(() => props.currentPage, (val) => {
36
+ innerCurrentPage.value = val
37
+ })
38
+
39
+ const pageCount = computed(() => {
40
+ const count = Math.ceil(props.total / props.pageSize)
41
+ return count > 0 ? count : 1
42
+ })
43
+
44
+ const pagers = computed(() => {
45
+ const count = pageCount.value
46
+ const current = innerCurrentPage.value
47
+ const pagerCount = 7 // Default Element Plus pager count
48
+
49
+ const showPrevMore = false
50
+ const showNextMore = false
51
+
52
+ if (count <= pagerCount) {
53
+ const array = []
54
+ for (let i = 1; i <= count; i++) {
55
+ array.push(i)
56
+ }
57
+ return array
58
+ }
59
+
60
+ // Logic for large number of pages
61
+ // Simplified logic for now, Element Plus logic is complex
62
+ // If we want exact replica, we need more logic.
63
+ // For now, let's implement a simpler version that shows current +/- 2 and first/last
64
+
65
+ const array: (number | string)[] = []
66
+
67
+ if (current <= 4) {
68
+ for (let i = 1; i <= 6; i++) {
69
+ array.push(i)
70
+ }
71
+ array.push('more-next') // ...
72
+ array.push(count)
73
+ }
74
+ else if (current >= count - 3) {
75
+ array.push(1)
76
+ array.push('more-prev') // ...
77
+ for (let i = count - 5; i <= count; i++) {
78
+ array.push(i)
79
+ }
80
+ }
81
+ else {
82
+ array.push(1)
83
+ array.push('more-prev') // ...
84
+ for (let i = current - 2; i <= current + 2; i++) {
85
+ array.push(i)
86
+ }
87
+ array.push('more-next') // ...
88
+ array.push(count)
89
+ }
90
+
91
+ return array
92
+ })
93
+
94
+ function handleCurrentChange(val: number) {
95
+ if (val < 1)
96
+ val = 1
97
+ if (val > pageCount.value)
98
+ val = pageCount.value
99
+
100
+ if (innerCurrentPage.value !== val) {
101
+ innerCurrentPage.value = val
102
+ emit('update:current-page', val)
103
+ emit('currentChange', val)
104
+ }
105
+ }
106
+
107
+ function prev() {
108
+ handleCurrentChange(innerCurrentPage.value - 1)
109
+ }
110
+
111
+ function next() {
112
+ handleCurrentChange(innerCurrentPage.value + 1)
113
+ }
114
+
115
+ function onPagerClick(page: number | string) {
116
+ if (typeof page === 'number') {
117
+ handleCurrentChange(page)
118
+ }
119
+ else {
120
+ const pagerCountOffset = 5
121
+ let newPage = innerCurrentPage.value
122
+ if (page === 'more-prev') {
123
+ newPage -= pagerCountOffset
124
+ }
125
+ else if (page === 'more-next') {
126
+ newPage += pagerCountOffset
127
+ }
128
+ handleCurrentChange(newPage)
129
+ }
130
+ }
131
+
132
+ // Jumper
133
+ function handleJumperChange(evt: Event) {
134
+ const target = evt.target as HTMLInputElement
135
+ const val = parseInt(target.value)
136
+ if (!isNaN(val)) {
137
+ handleCurrentChange(val)
138
+ target.value = '' // Clear or keep? Element Plus keeps it until blur/enter
139
+ }
140
+ }
141
+ </script>
142
+
143
+ <template>
144
+ <div class="sugar-pagination" :class="{ 'is-background': background, 'sugar-pagination--small': small }">
145
+ <!-- Prev -->
146
+ <button
147
+ type="button"
148
+ class="btn-prev"
149
+ :disabled="innerCurrentPage <= 1"
150
+ @click="prev"
151
+ >
152
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"><path fill="currentColor" d="M609.408 149.376 277.76 489.6a32 32 0 0 0 0 44.672l331.648 340.352a29.12 29.12 0 0 0 41.728 0 30.592 30.592 0 0 0 0-42.752L339.264 511.936l311.872-319.872a30.592 30.592 0 0 0 0-42.688 29.12 29.12 0 0 0-41.728 0z" /></svg>
153
+ </button>
154
+
155
+ <!-- Pager -->
156
+ <ul class="sugar-pager">
157
+ <li
158
+ v-for="(page, index) in pagers"
159
+ :key="index"
160
+ :class="{ 'is-active': innerCurrentPage === page, 'more': typeof page === 'string' }"
161
+ class="number"
162
+ @click="onPagerClick(page)"
163
+ >
164
+ <template v-if="typeof page === 'number'">
165
+ {{ page }}
166
+ </template>
167
+ <template v-else>
168
+ <svg v-if="page === 'more-prev'" class="icon-more" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"><path fill="currentColor" d="M529.408 149.376a29.12 29.12 0 0 1 41.728 0 30.592 30.592 0 0 1 0 42.688L259.264 511.936l311.872 319.936a30.592 30.592 0 0 1-.512 43.264 29.12 29.12 0 0 1-41.216-.512L197.76 534.272a32 32 0 0 1 0-44.672l331.648-340.224zm256 0a29.12 29.12 0 0 1 41.728 0 30.592 30.592 0 0 1 0 42.688L515.264 511.936l311.872 319.936a30.592 30.592 0 0 1-.512 43.264 29.12 29.12 0 0 1-41.216-.512L453.76 534.272a32 32 0 0 1 0-44.672l331.648-340.224z" /></svg>
169
+ <svg v-else-if="page === 'more-next'" class="icon-more" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em"><path fill="currentColor" d="M452.864 149.312a29.12 29.12 0 0 1 41.728.064L826.24 489.664a32 32 0 0 1 0 44.672L494.592 874.624a29.12 29.12 0 0 1-41.728 0 30.592 30.592 0 0 1 0-42.752L764.736 512 452.864 192a30.592 30.592 0 0 1 0-42.688m-256 0a29.12 29.12 0 0 1 41.728.064L570.24 489.664a32 32 0 0 1 0 44.672L238.592 874.624a29.12 29.12 0 0 1-41.728 0 30.592 30.592 0 0 1 0-42.752L508.736 512 196.864 192a30.592 30.592 0 0 1 0-42.688z" /></svg>
170
+ <svg class="icon-more-text" viewBox="0 0 1024 1024" width="1em" height="1em"><path fill="currentColor" d="M176 416a112 112 0 1 1 0 224 112 112 0 0 1 0-224m336 0a112 112 0 1 1 0 224 112 112 0 0 1 0-224m336 0a112 112 0 1 1 0 224 112 112 0 0 1 0-224" /></svg>
171
+ </template>
172
+ </li>
173
+ </ul>
174
+
175
+ <!-- Next -->
176
+ <button
177
+ type="button"
178
+ class="btn-next"
179
+ :disabled="innerCurrentPage >= pageCount"
180
+ @click="next"
181
+ >
182
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em"><path fill="currentColor" d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-44.672L382.592 149.376a29.12 29.12 0 0 0-41.728 0z" /></svg>
183
+ </button>
184
+
185
+ <!-- Jumper -->
186
+ <span v-if="layout.includes('jumper')" class="sugar-pagination__jump">
187
+ <span style="margin-right: 4px;white-space: nowrap;">Go to</span>
188
+ <div class="sugar-input sugar-pagination__editor is-in-pagination">
189
+ <div class="sugar-input__wrapper">
190
+ <input
191
+ class="sugar-input__inner"
192
+ type="number"
193
+ :min="1"
194
+ :max="pageCount"
195
+ :value="innerCurrentPage"
196
+ @change="handleJumperChange"
197
+ >
198
+ </div>
199
+ </div>
200
+ </span>
201
+ </div>
202
+ </template>
203
+
204
+ <style lang="scss" scoped>
205
+ .sugar-pagination {
206
+ display: flex;
207
+ justify-content: center;
208
+ align-items: center;
209
+ padding: 2px 5px;
210
+ color: var(--vp-c-text-1);
211
+ font-size: 12px;
212
+
213
+ &--small {
214
+ .btn-prev, .btn-next, .sugar-pager li {
215
+ height: 24px;
216
+ line-height: 24px;
217
+ min-width: 24px;
218
+ font-size: 12px;
219
+ }
220
+ }
221
+
222
+ button {
223
+ display: flex;
224
+ justify-content: center;
225
+ align-items: center;
226
+ background: transparent;
227
+ border: none;
228
+ cursor: pointer;
229
+ font-size: 12px;
230
+ padding: 0 6px;
231
+ min-width: 24px;
232
+ height: 24px;
233
+ line-height: 24px;
234
+ color: var(--vp-c-text-1);
235
+
236
+ &:disabled {
237
+ color: var(--vp-c-text-3);
238
+ cursor: not-allowed;
239
+ }
240
+
241
+ &:hover:not(:disabled) {
242
+ color: var(--vp-c-brand-2);
243
+ }
244
+ }
245
+
246
+ .sugar-pager {
247
+ user-select: none;
248
+ list-style: none;
249
+ display: flex;
250
+ padding: 0;
251
+ margin: 0;
252
+
253
+ li {
254
+ padding: 0 4px;
255
+ background: transparent;
256
+ vertical-align: top;
257
+ display: inline-block;
258
+ font-size: 12px;
259
+ min-width: 24px;
260
+ height: 24px;
261
+ line-height: 24px;
262
+ cursor: pointer;
263
+ box-sizing: border-box;
264
+ text-align: center;
265
+ margin: 0 4px;
266
+ border-radius: 2px;
267
+ display: flex;
268
+ justify-content: center;
269
+ align-items: center;
270
+
271
+ &.is-active {
272
+ color: var(--vp-c-brand-2);
273
+ cursor: default;
274
+ font-weight: normal;
275
+ }
276
+
277
+ &:hover:not(.is-active):not(.more) {
278
+ color: var(--vp-c-brand-2);
279
+ }
280
+
281
+ &.more {
282
+ cursor: pointer;
283
+
284
+ .icon-more {
285
+ display: none;
286
+ }
287
+
288
+ .icon-more-text {
289
+ display: block;
290
+ }
291
+
292
+ &:hover {
293
+ color: var(--vp-c-brand-2);
294
+
295
+ .icon-more {
296
+ display: inline-block;
297
+ }
298
+
299
+ .icon-more-text {
300
+ display: none;
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }
306
+
307
+ &.is-background {
308
+ .btn-prev, .btn-next, .sugar-pager li {
309
+ background-color: var(--vp-c-bg-alt);
310
+ color: var(--vp-c-text-2);
311
+ margin: 0 3px;
312
+ border-radius: 2px;
313
+ font-weight: normal;
314
+ }
315
+
316
+ .btn-prev:disabled, .btn-next:disabled {
317
+ color: var(--vp-c-text-3);
318
+ background-color: var(--vp-c-bg-alt);
319
+ }
320
+
321
+ .sugar-pager li:not(.disabled).is-active {
322
+ background-color: var(--vp-c-brand-2);
323
+ color: #fff;
324
+ }
325
+
326
+ .sugar-pager li:not(.disabled):hover:not(.is-active):not(.more) {
327
+ color: var(--vp-c-brand-2);
328
+ }
329
+ }
330
+
331
+ &__jump {
332
+ display: flex;
333
+ align-items: center;
334
+ margin-left: 24px;
335
+ font-weight: normal;
336
+ color: var(--vp-c-text-2);
337
+ }
338
+
339
+ &__editor {
340
+ margin: 0 8px;
341
+ width: 50px;
342
+ }
343
+ }
344
+
345
+ .sugar-input {
346
+ display: inline-flex;
347
+ position: relative;
348
+ font-size: 12px;
349
+ line-height: 24px;
350
+ box-sizing: border-box;
351
+ width: 100%;
352
+ }
353
+
354
+ .sugar-input__wrapper {
355
+ display: inline-flex;
356
+ flex-grow: 1;
357
+ align-items: center;
358
+ justify-content: center;
359
+ padding: 1px 11px;
360
+ background-color: var(--vp-c-bg);
361
+ background-image: none;
362
+ border-radius: 4px;
363
+ transition: box-shadow .2s cubic-bezier(.645,.045,.355,1);
364
+
365
+ &:focus-within {
366
+ box-shadow: 0 0 0 1px var(--vp-c-brand-2) inset;
367
+ }
368
+ }
369
+
370
+ .sugar-input__inner {
371
+ width: 100%;
372
+ flex-grow: 1;
373
+ -webkit-appearance: none;
374
+ color: var(--vp-c-text-1);
375
+ font-size: inherit;
376
+ height: 24px;
377
+ line-height: 24px;
378
+ padding: 0;
379
+ outline: none;
380
+ border: none;
381
+ background: none;
382
+ box-sizing: border-box;
383
+ text-align: center;
384
+
385
+ /* Chrome, Safari, Edge, Opera */
386
+ &::-webkit-outer-spin-button,
387
+ &::-webkit-inner-spin-button {
388
+ -webkit-appearance: none;
389
+ margin: 0;
390
+ }
391
+
392
+ /* Firefox */
393
+ &[type=number] {
394
+ -moz-appearance: textfield;
395
+ }
396
+ }
397
+ </style>
@@ -0,0 +1,163 @@
1
+ <script lang="ts" setup>
2
+ defineProps({
3
+ type: { type: String, default: 'primary' },
4
+ closable: { type: Boolean, default: false }
5
+ })
6
+
7
+ defineEmits(['close', 'click'])
8
+ </script>
9
+
10
+ <template>
11
+ <span class="blog-tag" :class="[`blog-tag--${type || 'primary'}`]" @click="$emit('click', $event)">
12
+ <slot />
13
+ <span v-if="closable" class="close" @click.stop="$emit('close', $event)">
14
+ <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em">
15
+ <path
16
+ fill="currentColor"
17
+ d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z"
18
+ />
19
+ </svg>
20
+ </span>
21
+ </span>
22
+ </template>
23
+
24
+ <style lang="scss">
25
+ .blog-tag {
26
+ display: inline-flex;
27
+ justify-content: center;
28
+ align-items: center;
29
+ height: 24px;
30
+ padding: 0 9px;
31
+ font-size: 12px;
32
+ line-height: 1;
33
+ border-width: 1px;
34
+ border-style: solid;
35
+ border-radius: 4px;
36
+ box-sizing: border-box;
37
+ white-space: nowrap;
38
+ vertical-align: middle;
39
+ color: #fff;
40
+
41
+ >.close {
42
+ margin-left: 6px;
43
+ font-size: 12px;
44
+ cursor: pointer;
45
+ border-radius: 50%;
46
+ display: inline-flex;
47
+ align-items: center;
48
+ justify-content: center;
49
+ width: 14px;
50
+ height: 14px;
51
+ transition: all 0.3s;
52
+ }
53
+ }
54
+
55
+ /* Primary */
56
+ .blog-tag--primary {
57
+ background-color: #409eff;
58
+ border-color: #409eff;
59
+
60
+ .close:hover {
61
+ background-color: #79bbff;
62
+ }
63
+ }
64
+
65
+ /* Success */
66
+ .blog-tag--success {
67
+ background-color: #67c23a;
68
+ border-color: #67c23a;
69
+
70
+ .close:hover {
71
+ background-color: #95d475;
72
+ }
73
+ }
74
+
75
+ /* Info */
76
+ .blog-tag--info {
77
+ background-color: #909399;
78
+ border-color: #909399;
79
+
80
+ .close:hover {
81
+ background-color: #b1b3b8;
82
+ }
83
+ }
84
+
85
+ /* Warning */
86
+ .blog-tag--warning {
87
+ background-color: #e6a23c;
88
+ border-color: #e6a23c;
89
+
90
+ .close:hover {
91
+ background-color: #eebe77;
92
+ }
93
+ }
94
+
95
+ /* Danger */
96
+ .blog-tag--danger {
97
+ background-color: #f56c6c;
98
+ border-color: #f56c6c;
99
+
100
+ .close:hover {
101
+ background-color: #f89898;
102
+ }
103
+ }
104
+ </style>
105
+
106
+ <style lang="scss">
107
+ html.dark {
108
+ .blog-tag--primary {
109
+ background-color: #18222c;
110
+ border-color: #1d3043;
111
+ color: #409eff;
112
+
113
+ .close:hover {
114
+ background-color: #409eff;
115
+ color: #fff;
116
+ }
117
+ }
118
+
119
+ .blog-tag--success {
120
+ background-color: #1c2518;
121
+ border-color: #25371c;
122
+ color: #67c23a;
123
+
124
+ .close:hover {
125
+ background-color: #95d475;
126
+ color: #fff;
127
+ }
128
+ }
129
+
130
+ .blog-tag--info {
131
+ background-color: #202121;
132
+ border-color: #2d2d2f;
133
+ color: #909399;
134
+
135
+ .close:hover {
136
+ background-color: #909399;
137
+ color: #fff;
138
+ }
139
+ }
140
+
141
+ .blog-tag--warning {
142
+ background-color: #292218;
143
+ border-color: #3e301c;
144
+ color: #e6a23c;
145
+
146
+ .close:hover {
147
+ background-color: #e6a23c;
148
+ color: #fff;
149
+ }
150
+ }
151
+
152
+ .blog-tag--danger {
153
+ background-color: #2b1d1d;
154
+ border-color: #412626;
155
+ color: #f56c6c;
156
+
157
+ .close:hover {
158
+ background-color: #f56c6c;
159
+ color: #fff;
160
+ }
161
+ }
162
+ }
163
+ </style>
@@ -1,21 +1,19 @@
1
1
  <script lang="ts" setup>
2
- import { ElCarousel, ElCarouselItem, ElImage, ElMessage } from 'element-plus'
3
2
  import VPDocAsideOutline from 'vitepress/dist/client/theme-default/components/VPDocAsideOutline.vue'
4
3
  import { computed, reactive, ref, watch, watchEffect } from 'vue'
5
- import { slugify } from '@mdit-vue/shared'
6
4
  import { useWindowSize } from '@vueuse/core'
7
- import {
8
- formatDate,
9
- getGithubDirUpdateTime,
10
- getGithubUpdateTime
11
- } from '../utils/client'
5
+ import { formatDate, getGithubDirUpdateTime, getGithubUpdateTime, slugify } from '../utils/client'
12
6
  import {
13
7
  useActiveAnchor,
14
8
  useAutoUpdateAnchor,
15
- useUserWorks
9
+ useUserWorks,
16
10
  } from '../composables/config/blog'
17
11
  import type { Theme } from '../composables/config'
12
+ import Carousel from './Carousel.vue'
13
+ import CarouselItem from './CarouselItem.vue'
14
+ import Image from './Image.vue'
18
15
 
16
+ // TODO:作品集组件
19
17
  const currentAnchor = useAutoUpdateAnchor()
20
18
  // 更新锚点的时候更新 url 中的 hash
21
19
  watch(
@@ -165,10 +163,10 @@ watchEffect(() => {
165
163
  const { width } = useWindowSize()
166
164
  const isCardMode = computed(() => width.value > 768)
167
165
  function handleChooseTag(tag: string) {
168
- ElMessage({
169
- message: `点击了${tag}标签,标签过滤功能开发中ing...`,
170
- type: 'warning'
171
- })
166
+ // Message({
167
+ // message: `点击了${tag}标签,标签过滤功能开发中ing...`,
168
+ // type: 'warning',
169
+ // })
172
170
  }
173
171
  </script>
174
172
 
@@ -276,18 +274,17 @@ function handleChooseTag(tag: string) {
276
274
  <div v-if="work.covers?.length" class="images">
277
275
  <!-- swiper -->
278
276
  <div v-if="work.coverLayout === 'swiper'" class="swiper-mode">
279
- <ElCarousel autoplay height="260px" :type="isCardMode && work.covers.length >= 3 ? 'card' : ''">
280
- <ElCarouselItem v-for="(url, idx) in work.covers" :key="url" style="text-align: center">
281
- <ElImage
282
- :key="url" preview-teleported :src="url" loading="lazy" :preview-src-list="work.covers"
283
- :initial-index="idx" hide-on-click-modal :alt="`${work.title}-${idx}`"
277
+ <Carousel autoplay height="260px" :type="isCardMode && work.covers.length >= 3 ? 'card' : ''">
278
+ <CarouselItem v-for="(url) in work.covers" :key="url" style="text-align: center">
279
+ <Image
280
+ :src="url" loading="lazy"
284
281
  />
285
- </ElCarouselItem>
286
- </ElCarousel>
282
+ </CarouselItem>
283
+ </Carousel>
287
284
  </div>
288
285
  <!-- list -->
289
286
  <div v-if="work.coverLayout === 'list'" class="list-mode">
290
- <ElImage
287
+ <Image
291
288
  v-for="(url, idx) in work.covers" :key="url" :src="url" loading="lazy"
292
289
  :preview-src-list="work.covers" :initial-index="idx" hide-on-click-modal
293
290
  />
@@ -504,7 +501,7 @@ function handleChooseTag(tag: string) {
504
501
  flex-wrap: wrap;
505
502
  justify-content: center;
506
503
 
507
- .el-image {
504
+ .sugar-image {
508
505
  :deep(img) {
509
506
  object-fit: contain;
510
507
  // max-height: 360px;
@@ -515,7 +512,7 @@ function handleChooseTag(tag: string) {
515
512
  .swiper-mode {
516
513
  margin-top: 16px;
517
514
 
518
- .el-image {
515
+ .sugar-image {
519
516
  :deep(img) {
520
517
  object-fit: contain;
521
518
  max-height: 260px;
@@ -262,7 +262,12 @@ export function useActiveAnchor() {
262
262
  onMounted(() => {
263
263
  const { hash } = window.location
264
264
  if (hash) {
265
- el.value = document.querySelector(decodeURIComponent(hash)) as any
265
+ try {
266
+ el.value = document.querySelector(decodeURIComponent(hash)) as any
267
+ }
268
+ catch (error) {
269
+ console.warn('useActiveAnchor error', error)
270
+ }
266
271
  }
267
272
  })
268
273
  return el
@@ -272,7 +272,7 @@ export namespace Theme {
272
272
  tag?: string
273
273
  }
274
274
  export interface Alert {
275
- type: 'success' | 'warning' | 'info' | 'error'
275
+ type: 'success' | 'warning' | 'info' | 'error' | 'primary'
276
276
  /**
277
277
  * 细粒度的时间控制
278
278
  * 默认展示时间,-1 只展示1次,其它数字为每次都展示,一定时间后自动消失,0为不自动消失
@@ -424,7 +424,7 @@ export namespace Theme {
424
424
  authorList?: Omit<FriendLink, 'avatar'>[]
425
425
  /**
426
426
  * 启用 [vitepress-plugin-tabs](https://www.npmjs.com/package/vitepress-plugin-tabs)
427
- * @default false
427
+ * @default true
428
428
  */
429
429
  tabs?: boolean
430
430
  works?: UserWorks