valaxy-theme-hairy 0.2.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. package/client/index.ts +1 -0
  2. package/components/HairyBody.vue +15 -17
  3. package/components/HairyComment.vue +33 -0
  4. package/components/HairyContainer.vue +17 -0
  5. package/components/{HairyUserPopup.vue → HairyDrawer.vue} +16 -16
  6. package/components/HairyFooter.vue +12 -9
  7. package/components/HairyHeader.vue +10 -9
  8. package/components/HairyImage.vue +3 -2
  9. package/components/HairyImageGroup.vue +12 -16
  10. package/components/HairyNavbar.vue +56 -0
  11. package/components/HairyPageArchives.vue +59 -0
  12. package/components/HairyPageTags.vue +48 -0
  13. package/components/{HairyPostList.vue → HairyPosts.vue} +3 -3
  14. package/components/{HairyNavSearch.vue → HairySearch.vue} +23 -87
  15. package/components/{HairyUserCard.vue → HairySidebar.vue} +4 -4
  16. package/components/HairyTabbar.vue +56 -0
  17. package/components/PageTags.vue +48 -0
  18. package/components/ValaxyMain.vue +3 -3
  19. package/components/navbar/HairyNav.vue +16 -0
  20. package/components/navbar/HairyNavExpand.vue +12 -0
  21. package/components/navbar/HairyNavItem.vue +35 -0
  22. package/components/navbar/HairyNavbarBackground.vue +7 -0
  23. package/components/navbar/HairyNavbarSearch.vue +8 -0
  24. package/components/{HairyNavTitle.vue → navbar/HairyNavbarTitle.vue} +5 -3
  25. package/components/navbar/HairyNavbarToggleDark.vue +22 -0
  26. package/components/{HairyBreadcrumb.vue → parts/HairyBreadcrumb.vue} +2 -2
  27. package/components/{HairyBreadcrumbItem.vue → parts/HairyBreadcrumbItem.vue} +1 -4
  28. package/components/{lib/fish.js → parts/HairyFootFish.js} +5 -7
  29. package/components/parts/HairyFootFish.vue +38 -0
  30. package/components/{HairyPostTitle.vue → parts/HairyHeadHero.vue} +6 -5
  31. package/components/{HairyWaves.vue → parts/HairyHeadWaves.vue} +5 -5
  32. package/components/parts/HairyImageGlobal.vue +51 -0
  33. package/components/{HairyImageViewer.vue → parts/HairyImageViewer.vue} +5 -4
  34. package/components/parts/HairyLink.vue +21 -0
  35. package/components/{HairyMenu.vue → parts/HairyMenu.vue} +2 -1
  36. package/components/{HairyMenuItem.vue → parts/HairyMenuItem.vue} +11 -4
  37. package/components/parts/HairyOutline.vue +99 -0
  38. package/components/parts/HairyOutlineItem.vue +48 -0
  39. package/components/{HairySocialLinks.vue → parts/HairySocialLinks.vue} +2 -2
  40. package/components/{HairyTimelinePostItem.vue → parts/HairyTimelineContent.vue} +7 -8
  41. package/components/parts/HairyUserNav.vue +95 -0
  42. package/components/{article-layout → posts}/HairyArticleImage.vue +18 -19
  43. package/components/{article-layout → posts}/HairyArticleSeries.vue +8 -5
  44. package/components/{article-layout → posts}/HairyArticleText.vue +11 -4
  45. package/components/posts/HairyPostFooter.vue +15 -0
  46. package/components/{article-layout → posts}/HairyPostImageList.vue +4 -5
  47. package/components/{article-layout → posts}/HairyPostTextsList.vue +0 -1
  48. package/components/posts/HairyPostToggleLayout.vue +36 -0
  49. package/components/third/HairyAlgoliaSearch.vue +17 -0
  50. package/components/third/HairyFuseSearch.vue +10 -0
  51. package/components/third/HairyFuseSearchDialog.vue +32 -0
  52. package/components/third/HairyFuseSearchDropdown.vue +77 -0
  53. package/components/third/HairyFuseSearchFooter.vue +28 -0
  54. package/components/third/HairyFuseSearchHeader.vue +30 -0
  55. package/components/third/HairyFuseSearchHit.vue +52 -0
  56. package/components/third/HairySearchBtnDisplay.vue +29 -0
  57. package/components/third/HairySearchBtnInput.vue +20 -0
  58. package/components/third/HairySearchBtnKeys.vue +19 -0
  59. package/components/{HairyCarousel.vue → third/HairySwiperCarousel.vue} +6 -6
  60. package/{hooks/useYearArchives.ts → composables/archives.ts} +4 -3
  61. package/composables/category.ts +43 -0
  62. package/composables/config.ts +11 -0
  63. package/composables/dark.ts +13 -0
  64. package/composables/fuse.ts +60 -0
  65. package/composables/index.ts +8 -0
  66. package/composables/layout.ts +16 -0
  67. package/composables/outline.ts +49 -0
  68. package/composables/tags.ts +36 -0
  69. package/layouts/archive-month.vue +13 -0
  70. package/layouts/archive-year.vue +13 -0
  71. package/layouts/archives.vue +9 -9
  72. package/layouts/categories.vue +11 -4
  73. package/layouts/default.vue +9 -3
  74. package/layouts/home.vue +28 -18
  75. package/layouts/post.vue +42 -36
  76. package/layouts/tag.vue +8 -4
  77. package/layouts/tags.vue +12 -4
  78. package/{modules → library}/loading.ts +18 -6
  79. package/{modules → library}/scroll.ts +3 -2
  80. package/locales/zh-CN.yml +0 -2
  81. package/node/images/default.json +139 -0
  82. package/node/images/index.ts +46 -0
  83. package/node/index.ts +2 -0
  84. package/node/theme/index.ts +78 -0
  85. package/package.json +22 -28
  86. package/pages/archives/[year]/[month]/index.vue +15 -18
  87. package/pages/archives/[year]/index.vue +20 -20
  88. package/pages/archives/index.vue +1 -54
  89. package/pages/categories/{[...categories].vue → [...its].vue} +29 -36
  90. package/pages/index.vue +1 -1
  91. package/pages/page/[page].vue +2 -2
  92. package/pages/tags/[tag]/index.vue +38 -0
  93. package/pages/tags/index.vue +1 -36
  94. package/setup/main.ts +1 -1
  95. package/store/index.ts +1 -0
  96. package/store/modules/global.ts +12 -0
  97. package/styles/components/index.scss +4 -0
  98. package/styles/{markdown.scss → components/markdown.scss} +2 -1
  99. package/styles/components/nprogress.scss +16 -0
  100. package/styles/css-vars.scss +11 -0
  101. package/styles/element-plus/tabs.scss +1 -1
  102. package/styles/element-plus/timeline.scss +1 -1
  103. package/styles/global.scss +39 -0
  104. package/styles/index.scss +4 -73
  105. package/tsconfig.json +27 -0
  106. package/types/index.d.ts +163 -0
  107. package/unocss.config.ts +5 -1
  108. package/utils/index.ts +21 -39
  109. package/valaxy.config.ts +21 -24
  110. package/@types/markdown-it.d.ts +0 -1
  111. package/@types/markdown-toc.d.ts +0 -1
  112. package/@types/types.d.ts +0 -1
  113. package/@types/valaxy.d.ts +0 -10
  114. package/components/HairyAlgoliaSearchBox.vue +0 -118
  115. package/components/HairyBackToTop.vue +0 -72
  116. package/components/HairyDivider.vue +0 -0
  117. package/components/HairyFooterFish.vue +0 -29
  118. package/components/HairyLayout.vue +0 -28
  119. package/components/HairyLink.vue +0 -10
  120. package/components/HairyLinks.vue +0 -69
  121. package/components/HairyMeting.vue +0 -19
  122. package/components/HairyNav.vue +0 -42
  123. package/components/HairyNavBackground.vue +0 -7
  124. package/components/HairyNavMenu.vue +0 -11
  125. package/components/HairyNavToggleDark.vue +0 -16
  126. package/components/HairyPostToggleLayout.vue +0 -33
  127. package/components/HairyToc.vue +0 -135
  128. package/components/HairyUserNav.vue +0 -64
  129. package/components/HairyUserTab.vue +0 -40
  130. package/components/HairyWaline.vue +0 -44
  131. package/hooks/setupDefaultDark.ts +0 -11
  132. package/hooks/useCategory.ts +0 -18
  133. package/hooks/useCategoryPost.ts +0 -21
  134. package/hooks/useContext.ts +0 -13
  135. package/hooks/useHeaderHeight.ts +0 -9
  136. package/hooks/usePostLayout.ts +0 -16
  137. package/images.json +0 -140
  138. package/index.d.ts +0 -100
  139. package/layouts/hairy.vue +0 -36
  140. package/layouts/month.vue +0 -6
  141. package/layouts/year.vue +0 -6
  142. package/node/addon-hairy.ts +0 -36
  143. package/node/addon-images.ts +0 -61
  144. package/node/addon-meting.ts +0 -13
  145. package/node/addon-statistics.ts +0 -19
  146. package/node/addon-toc.ts +0 -20
  147. package/node/utils.ts +0 -20
  148. package/pages/tags/[tag].vue +0 -40
  149. package/utils/createContext.ts +0 -40
  150. package/utils/fonts.ts +0 -15
  151. /package/components/{HairyUserStats.vue → parts/HairyUserStats.vue} +0 -0
  152. /package/components/{article-layout → posts}/HairyArticleTop.vue +0 -0
  153. /package/{modules → library}/loading.scss +0 -0
  154. /package/{shims.d.ts → node/images/shims.d.ts} +0 -0
  155. /package/styles/{aplayer.scss → components/aplayer.scss} +0 -0
  156. /package/styles/{scrollbar.scss → components/scrollbar.scss} +0 -0
