@sugarat/theme 0.5.10 → 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.
- package/node.d.ts +2 -4
- package/node.js +206 -156
- package/node.mjs +205 -154
- package/package.json +10 -14
- package/src/components/Alert.vue +308 -0
- package/src/components/Avatar.vue +66 -0
- package/src/components/BlogAlert.vue +4 -4
- package/src/components/BlogApp.vue +4 -0
- package/src/components/BlogArticleAnalyze.vue +70 -32
- package/src/components/BlogButtonAfterArticle.vue +4 -4
- package/src/components/BlogFriendLink.vue +54 -27
- package/src/components/BlogHomeInfo.vue +1 -3
- package/src/components/BlogHomeTags.vue +8 -14
- package/src/components/BlogHotArticle.vue +3 -3
- package/src/components/BlogImagePreview.vue +3 -3
- package/src/components/BlogList.vue +7 -8
- package/src/components/BlogRecommendArticle.vue +3 -3
- package/src/components/Button.vue +165 -0
- package/src/components/Carousel.vue +254 -0
- package/src/components/CarouselItem.vue +154 -0
- package/src/components/Image.vue +34 -0
- package/src/components/ImageViewer.vue +406 -0
- package/src/components/Pagination.vue +397 -0
- package/src/components/Tag.vue +163 -0
- package/src/components/UserWorks.vue +19 -22
- package/src/composables/config/blog.ts +6 -1
- package/src/composables/config/index.ts +2 -2
- package/src/index.ts +10 -17
- package/src/node.ts +0 -3
- package/src/styles/el-base.css +340 -0
- package/src/utils/client/index.ts +17 -0
- package/src/utils/node/mdPlugins.ts +1 -1
- package/src/utils/node/theme.ts +5 -2
- package/src/utils/node/vitePlugins.ts +51 -18
|
@@ -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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
<
|
|
280
|
-
<
|
|
281
|
-
<
|
|
282
|
-
:
|
|
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
|
-
</
|
|
286
|
-
</
|
|
282
|
+
</CarouselItem>
|
|
283
|
+
</Carousel>
|
|
287
284
|
</div>
|
|
288
285
|
<!-- list -->
|
|
289
286
|
<div v-if="work.coverLayout === 'list'" class="list-mode">
|
|
290
|
-
<
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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
|
-
|
|
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
|
|
427
|
+
* @default true
|
|
428
428
|
*/
|
|
429
429
|
tabs?: boolean
|
|
430
430
|
works?: UserWorks
|