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.
- package/client/index.ts +1 -0
- package/components/HairyBody.vue +15 -17
- package/components/HairyComment.vue +33 -0
- package/components/HairyContainer.vue +17 -0
- package/components/{HairyUserPopup.vue → HairyDrawer.vue} +16 -16
- package/components/HairyFooter.vue +12 -9
- package/components/HairyHeader.vue +10 -9
- package/components/HairyImage.vue +3 -2
- package/components/HairyImageGroup.vue +12 -16
- package/components/HairyNavbar.vue +56 -0
- package/components/HairyPageArchives.vue +59 -0
- package/components/HairyPageTags.vue +48 -0
- package/components/{HairyPostList.vue → HairyPosts.vue} +3 -3
- package/components/{HairyNavSearch.vue → HairySearch.vue} +23 -87
- package/components/{HairyUserCard.vue → HairySidebar.vue} +4 -4
- package/components/HairyTabbar.vue +56 -0
- package/components/PageTags.vue +48 -0
- package/components/ValaxyMain.vue +3 -3
- package/components/navbar/HairyNav.vue +16 -0
- package/components/navbar/HairyNavExpand.vue +12 -0
- package/components/navbar/HairyNavItem.vue +35 -0
- package/components/navbar/HairyNavbarBackground.vue +7 -0
- package/components/navbar/HairyNavbarSearch.vue +8 -0
- package/components/{HairyNavTitle.vue → navbar/HairyNavbarTitle.vue} +5 -3
- package/components/navbar/HairyNavbarToggleDark.vue +22 -0
- package/components/{HairyBreadcrumb.vue → parts/HairyBreadcrumb.vue} +2 -2
- package/components/{HairyBreadcrumbItem.vue → parts/HairyBreadcrumbItem.vue} +1 -4
- package/components/{lib/fish.js → parts/HairyFootFish.js} +5 -7
- package/components/parts/HairyFootFish.vue +38 -0
- package/components/{HairyPostTitle.vue → parts/HairyHeadHero.vue} +6 -5
- package/components/{HairyWaves.vue → parts/HairyHeadWaves.vue} +5 -5
- package/components/parts/HairyImageGlobal.vue +51 -0
- package/components/{HairyImageViewer.vue → parts/HairyImageViewer.vue} +5 -4
- package/components/parts/HairyLink.vue +21 -0
- package/components/{HairyMenu.vue → parts/HairyMenu.vue} +2 -1
- package/components/{HairyMenuItem.vue → parts/HairyMenuItem.vue} +11 -4
- package/components/parts/HairyOutline.vue +99 -0
- package/components/parts/HairyOutlineItem.vue +48 -0
- package/components/{HairySocialLinks.vue → parts/HairySocialLinks.vue} +2 -2
- package/components/{HairyTimelinePostItem.vue → parts/HairyTimelineContent.vue} +7 -8
- package/components/parts/HairyUserNav.vue +95 -0
- package/components/{article-layout → posts}/HairyArticleImage.vue +18 -19
- package/components/{article-layout → posts}/HairyArticleSeries.vue +8 -5
- package/components/{article-layout → posts}/HairyArticleText.vue +11 -4
- package/components/posts/HairyPostFooter.vue +15 -0
- package/components/{article-layout → posts}/HairyPostImageList.vue +4 -5
- package/components/{article-layout → posts}/HairyPostTextsList.vue +0 -1
- package/components/posts/HairyPostToggleLayout.vue +36 -0
- package/components/third/HairyAlgoliaSearch.vue +17 -0
- package/components/third/HairyFuseSearch.vue +10 -0
- package/components/third/HairyFuseSearchDialog.vue +32 -0
- package/components/third/HairyFuseSearchDropdown.vue +77 -0
- package/components/third/HairyFuseSearchFooter.vue +28 -0
- package/components/third/HairyFuseSearchHeader.vue +30 -0
- package/components/third/HairyFuseSearchHit.vue +52 -0
- package/components/third/HairySearchBtnDisplay.vue +29 -0
- package/components/third/HairySearchBtnInput.vue +20 -0
- package/components/third/HairySearchBtnKeys.vue +19 -0
- package/components/{HairyCarousel.vue → third/HairySwiperCarousel.vue} +6 -6
- package/{hooks/useYearArchives.ts → composables/archives.ts} +4 -3
- package/composables/category.ts +43 -0
- package/composables/config.ts +11 -0
- package/composables/dark.ts +13 -0
- package/composables/fuse.ts +60 -0
- package/composables/index.ts +8 -0
- package/composables/layout.ts +16 -0
- package/composables/outline.ts +49 -0
- package/composables/tags.ts +36 -0
- package/layouts/archive-month.vue +13 -0
- package/layouts/archive-year.vue +13 -0
- package/layouts/archives.vue +9 -9
- package/layouts/categories.vue +11 -4
- package/layouts/default.vue +9 -3
- package/layouts/home.vue +28 -18
- package/layouts/post.vue +42 -36
- package/layouts/tag.vue +8 -4
- package/layouts/tags.vue +12 -4
- package/{modules → library}/loading.ts +18 -6
- package/{modules → library}/scroll.ts +3 -2
- package/locales/zh-CN.yml +0 -2
- package/node/images/default.json +139 -0
- package/node/images/index.ts +46 -0
- package/node/index.ts +2 -0
- package/node/theme/index.ts +78 -0
- package/package.json +22 -28
- package/pages/archives/[year]/[month]/index.vue +15 -18
- package/pages/archives/[year]/index.vue +20 -20
- package/pages/archives/index.vue +1 -54
- package/pages/categories/{[...categories].vue → [...its].vue} +29 -36
- package/pages/index.vue +1 -1
- package/pages/page/[page].vue +2 -2
- package/pages/tags/[tag]/index.vue +38 -0
- package/pages/tags/index.vue +1 -36
- package/setup/main.ts +1 -1
- package/store/index.ts +1 -0
- package/store/modules/global.ts +12 -0
- package/styles/components/index.scss +4 -0
- package/styles/{markdown.scss → components/markdown.scss} +2 -1
- package/styles/components/nprogress.scss +16 -0
- package/styles/css-vars.scss +11 -0
- package/styles/element-plus/tabs.scss +1 -1
- package/styles/element-plus/timeline.scss +1 -1
- package/styles/global.scss +39 -0
- package/styles/index.scss +4 -73
- package/tsconfig.json +27 -0
- package/types/index.d.ts +163 -0
- package/unocss.config.ts +5 -1
- package/utils/index.ts +21 -39
- package/valaxy.config.ts +21 -24
- package/@types/markdown-it.d.ts +0 -1
- package/@types/markdown-toc.d.ts +0 -1
- package/@types/types.d.ts +0 -1
- package/@types/valaxy.d.ts +0 -10
- package/components/HairyAlgoliaSearchBox.vue +0 -118
- package/components/HairyBackToTop.vue +0 -72
- package/components/HairyDivider.vue +0 -0
- package/components/HairyFooterFish.vue +0 -29
- package/components/HairyLayout.vue +0 -28
- package/components/HairyLink.vue +0 -10
- package/components/HairyLinks.vue +0 -69
- package/components/HairyMeting.vue +0 -19
- package/components/HairyNav.vue +0 -42
- package/components/HairyNavBackground.vue +0 -7
- package/components/HairyNavMenu.vue +0 -11
- package/components/HairyNavToggleDark.vue +0 -16
- package/components/HairyPostToggleLayout.vue +0 -33
- package/components/HairyToc.vue +0 -135
- package/components/HairyUserNav.vue +0 -64
- package/components/HairyUserTab.vue +0 -40
- package/components/HairyWaline.vue +0 -44
- package/hooks/setupDefaultDark.ts +0 -11
- package/hooks/useCategory.ts +0 -18
- package/hooks/useCategoryPost.ts +0 -21
- package/hooks/useContext.ts +0 -13
- package/hooks/useHeaderHeight.ts +0 -9
- package/hooks/usePostLayout.ts +0 -16
- package/images.json +0 -140
- package/index.d.ts +0 -100
- package/layouts/hairy.vue +0 -36
- package/layouts/month.vue +0 -6
- package/layouts/year.vue +0 -6
- package/node/addon-hairy.ts +0 -36
- package/node/addon-images.ts +0 -61
- package/node/addon-meting.ts +0 -13
- package/node/addon-statistics.ts +0 -19
- package/node/addon-toc.ts +0 -20
- package/node/utils.ts +0 -20
- package/pages/tags/[tag].vue +0 -40
- package/utils/createContext.ts +0 -40
- package/utils/fonts.ts +0 -15
- /package/components/{HairyUserStats.vue → parts/HairyUserStats.vue} +0 -0
- /package/components/{article-layout → posts}/HairyArticleTop.vue +0 -0
- /package/{modules → library}/loading.scss +0 -0
- /package/{shims.d.ts → node/images/shims.d.ts} +0 -0
- /package/styles/{aplayer.scss → components/aplayer.scss} +0 -0
- /package/styles/{scrollbar.scss → components/scrollbar.scss} +0 -0
package/client/index.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export * from '../composables'
|
package/components/HairyBody.vue
CHANGED
@@ -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="
|
13
|
-
<div class="mx-auto
|
14
|
-
<div class="relative flex-1 pt-2
|
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
|
-
<
|
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
|
-
<
|
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
|
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/
|
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 {
|
6
|
-
import {
|
7
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
11
|
+
const { showDrawer } = storeToRefs(useGlobalStore())
|
12
|
+
|
13
|
+
watch(() => route.fullPath, () => showDrawer.value = false)
|
14
14
|
</script>
|
15
15
|
|
16
16
|
<template>
|
17
|
-
<
|
18
|
-
<
|
19
|
-
<
|
20
|
-
<
|
21
|
-
|
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
|
6
|
+
import type { HairyTheme } from 'valaxy-theme-hairy'
|
7
7
|
|
8
8
|
const { t } = useI18n()
|
9
9
|
|
10
10
|
const config = useConfig()
|
11
|
-
const
|
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
|
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
|
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>{{
|
47
|
+
<span>{{ sideConfig.author.name }}</span>
|
45
48
|
<span class="mx-2">|</span>
|
46
|
-
<span
|
49
|
+
<span class="flex items-center">
|
47
50
|
<div class="i-ri-eye-fill mr-1" />
|
48
|
-
<span class="waline-pageview-count" data-path="/"
|
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
|
-
<
|
60
|
+
<HairyFootFish />
|
58
61
|
</footer>
|
59
62
|
</template>
|
@@ -1,26 +1,27 @@
|
|
1
1
|
<script lang="ts" setup>
|
2
|
-
import {
|
2
|
+
import { storeToRefs } from 'pinia'
|
3
|
+
import { useGlobalStore } from '../store'
|
3
4
|
|
4
5
|
defineProps<{
|
5
|
-
headline?:
|
6
|
-
title?:
|
6
|
+
headline?: string
|
7
|
+
title?: string
|
7
8
|
description?: string
|
8
9
|
}>()
|
9
10
|
|
10
|
-
const { headerRef } =
|
11
|
+
const { headerRef } = storeToRefs(useGlobalStore())
|
11
12
|
</script>
|
12
13
|
|
13
14
|
<template>
|
14
|
-
<header ref="headerRef" class="
|
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
|
-
<
|
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
|
-
</
|
21
|
+
</HairyHeadHero>
|
21
22
|
</div>
|
22
|
-
<
|
23
|
-
<
|
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/
|
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<
|
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 {
|
3
|
+
import { renderOverlay } from '@overlastic/vue'
|
4
4
|
import type { ImageViewerProps } from 'element-plus/es/components/image-viewer/index'
|
5
|
-
import
|
6
|
-
import
|
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?:
|
11
|
-
col?:
|
12
|
-
gap?:
|
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
|
-
|
37
|
+
function preview(url: string) {
|
40
38
|
const initialIndex = paths.value.findIndex(v => v === url) || 0
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
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 {
|
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 =
|
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
|
|