valaxy-theme-hairy 0.2.2 → 1.0.0

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.
Files changed (153) 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 +13 -0
  5. package/components/{HairyUserPopup.vue → HairyDrawer.vue} +14 -13
  6. package/components/HairyFooter.vue +12 -9
  7. package/components/HairyHeader.vue +10 -9
  8. package/components/HairyImage.vue +2 -1
  9. package/components/HairyImageGroup.vue +12 -16
  10. package/components/HairyNavbar.vue +56 -0
  11. package/components/{HairyPostList.vue → HairyPosts.vue} +3 -3
  12. package/components/{HairyNavSearch.vue → HairySearch.vue} +23 -87
  13. package/components/{HairyUserCard.vue → HairySidebar.vue} +4 -4
  14. package/components/{HairyUserTab.vue → HairyTabbar.vue} +27 -11
  15. package/components/PageTags.vue +48 -0
  16. package/components/ValaxyMain.vue +3 -3
  17. package/components/navbar/HairyNav.vue +16 -0
  18. package/components/navbar/HairyNavExpand.vue +12 -0
  19. package/components/navbar/HairyNavItem.vue +35 -0
  20. package/components/navbar/HairyNavbarBackground.vue +7 -0
  21. package/components/navbar/HairyNavbarSearch.vue +8 -0
  22. package/components/{HairyNavTitle.vue → navbar/HairyNavbarTitle.vue} +5 -3
  23. package/components/navbar/HairyNavbarToggleDark.vue +22 -0
  24. package/components/{HairyBreadcrumb.vue → parts/HairyBreadcrumb.vue} +1 -1
  25. package/components/{HairyBreadcrumbItem.vue → parts/HairyBreadcrumbItem.vue} +1 -4
  26. package/components/{lib/fish.js → parts/HairyFootFish.js} +5 -7
  27. package/components/parts/HairyFootFish.vue +38 -0
  28. package/components/{HairyPostTitle.vue → parts/HairyHeadHero.vue} +6 -5
  29. package/components/{HairyWaves.vue → parts/HairyHeadWaves.vue} +5 -5
  30. package/components/parts/HairyImageGlobal.vue +51 -0
  31. package/components/{HairyImageViewer.vue → parts/HairyImageViewer.vue} +4 -3
  32. package/components/parts/HairyLink.vue +21 -0
  33. package/components/{HairyMenu.vue → parts/HairyMenu.vue} +2 -1
  34. package/components/{HairyMenuItem.vue → parts/HairyMenuItem.vue} +11 -4
  35. package/components/parts/HairyOutline.vue +99 -0
  36. package/components/parts/HairyOutlineItem.vue +48 -0
  37. package/components/{HairySocialLinks.vue → parts/HairySocialLinks.vue} +2 -2
  38. package/components/{HairyTimelinePostItem.vue → parts/HairyTimelineContent.vue} +7 -8
  39. package/components/parts/HairyUserNav.vue +95 -0
  40. package/components/{article-layout → posts}/HairyArticleImage.vue +18 -19
  41. package/components/{article-layout → posts}/HairyArticleSeries.vue +8 -5
  42. package/components/{article-layout → posts}/HairyArticleText.vue +11 -4
  43. package/components/posts/HairyPostFooter.vue +15 -0
  44. package/components/{article-layout → posts}/HairyPostImageList.vue +4 -5
  45. package/components/{article-layout → posts}/HairyPostTextsList.vue +0 -1
  46. package/components/posts/HairyPostToggleLayout.vue +36 -0
  47. package/components/third/HairyAlgoliaSearch.vue +17 -0
  48. package/components/third/HairyFuseSearch.vue +10 -0
  49. package/components/third/HairyFuseSearchDialog.vue +32 -0
  50. package/components/third/HairyFuseSearchDropdown.vue +77 -0
  51. package/components/third/HairyFuseSearchFooter.vue +28 -0
  52. package/components/third/HairyFuseSearchHeader.vue +30 -0
  53. package/components/third/HairyFuseSearchHit.vue +52 -0
  54. package/components/third/HairySearchBtnDisplay.vue +29 -0
  55. package/components/third/HairySearchBtnInput.vue +20 -0
  56. package/components/third/HairySearchBtnKeys.vue +19 -0
  57. package/components/{HairyCarousel.vue → third/HairySwiperCarousel.vue} +6 -6
  58. package/{hooks/useYearArchives.ts → composables/archives.ts} +4 -3
  59. package/composables/category.ts +43 -0
  60. package/composables/config.ts +11 -0
  61. package/composables/dark.ts +13 -0
  62. package/composables/fuse.ts +60 -0
  63. package/composables/index.ts +8 -0
  64. package/composables/layout.ts +16 -0
  65. package/composables/outline.ts +49 -0
  66. package/composables/tags.ts +36 -0
  67. package/layouts/archive-month.vue +13 -0
  68. package/layouts/archive-year.vue +13 -0
  69. package/layouts/archive.vue +11 -0
  70. package/layouts/categories.vue +11 -4
  71. package/layouts/default.vue +8 -7
  72. package/layouts/home.vue +28 -18
  73. package/layouts/post.vue +41 -35
  74. package/layouts/tag.vue +8 -4
  75. package/layouts/tags.vue +11 -4
  76. package/{modules → library}/loading.ts +18 -6
  77. package/{modules → library}/scroll.ts +3 -2
  78. package/locales/zh-CN.yml +0 -2
  79. package/node/images/default.json +139 -0
  80. package/node/images/index.ts +46 -0
  81. package/node/index.ts +2 -0
  82. package/node/theme/index.ts +78 -0
  83. package/package.json +22 -28
  84. package/pages/archives/[year]/[month]/index.vue +15 -16
  85. package/pages/archives/[year]/index.vue +20 -18
  86. package/pages/archives/index.vue +10 -8
  87. package/pages/categories/{[...categories].vue → [...its].vue} +29 -34
  88. package/pages/index.vue +1 -1
  89. package/pages/page/[page].vue +2 -2
  90. package/pages/tags/{[tag].vue → [tag]/index.vue} +12 -12
  91. package/pages/tags/index.vue +12 -5
  92. package/setup/main.ts +1 -1
  93. package/store/index.ts +1 -0
  94. package/store/modules/global.ts +12 -0
  95. package/styles/components/index.scss +4 -0
  96. package/styles/{markdown.scss → components/markdown.scss} +2 -1
  97. package/styles/components/nprogress.scss +16 -0
  98. package/styles/css-vars.scss +11 -0
  99. package/styles/element-plus/tabs.scss +1 -1
  100. package/styles/element-plus/timeline.scss +1 -1
  101. package/styles/global.scss +39 -0
  102. package/styles/index.scss +4 -73
  103. package/tsconfig.json +27 -0
  104. package/types/index.d.ts +163 -0
  105. package/unocss.config.ts +5 -1
  106. package/utils/index.ts +21 -39
  107. package/valaxy.config.ts +21 -24
  108. package/@types/markdown-it.d.ts +0 -1
  109. package/@types/markdown-toc.d.ts +0 -1
  110. package/@types/types.d.ts +0 -1
  111. package/@types/valaxy.d.ts +0 -10
  112. package/components/HairyAlgoliaSearchBox.vue +0 -118
  113. package/components/HairyBackToTop.vue +0 -72
  114. package/components/HairyDivider.vue +0 -0
  115. package/components/HairyFooterFish.vue +0 -29
  116. package/components/HairyLayout.vue +0 -28
  117. package/components/HairyLink.vue +0 -10
  118. package/components/HairyLinks.vue +0 -69
  119. package/components/HairyMeting.vue +0 -19
  120. package/components/HairyNav.vue +0 -42
  121. package/components/HairyNavBackground.vue +0 -7
  122. package/components/HairyNavMenu.vue +0 -11
  123. package/components/HairyNavToggleDark.vue +0 -16
  124. package/components/HairyPostToggleLayout.vue +0 -33
  125. package/components/HairyToc.vue +0 -135
  126. package/components/HairyUserNav.vue +0 -64
  127. package/components/HairyWaline.vue +0 -44
  128. package/hooks/setupDefaultDark.ts +0 -11
  129. package/hooks/useCategory.ts +0 -18
  130. package/hooks/useCategoryPost.ts +0 -21
  131. package/hooks/useContext.ts +0 -13
  132. package/hooks/useHeaderHeight.ts +0 -9
  133. package/hooks/usePostLayout.ts +0 -16
  134. package/images.json +0 -140
  135. package/index.d.ts +0 -100
  136. package/layouts/archives.vue +0 -11
  137. package/layouts/hairy.vue +0 -36
  138. package/layouts/month.vue +0 -6
  139. package/layouts/year.vue +0 -6
  140. package/node/addon-hairy.ts +0 -36
  141. package/node/addon-images.ts +0 -61
  142. package/node/addon-meting.ts +0 -13
  143. package/node/addon-statistics.ts +0 -19
  144. package/node/addon-toc.ts +0 -20
  145. package/node/utils.ts +0 -20
  146. package/utils/createContext.ts +0 -40
  147. package/utils/fonts.ts +0 -15
  148. /package/components/{HairyUserStats.vue → parts/HairyUserStats.vue} +0 -0
  149. /package/components/{article-layout → posts}/HairyArticleTop.vue +0 -0
  150. /package/{modules → library}/loading.scss +0 -0
  151. /package/{shims.d.ts → node/images/shims.d.ts} +0 -0
  152. /package/styles/{aplayer.scss → components/aplayer.scss} +0 -0
  153. /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,13 @@
