valaxy-theme-hairy 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. package/LICENSE +21 -21
  2. package/client/index.ts +1 -1
  3. package/components/HairyBody.vue +49 -49
  4. package/components/HairyCodepen.vue +40 -40
  5. package/components/HairyComment.vue +33 -33
  6. package/components/HairyContainer.vue +17 -17
  7. package/components/HairyDrawer.vue +44 -44
  8. package/components/HairyFooter.vue +62 -62
  9. package/components/HairyHeader.vue +32 -32
  10. package/components/HairyImage.vue +15 -15
  11. package/components/HairyImageGroup.vue +65 -65
  12. package/components/HairyNavbar.vue +56 -56
  13. package/components/HairyPageArchives.vue +59 -59
  14. package/components/HairyPageTags.vue +48 -48
  15. package/components/HairyPosts.vue +54 -54
  16. package/components/HairySearch.vue +201 -201
  17. package/components/HairySidebar.vue +30 -30
  18. package/components/HairyTabbar.vue +56 -56
  19. package/components/PageTags.vue +48 -48
  20. package/components/ValaxyMain.vue +45 -45
  21. package/components/navbar/HairyNav.vue +16 -16
  22. package/components/navbar/HairyNavExpand.vue +12 -12
  23. package/components/navbar/HairyNavItem.vue +35 -35
  24. package/components/navbar/HairyNavbarBackground.vue +7 -7
  25. package/components/navbar/HairyNavbarSearch.vue +8 -8
  26. package/components/navbar/HairyNavbarTitle.vue +15 -15
  27. package/components/navbar/HairyNavbarToggleDark.vue +22 -22
  28. package/components/parts/HairyBreadcrumb.vue +51 -51
  29. package/components/parts/HairyBreadcrumbItem.vue +11 -11
  30. package/components/parts/HairyFootFish.js +352 -352
  31. package/components/parts/HairyFootFish.vue +38 -38
  32. package/components/parts/HairyHeadHero.vue +34 -34
  33. package/components/parts/HairyHeadWaves.vue +67 -67
  34. package/components/parts/HairyImageGlobal.vue +51 -51
  35. package/components/parts/HairyImageViewer.vue +23 -23
  36. package/components/parts/HairyLink.vue +21 -21
  37. package/components/parts/HairyMenu.vue +16 -16
  38. package/components/parts/HairyMenuItem.vue +47 -47
  39. package/components/parts/HairyOutline.vue +99 -99
  40. package/components/parts/HairyOutlineItem.vue +48 -48
  41. package/components/parts/HairySocialLinks.vue +27 -27
  42. package/components/parts/HairyTimelineContent.vue +39 -39
  43. package/components/parts/HairyUserNav.vue +95 -95
  44. package/components/parts/HairyUserStats.vue +18 -18
  45. package/components/posts/HairyArticleImage.vue +126 -126
  46. package/components/posts/HairyArticleSeries.vue +89 -89
  47. package/components/posts/HairyArticleText.vue +43 -43
  48. package/components/posts/HairyPostFooter.vue +15 -15
  49. package/components/posts/HairyPostImageList.vue +27 -27
  50. package/components/posts/HairyPostTextsList.vue +22 -22
  51. package/components/posts/HairyPostToggleLayout.vue +36 -36
  52. package/components/third/HairyAlgoliaSearch.vue +17 -17
  53. package/components/third/HairyFuseSearch.vue +10 -10
  54. package/components/third/HairyFuseSearchDialog.vue +32 -32
  55. package/components/third/HairyFuseSearchDropdown.vue +77 -77
  56. package/components/third/HairyFuseSearchFooter.vue +28 -28
  57. package/components/third/HairyFuseSearchHeader.vue +30 -30
  58. package/components/third/HairyFuseSearchHit.vue +52 -52
  59. package/components/third/HairySearchBtnDisplay.vue +29 -29
  60. package/components/third/HairySearchBtnInput.vue +20 -20
  61. package/components/third/HairySearchBtnKeys.vue +19 -19
  62. package/components/third/HairySwiperCarousel.vue +45 -45
  63. package/composables/archives.ts +48 -48
  64. package/composables/category.ts +43 -43
  65. package/composables/config.ts +11 -11
  66. package/composables/dark.ts +13 -13
  67. package/composables/fuse.ts +60 -60
  68. package/composables/index.ts +7 -7
  69. package/composables/layout.ts +16 -16
  70. package/composables/outline.ts +49 -49
  71. package/composables/tags.ts +36 -36
  72. package/layouts/archive-month.vue +13 -13
  73. package/layouts/archive-year.vue +13 -13
  74. package/layouts/archives.vue +11 -11
  75. package/layouts/categories.vue +13 -13
  76. package/layouts/default.vue +13 -15
  77. package/layouts/home.vue +33 -33
  78. package/layouts/post.vue +54 -54
  79. package/layouts/tag.vue +10 -10
  80. package/layouts/tags.vue +10 -14
  81. package/library/loading.scss +535 -535
  82. package/library/loading.ts +60 -60
  83. package/library/scroll.ts +22 -22
  84. package/locales/en.yml +1 -1
  85. package/locales/zh-CN.yml +1 -1
  86. package/node/images/default.json +139 -139
  87. package/node/images/index.ts +46 -46
  88. package/node/images/shims.d.ts +8 -8
  89. package/node/index.ts +2 -2
  90. package/node/theme/index.ts +78 -78
  91. package/package.json +1 -1
  92. package/pages/archives/[year]/[month]/index.vue +48 -48
  93. package/pages/archives/[year]/index.vue +73 -73
  94. package/pages/archives/index.md +6 -0
  95. package/pages/categories/[...its].vue +108 -108
  96. package/pages/index.vue +8 -8
  97. package/pages/page/[page].vue +12 -12
  98. package/pages/tags/[tag]/index.vue +38 -38
  99. package/pages/tags/index.md +7 -0
  100. package/setup/main.ts +9 -9
  101. package/store/index.ts +1 -1
  102. package/store/modules/global.ts +12 -12
  103. package/styles/components/aplayer.scss +75 -75
  104. package/styles/components/index.scss +3 -3
  105. package/styles/components/markdown.scss +89 -89
  106. package/styles/components/nprogress.scss +15 -15
  107. package/styles/components/scrollbar.scss +25 -25
  108. package/styles/css-vars.scss +171 -171
  109. package/styles/element-plus/index.scss +1 -1
  110. package/styles/element-plus/tabs.scss +25 -25
  111. package/styles/element-plus/timeline.scss +18 -18
  112. package/styles/font-face.scss +19 -19
  113. package/styles/global.scss +38 -38
  114. package/styles/index.scss +3 -3
  115. package/tsconfig.json +27 -27
  116. package/types/index.d.ts +163 -163
  117. package/unocss.config.ts +43 -43
  118. package/utils/index.ts +37 -37
  119. package/valaxy.config.ts +26 -26
  120. package/pages/archives/index.vue +0 -6
  121. package/pages/tags/index.vue +0 -6