@@ -0,0 +1 @@
1
+ export * from '../composables'
@@ -1,43 +1,38 @@
1
1
  <script lang="ts" setup>
2
- import { useFrontmatter } from 'valaxy'
3
- import { computed } from 'vue'
4
- import { useRoute } from 'vue-router'
5
- const fr = useFrontmatter()
6
- const route = useRoute()
7
-
8
- const showWaline = computed(() => route.path.includes('/posts/') || fr.value.waline)
9
2
  </script>
10
3
 
11
4
  <template>
12
- <div class="HairyBody min-h-49vh relative">
13
- <div class="mx-auto breakpoint flex z-1 relative">
14
- <div class="relative flex-1 pt-2 w-0">
5
+ <div class="min-h-49vh relative z-5">
6
+ <div class="mx-auto container flex z-1 relative">
7
+ <div class="relative flex-1 pt-2 main">
15
8
  <slot />
16
- <HairyWaline v-if="showWaline" />
9
+ <HairyComment />
17
10
  </div>
18
-
19
11
  <div class="ml-4 w-60 lg:block hidden">
20
12
  <div class="sticky top-3.125rem z-1">
21
13
  <slot v-if="$slots.slide" name="slide" />
22
- <HairyUserCard v-else />
14
+ <HairySidebar v-else />
23
15
  </div>
