valaxy-theme-yun 0.20.0-beta.2 → 0.20.0-beta.4
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/LICENSE +21 -0
- package/components/ValaxyMain.vue +2 -2
- package/components/YunAlbum.vue +13 -3
- package/components/YunAlbumList.vue +5 -11
- package/components/YunCategories.vue +2 -1
- package/components/YunCategory.vue +23 -37
- package/components/YunCategoryChildItem.vue +49 -0
- package/components/YunLayoutPostTag.vue +11 -1
- package/components/YunPostCollapse.vue +5 -3
- package/components/project/YunProjectCard.vue +29 -3
- package/components/project/YunProjectCollection.vue +1 -1
- package/components/project/YunProjectToggleButton.vue +1 -0
- package/composables/animation.ts +33 -0
- package/layouts/404.vue +1 -3
- package/layouts/albums.vue +25 -24
- package/layouts/archives.vue +0 -1
- package/layouts/categories.vue +8 -4
- package/layouts/gallery.vue +31 -30
- package/layouts/tags.vue +11 -5
- package/package.json +1 -1
- package/styles/animations/index.scss +37 -0
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2022 云游君 YunYouJun <me@yunyoujun.cn>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -45,10 +45,10 @@ onContentUpdated(() => {
|
|
45
45
|
}" flex="~ col grow"
|
46
46
|
p="lt-md:0"
|
47
47
|
>
|
48
|
-
<YunCard :cover="frontmatter.cover" m="0" class="relative" :style="styles as StyleValue">
|
48
|
+
<YunCard :cover="frontmatter.cover" m="0" class="relative pt-8" :style="styles as StyleValue">
|
49
49
|
<slot name="main-header">
|
50
50
|
<YunPageHeader
|
51
|
-
class="mb-2
|
51
|
+
class="mb-2"
|
52
52
|
:title="title"
|
53
53
|
:icon="frontmatter.icon || icon"
|
54
54
|
:color="frontmatter.color || color"
|
package/components/YunAlbum.vue
CHANGED
@@ -9,7 +9,7 @@ defineProps<{
|
|
9
9
|
|
10
10
|
<template>
|
11
11
|
<AppLink class="yun-album-list-item" :to="album.url">
|
12
|
-
<figure :title="album.desc">
|
12
|
+
<figure class="m-10" flex="~ col" :title="album.desc">
|
13
13
|
<img
|
14
14
|
loading="lazy"
|
15
15
|
class="yun-album-list-cover"
|
@@ -17,9 +17,19 @@ defineProps<{
|
|
17
17
|
:alt="album.caption"
|
18
18
|
:on-error="onImgError"
|
19
19
|
>
|
20
|
-
<figcaption>
|
21
|
-
|
20
|
+
<figcaption class="yun-album-caption yun-title-effects text-$va-c-text inline-flex">
|
21
|
+
{{ album.caption }}
|
22
22
|
</figcaption>
|
23
23
|
</figure>
|
24
24
|
</AppLink>
|
25
25
|
</template>
|
26
|
+
|
27
|
+
<style lang="scss">
|
28
|
+
.yun-album-caption {
|
29
|
+
position: absolute;
|
30
|
+
bottom: -3rem;
|
31
|
+
display: block;
|
32
|
+
text-align: center;
|
33
|
+
width: 100%;
|
34
|
+
}
|
35
|
+
</style>
|
@@ -7,8 +7,11 @@ defineProps<{
|
|
7
7
|
</script>
|
8
8
|
|
9
9
|
<template>
|
10
|
-
<div class="yun-album-list">
|
11
|
-
<YunAlbum
|
10
|
+
<div class="yun-album-list mb-4">
|
11
|
+
<YunAlbum
|
12
|
+
v-for="album in albums" :key="album.url"
|
13
|
+
:album="album"
|
14
|
+
/>
|
12
15
|
</div>
|
13
16
|
</template>
|
14
17
|
|
@@ -26,7 +29,6 @@ defineProps<{
|
|
26
29
|
figure {
|
27
30
|
position: relative;
|
28
31
|
width: 15rem;
|
29
|
-
margin: 2rem;
|
30
32
|
|
31
33
|
&::before {
|
32
34
|
content: '';
|
@@ -53,14 +55,6 @@ defineProps<{
|
|
53
55
|
object-fit: cover;
|
54
56
|
background-color: #eee;
|
55
57
|
}
|
56
|
-
|
57
|
-
figcaption {
|
58
|
-
position: absolute;
|
59
|
-
bottom: -2.5rem;
|
60
|
-
display: block;
|
61
|
-
text-align: center;
|
62
|
-
width: 100%;
|
63
|
-
}
|
64
58
|
}
|
65
59
|
}
|
66
60
|
}
|
@@ -26,11 +26,12 @@ const categoryList = computed(() => {
|
|
26
26
|
<template>
|
27
27
|
<div flex="~ col">
|
28
28
|
<ul
|
29
|
-
v-for="category in categories.values()"
|
29
|
+
v-for="(category, i) in categories.values()"
|
30
30
|
:key="category.name"
|
31
31
|
class="category-list"
|
32
32
|
>
|
33
33
|
<YunCategory
|
34
|
+
:i="i"
|
34
35
|
:parent-key="category.name"
|
35
36
|
:category="category"
|
36
37
|
:level="level + 1"
|
@@ -1,11 +1,13 @@
|
|
1
1
|
<script lang="ts" setup>
|
2
|
-
import {
|
2
|
+
import { onMounted, ref } from 'vue'
|
3
3
|
import type { CategoryList, Post } from 'valaxy'
|
4
|
-
import {
|
4
|
+
import { useInvisibleElement } from 'valaxy'
|
5
5
|
import { useI18n } from 'vue-i18n'
|
6
|
-
import {
|
6
|
+
import { useRouter } from 'vue-router'
|
7
|
+
import { useYunSpringAnimation } from '../composables/animation'
|
7
8
|
|
8
9
|
const props = withDefaults(defineProps<{
|
10
|
+
i?: number
|
9
11
|
parentKey: string
|
10
12
|
// to eliminate the warning
|
11
13
|
category: Post | CategoryList
|
@@ -20,24 +22,10 @@ const props = withDefaults(defineProps<{
|
|
20
22
|
})
|
21
23
|
|
22
24
|
const router = useRouter()
|
23
|
-
const route = useRoute()
|
24
|
-
const categoryList = computed(() => {
|
25
|
-
const c = (route.query.category as string) || ''
|
26
|
-
return Array.isArray(c) ? [c] : c.split('/')
|
27
|
-
})
|
28
25
|
|
29
26
|
const collapse = ref(props.collapsable)
|
30
27
|
const { t } = useI18n()
|
31
28
|
|
32
|
-
/**
|
33
|
-
* i18n
|
34
|
-
*/
|
35
|
-
const { locale } = useI18n()
|
36
|
-
function getTitle(post: Post | any) {
|
37
|
-
const lang = locale.value === 'zh-CN' ? 'zh' : locale.value
|
38
|
-
return post[`title_${lang}`] ? post[`title_${lang}`] : post.title
|
39
|
-
}
|
40
|
-
|
41
29
|
const postCollapseElRef = ref<HTMLElement>()
|
42
30
|
const { show } = useInvisibleElement(postCollapseElRef)
|
43
31
|
/**
|
@@ -61,11 +49,21 @@ onMounted(() => {
|
|
61
49
|
if (postCollapseEl)
|
62
50
|
postCollapseElRef.value = postCollapseEl
|
63
51
|
})
|
52
|
+
|
53
|
+
const categoryRef = ref<HTMLElement>()
|
54
|
+
if (props.level === 1) {
|
55
|
+
useYunSpringAnimation(categoryRef, {
|
56
|
+
i: props.i || 0,
|
57
|
+
y: 20,
|
58
|
+
duration: 200,
|
59
|
+
})
|
60
|
+
}
|
64
61
|
</script>
|
65
62
|
|
66
63
|
<template>
|
67
64
|
<li
|
68
|
-
|
65
|
+
ref="categoryRef"
|
66
|
+
class="category-list-item inline-flex items-center cursor-pointer w-full gap-2 px-3 py-2 rounded"
|
69
67
|
hover="bg-black/5"
|
70
68
|
>
|
71
69
|
<span
|
@@ -98,28 +96,16 @@ onMounted(() => {
|
|
98
96
|
>
|
99
97
|
<ul v-if="!collapse">
|
100
98
|
<li
|
101
|
-
v-for="categoryItem,
|
99
|
+
v-for="categoryItem, cI in category.children.values()"
|
100
|
+
:key="cI"
|
102
101
|
class="post-list-item text-$va-c-text" m="l-4"
|
103
102
|
hover="text-$va-c-primary-lighter"
|
104
103
|
>
|
105
|
-
<
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
/>
|
111
|
-
</template>
|
112
|
-
|
113
|
-
<template v-else>
|
114
|
-
<RouterLink
|
115
|
-
v-if="categoryItem.title" :to="categoryItem.path || ''"
|
116
|
-
class="inline-flex items-center gap-2 px-3 py-2 w-full rounded transition"
|
117
|
-
hover="bg-black/5"
|
118
|
-
>
|
119
|
-
<div i-ri-file-text-line />
|
120
|
-
<span font="serif black">{{ getTitle(categoryItem) }}</span>
|
121
|
-
</RouterLink>
|
122
|
-
</template>
|
104
|
+
<YunCategoryChildItem
|
105
|
+
:i="cI"
|
106
|
+
:category-item="categoryItem"
|
107
|
+
:parent-key="parentKey"
|
108
|
+
/>
|
123
109
|
</li>
|
124
110
|
</ul>
|
125
111
|
</Transition>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<script setup lang="ts">
|
2
|
+
import type { Post } from 'valaxy'
|
3
|
+
import { isCategoryList } from 'valaxy'
|
4
|
+
import { computed } from 'vue'
|
5
|
+
import { useRoute } from 'vue-router'
|
6
|
+
import { useI18n } from 'vue-i18n'
|
7
|
+
|
8
|
+
defineProps<{
|
9
|
+
i?: number
|
10
|
+
categoryItem: any
|
11
|
+
parentKey?: string
|
12
|
+
}>()
|
13
|
+
|
14
|
+
/**
|
15
|
+
* i18n
|
16
|
+
*/
|
17
|
+
const { locale } = useI18n()
|
18
|
+
function getTitle(post: Post | any) {
|
19
|
+
const lang = locale.value === 'zh-CN' ? 'zh' : locale.value
|
20
|
+
return post[`title_${lang}`] ? post[`title_${lang}`] : post.title
|
21
|
+
}
|
22
|
+
const route = useRoute()
|
23
|
+
const categoryList = computed(() => {
|
24
|
+
const c = (route.query.category as string) || ''
|
25
|
+
return Array.isArray(c) ? [c] : c.split('/')
|
26
|
+
})
|
27
|
+
</script>
|
28
|
+
|
29
|
+
<template>
|
30
|
+
<template v-if="isCategoryList(categoryItem)">
|
31
|
+
<YunCategory
|
32
|
+
:parent-key="parentKey ? `${parentKey}/${categoryItem.name}` : categoryItem.name"
|
33
|
+
:category="categoryItem"
|
34
|
+
:collapsable="!categoryList.includes(categoryItem.name)"
|
35
|
+
/>
|
36
|
+
</template>
|
37
|
+
|
38
|
+
<template v-else>
|
39
|
+
<RouterLink
|
40
|
+
v-if="categoryItem.title"
|
41
|
+
:to="categoryItem.path || ''"
|
42
|
+
class="inline-flex items-center gap-2 px-3 py-2 w-full rounded"
|
43
|
+
hover="bg-black/5"
|
44
|
+
>
|
45
|
+
<div i-ri-file-text-line />
|
46
|
+
<span font="serif black">{{ getTitle(categoryItem) }}</span>
|
47
|
+
</RouterLink>
|
48
|
+
</template>
|
49
|
+
</template>
|
@@ -1,12 +1,22 @@
|
|
1
1
|
<script lang="ts" setup>
|
2
|
-
|
2
|
+
import { ref } from 'vue'
|
3
|
+
import { useYunSpringAnimation } from '../composables/animation'
|
4
|
+
|
5
|
+
const props = defineProps<{
|
6
|
+
i?: number
|
3
7
|
title: string
|
4
8
|
count: number
|
5
9
|
}>()
|
10
|
+
|
11
|
+
const tagRef = ref<HTMLElement>()
|
12
|
+
useYunSpringAnimation(tagRef, {
|
13
|
+
i: props.i || 0,
|
14
|
+
})
|
6
15
|
</script>
|
7
16
|
|
8
17
|
<template>
|
9
18
|
<span
|
19
|
+
ref="tagRef"
|
10
20
|
inline-flex my="2" p="1"
|
11
21
|
class="post-tag cursor-pointer items-baseline leading-4"
|
12
22
|
>
|
@@ -45,9 +45,11 @@ const sortedYears = computed(() => {
|
|
45
45
|
|
46
46
|
<template>
|
47
47
|
<div class="post-collapse px-10 lt-sm:px-5 max-w-3xl" relative>
|
48
|
-
<
|
49
|
-
|
50
|
-
|
48
|
+
<Transition appear enter-active-class="animate-fade-in animate-duration-400">
|
49
|
+
<div w="full" text="center" class="yun-text-light" p="2">
|
50
|
+
{{ t('counter.archives', posts.length) }}
|
51
|
+
</div>
|
52
|
+
</Transition>
|
51
53
|
|
52
54
|
<div class="post-collapse-action" text="center">
|
53
55
|
<button class="yun-icon-btn shadow hover:shadow-md" @click="isDesc = !isDesc">
|
@@ -1,9 +1,34 @@
|
|
1
1
|
<script setup lang="ts">
|
2
|
-
import { type CSSProperties, computed } from 'vue'
|
2
|
+
import { type CSSProperties, computed, ref } from 'vue'
|
3
3
|
import { TinyColor } from '@ctrl/tinycolor'
|
4
|
+
import { useMotion } from '@vueuse/motion'
|
4
5
|
import type { ProjectItem } from '../../types'
|
6
|
+
import { cubicBezier } from '../../client/constants'
|
7
|
+
|
8
|
+
const props = defineProps<{
|
9
|
+
i: number
|
10
|
+
project: ProjectItem
|
11
|
+
}>()
|
12
|
+
|
13
|
+
const cardRef = ref<HTMLElement>()
|
14
|
+
useMotion(cardRef, {
|
15
|
+
initial: {
|
16
|
+
opacity: 0,
|
17
|
+
y: 50,
|
18
|
+
},
|
19
|
+
enter: {
|
20
|
+
opacity: 1,
|
21
|
+
y: 0,
|
22
|
+
transition: {
|
23
|
+
delay: props.i * 50,
|
24
|
+
type: 'spring',
|
25
|
+
ease: cubicBezier.easeIn,
|
26
|
+
damping: 8,
|
27
|
+
duration: 400,
|
28
|
+
},
|
29
|
+
},
|
30
|
+
})
|
5
31
|
|
6
|
-
const props = defineProps<{ project: ProjectItem }>()
|
7
32
|
const cardStyle = computed(() => {
|
8
33
|
const styles: CSSProperties = {
|
9
34
|
color: props.project.textColor,
|
@@ -63,8 +88,9 @@ const links = computed(() => [
|
|
63
88
|
|
64
89
|
<template>
|
65
90
|
<div
|
91
|
+
ref="cardRef"
|
66
92
|
flex="~ col center"
|
67
|
-
class="m-2 w-90 transform rounded shadow-md grayscale-30
|
93
|
+
class="m-2 w-90 transform rounded shadow-md grayscale-30"
|
68
94
|
bg="opacity-80 gradient-to-br"
|
69
95
|
p="x-2 b-12"
|
70
96
|
hover="shadow-lg grayscale-0"
|
@@ -11,5 +11,5 @@ defineProps<{
|
|
11
11
|
<div class="w-full flex justify-center" text="xl" font="black" m="b-2 t-4">
|
12
12
|
{{ title }}
|
13
13
|
</div>
|
14
|
-
<YunProjectCard v-for="project, i in projects" :key="i" :project="project" />
|
14
|
+
<YunProjectCard v-for="project, i in projects" :key="i" :project="project" :i="i" />
|
15
15
|
</template>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { useMotion } from '@vueuse/motion'
|
2
|
+
import type { MaybeRef } from 'vue'
|
3
|
+
import { cubicBezier } from '../client/constants'
|
4
|
+
|
5
|
+
/**
|
6
|
+
* 统一的弹跳出现动画
|
7
|
+
*/
|
8
|
+
export function useYunSpringAnimation(target: MaybeRef<HTMLElement | undefined>, options: {
|
9
|
+
/**
|
10
|
+
* index order
|
11
|
+
*/
|
12
|
+
i: number
|
13
|
+
y?: number
|
14
|
+
duration?: number
|
15
|
+
}) {
|
16
|
+
useMotion(target, {
|
17
|
+
initial: {
|
18
|
+
opacity: 0,
|
19
|
+
y: options.y || 40,
|
20
|
+
},
|
21
|
+
enter: {
|
22
|
+
opacity: 1,
|
23
|
+
y: 0,
|
24
|
+
transition: {
|
25
|
+
delay: options.i * 50,
|
26
|
+
type: 'spring',
|
27
|
+
ease: cubicBezier.easeIn,
|
28
|
+
damping: 8,
|
29
|
+
duration: options.duration || 400,
|
30
|
+
},
|
31
|
+
},
|
32
|
+
})
|
33
|
+
}
|
package/layouts/404.vue
CHANGED
@@ -7,8 +7,6 @@ const { back } = useBack()
|
|
7
7
|
</script>
|
8
8
|
|
9
9
|
<template>
|
10
|
-
<YunSidebar :show-hamburger="true" />
|
11
|
-
|
12
10
|
<main class="va-main w-full h-screen" text="center" flex="~ col" justify="center" items="center">
|
13
11
|
<div class="not-found" title="404" font="mono">
|
14
12
|
404
|
@@ -27,6 +25,6 @@ const { back } = useBack()
|
|
27
25
|
<style lang="scss" scoped>
|
28
26
|
.not-found {
|
29
27
|
font-size: 10rem;
|
30
|
-
text-shadow: 0 5px 10px
|
28
|
+
text-shadow: 0 5px 10px rgb(0 0 0 / .25), 0 20px 20px rgb(0 0 0 / .15);
|
31
29
|
}
|
32
30
|
</style>
|
package/layouts/albums.vue
CHANGED
@@ -20,28 +20,29 @@ const albums = computed(() => frontmatter.value.albums || [])
|
|
20
20
|
</script>
|
21
21
|
|
22
22
|
<template>
|
23
|
-
<
|
24
|
-
<
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
23
|
+
<YunLayoutWrapper>
|
24
|
+
<YunLayoutLeft />
|
25
|
+
|
26
|
+
<RouterView v-slot="{ Component }">
|
27
|
+
<component :is="Component">
|
28
|
+
<template #main-header>
|
29
|
+
<YunPageHeader
|
30
|
+
:title="title || t('title.album')"
|
31
|
+
:icon="frontmatter.icon || 'i-ri-gallery-line'"
|
32
|
+
:color="frontmatter.color"
|
33
|
+
:page-title-class="frontmatter.pageTitleClass"
|
34
|
+
/>
|
35
|
+
</template>
|
36
|
+
<template #main-content>
|
37
|
+
<div text="center" class="yun-text-light" p="2">
|
38
|
+
{{ t('counter.albums', albums.length) }}
|
39
|
+
</div>
|
40
|
+
<YunAlbumList :albums="albums" />
|
41
|
+
<RouterView />
|
42
|
+
</template>
|
43
|
+
</component>
|
44
|
+
</RouterView>
|
45
|
+
</YunLayoutWrapper>
|
46
|
+
|
47
|
+
<YunFooter />
|
47
48
|
</template>
|
package/layouts/archives.vue
CHANGED
package/layouts/categories.vue
CHANGED
@@ -53,7 +53,6 @@ useSchemaOrg([
|
|
53
53
|
<component :is="Component">
|
54
54
|
<template #main-header>
|
55
55
|
<YunPageHeader
|
56
|
-
class="mt-8"
|
57
56
|
:title="title || t('menu.categories')"
|
58
57
|
:icon="pageIcon"
|
59
58
|
:color="frontmatter.color"
|
@@ -61,9 +60,14 @@ useSchemaOrg([
|
|
61
60
|
/>
|
62
61
|
</template>
|
63
62
|
<template #main-content>
|
64
|
-
<
|
65
|
-
|
66
|
-
|
63
|
+
<Transition
|
64
|
+
enter-active-class="animate-fade-in animate-duration-400"
|
65
|
+
appear
|
66
|
+
>
|
67
|
+
<div text="center" class="yun-text-light" p="2">
|
68
|
+
{{ t('counter.categories', Array.from(categories.children).length) }}
|
69
|
+
</div>
|
70
|
+
</Transition>
|
67
71
|
<YunCategories :categories="categories.children" />
|
68
72
|
<RouterView />
|
69
73
|
</template>
|
package/layouts/gallery.vue
CHANGED
@@ -29,34 +29,35 @@ const YunGallery = runtimeConfig.value.addons['valaxy-addon-lightgallery']
|
|
29
29
|
</script>
|
30
30
|
|
31
31
|
<template>
|
32
|
-
<
|
33
|
-
<
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
32
|
+
<YunLayoutWrapper>
|
33
|
+
<YunLayoutLeft />
|
34
|
+
|
35
|
+
<RouterView v-slot="{ Component }">
|
36
|
+
<component :is="Component">
|
37
|
+
<template #main-header>
|
38
|
+
<YunPageHeader
|
39
|
+
:title="title || t('title.gallery')"
|
40
|
+
:icon="frontmatter.icon || 'i-ri-gallery-line'"
|
41
|
+
:color="frontmatter.color"
|
42
|
+
:page-title-class="frontmatter.pageTitleClass"
|
43
|
+
/>
|
44
|
+
</template>
|
45
|
+
<template #main-content>
|
46
|
+
<div text="center" class="yun-text-light" p="2">
|
47
|
+
{{ t('counter.photos', photos.length) }}
|
48
|
+
</div>
|
49
|
+
<div class="page-action" text="center">
|
50
|
+
<a class="yun-icon-btn" :title="t('accessibility.back')" @click="() => router.back()">
|
51
|
+
<div i-ri-arrow-go-back-line />
|
52
|
+
</a>
|
53
|
+
</div>
|
54
|
+
<ValaxyGalleryDecrypt v-if="frontmatter.encryptedPhotos" :encrypted-photos="frontmatter.encryptedPhotos" />
|
55
|
+
<YunGallery v-else :photos="photos" />
|
56
|
+
<RouterView />
|
57
|
+
</template>
|
58
|
+
</component>
|
59
|
+
</RouterView>
|
60
|
+
</YunLayoutWrapper>
|
61
|
+
|
62
|
+
<YunFooter />
|
62
63
|
</template>
|
package/layouts/tags.vue
CHANGED
@@ -53,6 +53,7 @@ function displayTag(tag: string) {
|
|
53
53
|
}
|
54
54
|
|
55
55
|
const title = usePostTitle(frontmatter)
|
56
|
+
const tagArr = computed(() => Array.from(tags.value).sort())
|
56
57
|
|
57
58
|
// use flex to fix `overflow-wrap: break-words;` not working in Safari
|
58
59
|
</script>
|
@@ -65,7 +66,6 @@ const title = usePostTitle(frontmatter)
|
|
65
66
|
<component :is="Component">
|
66
67
|
<template #main-header>
|
67
68
|
<YunPageHeader
|
68
|
-
class="mt-8"
|
69
69
|
:title="title || t('menu.tags')"
|
70
70
|
:icon="frontmatter.icon || 'i-ri-tag-line'"
|
71
71
|
:color="frontmatter.color"
|
@@ -73,14 +73,20 @@ const title = usePostTitle(frontmatter)
|
|
73
73
|
/>
|
74
74
|
</template>
|
75
75
|
<template #main-content>
|
76
|
-
<
|
77
|
-
|
78
|
-
|
76
|
+
<Transition
|
77
|
+
enter-active-class="animate-fade-in animate-duration-400"
|
78
|
+
appear
|
79
|
+
>
|
80
|
+
<div class="yun-text-light" text="center" p="2">
|
81
|
+
{{ t('counter.tags', tagArr.length) }}
|
82
|
+
</div>
|
83
|
+
</Transition>
|
79
84
|
|
80
85
|
<div class="justify-center items-end" flex="~ wrap" gap="1">
|
81
86
|
<YunLayoutPostTag
|
82
|
-
v-for="[key, tag] in
|
87
|
+
v-for="([key, tag], i) in tagArr"
|
83
88
|
:key="key"
|
89
|
+
:i="i"
|
84
90
|
:title="key"
|
85
91
|
:count="tag.count"
|
86
92
|
:style="getTagStyle(tag.count)"
|
package/package.json
CHANGED
@@ -34,3 +34,40 @@
|
|
34
34
|
opacity: 1;
|
35
35
|
}
|
36
36
|
}
|
37
|
+
|
38
|
+
// title-effects
|
39
|
+
.yun-title-effects {
|
40
|
+
position: relative;
|
41
|
+
|
42
|
+
&::before,
|
43
|
+
&::after {
|
44
|
+
content: "";
|
45
|
+
position: absolute;
|
46
|
+
width: 10px;
|
47
|
+
height: 10px;
|
48
|
+
opacity: 0;
|
49
|
+
border: 2px solid;
|
50
|
+
transition: 0.3s;
|
51
|
+
transition-timing-function: cubic-bezier(0.17, 0.67, 0.05, 1.29);
|
52
|
+
}
|
53
|
+
|
54
|
+
&::before {
|
55
|
+
top: 0;
|
56
|
+
left: 0;
|
57
|
+
border-width: 2px 0 0 2px;
|
58
|
+
transform: translate3d(10px, 10px, 0);
|
59
|
+
}
|
60
|
+
|
61
|
+
&::after {
|
62
|
+
right: 0;
|
63
|
+
bottom: 0;
|
64
|
+
border-width: 0 2px 2px 0;
|
65
|
+
transform: translate3d(-10px, -10px, 0);
|
66
|
+
}
|
67
|
+
|
68
|
+
&:hover::before,
|
69
|
+
&:hover::after {
|
70
|
+
opacity: 1;
|
71
|
+
transform: translate3d(0, 0, 0);
|
72
|
+
}
|
73
|
+
}
|