@@ -1,126 +1,126 @@
1
- <script lang="ts" setup>
2
- import type { Post } from 'valaxy'
3
- import { computed, defineProps } from 'vue'
4
- import dayjs from 'dayjs'
5
- import { useRouter } from 'vue-router'
6
- import { useI18n } from 'vue-i18n'
7
- import { removeTags, toArray } from '../../utils'
8
- import { useLayoutPost } from '../../composables'
9
-
10
- const props = defineProps<{
11
- post: Post
12
- reverse?: boolean
13
- }>()
14
-
15
- const router = useRouter()
16
- const layout = useLayoutPost()
17
- const slice = computed(() => layout.value.includes('slice'))
18
- const image = computed(() => props.post.image?.toString())
19
- const text = computed(() => removeTags(props.post.excerpt))
20
- const i18n = useI18n()
21
- function onReadMore() {
22
- if (props.post.path)
23
- router.push(props.post.path)
24
- }
25
-
26
- function displayCategory(keys: string | string[] = []) {
27
- router.push({ path: `/categories/${toArray(keys).join('/')}` })
28
- }
29
- </script>
30
-
31
- <template>
32
- <li class="HairyArticleImage mb-10 py-2" :class="[slice && 'slice', reverse && 'reverse']">
33
- <article>
34
- <div class="flex justify-between items-center">
35
- <a class="text-size-2xl font-bold truncate cursor-pointer lt-sm:text-size-lg" :class="[reverse ? 'order-last' : 'order-first']" @click="onReadMore">{{ post.title }}</a>
36
- <div class="flex justify-end gap-2 text-size-sm lt-sm:text-size-xs">
37
- <span>{{ dayjs(post.date).format('YYYY-MM-DD') }}</span>
38
- <span>{{ post.wordCount }}字</span>
39
- <span class="lt-sm:hidden">{{ post.readingTime }}分钟</span>
40
- </div>
41
- </div>
42
- <div class="h-200px lt-sm:h-150px flex bg-light-2 dark:bg-transparent rounded-5" :class="[reverse ? 'pl-4' : 'pr-4']">
43
- <div class="flex-1 post-image-content" :class="[reverse ? 'order-last' : 'order-first']">
44
- <img
45
- class="post-image rounded-1 w-full h-full object-cover cursor-pointer" :src="image"
46
- @click="onReadMore"
47
- >
48
- </div>
49
- <div class="flex-1 flex flex-col justify-between py-2 dark:py-0">
50
- <div class="flex-1 text-size-sm">
51
- <div class="line-clamp-text">
52
- {{ text }}
53
- </div>
54
- </div>
55
- <div class="flex justify-between items-center">
56
- <a class="cursor-pointer" :class="[reverse && 'order-1']">
57
- <span v-if="post.categories?.length" @click="displayCategory(post.categories)">
58
- {{ i18n.t(toArray(post.categories).at(-1) || '') }}
59
- </span>
60
- </a>
61
- <div class="text-base leading-6 font-medium">
62
- <a class="link cursor-pointer" aria-label="read more" @click="onReadMore">
63
- <span v-if="reverse">←</span>
64
- <span class="hidden md:block">Read more</span>
65
- <span v-if="!reverse">→</span>
66
- </a>
67
- </div>
68
- </div>
69
- </div>
70
- </div>
71
- </article>
72
- </li>
73
- </template>
74
-
75
- <style lang="scss" scoped>
76
- .line-clamp-text {
77
- word-break: break-all;
78
- overflow: hidden;
79
- text-overflow: ellipsis;
80
- display: -webkit-box;
81
- text-overflow: ellipsis;
82
- -webkit-box-orient: vertical;
83
- -webkit-line-clamp: 5;
84
- }
85
-
86
- .dark {
87
- .post-image {
88
- @apply opacity-75 hover:opacity-90 ;
89
- }
90
- }
91
-
92
- .post-image-content {
93
- margin-right: 1rem;
94
- }
95
-
96
- .slice {
97
- .post-image-content {
98
- webkit-clip-path: polygon(0 0, 92% 0, 100% 100%, 0 100%);
99
- clip-path: polygon(0 0, 92% 0, 100% 100%, 0 100%);
100
- border-radius: 0.625rem 0 0 0.625rem;
101
- overflow: hidden;
102
- }
103
- }
104
-
105
- .reverse {
106
- .post-image-content {
107
- margin-right: 0;
108
- margin-left: 1rem;
109
- clip-path: polygon(0 0,100% 0,100% 100%,8% 100%);
110
- border-radius: 0 0.625rem 0.625rem 0;
111
- overflow: hidden;
112
- }
113
- }
114
-
115
- .HairyArticleImage.slice {
116
- .post-image {
117
- // @apply transition-all;
118
- }
119
-
120
- &:hover {
121
- .post-image {
122
- transform: scale(1.05) rotate(1deg);
123
- }
124
- }
125
- }
126
- </style>
1
+ <script lang="ts" setup>
2
+ import type { Post } from 'valaxy'
3
+ import { computed, defineProps } from 'vue'
4
+ import dayjs from 'dayjs'
5
+ import { useRouter } from 'vue-router'
6
+ import { useI18n } from 'vue-i18n'
7
+ import { removeTags, toArray } from '../../utils'
8
+ import { useLayoutPost } from '../../composables'
9
+
10
+ const props = defineProps<{
11
+ post: Post
12
+ reverse?: boolean
13
+ }>()
14
+
15
+ const router = useRouter()
16
+ const layout = useLayoutPost()
17
+ const slice = computed(() => layout.value.includes('slice'))
18
+ const image = computed(() => props.post.image?.toString())
19
+ const text = computed(() => removeTags(props.post.excerpt))
20
+ const i18n = useI18n()
21
+ function onReadMore() {
22
+ if (props.post.path)
23
+ router.push(props.post.path)
24
+ }
25
+
26
+ function displayCategory(keys: string | string[] = []) {
27
+ router.push({ path: `/categories/${toArray(keys).join('/')}` })
28
+ }
29
+ </script>
30
+
31
+ <template>
32
+ <li class="HairyArticleImage mb-10 py-2" :class="[slice && 'slice', reverse && 'reverse']">
33
+ <article>
34
+ <div class="flex justify-between items-center">
35
+ <a class="text-size-2xl font-bold truncate cursor-pointer lt-sm:text-size-lg" :class="[reverse ? 'order-last' : 'order-first']" @click="onReadMore">{{ post.title }}</a>
36
+ <div class="flex justify-end gap-2 text-size-sm lt-sm:text-size-xs">
37
+ <span>{{ dayjs(post.date).format('YYYY-MM-DD') }}</span>
38
+ <span>{{ post.wordCount }}字</span>
39
+ <span class="lt-sm:hidden">{{ post.readingTime }}分钟</span>
40
+ </div>
41
+ </div>
42
+ <div class="h-200px lt-sm:h-150px flex bg-light-2 dark:bg-transparent rounded-5" :class="[reverse ? 'pl-4' : 'pr-4']">
43
+ <div class="flex-1 post-image-content" :class="[reverse ? 'order-last' : 'order-first']">
44
+ <img
45
+ class="post-image rounded-1 w-full h-full object-cover cursor-pointer" :src="image"
46
+ @click="onReadMore"
47
+ >
48
+ </div>
49
+ <div class="flex-1 flex flex-col justify-between py-2 dark:py-0">
50
+ <div class="flex-1 text-size-sm">
51
+ <div class="line-clamp-text">
52
+ {{ text }}
53
+ </div>
54
+ </div>
55
+ <div class="flex justify-between items-center">
56
+ <a class="cursor-pointer" :class="[reverse && 'order-1']">
57
+ <span v-if="post.categories?.length" @click="displayCategory(post.categories)">
58
+ {{ i18n.t(toArray(post.categories).at(-1) || '') }}
59
+ </span>
60
+ </a>
61
+ <div class="text-base leading-6 font-medium">
62
+ <a class="link cursor-pointer" aria-label="read more" @click="onReadMore">
63
+ <span v-if="reverse">←</span>
64
+ <span class="hidden md:block">Read more</span>
65
+ <span v-if="!reverse">→</span>
66
+ </a>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ </article>
72
+ </li>
73
+ </template>
74
+
75
+ <style lang="scss" scoped>
76
+ .line-clamp-text {
77
+ word-break: break-all;
78
+ overflow: hidden;
79
+ text-overflow: ellipsis;
80
+ display: -webkit-box;
81
+ text-overflow: ellipsis;
82
+ -webkit-box-orient: vertical;
83
+ -webkit-line-clamp: 5;
84
+ }
85
+
86
+ .dark {
87
+ .post-image {
88
+ @apply opacity-75 hover:opacity-90 ;
89
+ }
90
+ }
91
+
92
+ .post-image-content {
93
+ margin-right: 1rem;
94
+ }
95
+
96
+ .slice {
97
+ .post-image-content {
98
+ webkit-clip-path: polygon(0 0, 92% 0, 100% 100%, 0 100%);
99
+ clip-path: polygon(0 0, 92% 0, 100% 100%, 0 100%);
100
+ border-radius: 0.625rem 0 0 0.625rem;
101
+ overflow: hidden;
102
+ }
103
+ }
104
+
105
+ .reverse {
106
+ .post-image-content {
107
+ margin-right: 0;
108
+ margin-left: 1rem;
109
+ clip-path: polygon(0 0,100% 0,100% 100%,8% 100%);
110
+ border-radius: 0 0.625rem 0.625rem 0;
111
+ overflow: hidden;
112
+ }
113
+ }
114
+
115
+ .HairyArticleImage.slice {
116
+ .post-image {
117
+ // @apply transition-all;
118
+ }
119
+
120
+ &:hover {
121
+ .post-image {
122
+ transform: scale(1.05) rotate(1deg);
123
+ }
124
+ }
125
+ }
126
+ </style>
@@ -1,89 +1,89 @@
1
- <script lang="ts" setup>
2
- import type { PostFrontMatter } from 'valaxy'
3
- import { useFrontmatter } from 'valaxy'
4
- import { computed, inject, nextTick, ref } from 'vue'
5
- import { useRouter } from 'vue-router'
6
- import { toArray } from '../../utils'
7
- import { useCategory } from '../../composables'
8
-
9
- const frontmatter = useFrontmatter()
10
- const paths = computed(() => toArray(frontmatter.value.categories).filter(Boolean) as string[])
11
- const category = useCategory(paths)
12
-
13
- const posts = computed(() => {
14
- const result = [...(category.value.children?.values() || [])] as PostFrontMatter[]
15
- return result.sort((a, b) => (a.date || 1) > (b.date || 1) ? 1 : -1)
16
- })
17
-
18
- const router = useRouter()
19
-
20
- const active = inject('HairyUserTab:active', ref(''))
21
-
22
- function isCurrent(title = '') {
23
- return frontmatter.value.title === title
24
- }
25
-
26
- async function changePost(path = '') {
27
- router.push(path)
28
- await nextTick()
29
- active.value = 'aside'
30
- }
31
- </script>
32
-
33
- <template>
34
- <div class="pl-16px text-14px relative overflow-hidden animate__animated animate__fadeIn">
35
- <div class="outline-title">
36
- On this Series
37
- </div>
38
- <ul class="va-toc relative z-1">
39
- <a v-for="(item, index) of posts" :key="index" class="va-toc-item" @click="changePost(item.path)">
40
- <a class="outline-link" :class="[isCurrent(item.title) && 'active']">{{ index + 1 }}.{{ item.title }}</a>
41
- </a>
42
- </ul>
43
- </div>
44
- </template>
45
-
46
- <style lang="scss" scoped>
47
- .outline-title {
48
- letter-spacing: 0.4px;
49
- line-height: 28px;
50
- font-size: 14px;
51
- font-weight: 600;
52
- }
53
-
54
- .outline-link {
55
- display: block;
56
- position: relative;
57
- line-height: 28px;
58
- color: var(--va-c-text-light);
59
- white-space: nowrap;
60
- text-overflow: ellipsis;
61
- transition: color 0.5s;
62
- cursor: pointer;
63
-
64
- &:hover {
65
- color: var(--va-c-brand);
66
- transition: color 0.25s;
67
- }
68
-
69
- &.active {
70
- color: var(--va-c-brand);
71
- transition: color .25s;
72
-
73
- &::after {
74
- position: absolute;
75
- content: '';
76
- left: -1.12rem;
77
- top: 0;
78
- bottom: 0;
79
- margin: auto;
80
- width: 4px;
81
- height: 18px;
82
- background-color: var(--va-c-brand);
83
- transition: top 0.25s cubic-bezier(0, 1, 0.5, 1), background-color 0.5s, opacity 0.25s;
84
- border-top-right-radius: 2px;
85
- border-bottom-right-radius: 2px;
86
- }
87
- }
88
- }
89
- </style>
1
+ <script lang="ts" setup>
2
+ import type { PostFrontMatter } from 'valaxy'
3
+ import { useFrontmatter } from 'valaxy'
4
+ import { computed, inject, nextTick, ref } from 'vue'
5
+ import { useRouter } from 'vue-router'
6
+ import { toArray } from '../../utils'
7
+ import { useCategory } from '../../composables'
8
+
9
+ const frontmatter = useFrontmatter()
10
+ const paths = computed(() => toArray(frontmatter.value.categories).filter(Boolean) as string[])
11
+ const category = useCategory(paths)
12
+
13
+ const posts = computed(() => {
14
+ const result = [...(category.value.children?.values() || [])] as PostFrontMatter[]
15
+ return result.sort((a, b) => (a.date || 1) > (b.date || 1) ? 1 : -1)
16
+ })
17
+
18
+ const router = useRouter()
19
+
20
+ const active = inject('HairyUserTab:active', ref(''))
21
+
22
+ function isCurrent(title = '') {
23
+ return frontmatter.value.title === title
24
+ }
25
+
26
+ async function changePost(path = '') {
27
+ router.push(path)
28
+ await nextTick()
29
+ active.value = 'aside'
30
+ }
31
+ </script>
32
+
33
+ <template>
34
+ <div class="pl-16px text-14px relative overflow-hidden animate__animated animate__fadeIn">
35
+ <div class="outline-title">
36
+ On this Series
37
+ </div>
38
+ <ul class="va-toc relative z-1">
39
+ <a v-for="(item, index) of posts" :key="index" class="va-toc-item" @click="changePost(item.path)">
40
+ <a class="outline-link" :class="[isCurrent(item.title) && 'active']">{{ index + 1 }}.{{ item.title }}</a>
41
+ </a>
42
+ </ul>
43
+ </div>
44
+ </template>
45
+
46
+ <style lang="scss" scoped>
47
+ .outline-title {
48
+ letter-spacing: 0.4px;
49
+ line-height: 28px;
50
+ font-size: 14px;
51
+ font-weight: 600;
52
+ }
53
+
54
+ .outline-link {
55
+ display: block;
56
+ position: relative;
57
+ line-height: 28px;
58
+ color: var(--va-c-text-light);
59
+ white-space: nowrap;
60
+ text-overflow: ellipsis;
61
+ transition: color 0.5s;
62
+ cursor: pointer;
63
+
64
+ &:hover {
65
+ color: var(--va-c-brand);
66
+ transition: color 0.25s;
67
+ }
68
+
69
+ &.active {
70
+ color: var(--va-c-brand);
71
+ transition: color .25s;
72
+
73
+ &::after {
74
+ position: absolute;
75
+ content: '';
76
+ left: -1.12rem;
77
+ top: 0;
78
+ bottom: 0;
79
+ margin: auto;
80
+ width: 4px;
81
+ height: 18px;
82
+ background-color: var(--va-c-brand);
83
+ transition: top 0.25s cubic-bezier(0, 1, 0.5, 1), background-color 0.5s, opacity 0.25s;
84
+ border-top-right-radius: 2px;
85
+ border-bottom-right-radius: 2px;
86
+ }
87
+ }
88
+ }
89
+ </style>
@@ -1,43 +1,43 @@
1
- <script lang="ts" setup>
2
- import type { Post } from 'valaxy'
3
- import { computed, defineProps } from 'vue'
4
- import { removeTags } from '../../utils'
5
- import { useLayoutPost } from '../../composables'
6
-
7
- const props = defineProps<{
8
- post: Post
9
- }>()
10
-
11
- const layout = useLayoutPost()
12
-
13
- const text = computed(() => {
14
- if (layout.value === 'text')
15
- return removeTags(props.post.excerpt)
16
- return props.post.excerpt
17
- })
18
- </script>
19
-
20
- <template>
21
- <li class="py-12">
22
- <article class="space-y-2 xl:grid xl:grid-cols-4 xl:space-y-0 xl:items-baseline">
23
- <div class="space-y-5 xl:col-span-4">
24
- <div class="space-y-6">
25
- <h2 class="text-2xl leading-8 font-bold tracking-tight">
26
- <a class="st-text" :href="post.path">{{ post.title }}</a>
27
- </h2>
28
- <div
29
- v-if="text"
30
- class="prose max-w-none text-gray-500"
31
- v-html="text"
32
- />
33
- </div>
34
- <div class="text-base leading-6 font-medium">
35
- <a class="link" aria-label="read more" :href="post.path">
36
- <span class="hidden md:block">Read more</span>
37
- <span> →</span>
38
- </a>
39
- </div>
40
- </div>
41
- </article>
42
- </li>
43
- </template>
1
+ <script lang="ts" setup>
2
+ import type { Post } from 'valaxy'
3
+ import { computed, defineProps } from 'vue'
4
+ import { removeTags } from '../../utils'
5
+ import { useLayoutPost } from '../../composables'
6
+
7
+ const props = defineProps<{
8
+ post: Post
9
+ }>()
10
+
11
+ const layout = useLayoutPost()
12
+
13
+ const text = computed(() => {
14
+ if (layout.value === 'text')
15
+ return removeTags(props.post.excerpt)
16
+ return props.post.excerpt
17
+ })
18
+ </script>
19
+
20
+ <template>
21
+ <li class="py-12">
22
+ <article class="space-y-2 xl:grid xl:grid-cols-4 xl:space-y-0 xl:items-baseline">
23
+ <div class="space-y-5 xl:col-span-4">
24
+ <div class="space-y-6">
25
+ <h2 class="text-2xl leading-8 font-bold tracking-tight">
26
+ <a class="st-text" :href="post.path">{{ post.title }}</a>
27
+ </h2>
28
+ <div
29
+ v-if="text"
30
+ class="prose max-w-none text-gray-500"
31
+ v-html="text"
32
+ />
33
+ </div>
34
+ <div class="text-base leading-6 font-medium">
35
+ <a class="link" aria-label="read more" :href="post.path">
36
+ <span class="hidden md:block">Read more</span>
37
+ <span> →</span>
38
+ </a>
39
+ </div>
40
+ </div>
41
+ </article>
42
+ </li>
43
+ </template>
@@ -1,15 +1,15 @@
1
- <script lang="ts" setup>
2
- import { useRoute } from 'vue-router'
3
-
4
- const route = useRoute()
5
- </script>
6
-
7
- <template>
8
- <div class="mb-15">
9
- <div class="border-t border-gray-200 dark:border-gray-600" />
10
- <div class="flex items-center justify-end mt-2">
11
- <div class="i-ri-eye-fill mr-2" />
12
- 阅读次数 <span class="waline-pageview-count mx-2" :data-path="route.path"> - </span> 次
13
- </div>
14
- </div>
15
- </template>
1
+ <script lang="ts" setup>
2
+ import { useRoute } from 'vue-router'
3
+
4
+ const route = useRoute()
5
+ </script>
6
+
7
+ <template>
8
+ <div class="mb-15">
9
+ <div class="border-t border-gray-200 dark:border-gray-600" />
10
+ <div class="flex items-center justify-end mt-2">
11
+ <div class="i-ri-eye-fill mr-2" />
12
+ 阅读次数 <span class="waline-pageview-count mx-2" :data-path="route.path"> - </span> 次
13
+ </div>
14
+ </div>
15
+ </template>
@@ -1,27 +1,27 @@
1
- <script lang="ts" setup>
2
- import type { Ref } from 'vue'
3
- import { computed } from 'vue'
4
- import type { Post } from 'valaxy'
5
- import { usePostList } from 'valaxy'
6
- import { useLayoutPost } from '../../composables'
7
-
8
- const props = withDefaults(defineProps<{
9
- type?: string
10
- posts?: Post[]
11
- }>(), {
12
- })
13
-
14
- const layout = useLayoutPost()
15
- const reverse = computed(() => layout.value.includes('reverse'))
16
-
17
- const routes = usePostList() as any as Ref<Post[]>
18
- const posts = computed(() => props.posts || routes.value)
19
- </script>
20
-
21
- <template>
22
- <ul class="divide-y divide-gray-200 dark:divide-gray-700">
23
- <Transition v-for="post, i in posts" :key="i" name="fade">
24
- <HairyArticleImage :post="post" :reverse="reverse && !((i % 2) === 0)" />
25
- </Transition>
26
- </ul>
27
- </template>
1
+ <script lang="ts" setup>
2
+ import type { Ref } from 'vue'
3
+ import { computed } from 'vue'
4
+ import type { Post } from 'valaxy'
5
+ import { usePostList } from 'valaxy'
6
+ import { useLayoutPost } from '../../composables'
7
+
8
+ const props = withDefaults(defineProps<{
9
+ type?: string
10
+ posts?: Post[]
11
+ }>(), {
12
+ })
13
+
14
+ const layout = useLayoutPost()
15
+ const reverse = computed(() => layout.value.includes('reverse'))
16
+
17
+ const routes = usePostList() as any as Ref<Post[]>
18
+ const posts = computed(() => props.posts || routes.value)
19
+ </script>
20
+
21
+ <template>
22
+ <ul class="divide-y divide-gray-200 dark:divide-gray-700">
23
+ <Transition v-for="post, i in posts" :key="i" name="fade">
24
+ <HairyArticleImage :post="post" :reverse="reverse && !((i % 2) === 0)" />
25
+ </Transition>
26
+ </ul>
27
+ </template>
@@ -1,22 +1,22 @@
1
- <script lang="ts" setup>
2
- import type { Ref } from 'vue'
3
- import { computed } from 'vue'
4
- import type { Post } from 'valaxy'
5
- import { usePostList } from 'valaxy'
6
-
7
- const props = withDefaults(defineProps<{
8
- type?: string
9
- posts?: Post[]
10
- }>(), {})
11
-
12
- const routes = usePostList() as any as Ref<Post[]>
13
- const posts = computed(() => props.posts || routes.value)
14
- </script>
15
-
16
- <template>
17
- <ul class="divide-y divide-gray-200 dark:divide-gray-700">
18
- <Transition v-for="post, i in posts" :key="i" name="fade">
19
- <HairyArticleText :post="post" />
20
- </Transition>
21
- </ul>
22
- </template>
1
+ <script lang="ts" setup>
2
+ import type { Ref } from 'vue'
3
+ import { computed } from 'vue'
4
+ import type { Post } from 'valaxy'
5
+ import { usePostList } from 'valaxy'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ type?: string
9
+ posts?: Post[]
10
+ }>(), {})
11
+
12
+ const routes = usePostList() as any as Ref<Post[]>
13
+ const posts = computed(() => props.posts || routes.value)
14
+ </script>
15
+
16
+ <template>
17
+ <ul class="divide-y divide-gray-200 dark:divide-gray-700">
18
+ <Transition v-for="post, i in posts" :key="i" name="fade">
19
+ <HairyArticleText :post="post" />
20
+ </Transition>
21
+ </ul>
22
+ </template>