24
16
  </div>
25
17
  </div>
18
+
26
19
  <div class="HairyBodyBackground" />
27
20
  </div>
28
21
  </template>
29
22
 
30
23
  <style lang="scss">
31
24
  .HairyBodyBackground {
32
- @apply transition-all duration-200;
33
- @apply absolute top-0 max-h-150vh top-5 bottom-0 w-full transition-opacity;
25
+ @apply absolute top-0 max-h-150vh top-5 bottom-0 w-full;
34
26
  opacity: 0;
35
27
  }
28
+ .main {
29
+ background: linear-gradient(to bottom,#fafafa 0,#fff 20%) no-repeat top;
30
+ padding: 1.25rem;
31
+ border-radius: 10px
32
+ }
36
33
 
37
34
  .dark {
38
35
  .HairyBodyBackground {
39
- transition-delay: 200ms;
40
- transition-delay: 0;
41
36
  opacity: 1;
42
37
  background-image:
43
38
  linear-gradient(to bottom, var(--hy-c-waves-dimm) 0%, transparent 60%, var(--hy-c-waves-dimm) 100%), url(./images/bg.jpg);
@@ -47,5 +42,8 @@ const showWaline = computed(() => route.path.includes('/posts/') || fr.value.wal
47
42
  filter: blur(0px);
48
43
  background-size: cover;
49
44
  }
45
+ .main {
46
+ background: transparent;
47
+ }
50
48
  }
51
49
  </style>
@@ -0,0 +1,33 @@
1
+ <script lang="ts" setup>
2
+ import { useAddonWaline } from 'valaxy-addon-waline'
3
+
4
+ const addon = useAddonWaline()
5
+ </script>
6
+
7
+ <template>
8
+ <WalineClient w="full" :options="addon.options" />
9
+ </template>
10
+
11
+ <style lang="scss">
12
+ // 可以在此处覆盖 waline 样式
13
+ :root {
14
+ --waline-theme-color: var(--hy-c-primary);
15
+ --waline-active-color: var(--hy-c-primary-dark)
16
+ }
17
+
18
+ .wl-editor {
19
+ padding: 4px;
20
+ width: calc(100% - 1rem - 8px);
21
+ }
22
+ .wl-emoji-popup {
23
+ border-bottom: none !important;
24
+ z-index: 1000;
25
+ }
26
+ .wl-emoji-popup .wl-tabs {
27
+ height: auto !important;
28
+ overflow-x: auto !important;
29
+ padding: 0 !important;
30
+ margin-left: -1px;
31
+ margin-right: -1px;
32
+ }
33
+ </style>
@@ -0,0 +1,17 @@
1
+ <script lang="ts" setup>
2
+ import { onMounted } from 'vue'
3
+ import { setupDefaultDark } from '../composables'
4
+
5
+ import 'element-plus/theme-chalk/base.css'
6
+ import 'element-plus/theme-chalk/el-timeline.css'
7
+ import 'element-plus/theme-chalk/el-timeline-item.css'
8
+
9
+ onMounted(setupDefaultDark)
10
+ </script>
11
+
12
+ <template>
13
+ <div class="min-h-80vh">
14
+ <slot />
15
+ <HairyDrawer />
16
+ </div>
17
+ </template>
@@ -1,33 +1,33 @@
1
1
  <script lang="ts" setup>
2
- import 'element-plus/es/components/drawer/style/index'
2
+ import 'element-plus/theme-chalk/el-dialog.css'
3
3
  import { ElDrawer } from 'element-plus/es/components/drawer/index'
4
4
  import { useRoute } from 'vue-router'
5
- import { computed, watch } from 'vue'
6
- import { useContext } from '../hooks/useContext'
7
- const { drawerShow } = useContext()
5
+ import { watch } from 'vue'
6
+ import { storeToRefs } from 'pinia'
7
+ import { useGlobalStore } from '../store'
8
+
8
9
  const route = useRoute()
9
- const isPost = computed(() => route.fullPath.includes('/posts/'))
10
10
 
11
- watch(() => route.fullPath, () => {
12
- drawerShow.value = false
13
- })
11
+ const { showDrawer } = storeToRefs(useGlobalStore())
12
+
13
+ watch(() => route.fullPath, () => showDrawer.value = false)
14
14
  </script>
15
15
 
16
16
  <template>
17
- <el-drawer v-model="drawerShow" direction="ltr" size="auto" @close="drawerShow = false">
18
- <HairyUserTab v-if="isPost" />
19
- <HairyUserCard v-else />
20
- <div class="dark:hidden absolute inset-0 bg-white bg-opacity-85 blur-5" />
21
- </el-drawer>
17
+ <ElDrawer v-model="showDrawer" direction="ltr" size="auto" @close="showDrawer = false">
18
+ <div class="h-24px" />
19
+ <HairyTabbar v-if="route.fullPath.includes('/posts/')" />
20
+ <HairySidebar v-else />
21
+ <div class="dark:hidden absolute inset-0 bg-white bg-opacity-85" />
22
+ </ElDrawer>
22
23
  </template>
23
24
 
24
25
  <style lang="scss">
25
26
  .el-drawer {
27
+ background-color: transparent;
26
28
  .el-drawer__header {
27
29
  display: none;
28
30
  }
29
-
30
- background-color: transparent;
31
31
  .el-icon.el-drawer__close {
32
32
  font-size: 24px;
33
33
  }
@@ -38,7 +38,7 @@ watch(() => route.fullPath, () => {
38
38
  .dark {
39
39
  .el-drawer {
40
40
  background: radial-gradient(black, transparent);
41
-
41
+ box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
42
42
  }
43
43
  }
44
44
  </style>
@@ -1,23 +1,26 @@
1
1
  <script lang="ts" setup>
2
2
  import { capitalize, computed } from 'vue'
3
- import { useConfig, useThemeConfig } from 'valaxy'
3
+ import { useConfig, useSiteConfig, useThemeConfig } from 'valaxy'
4
4
  import { useI18n } from 'vue-i18n'
5
5
  import pkg from 'valaxy/package.json'
6
- import HairyFooterFish from './HairyFooterFish.vue'
6
+ import type { HairyTheme } from 'valaxy-theme-hairy'
7
7
 
8
8
  const { t } = useI18n()
9
9
 
10
10
  const config = useConfig()
11
- const themeConfig = useThemeConfig()
11
+ const sideConfig = useSiteConfig()
12
+ const themeConfig = useThemeConfig<HairyTheme.Config>()
12
13
 
13
14
  const year = new Date().getFullYear()
14
15
 
15
16
  const isThisYear = computed(() => {
16
- return year === themeConfig.value.footer.since
17
+ return year === themeConfig.value.footer?.since
17
18
  })
18
19
 
19
20
  const poweredHtml = computed(() => t('footer.powered', [`<a href="${pkg.repository}" target="_blank" rel="noopener">Valaxy</a> v${pkg.version}`]))
20
- const footerIcon = computed(() => themeConfig.value.footer.icon)
21
+ const footerIcon = computed(() => themeConfig.value.footer?.icon)
22
+
23
+ // const frontmatter = useFrontmatter()
21
24
  </script>
22
25
 
23
26
  <template>
@@ -41,11 +44,11 @@ const footerIcon = computed(() => themeConfig.value.footer.icon)
41
44
  <div :class="footerIcon.name" />
42
45
  </a>
43
46
 
44
- <span>{{ config.author.name }}</span>
47
+ <span>{{ sideConfig.author.name }}</span>
45
48
  <span class="mx-2">|</span>
46
- <span v-if="config.comment.waline" class="flex items-center">
49
+ <span class="flex items-center">
47
50
  <div class="i-ri-eye-fill mr-1" />
48
- <span class="waline-pageview-count" data-path="/">1</span>
51
+ <span class="waline-pageview-count" data-path="/">-</span>
49
52
  </span>
50
53
  </div>
51
54
  <div v-if="themeConfig.footer.powered" class="powered" m="2">
@@ -54,6 +57,6 @@ const footerIcon = computed(() => themeConfig.value.footer.icon)
54
57
  </div>
55
58
 
56
59
  <slot />
57
- <HairyFooterFish />
60
+ <HairyFootFish />
58
61
  </footer>
59
62
  </template>
@@ -1,26 +1,27 @@
1
1
  <script lang="ts" setup>
2
- import { useContext } from '../hooks/useContext'
2
+ import { storeToRefs } from 'pinia'
3
+ import { useGlobalStore } from '../store'
3
4
 
4
5
  defineProps<{
5
- headline?: String
6
- title?: String
6
+ headline?: string
7
+ title?: string
7
8
  description?: string
8
9
  }>()
9
10
 
10
- const { headerRef } = useContext()
11
+ const { headerRef } = storeToRefs(useGlobalStore())
11
12
  </script>
12
13
 
13
14
  <template>
14
- <header ref="headerRef" class="HairyHeader relative animate__animated animate__fadeIn">
15
+ <header ref="headerRef" class="relative animate__animated animate__fadeIn">
15
16
  <div class="h-30vh lt-md:h-60vh min-h-80 flex-center">
16
- <HairyPostTitle v-if="title" class="relative z-2" :title="title" v-bind="$props">
17
+ <HairyHeadHero v-if="title || headline || description || $slots.description" class="relative z-2" :title="title" v-bind="$props">
17
18
  <template #description>
18
19
  <slot name="description" />
19
20
  </template>
20
- </HairyPostTitle>
21
+ </HairyHeadHero>
21
22
  </div>
22
- <HairyCarousel class="inset-0" style="position: absolute" />
23
- <HairyWaves class="relative z-10" />
23
+ <HairySwiperCarousel class="inset-0" style="position: absolute" />
24
+ <HairyHeadWaves class="relative z-10" />
24
25
  </header>
25
26
  </template>
26
27
 
@@ -1,10 +1,11 @@
1
1
  <script lang="ts" setup>
2
2
  import { ElImage, imageProps } from 'element-plus/es/components/image/index'
3
- import 'element-plus/es/components/image/style/index'
3
+ import 'element-plus/theme-chalk/el-image.css'
4
4
  import { inject } from 'vue'
5
+
5
6
  const props = defineProps(imageProps)
6
7
 
7
- const preview = inject<(url: string) => void>('HairyImageGroup:preview')
8
+ const preview = inject<any>('HairyImageGroup:preview', undefined)
8
9
  </script>
9
10
 
10
11
  <template>
@@ -1,19 +1,17 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed, provide, useCssVars, useSlots } from 'vue'
3
- import { executeOverlay } from 'unoverlay-vue'
3
+ import { renderOverlay } from '@overlastic/vue'
4
4
  import type { ImageViewerProps } from 'element-plus/es/components/image-viewer/index'
5
- import type { AtWillNumber } from '../utils'
6
- import { atWillToUnit } from '../utils'
7
- import HairyImageViewer from './HairyImageViewer.vue'
5
+ import { atWillToUnit } from '@hairy/utils'
6
+ import HairyImageViewer from './parts/HairyImageViewer.vue'
8
7
 
9
8
  const props = withDefaults(defineProps<{
10
- row?: AtWillNumber
11
- col?: AtWillNumber
12
- gap?: AtWillNumber
9
+ row?: string | number
10
+ col?: string | number
11
+ gap?: string | number
13
12
  justify?: string
14
13
  align?: string
15
- }>(),
16
- {
14
+ }>(), {
17
15
  row: 'auto',
18
16
  col: 'auto',
19
17
  gap: 10,
@@ -36,13 +34,11 @@ const paths = computed(() => slots
36
34
  .filter(Boolean) as string[],
37
35
  )
38
36
 
39
- const preview = (url: string) => {
37
+ function preview(url: string) {
40
38
  const initialIndex = paths.value.findIndex(v => v === url) || 0
41
- executeOverlay<Partial<ImageViewerProps>>(HairyImageViewer, {
42
- props: {
43
- urlList: paths.value,
44
- initialIndex,
45
- },
39
+ renderOverlay<Partial<ImageViewerProps>>(HairyImageViewer, {
40
+ urlList: paths.value,
41
+ initialIndex,
46
42
  })
47
43
  }
48
44
 
@@ -51,7 +47,7 @@ provide('HairyImageGroup:preview', preview)
51
47
 
52
48
  <template>
53
49
  <div class="HairyImageGroup">
54
- <slot></slot>
50
+ <slot />
55
51
  </div>
56
52
  </template>
57
53
 
@@ -0,0 +1,56 @@
1
+ <script lang="ts" setup>
2
+ import { storeToRefs } from 'pinia'
3
+ import { computed, onMounted, ref } from 'vue'
4
+ import { useElementSize, useScroll, whenever } from '@vueuse/core'
5
+ import { useSiteConfig } from 'valaxy'
6
+ import { useGlobalStore } from '../store'
7
+
8
+ // get header height
9
+ const globalStore = useGlobalStore()
10
+ const { headerRef } = storeToRefs(globalStore)
11
+ const headerSize = useElementSize(headerRef)
12
+ const headerHeight = computed(() => headerSize.height.value)
13
+
14
+ // get document scroll
15
+ const documentRef = ref()
16
+ const scroll = useScroll(documentRef)
17
+ const dire = ref<'top' | 'bottom'>('top')
18
+
19
+ whenever(() => scroll.directions.top, () => dire.value = 'top')
20
+ whenever(() => scroll.directions.bottom, () => dire.value = 'bottom')
21
+
22
+ const show = computed(() => {
23
+ return scroll.y.value < (headerHeight.value / 2)
24
+ || dire.value === 'top'
25
+ })
26
+ const config = useSiteConfig()
27
+ onMounted(() => documentRef.value = document)
28
+ </script>
29
+
30
+ <template>
31
+ <div
32
+ class="fixed w-full h-3.125rem lt-sm:h-3.5rem top-0 opacity-0 z-10000"
33
+ :class="[show && 'opacity-100']"
34
+ >
35
+ <div class="px-12px md:px-0 mx-auto container flex relative z-1 h-full">
36
+ <div class="flex items-center lt-sm:order-1 lt-sm:flex-1 justify-center">
37
+ <HairyLink class="px-2.5" type="white" :href="config.url">
38
+ {{ config.title }}
39
+ </HairyLink>
40
+ </div>
41
+ <div class="flex items-center sm:flex-1">
42
+ <HairyNavExpand class="sm:hidden pl-2 pr-13" />
43
+ <HairyNav class="lt-sm:hidden" />
44
+ <slot name="nav" />
45
+ </div>
46
+ <div class="flex-center order-1">
47
+ <HairyNavbarToggleDark />
48
+ <HairySearch />
49
+ </div>
50
+ </div>
51
+
52
+ <HairyNavbarBackground />
53
+ </div>
54
+ </template>
55
+
56
+ <style lang="scss" scoped></style>
@@ -0,0 +1,59 @@
1
+ <script lang="ts" setup>
2
+ import { ElTimeline, ElTimelineItem } from 'element-plus/es/components/timeline/index'
3
+ import { usePostList } from 'valaxy'
4
+
5
+ import { getArchiveLink } from '../utils'
6
+ import { useYearArchives } from '../composables'
7
+
8
+ const activities = useYearArchives()
9
+ const posts = usePostList()
10
+ </script>
11
+
12
+ <template>
13
+ <HairyBreadcrumb class="mb-5" size="large" after="归档">
14
+ <HairyBreadcrumbItem to="/">
15
+ 首页
16
+ </HairyBreadcrumbItem>
17
+ <HairyBreadcrumbItem>
18
+ 目前共计 {{ posts.length }} 篇文章
19
+ </HairyBreadcrumbItem>
20
+ </HairyBreadcrumb>
21
+ <ElTimeline>
22
+ <ElTimelineItem
23
+ v-for="(activity, index) in activities"
24
+ :key="index"
25
+ size="large"
26
+ hollow
27
+ >
28
+ <div class="activity inline-flex items-center">
29
+ <HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year))">
30
+ {{ activity.year }}
31
+ </HairyLink>
32
+ <span class="text-gray-5 mx-2">/</span>
33
+ <HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year, activity.month))">
34
+ {{ activity.month }}
35
+ </HairyLink>
36
+ <span class="text-gray-5 text-size-5 ml-1">({{ activity.count }}篇)</span>
37
+ </div>
38
+ <HairyTimelineContent v-for="(item, index) in activity.posts.slice(0, 2)" :key="index" :post="item" />
39
+ <div v-if="activity.posts.length > 2">
40
+ <HairyLink @click="$router.push(getArchiveLink(activity.year))">
41
+ ....
42
+ </HairyLink>
43
+ </div>
44
+ </ElTimelineItem>
45
+ </ElTimeline>
46
+ </template>
47
+
48
+ <route lang="yaml">
49
+ meta:
50
+ layout: archive
51
+ </route>
52
+
53
+ <style lang="scss" scoped>
54
+ .activity:hover {
55
+ .HairyLink {
56
+ color: var(--hy-c-primary);
57
+ }
58
+ }
59
+ </style>
@@ -0,0 +1,48 @@
1
+ <script lang="ts" setup>
2
+ import { useRouter } from 'vue-router'
3
+ import { useHairyTags } from '../composables'
4
+
5
+ const router = useRouter()
6
+
7
+ const { getTagStyle, tags } = useHairyTags({
8
+ primary: '#1bc9a6',
9
+ })
10
+
11
+ function displayTag(tag: string) {
12
+ router.push(`/tags/${tag}`)
13
+ }
14
+ </script>
15
+
16
+ <template>
17
+ <div class="min-h-59vh flex-center flex-col">
18
+ <div text="center" class="text-size-2.5em pt-10 mb-5">
19
+ 目前共计 {{ Array.from(tags).length }} 个标签
20
+ </div>
21
+ <div text="center" class="max-w-7xl flex flex-wrap justify-center items-center gap-2">
22
+ <a
23
+ v-for="[key, tag] in Array.from(tags).sort()"
24
+ :key="key" class="post-tag cursor-pointer"
25
+ :style="getTagStyle(tag.count)"
26
+ p="1"
27
+ @click="displayTag(key.toString())"
28
+ >
29
+ {{ key }}
30
+ </a>
31
+ </div>
32
+ </div>
33
+ </template>
34
+
35
+ <route lang="yaml">
36
+ meta:
37
+ layout: tags
38
+ </route>
39
+
40
+ <style lang="scss" scoped>
41
+ a {
42
+ color: var(--yun-tag-color);
43
+ &:hover {
44
+ --un-text-opacity: 1;
45
+ color: var(--hy-c-primary-dark);
46
+ }
47
+ }
48
+ </style>
@@ -2,7 +2,7 @@
2
2
  import { computed, defineProps, ref, withDefaults } from 'vue'
3
3
  import type { Post } from 'valaxy'
4
4
  import { usePostList } from 'valaxy'
5
- import { usePostLayout } from '../hooks/usePostLayout'
5
+ import { useLayoutPost } from '../composables'
6
6
 
7
7
  const props = withDefaults(defineProps<{
8
8
  type?: string
@@ -13,7 +13,7 @@ const props = withDefaults(defineProps<{
13
13
  curPage: 1,
14
14
  pagination: false,
15
15
  })
16
- const layout = usePostLayout()
16
+ const layout = useLayoutPost()
17
17
 
18
18
  const pageSize = ref(7)
19
19
  const routes = usePostList({ type: props.type || '' })
@@ -27,7 +27,7 @@ const displayedPosts = computed(() => props.pagination ? pagePosts.value : posts
27
27
  <HairyPostToggleLayout />
28
28
  <HairyPostImageList v-if="layout.includes('image')" :posts="displayedPosts" />
29
29
  <HairyPostTextsList v-else :posts="displayedPosts" />
30
- <ValaxyPagination v-if="pagination" :cur-page="curPage" :page-size="pageSize" :total="posts.length" />
30
+ <ValaxyPagination v-if="pagination" class="mb-6" :cur-page="curPage" :page-size="pageSize" :total="posts.length" />
31
31
  </div>
32
32
  </template>
33
33