1
+ <script lang="ts" setup>
2
+ import { onMounted } from 'vue'
3
+ import { setupDefaultDark } from '../composables'
4
+
5
+ onMounted(setupDefaultDark)
6
+ </script>
7
+
8
+ <template>
9
+ <div class="min-h-80vh">
10
+ <slot />
11
+ <HairyDrawer />
12
+ </div>
13
+ </template>
@@ -2,23 +2,24 @@
2
2
  import 'element-plus/es/components/drawer/style/index'
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">
@@ -38,7 +39,7 @@ watch(() => route.fullPath, () => {
38
39
  .dark {
39
40
  .el-drawer {
40
41
  background: radial-gradient(black, transparent);
41
-
42
+ box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
42
43
  }
43
44
  }
44
45
  </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
 
@@ -2,9 +2,10 @@
2
2
  import { ElImage, imageProps } from 'element-plus/es/components/image/index'
3
3
  import 'element-plus/es/components/image/style/index'
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>
@@ -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
 
@@ -1,89 +1,18 @@
1
1
  <script lang="ts" setup>
2
- import '@docsearch/css'
3
- import { computed, defineAsyncComponent, onMounted, onUnmounted, ref } from 'vue'
4
- import { useConfig } from 'valaxy'
2
+ import { useSiteConfig } from 'valaxy'
3
+ import { computed } from 'vue'
5
4
 
6
- const HairyAlgoliaSearchBox = __ALGOLIA__
7
- ? defineAsyncComponent(() => import('./HairyAlgoliaSearchBox.vue'))
8
- : () => null
9
-
10
- const config = useConfig()
11
- const search = computed(() => config.value.search)
12
- const enable = computed(() => search.value.algolia.enable)
13
-
14
- // to avoid loading the docsearch js upfront (which is more than 1/3 of the
15
- // payload), we delay initializing it until the user has actually clicked or
16
- // hit the hotkey to invoke it.
17
- const loaded = ref(false)
18
-
19
- const metaKey = ref()
20
-
21
- onMounted(() => {
22
- if (!search.value.enable || !search.value.algolia.enable)
23
- return
24
-
25
- // meta key detect (same logic as in @docsearch/js)
26
- metaKey.value.textContent = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)
27
- ? '⌘'
28
- : 'Ctrl'
29
-
30
- const handleSearchHotKey = (e: KeyboardEvent) => {
31
- if (e.key === 'k' && (e.ctrlKey || e.metaKey)) {
32
- e.preventDefault()
33
- load()
34
- remove()
35
- }
36
- }
37
- function remove() {
38
- window.removeEventListener('keydown', handleSearchHotKey)
39
- }
40
-
41
- window.addEventListener('keydown', handleSearchHotKey)
42
- onUnmounted(remove)
43
- })
44
- function load() {
45
- if (!loaded.value)
46
- loaded.value = true
47
- }
5
+ const siteConfig = useSiteConfig()
6
+ const isAlgolia = computed(() => siteConfig.value.search.type === 'algolia')
7
+ const isFuse = computed(() => siteConfig.value.search.type === 'fuse')
48
8
  </script>
49
9
 
50
10
  <template>
51
- <div v-if="enable" class="VPNavBarSearch">
52
- <HairyAlgoliaSearchBox v-if="loaded" />
53
- <div v-else id="docsearch" @click="load">
54
- <button
55
- type="button"
56
- class="DocSearch DocSearch-Button"
57
- aria-label="Search"
58
- >
59
- <span class="DocSearch-Button-Container lt-sm:text-size-xl">
60
- <svg
61
- class="DocSearch-Search-Icon"
62
- width="20"
63
- height="20"
64
- viewBox="0 0 20 20"
65
- >
66
- <path
67
- d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
68
- stroke="currentColor"
69
- fill="none"
70
- fill-rule="evenodd"
71
- stroke-linecap="round"
72
- stroke-linejoin="round"
73
- />
74
- </svg>
75
- <span class="DocSearch-Button-Placeholder">Search</span>
76
- </span>
77
- <span class="DocSearch-Button-Keys">
78
- <kbd ref="metaKey" class="DocSearch-Button-Key">Meta</kbd>
79
- <kbd class="DocSearch-Button-Key">K</kbd>
80
- </span>
81
- </button>
82
- </div>
83
- </div>
11
+ <HairyAlgoliaSearch v-if="isAlgolia" />
12
+ <HairyFuseSearch v-if="isFuse" />
84
13
  </template>
85
14
 
86
- <style>
15
+ <style lang="scss">
87
16
  .VPNavBarSearch {
88
17
  display: flex;
89
18
  align-items: center;
@@ -133,7 +62,7 @@ function load() {
133
62
  width: 32px;
134
63
  height: 55px;
135
64
  background: transparent;
136
- transition: border-color 0.25s;
65
+ transition: all 0.25s;
137
66
  }
138
67
 
139
68
  .DocSearch-Button:hover {
@@ -146,7 +75,7 @@ function load() {
146
75
  }
147
76
 
148
77
  .DocSearch-Button:focus:not(:focus-visible) {
149
- outline: none !important;
78
+ outline: none;
150
79
  }
151
80
 
152
81
  @media (min-width: 768px) {
@@ -161,8 +90,15 @@ function load() {
161
90
  }
162
91
 
163
92
  .DocSearch-Button:hover {
93
+ background-color: rgba(255, 255, 255, 0.4);
164
94
  border-color: var(--hy-c-brand);
165
- /* background: var(--hy-c-bg-alt); */
95
+ }
96
+
97
+ .dark {
98
+ .DocSearch-Button:hover {
99
+ background-color: transparent;
100
+ border-color: var(--hy-c-brand);
101
+ }
166
102
  }
167
103
  }
168
104
 
@@ -242,7 +178,7 @@ function load() {
242
178
  transition: color 0.5s, border-color 0.5s;
243
179
  }
244
180
 
245
- .DocSearch-Button .DocSearch-Button-Key + .DocSearch-Button-Key {
181
+ .DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key {
246
182
  border-right: 1px solid var(--hy-c-divider);
247
183
  border-left: none;
248
184
  border-radius: 0 4px 4px 0;
@@ -250,10 +186,6 @@ function load() {
250
186
  padding-right: 6px;
251
187
  }
252
188
 
253
- .dark .DocSearch-Footer {
254
- border-top: 1px solid var(--hy-c-divider);
255
- }
256
-
257
189
  .DocSearch-Form {
258
190
  border: 1px solid var(--hy-c-brand);
259
191
  background-color: var(--hy-c-white);
@@ -262,4 +194,8 @@ function load() {
262
194
  .dark .DocSearch-Form {
263
195
  background-color: var(--hy-c-bg-mute);
264
196
  }
197
+
198
+ .dark .DocSearch-Footer {
199
+ border-top: 1px solid var(--hy-c-divider);
200
+ }
265
201
  </style>
@@ -1,10 +1,10 @@
1
1
  <script lang="ts" setup>
2
- import { useConfig, useThemeConfig } from 'valaxy'
2
+ import { useSiteConfig, useThemeConfig } from 'valaxy'
3
3
  import { computed } from 'vue'
4
4
  import type { HairyTheme } from 'valaxy-theme-hairy'
5
5
 
6
- const config = useConfig()
7
- const theme = useThemeConfig<HairyTheme>()
6
+ const config = useSiteConfig()
7
+ const theme = useThemeConfig<HairyTheme.Config>()
8
8
 
9
9
  const name = computed(() => theme.value.user?.name || config.value.author.name)
10
10
  const description = computed(() => theme.value.user?.description || config.value.description)
@@ -13,7 +13,7 @@ const description = computed(() => theme.value.user?.description || config.value
13
13
  <template>
14
14
  <div class="pt-5 animate__animated animate__fadeIn relative z-1">
15
15
  <div class="flex flex-col items-center">
16
- <img class="mx-auto w-40 rounded-full -mx-1px" :src="config.author.avatar" />
16
+ <img class="mx-auto w-40 rounded-full -mx-1px" :src="config.author.avatar">
17
17
  <div class="leading-loose mt-2">
18
18
  {{ name }}
19
19
  </div>
@@ -2,23 +2,39 @@
2
2
  import { ElTabPane, ElTabs } from 'element-plus/es/components/tabs/index'
3
3
  import 'element-plus/es/components/tabs/style/index'
4
4
  import 'element-plus/es/components/tab-pane/style/index'
5
- import { provide, ref } from 'vue'
5
+ import { computed, provide, ref } from 'vue'
6
+
7
+ import type { DefaultTheme } from 'valaxy/types'
8
+ import { useFrontmatter, useThemeConfig } from 'valaxy'
9
+
6
10
  const active = ref('aside')
11
+
12
+ const frontmatter = useFrontmatter()
13
+ const themeConfig = useThemeConfig()
14
+
15
+ const pageOutline = computed<DefaultTheme.Config['outline']>(
16
+ () => frontmatter.value.outline ?? themeConfig.value.outline,
17
+ )
18
+
19
+ const pageOutlineNotUndefined = computed(() =>
20
+ typeof pageOutline.value !== 'undefined',
21
+ )
22
+
7
23
  provide('HairyUserTab:active', active)
8
24
  </script>
9
25
 
10
26
  <template>
11
- <el-tabs v-model="active" class="pt-3">
12
- <el-tab-pane name="aside">
27
+ <ElTabs v-model="active" class="pt-3">
28
+ <ElTabPane v-if="pageOutlineNotUndefined" name="aside">
13
29
  <template #label>
14
30
  <div class="flex items-center">
15
31
  <div class="i-ri-list-check-2" />
16
32
  <span class="ml-1">Aside</span>
17
33
  </div>
18
34
  </template>
19
- <HairyToc />
20
- </el-tab-pane>
21
- <el-tab-pane label="Series" name="series">
35
+ <HairyOutline />
36
+ </ElTabPane>
37
+ <ElTabPane label="Series" name="series">
22
38
  <template #label>
23
39
  <div class="flex items-center gap-1">
24
40
  <div class="i-ri-flow-chart" />
@@ -26,15 +42,15 @@ provide('HairyUserTab:active', active)
26
42
  </div>
27
43
  </template>
28
44
  <HairyArticleSeries />
29
- </el-tab-pane>
30
- <el-tab-pane label="User" name="user">
45
+ </ElTabPane>
46
+ <ElTabPane label="User" name="user">
31
47
  <template #label>
32
48
  <div class="flex items-center gap-1">
33
49
  <div class="i-ri-user-line" />
34
50
  <span class="ml-1">User</span>
35
51
  </div>
36
52
  </template>
37
- <HairyUserCard />
38
- </el-tab-pane>
39
- </el-tabs>
53
+ <HairySidebar />
54
+ </ElTabPane>
55
+ </ElTabs>
40
56
  </template>