valaxy-theme-yun 0.20.0-beta.1 → 0.20.0-beta.11
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 +12 -1
- package/components/YunNotice.vue +6 -5
- package/components/YunOverview.vue +0 -5
- package/components/YunPagination.vue +12 -5
- package/components/YunPostCollapse.vue +5 -3
- package/components/YunPostList.vue +8 -7
- package/components/YunPrologue.vue +1 -1
- package/components/animation/LineBurstEffects.vue +8 -5
- package/components/author/YunAuthorAvatar.vue +2 -1
- 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 +81 -109
- 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 +37 -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 +6 -12
- package/layouts/tags.vue +11 -5
- package/package.json +9 -5
- package/styles/animations/index.scss +45 -0
- package/styles/css-vars.scss +1 -1
- 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,23 @@
|
|
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
|
+
delay: 25,
|
15
|
+
})
|
6
16
|
</script>
|
7
17
|
|
8
18
|
<template>
|
9
19
|
<span
|
20
|
+
ref="tagRef"
|
10
21
|
inline-flex my="2" p="1"
|
11
22
|
class="post-tag cursor-pointer items-baseline leading-4"
|
12
23
|
>
|
package/components/YunNotice.vue
CHANGED
@@ -5,16 +5,17 @@ defineProps<{
|
|
5
5
|
</script>
|
6
6
|
|
7
7
|
<template>
|
8
|
-
<div class="
|
9
|
-
<
|
10
|
-
|
8
|
+
<div class="w-full px-4 flex-center">
|
9
|
+
<div class="yun-notice w-full">
|
10
|
+
<span v-html="content" />
|
11
|
+
<slot />
|
12
|
+
</div>
|
11
13
|
</div>
|
12
14
|
</template>
|
13
15
|
|
14
16
|
<style>
|
15
17
|
.yun-notice {
|
16
18
|
border: 1px solid var(--va-c-text);
|
17
|
-
width: calc(100% - 2rem);
|
18
19
|
display: flex;
|
19
20
|
flex-direction: column;
|
20
21
|
justify-content: center;
|
@@ -23,6 +24,6 @@ defineProps<{
|
|
23
24
|
font-weight: bold;
|
24
25
|
padding: 1rem;
|
25
26
|
max-width: var(--yun-post-card-max-width);
|
26
|
-
background-color:
|
27
|
+
background-color: rgb(200 200 200 / 0.1);
|
27
28
|
}
|
28
29
|
</style>
|
@@ -16,6 +16,10 @@ const { curPage, totalPages, showPage, getTo, surLen, prevTo, nextTo, showPrev,
|
|
16
16
|
total: props.total,
|
17
17
|
pageSize: props.pageSize,
|
18
18
|
})
|
19
|
+
|
20
|
+
defineExpose({
|
21
|
+
curPage,
|
22
|
+
})
|
19
23
|
</script>
|
20
24
|
|
21
25
|
<template>
|
@@ -48,7 +52,7 @@ const { curPage, totalPages, showPage, getTo, surLen, prevTo, nextTo, showPrev,
|
|
48
52
|
|
49
53
|
<style lang="scss">
|
50
54
|
:root {
|
51
|
-
--page-btn-bg-color:
|
55
|
+
--page-btn-bg-color: rgb(255 255 255 / 0.5);
|
52
56
|
--page-btn-hover-bg-color: var(--va-c-primary-lighter);
|
53
57
|
--page-btn-active-bg-color: var(--va-c-primary-light);
|
54
58
|
}
|
@@ -69,10 +73,10 @@ const { curPage, totalPages, showPage, getTo, surLen, prevTo, nextTo, showPrev,
|
|
69
73
|
width: 2rem;
|
70
74
|
height: 2rem;
|
71
75
|
margin: 0;
|
72
|
-
transition: background-color var(--va-transition-duration) ease;
|
73
76
|
|
74
77
|
// disabled attr
|
75
78
|
&[disabled] {
|
79
|
+
color: var(--va-c-text-light);
|
76
80
|
background-color: var(--va-c-bg-mute);
|
77
81
|
}
|
78
82
|
}
|
@@ -84,19 +88,22 @@ const { curPage, totalPages, showPage, getTo, surLen, prevTo, nextTo, showPrev,
|
|
84
88
|
background-color: var(--page-btn-bg-color);
|
85
89
|
|
86
90
|
&:hover {
|
87
|
-
color: var(--va-c-bg);
|
91
|
+
// color: var(--va-c-bg);
|
92
|
+
color: white;
|
88
93
|
background: var(--page-btn-hover-bg-color);
|
89
94
|
}
|
90
95
|
|
91
96
|
&:active {
|
92
|
-
color: var(--va-c-bg);
|
97
|
+
// color: var(--va-c-bg);
|
98
|
+
color: white;
|
93
99
|
background: var(--page-btn-active-bg-color);
|
94
100
|
}
|
95
101
|
|
96
102
|
&.active {
|
103
|
+
// color: var(--va-c-bg);
|
104
|
+
color: white;
|
97
105
|
font-weight: normal;
|
98
106
|
background: var(--page-btn-active-bg-color);
|
99
|
-
color: var(--va-c-bg);
|
100
107
|
cursor: default;
|
101
108
|
}
|
102
109
|
|
@@ -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,15 +1,15 @@
|
|
1
1
|
<script setup lang="ts">
|
2
|
-
import { computed } from 'vue'
|
2
|
+
import { computed, ref } from 'vue'
|
3
3
|
import { useSiteConfig, useSiteStore } from 'valaxy'
|
4
4
|
import type { Post } from 'valaxy/types'
|
5
5
|
|
6
6
|
const props = withDefaults(defineProps<{
|
7
7
|
type?: string
|
8
8
|
posts?: Post[]
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
}>(), {})
|
10
|
+
|
11
|
+
const paginationRef = ref()
|
12
|
+
const curPage = computed(() => paginationRef.value?.curPage || 1)
|
13
13
|
|
14
14
|
const site = useSiteStore()
|
15
15
|
const siteConfig = useSiteConfig()
|
@@ -21,8 +21,8 @@ const posts = computed(() => (
|
|
21
21
|
|
22
22
|
const displayedPosts = computed(() =>
|
23
23
|
posts.value.slice(
|
24
|
-
(
|
25
|
-
|
24
|
+
(curPage.value - 1) * pageSize.value,
|
25
|
+
curPage.value * pageSize.value,
|
26
26
|
),
|
27
27
|
)
|
28
28
|
</script>
|
@@ -39,6 +39,7 @@ const displayedPosts = computed(() =>
|
|
39
39
|
</div>
|
40
40
|
|
41
41
|
<YunPagination
|
42
|
+
ref="paginationRef"
|
42
43
|
class="mt-5"
|
43
44
|
:total="posts.length" :page-size="pageSize"
|
44
45
|
/>
|
@@ -1,16 +1,19 @@
|
|
1
1
|
<script setup lang="ts">
|
2
2
|
// 播放完销毁 css 动画
|
3
|
+
import { sleep } from 'valaxy'
|
3
4
|
import { onMounted, ref } from 'vue'
|
4
5
|
|
5
6
|
const props = defineProps<{
|
7
|
+
delay: number
|
6
8
|
duration: number
|
7
9
|
}>()
|
8
10
|
|
9
|
-
const destroy = ref(
|
10
|
-
onMounted(() => {
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
const destroy = ref(true)
|
12
|
+
onMounted(async () => {
|
13
|
+
await sleep(props.delay)
|
14
|
+
destroy.value = false
|
15
|
+
await sleep(props.duration)
|
16
|
+
destroy.value = true
|
14
17
|
})
|
15
18
|
</script>
|
16
19
|
|
@@ -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>
|