valaxy-theme-yun 0.28.3 → 0.28.5
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/components/YunGirls.vue +9 -2
- package/components/YunLinks.vue +29 -2
- package/components/YunPostCard.vue +78 -104
- package/components/theme/nimbo/YunNimboNavMenu.vue +7 -13
- package/components/theme/strato/YunStratoNavMenu.vue +16 -0
- package/layouts/home.vue +2 -1
- package/package.json +5 -5
- package/styles/css-vars.scss +3 -0
- package/types/index.d.ts +1 -1
package/components/YunGirls.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type { GirlType } from '../types'
|
|
3
|
+
import { computed } from 'vue'
|
|
3
4
|
import { useRandomData } from '../composables'
|
|
4
5
|
|
|
5
6
|
const props = defineProps<{
|
|
@@ -8,12 +9,18 @@ const props = defineProps<{
|
|
|
8
9
|
}>()
|
|
9
10
|
|
|
10
11
|
const { data } = useRandomData(props.girls, props.random)
|
|
12
|
+
const isUrlSource = computed(() => typeof props.girls === 'string')
|
|
11
13
|
</script>
|
|
12
14
|
|
|
13
15
|
<template>
|
|
14
16
|
<div class="girls">
|
|
15
|
-
<
|
|
16
|
-
<
|
|
17
|
+
<ClientOnly v-if="isUrlSource">
|
|
18
|
+
<ul class="girl-items">
|
|
19
|
+
<YunGirlItem v-for="girl, i in data" :key="girl.url" :i="i" :girl="girl" />
|
|
20
|
+
</ul>
|
|
21
|
+
</ClientOnly>
|
|
22
|
+
<ul v-else class="girl-items">
|
|
23
|
+
<YunGirlItem v-for="girl, i in data" :key="girl.url" :i="i" :girl="girl" />
|
|
17
24
|
</ul>
|
|
18
25
|
</div>
|
|
19
26
|
</template>
|
package/components/YunLinks.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type { LinkType } from '../types'
|
|
3
|
+
import { computed } from 'vue'
|
|
3
4
|
import { useRandomData } from '../composables'
|
|
4
5
|
|
|
5
6
|
const props = defineProps<{
|
|
@@ -12,14 +13,40 @@ const props = defineProps<{
|
|
|
12
13
|
}>()
|
|
13
14
|
|
|
14
15
|
const { data } = useRandomData(props.links, props.random)
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* When links source is a URL (string), data is fetched asynchronously on the
|
|
19
|
+
* client side only. During SSG the list is empty, but after hydration the
|
|
20
|
+
* fetched items are injected into the DOM. Wrapping the list in
|
|
21
|
+
* `<ClientOnly>` avoids a hydration-mismatch between the static (empty) HTML
|
|
22
|
+
* and the client-rendered (populated) list, which could cause `replaceChild`
|
|
23
|
+
* errors or the list not appearing at all.
|
|
24
|
+
*
|
|
25
|
+
* For static array data the mismatch risk is lower (SSR and client render
|
|
26
|
+
* the same initial order), so `<ClientOnly>` is not applied.
|
|
27
|
+
*/
|
|
28
|
+
const isUrlSource = computed(() => typeof props.links === 'string')
|
|
15
29
|
</script>
|
|
16
30
|
|
|
17
31
|
<template>
|
|
18
32
|
<div class="yun-links">
|
|
19
|
-
|
|
33
|
+
<!--
|
|
34
|
+
Use ClientOnly when links are fetched from a URL to prevent
|
|
35
|
+
hydration mismatch (SSG renders empty list, client fills it).
|
|
36
|
+
-->
|
|
37
|
+
<ClientOnly v-if="isUrlSource">
|
|
38
|
+
<ul class="yun-link-items" flex="center wrap">
|
|
39
|
+
<YunLinkItem
|
|
40
|
+
v-for="link, i in data"
|
|
41
|
+
:key="link.url"
|
|
42
|
+
:i="i" :link="link" :error-img="errorImg"
|
|
43
|
+
/>
|
|
44
|
+
</ul>
|
|
45
|
+
</ClientOnly>
|
|
46
|
+
<ul v-else class="yun-link-items" flex="center wrap">
|
|
20
47
|
<YunLinkItem
|
|
21
48
|
v-for="link, i in data"
|
|
22
|
-
:key="
|
|
49
|
+
:key="link.url"
|
|
23
50
|
:i="i" :link="link" :error-img="errorImg"
|
|
24
51
|
/>
|
|
25
52
|
</ul>
|
|
@@ -23,89 +23,82 @@ const postTitleClass = computed(() => {
|
|
|
23
23
|
}
|
|
24
24
|
return props.post.postTitleClass || gradientClasses.value
|
|
25
25
|
})
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Guard navigation so clicks on nested interactive elements (e.g. external links)
|
|
29
|
-
* don't also trigger the card's route navigation.
|
|
30
|
-
*/
|
|
31
|
-
function guardedNavigate(e: Event, navigate: () => void) {
|
|
32
|
-
if ((e.target as HTMLElement)?.closest('a'))
|
|
33
|
-
return
|
|
34
|
-
navigate()
|
|
35
|
-
}
|
|
36
26
|
</script>
|
|
37
27
|
|
|
38
28
|
<template>
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<YunPostMeta :frontmatter="post" />
|
|
62
|
-
|
|
63
|
-
<div class="post-card-excerpt" flex="~ grow col" w="full" justify="center" items="center">
|
|
64
|
-
<div v-if="post.excerpt_type === 'text'" py="1" />
|
|
65
|
-
<template v-if="post.excerpt">
|
|
66
|
-
<div
|
|
67
|
-
v-if="post.excerpt_type === 'html'"
|
|
68
|
-
class="post-card-excerpt-content markdown-body" op="90" text="left" w="full" p="x-6 y-2"
|
|
69
|
-
>
|
|
70
|
-
<ValaxyDynamicComponent :template-str="post.excerpt" />
|
|
71
|
-
</div>
|
|
72
|
-
<div
|
|
73
|
-
v-else
|
|
74
|
-
class="post-card-excerpt-content markdown-body" op="90" text="left" w="full" p="x-6 y-2"
|
|
75
|
-
v-html="post.excerpt"
|
|
76
|
-
/>
|
|
77
|
-
</template>
|
|
78
|
-
<div v-else m="b-5" />
|
|
29
|
+
<div class="post-card-link flex-center w-full">
|
|
30
|
+
<YunCard
|
|
31
|
+
class="post-card-wrapper w-full hover:scale-102 hover:z-1"
|
|
32
|
+
mx="4"
|
|
33
|
+
:class="post.cover ? 'post-card-image' : 'post-card'"
|
|
34
|
+
overflow="hidden" v-bind="styles ? { style: styles } : {}"
|
|
35
|
+
>
|
|
36
|
+
<!-- Overlay link covers the entire card -->
|
|
37
|
+
<AppLink class="post-card-overlay" :to="post.path || ''" :aria-label="$tO(post.title)" tabindex="0" />
|
|
38
|
+
|
|
39
|
+
<div class="flex flex-1 of-hidden justify-start items-start post-card-info" w="full">
|
|
40
|
+
<img
|
|
41
|
+
v-if="post.cover" :src="post.cover" :alt="t('post.cover')" width="320" height="180"
|
|
42
|
+
class="post-card-cover cover object-cover object-center md:shadow" loading="lazy"
|
|
43
|
+
>
|
|
44
|
+
|
|
45
|
+
<div class="post-card-body flex flex-col items-center relative" :class="post.cover && 'post-card-body-with-cover'" w="full">
|
|
46
|
+
<AppLink class="post-title-link" :to="post.path || ''" m="t-3" :class="postTitleClass" tabindex="-1">
|
|
47
|
+
<div class="post-card-title flex-center title text-2xl" text="center" font="serif black">
|
|
48
|
+
<div v-if="post.type" class="inline-flex" m="r-1" :class="icon" />
|
|
49
|
+
<span>{{ $tO(post.title) }}</span>
|
|
79
50
|
</div>
|
|
51
|
+
</AppLink>
|
|
52
|
+
|
|
53
|
+
<YunPostMeta :frontmatter="post" />
|
|
54
|
+
|
|
55
|
+
<div class="post-card-excerpt" flex="~ grow col" w="full" justify="center" items="center">
|
|
56
|
+
<div v-if="post.excerpt_type === 'text'" py="1" />
|
|
57
|
+
<template v-if="post.excerpt">
|
|
58
|
+
<div
|
|
59
|
+
v-if="post.excerpt_type === 'html'"
|
|
60
|
+
class="post-card-excerpt-content markdown-body" op="90" text="left" w="full" p="x-6 y-2"
|
|
61
|
+
>
|
|
62
|
+
<ValaxyDynamicComponent :template-str="post.excerpt" />
|
|
63
|
+
</div>
|
|
64
|
+
<div
|
|
65
|
+
v-else
|
|
66
|
+
class="post-card-excerpt-content markdown-body" op="90" text="left" w="full" p="x-6 y-2"
|
|
67
|
+
v-html="post.excerpt"
|
|
68
|
+
/>
|
|
69
|
+
</template>
|
|
70
|
+
<div v-else m="b-5" />
|
|
71
|
+
</div>
|
|
80
72
|
|
|
81
|
-
|
|
73
|
+
<YunExcerptBottomGradient v-if="post.excerpt" />
|
|
82
74
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
</div>
|
|
75
|
+
<a
|
|
76
|
+
v-if="post.url" :href="post.url" class="post-link-btn shadow hover:shadow-md" rounded target="_blank"
|
|
77
|
+
rel="noopener noreferrer"
|
|
78
|
+
m="b-4"
|
|
79
|
+
>
|
|
80
|
+
{{ t('post.view_link') }}
|
|
81
|
+
</a>
|
|
91
82
|
</div>
|
|
83
|
+
</div>
|
|
92
84
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
</div>
|
|
99
|
-
|
|
100
|
-
<YunPostTags v-if="post.tags" m="l-2" :tags="post.tags" />
|
|
85
|
+
<!-- always show -->
|
|
86
|
+
<div w="full" class="yun-card-actions flex items-center justify-between" p="x-4 y-2" text="sm">
|
|
87
|
+
<div class="post-categories inline-flex gap-2" flex="wrap 1" items="center">
|
|
88
|
+
<YunPostCategories :categories="post.categories" />
|
|
89
|
+
<YunPostCollectionBadge v-if="postCollections.length" :collections="postCollections" />
|
|
101
90
|
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
91
|
+
|
|
92
|
+
<YunPostTags v-if="post.tags" m="l-2" :tags="post.tags" />
|
|
93
|
+
</div>
|
|
94
|
+
</YunCard>
|
|
95
|
+
</div>
|
|
105
96
|
</template>
|
|
106
97
|
|
|
107
98
|
<style lang="scss">
|
|
108
99
|
.post-card-wrapper {
|
|
100
|
+
// Stacking context for the overlay
|
|
101
|
+
position: relative;
|
|
109
102
|
transition: box-shadow var(--va-transition-duration), scale var(--va-transition-duration);
|
|
110
103
|
|
|
111
104
|
&:hover {
|
|
@@ -117,32 +110,17 @@ function guardedNavigate(e: Event, navigate: () => void) {
|
|
|
117
110
|
gap: 0.15rem;
|
|
118
111
|
}
|
|
119
112
|
|
|
120
|
-
.post-card {
|
|
121
|
-
// safari not support
|
|
122
|
-
// animation: card-appear 0.6s ease-in-out forwards, card-appear 0.6s ease-in-out forwards reverse;
|
|
123
|
-
// animation-timeline: view();
|
|
124
|
-
// animation-range: entry, exit;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
113
|
.post-card-link {
|
|
128
|
-
text-decoration: none;
|
|
129
|
-
color: inherit;
|
|
130
|
-
|
|
131
114
|
// max-w-$yun-post-card-max-width
|
|
132
115
|
max-width: calc(var(--yun-post-card-max-width) + 2rem);
|
|
116
|
+
}
|
|
133
117
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
color: inherit;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
&:focus {
|
|
144
|
-
outline: none;
|
|
145
|
-
}
|
|
118
|
+
// Overlay link covers the entire card as the click target
|
|
119
|
+
// Sits above normal content but below interactive elements
|
|
120
|
+
.post-card-overlay {
|
|
121
|
+
position: absolute;
|
|
122
|
+
inset: 0;
|
|
123
|
+
z-index: 1;
|
|
146
124
|
|
|
147
125
|
&:focus-visible {
|
|
148
126
|
outline: 2px solid var(--va-c-primary);
|
|
@@ -151,6 +129,14 @@ function guardedNavigate(e: Event, navigate: () => void) {
|
|
|
151
129
|
}
|
|
152
130
|
}
|
|
153
131
|
|
|
132
|
+
// Interactive elements (title, tags, categories, external link) float above the overlay
|
|
133
|
+
.post-title-link,
|
|
134
|
+
.yun-card-actions,
|
|
135
|
+
.post-link-btn {
|
|
136
|
+
position: relative;
|
|
137
|
+
z-index: 2;
|
|
138
|
+
}
|
|
139
|
+
|
|
154
140
|
.post-card-link :hover {
|
|
155
141
|
cursor: var(--cursor-pointer), pointer;
|
|
156
142
|
}
|
|
@@ -160,18 +146,6 @@ function guardedNavigate(e: Event, navigate: () => void) {
|
|
|
160
146
|
line-height: 1.7;
|
|
161
147
|
}
|
|
162
148
|
|
|
163
|
-
@keyframes card-appear {
|
|
164
|
-
0% {
|
|
165
|
-
opacity: 0;
|
|
166
|
-
transform: scale(0.8) translateY(20px);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
100% {
|
|
170
|
-
opacity: 1;
|
|
171
|
-
transform: scale(1) translateY(0);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
149
|
.yun-card-actions {
|
|
176
150
|
border-top: 1px solid rgb(122 122 122 / 0.08);
|
|
177
151
|
}
|
|
@@ -47,7 +47,7 @@ const app = useAppStore()
|
|
|
47
47
|
v-if="showMenu"
|
|
48
48
|
class="yun-nav-menu z-$yun-z-nav-menu fixed bg-transparent"
|
|
49
49
|
:class="{
|
|
50
|
-
play: playAnimation,
|
|
50
|
+
'shadow play': playAnimation,
|
|
51
51
|
}"
|
|
52
52
|
>
|
|
53
53
|
<!-- -->
|
|
@@ -113,7 +113,6 @@ const app = useAppStore()
|
|
|
113
113
|
// safari not support
|
|
114
114
|
// animation-timeline: scroll();
|
|
115
115
|
// animation-range: 0 calc(30vh), exit;
|
|
116
|
-
box-shadow: none;
|
|
117
116
|
display: flex;
|
|
118
117
|
|
|
119
118
|
// top: var(--rect-margin);
|
|
@@ -126,19 +125,14 @@ const app = useAppStore()
|
|
|
126
125
|
align-items: center;
|
|
127
126
|
justify-content: space-between;
|
|
128
127
|
height: var(--yun-nav-height, 50px);
|
|
129
|
-
transition:
|
|
128
|
+
transition: background-color var(--va-transition-duration-moderate) map.get($cubic-bezier, 'ease-in'),
|
|
129
|
+
backdrop-filter var(--va-transition-duration-moderate) map.get($cubic-bezier, 'ease-in'),
|
|
130
|
+
box-shadow var(--va-transition-duration-moderate) map.get($cubic-bezier, 'ease-in');
|
|
130
131
|
|
|
131
132
|
&.play {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
background-color: var(--va-c-bg);
|
|
136
|
-
border-color: rgb(0 0 0 / 0.1);
|
|
137
|
-
|
|
138
|
-
--un-shadow: var(--un-shadow-inset) 0 20px 25px -5px var(--un-shadow-color, rgb(0 0 0 / 0.1)), var(--un-shadow-inset) 0 8px 10px -6px var(--un-shadow-color, rgb(0 0 0 / 0.1));
|
|
139
|
-
|
|
140
|
-
box-shadow: var(--un-ring-offset-shadow), var(--un-ring-shadow),
|
|
141
|
-
var(--un-shadow);
|
|
133
|
+
background-color: var(--yun-nav-bg-color);
|
|
134
|
+
backdrop-filter: blur(var(--yun-nav-blur));
|
|
135
|
+
-webkit-backdrop-filter: blur(var(--yun-nav-blur));
|
|
142
136
|
}
|
|
143
137
|
|
|
144
138
|
.vt-hamburger-top, .vt-hamburger-middle, .vt-hamburger-bottom {
|
|
@@ -87,3 +87,19 @@ const isHomePage = computed(() => route.meta.layout === 'home')
|
|
|
87
87
|
</div>
|
|
88
88
|
</Transition>
|
|
89
89
|
</template>
|
|
90
|
+
|
|
91
|
+
<style lang="scss" scoped>
|
|
92
|
+
@use 'sass:map';
|
|
93
|
+
@use 'valaxy-theme-yun/styles/vars.scss' as *;
|
|
94
|
+
|
|
95
|
+
.yun-nav-menu {
|
|
96
|
+
height: var(--yun-nav-height, 50px);
|
|
97
|
+
transition: all var(--va-transition-duration-moderate) map.get($cubic-bezier, 'ease-in');
|
|
98
|
+
|
|
99
|
+
&.play {
|
|
100
|
+
background-color: var(--yun-nav-bg-color);
|
|
101
|
+
backdrop-filter: blur(var(--yun-nav-blur));
|
|
102
|
+
-webkit-backdrop-filter: blur(var(--yun-nav-blur));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
</style>
|
package/layouts/home.vue
CHANGED
|
@@ -19,7 +19,7 @@ const showNotice = computed(() => {
|
|
|
19
19
|
|
|
20
20
|
<template>
|
|
21
21
|
<YunLayoutWrapper :no-margin="!isPage">
|
|
22
|
-
<div class="w-full flex flex-col items-center pb-
|
|
22
|
+
<div class="w-full flex flex-col items-center pb-4">
|
|
23
23
|
<template v-if="themeConfig.banner?.enable">
|
|
24
24
|
<template v-if="!isPage">
|
|
25
25
|
<div class="w-full">
|
|
@@ -62,6 +62,7 @@ const showNotice = computed(() => {
|
|
|
62
62
|
}"
|
|
63
63
|
:content="themeConfig.notice?.content"
|
|
64
64
|
/>
|
|
65
|
+
<div v-else-if="!isPage" class="mt-4" />
|
|
65
66
|
|
|
66
67
|
<slot name="board" />
|
|
67
68
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valaxy-theme-yun",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.28.
|
|
4
|
+
"version": "0.28.5",
|
|
5
5
|
"author": {
|
|
6
6
|
"email": "me@yunyoujun.cn",
|
|
7
7
|
"name": "YunYouJun",
|
|
@@ -25,16 +25,16 @@
|
|
|
25
25
|
"@ctrl/tinycolor": "^4.2.0",
|
|
26
26
|
"@explosions/fireworks": "^0.2.0",
|
|
27
27
|
"@iconify-json/ant-design": "^1.2.5",
|
|
28
|
-
"@iconify-json/simple-icons": "^1.2.
|
|
28
|
+
"@iconify-json/simple-icons": "^1.2.78",
|
|
29
29
|
"@vueuse/motion": "^3.0.3",
|
|
30
30
|
"animejs": "^4.3.6",
|
|
31
|
-
"gsap": "^3.
|
|
32
|
-
"reka-ui": "^2.9.
|
|
31
|
+
"gsap": "^3.15.0",
|
|
32
|
+
"reka-ui": "^2.9.6"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/animejs": "^3.1.13",
|
|
36
36
|
"valaxy-addon-waline": "0.2.1",
|
|
37
|
-
"valaxy": "0.28.
|
|
37
|
+
"valaxy": "0.28.5"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"release": "bumpp && pnpm publish"
|
package/styles/css-vars.scss
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
--yun-home-hero-name-background: linear-gradient(120deg, var(--va-c-text) 30%, black);
|
|
10
10
|
--yun-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%);
|
|
11
11
|
--yun-nav-height: 50px;
|
|
12
|
+
--yun-nav-bg-color: rgb(255 255 255 / 0.8);
|
|
13
|
+
--yun-nav-blur: 12px;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
:root {
|
|
@@ -31,6 +33,7 @@ html.dark {
|
|
|
31
33
|
--va-c-bg: #1a1a1d;
|
|
32
34
|
--va-c-bg-soft: #121215;
|
|
33
35
|
--yun-home-hero-name-background: linear-gradient(120deg, var(--va-c-primary) 30%, #41d1ff);
|
|
36
|
+
--yun-nav-bg-color: rgb(26 26 29 / 0.8);
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
// animation
|