valaxy-theme-yun 0.20.0-beta.1 → 0.20.0-beta.10
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/bump.config.ts +7 -0
- package/components/ValaxyMain.vue +11 -18
- package/components/YunAdBoard.vue +4 -0
- 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/YunOverview.vue +0 -5
- package/components/YunPagination.vue +8 -5
- package/components/YunPostCollapse.vue +5 -3
- package/components/layout/YunLayoutWrapper.vue +3 -7
- package/components/project/YunProjectCard.vue +29 -3
- package/components/project/YunProjectCollection.vue +1 -1
- package/components/project/YunProjectToggleButton.vue +1 -0
- package/components/prologue/PrologueSquare.vue +9 -8
- package/components/prologue/YunAEFrame.vue +68 -85
- package/components/site/YunSiteDescription.vue +11 -0
- package/components/site/YunSiteLinkItem.vue +1 -1
- package/components/site/YunSiteSubtitle.vue +14 -0
- package/components/ui/YunDivider.vue +3 -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/home.vue +5 -11
- package/layouts/tags.vue +11 -5
- package/package.json +9 -5
- package/styles/animations/index.scss +37 -0
- package/styles/layout/index.scss +0 -5
- package/unocss.config.ts +0 -1
- package/utils/animation.ts +2 -0
- package/valaxy.config.ts +1 -0
package/bump.config.ts
ADDED
@@ -46,16 +46,17 @@ onContentUpdated(() => {
|
|
46
46
|
p="lt-md:0"
|
47
47
|
>
|
48
48
|
<YunCard :cover="frontmatter.cover" m="0" class="relative" :style="styles as StyleValue">
|
49
|
-
<
|
50
|
-
<
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
<div class="mt-8 mb-4">
|
50
|
+
<slot name="main-header">
|
51
|
+
<YunPageHeader
|
52
|
+
:title="title"
|
53
|
+
:icon="frontmatter.icon || icon"
|
54
|
+
:color="frontmatter.color || color"
|
55
|
+
:cover="frontmatter.cover"
|
56
|
+
:page-title-class="frontmatter.pageTitleClass"
|
57
|
+
/>
|
58
|
+
</slot>
|
59
|
+
</div>
|
59
60
|
<slot name="main-header-after" />
|
60
61
|
|
61
62
|
<div p="x-4 b-8" class="sm:px-6 lg:px-12 xl:px-16" w="full">
|
@@ -97,14 +98,6 @@ onContentUpdated(() => {
|
|
97
98
|
<style lang="scss">
|
98
99
|
@use 'valaxy/client/styles/mixins/index.scss' as *;
|
99
100
|
|
100
|
-
@include screen('md') {
|
101
|
-
.yun-main {
|
102
|
-
&.has-sidebar {
|
103
|
-
padding-left: var(--va-sidebar-width);
|
104
|
-
}
|
105
|
-
}
|
106
|
-
}
|
107
|
-
|
108
101
|
@include screen('xl') {
|
109
102
|
.content{
|
110
103
|
// 8px scrollbar width
|
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
|
>
|
@@ -48,7 +48,7 @@ const { curPage, totalPages, showPage, getTo, surLen, prevTo, nextTo, showPrev,
|
|
48
48
|
|
49
49
|
<style lang="scss">
|
50
50
|
:root {
|
51
|
-
--page-btn-bg-color:
|
51
|
+
--page-btn-bg-color: rgb(255 255 255 / 0.5);
|
52
52
|
--page-btn-hover-bg-color: var(--va-c-primary-lighter);
|
53
53
|
--page-btn-active-bg-color: var(--va-c-primary-light);
|
54
54
|
}
|
@@ -69,10 +69,10 @@ const { curPage, totalPages, showPage, getTo, surLen, prevTo, nextTo, showPrev,
|
|
69
69
|
width: 2rem;
|
70
70
|
height: 2rem;
|
71
71
|
margin: 0;
|
72
|
-
transition: background-color var(--va-transition-duration) ease;
|
73
72
|
|
74
73
|
// disabled attr
|
75
74
|
&[disabled] {
|
75
|
+
color: var(--va-c-text-light);
|
76
76
|
background-color: var(--va-c-bg-mute);
|
77
77
|
}
|
78
78
|
}
|
@@ -84,19 +84,22 @@ const { curPage, totalPages, showPage, getTo, surLen, prevTo, nextTo, showPrev,
|
|
84
84
|
background-color: var(--page-btn-bg-color);
|
85
85
|
|
86
86
|
&:hover {
|
87
|
-
color: var(--va-c-bg);
|
87
|
+
// color: var(--va-c-bg);
|
88
|
+
color: white;
|
88
89
|
background: var(--page-btn-hover-bg-color);
|
89
90
|
}
|
90
91
|
|
91
92
|
&:active {
|
92
|
-
color: var(--va-c-bg);
|
93
|
+
// color: var(--va-c-bg);
|
94
|
+
color: white;
|
93
95
|
background: var(--page-btn-active-bg-color);
|
94
96
|
}
|
95
97
|
|
96
98
|
&.active {
|
99
|
+
// color: var(--va-c-bg);
|
100
|
+
color: white;
|
97
101
|
font-weight: normal;
|
98
102
|
background: var(--page-btn-active-bg-color);
|
99
|
-
color: var(--va-c-bg);
|
100
103
|
cursor: default;
|
101
104
|
}
|
102
105
|
|
@@ -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,16 +1,12 @@
|
|
1
1
|
<script setup lang="ts">
|
2
|
-
|
3
|
-
|
4
|
-
const yun = useYunAppStore()
|
2
|
+
// common layout
|
5
3
|
</script>
|
6
4
|
|
7
5
|
<template>
|
8
6
|
<div
|
9
7
|
flex="~"
|
10
|
-
|
11
|
-
|
12
|
-
'flex-col': yun.size.isXs,
|
13
|
-
}"
|
8
|
+
m="t-24 md:t-36"
|
9
|
+
class="w-full max-w-screen-2xl m-auto justify-center items-start gap-4"
|
14
10
|
>
|
15
11
|
<slot />
|
16
12
|
</div>
|
@@ -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>
|
@@ -1,11 +1,9 @@
|
|
1
1
|
<script setup lang="ts">
|
2
2
|
import { useMotion } from '@vueuse/motion'
|
3
3
|
import { ref } from 'vue'
|
4
|
-
import { useSiteConfig } from 'valaxy'
|
5
4
|
import { cubicBezier } from '../../client/constants'
|
6
5
|
import { useThemeConfig } from '../../composables'
|
7
6
|
|
8
|
-
const siteConfig = useSiteConfig()
|
9
7
|
const themeConfig = useThemeConfig()
|
10
8
|
|
11
9
|
const showContent = ref(false)
|
@@ -107,14 +105,17 @@ useMotion(introRef, {
|
|
107
105
|
>
|
108
106
|
<YunAuthorName class="mt-3" />
|
109
107
|
<YunAuthorIntro />
|
110
|
-
|
111
|
-
<
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
108
|
+
|
109
|
+
<YunDivider />
|
110
|
+
|
111
|
+
<div flex="~ col" class="gap-2 items-center justify-center">
|
112
|
+
<YunSiteTitle />
|
113
|
+
<YunSiteSubtitle />
|
114
|
+
<YunSiteDescription />
|
116
115
|
</div>
|
117
116
|
|
117
|
+
<YunDivider />
|
118
|
+
|
118
119
|
<div
|
119
120
|
class="mt-4 flex-center w-50 md:w-100 m-auto gap-2"
|
120
121
|
flex="~ wrap"
|
@@ -1,100 +1,44 @@
|
|
1
1
|
<script setup lang="ts">
|
2
|
-
import
|
3
|
-
import { useMotion } from '@vueuse/motion'
|
4
|
-
import { useAppStore } from 'valaxy'
|
5
|
-
import { computed, ref } from 'vue'
|
6
|
-
|
7
|
-
const tlRef = ref<HTMLElement>()
|
8
|
-
const trRef = ref<HTMLElement>()
|
9
|
-
const blRef = ref<HTMLElement>()
|
10
|
-
const brRef = ref<HTMLElement>()
|
11
|
-
|
12
|
-
const app = useAppStore()
|
13
|
-
const cornerSize = computed(() => {
|
14
|
-
return app.isMobile ? 40 : 50
|
15
|
-
})
|
16
|
-
const cornerMargin = computed(() => {
|
17
|
-
return app.isMobile ? 10 : 30
|
18
|
-
})
|
19
|
-
const cornerBorderSize = computed(() => {
|
20
|
-
return app.isMobile ? 3 : 5
|
21
|
-
})
|
22
|
-
|
23
|
-
const cornerTransitionProps: PopmotionTransitionProps = {
|
24
|
-
type: 'spring',
|
25
|
-
duration: 600,
|
26
|
-
}
|
2
|
+
import { onMounted, ref } from 'vue'
|
27
3
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
y: -cornerMargin.value,
|
32
|
-
},
|
33
|
-
enter: {
|
34
|
-
x: 0,
|
35
|
-
y: 0,
|
36
|
-
transition: cornerTransitionProps,
|
37
|
-
},
|
38
|
-
})
|
39
|
-
|
40
|
-
useMotion(trRef, {
|
41
|
-
initial: {
|
42
|
-
x: cornerMargin.value,
|
43
|
-
y: -cornerMargin.value,
|
44
|
-
},
|
45
|
-
enter: {
|
46
|
-
x: 0,
|
47
|
-
y: 0,
|
48
|
-
transition: cornerTransitionProps,
|
49
|
-
},
|
50
|
-
})
|
51
|
-
|
52
|
-
useMotion(blRef, {
|
53
|
-
initial: {
|
54
|
-
x: -cornerMargin.value,
|
55
|
-
y: cornerMargin.value,
|
56
|
-
},
|
57
|
-
enter: {
|
58
|
-
x: 0,
|
59
|
-
y: 0,
|
60
|
-
transition: cornerTransitionProps,
|
61
|
-
},
|
62
|
-
})
|
63
|
-
|
64
|
-
useMotion(brRef, {
|
65
|
-
initial: {
|
66
|
-
x: cornerMargin.value,
|
67
|
-
y: cornerMargin.value,
|
68
|
-
},
|
69
|
-
enter: {
|
70
|
-
x: 0,
|
71
|
-
y: 0,
|
72
|
-
transition: cornerTransitionProps,
|
73
|
-
},
|
74
|
-
})
|
75
|
-
|
76
|
-
const cssVarStyles = computed(() => {
|
77
|
-
return {
|
78
|
-
'--corner-size': `${cornerSize.value}px`,
|
79
|
-
'--corner-margin': `${cornerMargin.value}px`,
|
80
|
-
'--corner-border-size': `${cornerBorderSize.value}px`,
|
81
|
-
}
|
4
|
+
const playAnim = ref(false)
|
5
|
+
onMounted(() => {
|
6
|
+
playAnim.value = true
|
82
7
|
})
|
83
8
|
</script>
|
84
9
|
|
85
10
|
<template>
|
86
11
|
<div
|
87
|
-
class="ae-frame"
|
12
|
+
class="yun-ae-frame"
|
13
|
+
:class="{
|
14
|
+
play: playAnim,
|
15
|
+
}"
|
88
16
|
>
|
89
|
-
<div
|
90
|
-
<div
|
91
|
-
<div
|
92
|
-
<div
|
17
|
+
<div class="tl absolute" />
|
18
|
+
<div class="tr absolute" />
|
19
|
+
<div class="bl absolute" />
|
20
|
+
<div class="br absolute" />
|
93
21
|
</div>
|
94
22
|
</template>
|
95
23
|
|
96
24
|
<style lang="scss">
|
97
|
-
|
25
|
+
@use 'sass:map';
|
26
|
+
@use 'valaxy/client/styles/mixins/index.scss' as *;
|
27
|
+
@use 'valaxy-theme-yun/styles/vars.scss' as *;
|
28
|
+
|
29
|
+
@include screen('md') {
|
30
|
+
.yun-ae-frame {
|
31
|
+
--corner-size: 50px;
|
32
|
+
--corner-margin: 30px;
|
33
|
+
--corner-border-size: 5px;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
.yun-ae-frame {
|
38
|
+
--corner-size: 40px;
|
39
|
+
--corner-margin: 10px;
|
40
|
+
--corner-border-size: 3px;
|
41
|
+
|
98
42
|
div {
|
99
43
|
width: var(--corner-size);
|
100
44
|
height: var(--corner-size);
|
@@ -151,5 +95,44 @@ const cssVarStyles = computed(() => {
|
|
151
95
|
}
|
152
96
|
}
|
153
97
|
}
|
98
|
+
|
99
|
+
.tl, .tr, .bl, .br {
|
100
|
+
position: absolute;
|
101
|
+
transition: transform 0.6s map.get($cubic-bezier, 'ease-in');
|
102
|
+
}
|
103
|
+
|
104
|
+
.tl {
|
105
|
+
transform: translate(calc(var(--corner-margin) * -1), calc(var(--corner-margin) * -1));
|
106
|
+
}
|
107
|
+
|
108
|
+
.tr {
|
109
|
+
transform: translate(calc(var(--corner-margin)), calc(var(--corner-margin) * -1));
|
110
|
+
}
|
111
|
+
|
112
|
+
.bl {
|
113
|
+
transform: translate(calc(var(--corner-margin) * -1), calc(var(--corner-margin)));
|
114
|
+
}
|
115
|
+
|
116
|
+
.br {
|
117
|
+
transform: translate(calc(var(--corner-margin)), calc(var(--corner-margin)));
|
118
|
+
}
|
119
|
+
|
120
|
+
&.play {
|
121
|
+
.tl {
|
122
|
+
transform: translate(0, 0);
|
123
|
+
}
|
124
|
+
|
125
|
+
.tr {
|
126
|
+
transform: translate(0, 0);
|
127
|
+
}
|
128
|
+
|
129
|
+
.bl {
|
130
|
+
transform: translate(0, 0);
|
131
|
+
}
|
132
|
+
|
133
|
+
.br {
|
134
|
+
transform: translate(0, 0);
|
135
|
+
}
|
136
|
+
}
|
154
137
|
}
|
155
138
|
</style>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<script setup lang="ts">
|
2
|
+
import { useSiteConfig } from 'valaxy'
|
3
|
+
|
4
|
+
const siteConfig = useSiteConfig()
|
5
|
+
</script>
|
6
|
+
|
7
|
+
<template>
|
8
|
+
<div v-if="siteConfig.description" class="site-description text-$va-c-text text-sm">
|
9
|
+
{{ siteConfig.description }}
|
10
|
+
</div>
|
11
|
+
</template>
|
@@ -15,7 +15,7 @@ const yunApp = useYunAppStore()
|
|
15
15
|
inline-flex
|
16
16
|
:to="page.url" :title="page.name"
|
17
17
|
:style="`color:${page.color}`"
|
18
|
-
hover="bg-
|
18
|
+
hover="bg-white/80 dark:bg-black/80"
|
19
19
|
@click="yunApp.fullscreenMenu.isOpen = false"
|
20
20
|
>
|
21
21
|
<div :class="page.icon" class="icon" />
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<script setup lang="ts">
|
2
|
+
import { useSiteConfig } from 'valaxy'
|
3
|
+
|
4
|
+
const siteConfig = useSiteConfig()
|
5
|
+
</script>
|
6
|
+
|
7
|
+
<template>
|
8
|
+
<h4
|
9
|
+
v-if="siteConfig.subtitle"
|
10
|
+
class="site-subtitle block text-$va-c-text op-80" text="sm"
|
11
|
+
>
|
12
|
+
{{ siteConfig.subtitle }}
|
13
|
+
</h4>
|
14
|
+
</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/home.vue
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
<script lang="ts" setup>
|
2
2
|
import { computed } from 'vue'
|
3
3
|
import { useRoute } from 'vue-router'
|
4
|
-
import { useYunAppStore } from '../stores'
|
5
4
|
import { useThemeConfig } from '../composables'
|
6
5
|
|
7
|
-
const yunStore = useYunAppStore()
|
8
6
|
const route = useRoute()
|
9
7
|
const themeConfig = useThemeConfig()
|
10
8
|
|
@@ -17,16 +15,12 @@ const showNotice = computed(() => {
|
|
17
15
|
</script>
|
18
16
|
|
19
17
|
<template>
|
20
|
-
<
|
21
|
-
class="
|
18
|
+
<YunLayoutWrapper
|
19
|
+
class="items-center flex-col"
|
22
20
|
:class="{
|
23
|
-
'
|
24
|
-
|
25
|
-
'pt-36': isPage,
|
26
|
-
}" flex="~ col" w="full"
|
21
|
+
'mt-0!': !isPage,
|
22
|
+
}"
|
27
23
|
>
|
28
|
-
<YunSidebar :show-hamburger="true" />
|
29
|
-
|
30
24
|
<template v-if="!isPage">
|
31
25
|
<YunBanner />
|
32
26
|
<YunSay v-if="themeConfig.say.enable" w="full" />
|
@@ -49,5 +43,5 @@ const showNotice = computed(() => {
|
|
49
43
|
</slot>
|
50
44
|
|
51
45
|
<YunFooter />
|
52
|
-
</
|
46
|
+
</YunLayoutWrapper>
|
53
47
|
</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
@@ -1,6 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "valaxy-theme-yun",
|
3
|
-
"
|
3
|
+
"type": "module",
|
4
|
+
"version": "0.20.0-beta.10",
|
4
5
|
"author": {
|
5
6
|
"email": "me@yunyoujun.cn",
|
6
7
|
"name": "YunYouJun",
|
@@ -19,9 +20,12 @@
|
|
19
20
|
},
|
20
21
|
"main": "index.ts",
|
21
22
|
"module": "index.ts",
|
23
|
+
"scripts": {
|
24
|
+
"release": "bumpp && npm publish"
|
25
|
+
},
|
22
26
|
"dependencies": {
|
23
27
|
"@ctrl/tinycolor": "^4.1.0",
|
24
|
-
"@explosions/fireworks": "^0.0
|
28
|
+
"@explosions/fireworks": "^0.1.0",
|
25
29
|
"@iconify-json/ant-design": "^1.2.1",
|
26
30
|
"@iconify-json/simple-icons": "^1.2.5",
|
27
31
|
"@vueuse/motion": "^2.2.5",
|
@@ -32,7 +36,7 @@
|
|
32
36
|
},
|
33
37
|
"devDependencies": {
|
34
38
|
"@types/animejs": "^3.1.12",
|
35
|
-
"valaxy
|
36
|
-
"valaxy": "
|
39
|
+
"valaxy": "workspace:*",
|
40
|
+
"valaxy-addon-waline": "workspace:*"
|
37
41
|
}
|
38
|
-
}
|
42
|
+
}
|
@@ -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
|
+
}
|
package/styles/layout/index.scss
CHANGED
package/unocss.config.ts
CHANGED
package/utils/animation.ts
CHANGED