valaxy-theme-yun 0.19.13 → 0.20.0-beta.2

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 (109) hide show
  1. package/App.vue +30 -4
  2. package/bump.config.ts +7 -0
  3. package/client/constants/index.ts +13 -0
  4. package/components/ValaxyMain.vue +48 -52
  5. package/components/YunAdBoard.vue +4 -0
  6. package/components/YunAside.vue +66 -43
  7. package/components/YunBackToTop.vue +11 -4
  8. package/components/YunBanner.vue +31 -15
  9. package/components/YunBg.vue +2 -0
  10. package/components/YunCard.vue +5 -1
  11. package/components/YunCategories.vue +14 -34
  12. package/components/YunCategory.vue +42 -11
  13. package/components/YunClassifyPopover.vue +59 -0
  14. package/components/YunCloud.vue +5 -10
  15. package/components/YunConfig.vue +2 -19
  16. package/components/YunDebug.vue +47 -0
  17. package/components/YunDock.vue +223 -0
  18. package/components/YunFooter.vue +56 -4
  19. package/components/YunFullscreenMenu.vue +57 -0
  20. package/components/YunGirlItem.vue +98 -0
  21. package/components/YunGirls.vue +2 -73
  22. package/components/YunGoDown.vue +8 -15
  23. package/components/YunLinkItem.vue +62 -0
  24. package/components/YunLinks.vue +15 -47
  25. package/components/YunNavMenu.vue +125 -0
  26. package/components/YunOutline.vue +1 -2
  27. package/components/YunOverlay.vue +31 -0
  28. package/components/YunOverview.vue +2 -74
  29. package/components/YunPageHeader.vue +1 -1
  30. package/components/YunPagination.vue +105 -0
  31. package/components/YunPostCard.vue +32 -3
  32. package/components/YunPostCategories.vue +3 -3
  33. package/components/YunPostCollapse.vue +7 -72
  34. package/components/YunPostCollapseItem.vue +137 -0
  35. package/components/YunPostDateMeta.vue +30 -0
  36. package/components/YunPostList.vue +6 -11
  37. package/components/YunPostMeta.vue +31 -39
  38. package/components/YunPostTags.vue +2 -2
  39. package/components/YunPostsInfo.vue +41 -0
  40. package/components/YunPrologue.vue +24 -0
  41. package/components/YunSearchBtn.vue +8 -6
  42. package/components/YunSelect.vue +1 -11
  43. package/components/YunSidebar.vue +7 -4
  44. package/components/YunSidebarCard.vue +10 -0
  45. package/components/YunSidebarNav.vue +0 -1
  46. package/components/YunSiteInfo.vue +72 -0
  47. package/components/YunSponsor.vue +21 -6
  48. package/components/animation/LineBurstEffects.vue +75 -0
  49. package/components/author/YunAuthorAvatar.vue +12 -0
  50. package/components/author/YunAuthorIntro.vue +11 -0
  51. package/components/author/YunAuthorName.vue +14 -0
  52. package/components/config/YunToggleDark.vue +37 -0
  53. package/components/layout/YunLayoutLeft.vue +12 -0
  54. package/components/layout/YunLayoutRight.vue +21 -0
  55. package/components/layout/YunLayoutWrapper.vue +17 -0
  56. package/components/menu/YunNavMenuItem.vue +22 -0
  57. package/components/menu/YunNavMenuTitle.vue +86 -0
  58. package/components/menu/YunPostClassifyNavItem.vue +30 -0
  59. package/components/page/YunPageHeaderGradient.vue +38 -0
  60. package/components/project/YunProjectCard.vue +94 -0
  61. package/components/project/YunProjectCollection.vue +15 -0
  62. package/components/project/YunProjectLinkItem.vue +60 -0
  63. package/components/project/YunProjectToggleButton.vue +16 -0
  64. package/components/project/YunProjects.vue +48 -0
  65. package/components/prologue/PrologueSocialIcon.vue +58 -0
  66. package/components/prologue/PrologueSocialLinks.vue +16 -0
  67. package/components/prologue/PrologueSquare.vue +144 -0
  68. package/components/prologue/YunAEFrame.vue +155 -0
  69. package/components/prologue/YunAERect.vue +127 -0
  70. package/components/site/YunFullscreenMenuItem.vue +26 -0
  71. package/components/site/YunFullscreenMenuList.vue +19 -0
  72. package/components/site/YunSiteLinkItem.vue +26 -0
  73. package/components/site/YunSiteLinks.vue +19 -0
  74. package/components/site/YunSiteTitle.vue +59 -0
  75. package/components/third/YunWalineMeta.vue +17 -5
  76. package/docs/zh-CN/config.md +0 -3
  77. package/layouts/archives.vue +33 -21
  78. package/layouts/categories.vue +43 -31
  79. package/layouts/default.vue +10 -5
  80. package/layouts/empty.vue +3 -0
  81. package/layouts/home.vue +12 -5
  82. package/layouts/post.vue +23 -20
  83. package/layouts/posts.vue +10 -0
  84. package/layouts/projects.vue +25 -0
  85. package/layouts/tags.vue +45 -41
  86. package/node/config.ts +2 -5
  87. package/package.json +15 -7
  88. package/pages/page/[page].vue +3 -6
  89. package/pages/posts/index.vue +11 -0
  90. package/setup/main.ts +51 -9
  91. package/stores/app.ts +25 -3
  92. package/styles/animations/index.scss +36 -0
  93. package/styles/common/markdown.scss +4 -0
  94. package/styles/css-vars.scss +19 -1
  95. package/styles/global.scss +8 -0
  96. package/styles/index.scss +1 -0
  97. package/styles/layout/index.scss +3 -0
  98. package/styles/modules/prologue.scss +1 -0
  99. package/styles/primevue/index.ts +7 -0
  100. package/styles/primevue/tooltip.scss +55 -0
  101. package/styles/primevue/tooltip.ts +14 -0
  102. package/styles/vars.scss +23 -2
  103. package/styles/widgets/banner.scss +26 -6
  104. package/types/index.d.ts +53 -5
  105. package/types/projects.ts +48 -0
  106. package/unocss.config.ts +1 -1
  107. package/utils/animation.ts +33 -0
  108. package/utils/index.ts +2 -0
  109. package/LICENSE +0 -21
@@ -1,14 +1,6 @@
1
1
  <script lang="ts" setup>
2
- import { onImgError } from '../utils'
3
2
  import { useRandomData } from '../composables'
4
-
5
- interface GirlType {
6
- name: string
7
- url: string
8
- avatar: string
9
- from?: string
10
- reason?: string
11
- }
3
+ import type { GirlType } from '../types'
12
4
 
13
5
  const props = defineProps<{
14
6
  girls: GirlType[] | string
@@ -21,19 +13,7 @@ const { data } = useRandomData(props.girls, props.random)
21
13
  <template>
22
14
  <div class="girls">
23
15
  <ul class="girl-items">
24
- <li v-for="girl, i in data" :key="girl.name" class="girl-item">
25
- <a
26
- class="girl-item-link"
27
- :href="girl.url || `https://zh.moegirl.org/${girl.name}`"
28
- :title="girl.reason" alt="portrait" target="_blank" rel="noopener"
29
- >
30
- <figure class="girl-info">
31
- <img class="girl-avatar" loading="lazy" :src="girl.avatar" :alt="girl.name" :onError="onImgError">
32
- <figcaption class="girl-name" :title="(i + 1).toString()">{{ girl.name }}</figcaption>
33
- <figcaption class="girl-from">{{ girl.from }}</figcaption>
34
- </figure>
35
- </a>
36
- </li>
16
+ <YunGirlItem v-for="girl, i in data" :key="i" :i="i" :girl="girl" />
37
17
  </ul>
38
18
  </div>
39
19
  </template>
@@ -53,55 +33,4 @@ const { data } = useRandomData(props.girls, props.random)
53
33
  .girls-number {
54
34
  color: white;
55
35
  }
56
-
57
- .girl-item {
58
- display: inline-flex;
59
- text-align: center;
60
- justify-content: center;
61
- width: 8rem;
62
- margin: 1rem;
63
-
64
- .girl {
65
- &-info {
66
- width: 100%;
67
- padding: 0;
68
- margin: 0;
69
- }
70
-
71
- &-avatar {
72
- object-fit: cover;
73
- object-position: center top;
74
- width: 4rem;
75
- height: 4rem;
76
- border-radius: 50%;
77
- padding: 0.2rem;
78
- background-color: #fff;
79
- box-shadow: 0 0 1rem rgba(0, 0, 0, 0.12);
80
- transition: 0.5s;
81
-
82
- &:hover {
83
- box-shadow: 0 0 2rem rgba(0, 0, 0, 0.12);
84
- }
85
- }
86
-
87
- &-name {
88
- font-size: 0.9rem;
89
- }
90
-
91
- &-from {
92
- font-size: 12px;
93
- font-family: var(--va-font-serif);
94
- font-weight: bold;
95
- color: var(--va-c-text-light);
96
-
97
- &::before {
98
- content: '「';
99
- }
100
-
101
- &::after {
102
- content: '」';
103
- }
104
- }
105
- }
106
- }
107
36
  </style>
@@ -1,18 +1,13 @@
1
1
  <script lang="ts" setup>
2
- function goDown() {
3
- const banner = document.getElementById('yun-banner')
4
- if (banner) {
5
- window.scrollTo({
6
- top: banner.clientHeight,
7
- behavior: 'smooth',
8
- })
9
- }
10
- }
2
+ import { goDown } from '../utils'
11
3
  </script>
12
4
 
13
5
  <template>
14
- <button class="go-down" aria-label="go-down" @click="goDown">
15
- <div i-ri-arrow-down-s-line inline-flex />
6
+ <button
7
+ class="go-down w-20 bottom-0 text-sm md:(bottom-2 text-40px)" aria-label="go-down"
8
+ @click="goDown"
9
+ >
10
+ <div i-ri-arrow-down-s-fill inline-flex />
16
11
  </button>
17
12
  </template>
18
13
 
@@ -23,11 +18,9 @@ function goDown() {
23
18
  justify-content: center;
24
19
  align-items: center;
25
20
  position: absolute;
26
- bottom: 1rem;
27
21
  z-index: var(--yun-z-go-down);
28
22
  animation: float 2s ease-in-out infinite;
29
- font-size: 2.5rem;
30
- color: var(--va-c-primary);
23
+ color: var(--va-c-text);
31
24
  transition: color var(--va-transition-duration);
32
25
 
33
26
  &:hover {
@@ -43,7 +36,7 @@ function goDown() {
43
36
 
44
37
  50% {
45
38
  opacity: 0.8;
46
- transform: translateY(-0.8rem);
39
+ transform: translateY(-0.3em);
47
40
  }
48
41
 
49
42
  100% {
@@ -0,0 +1,62 @@
1
+ <script setup lang="ts">
2
+ import { useMotion } from '@vueuse/motion'
3
+ import { ref } from 'vue'
4
+ import { onImgError } from '../utils'
5
+ import type { LinkType } from '../types'
6
+
7
+ const props = defineProps<{
8
+ i: number
9
+ errorImg?: string
10
+ link: LinkType
11
+ }>()
12
+
13
+ function onError(e: Event) {
14
+ onImgError(e, props.errorImg)
15
+ }
16
+
17
+ const itemRef = ref()
18
+ useMotion(itemRef, {
19
+ initial: {
20
+ opacity: 0,
21
+ translateY: 40,
22
+ },
23
+ enter: {
24
+ opacity: 1,
25
+ translateY: 0,
26
+ transition: {
27
+ type: 'spring',
28
+ duration: 400,
29
+ damping: 8,
30
+ delay: props.i * 50,
31
+ },
32
+ },
33
+ })
34
+ </script>
35
+
36
+ <template>
37
+ <li
38
+ ref="itemRef"
39
+ class="yun-link-item inline-flex"
40
+ :style="{
41
+ '--primary-color': link.color,
42
+ }"
43
+ >
44
+ <a
45
+ class="yun-link-url" p="x-4 y-2" :href="link.url" :title="link.name"
46
+ alt="portrait" rel="friend" target="_blank"
47
+ >
48
+ <div class="yun-link-left">
49
+ <img
50
+ class="yun-link-avatar" width="64" height="64" w="16" h="16"
51
+ loading="lazy"
52
+ :src="link.avatar" :alt="link.name"
53
+ @error="onError"
54
+ >
55
+ </div>
56
+ <div class="yun-link-info" m="l-2">
57
+ <div class="yun-link-blog" font="serif black">{{ link.blog }}</div>
58
+ <div class="yun-link-desc">{{ link.desc }}</div>
59
+ </div>
60
+ </a>
61
+ </li>
62
+ </template>
@@ -1,15 +1,6 @@
1
1
  <script lang="ts" setup>
2
2
  import { useRandomData } from '../composables'
3
- import { onImgError } from '../utils'
4
-
5
- interface LinkType {
6
- avatar: string
7
- name: string
8
- url: string
9
- color: string
10
- blog: string
11
- desc: string
12
- }
3
+ import type { LinkType } from '../types'
13
4
 
14
5
  const props = defineProps<{
15
6
  links: string | LinkType[]
@@ -21,50 +12,27 @@ const props = defineProps<{
21
12
  }>()
22
13
 
23
14
  const { data } = useRandomData(props.links, props.random)
24
-
25
- function onError(e: Event) {
26
- onImgError(e, props.errorImg)
27
- }
28
15
  </script>
29
16
 
30
17
  <template>
31
- <div class="links">
32
- <ul class="link-items">
33
- <li v-for="link, i in data" :key="i" class="link-item" :style="`--primary-color: ${link.color}`">
34
- <a class="link-url" p="x-4 y-2" :href="link.url" :title="link.name" alt="portrait" rel="friend" target="_blank">
35
- <div class="link-left">
36
- <img
37
- class="link-avatar" width="64" height="64" w="16" h="16"
38
- loading="lazy" :src="link.avatar" :alt="link.name"
39
- @error="onError"
40
- >
41
- </div>
42
- <div class="link-info" m="l-2">
43
- <div class="link-blog" font="serif black">{{ link.blog }}</div>
44
- <div class="link-desc">{{ link.desc }}</div>
45
- </div>
46
- </a>
47
- </li>
18
+ <div class="yun-links">
19
+ <ul class="yun-link-items" flex="center wrap">
20
+ <YunLinkItem
21
+ v-for="link, i in data"
22
+ :key="i"
23
+ :i="i" :link="link" :error-img="errorImg"
24
+ />
48
25
  </ul>
49
26
  </div>
50
27
  </template>
51
28
 
52
- <style lang="scss" scoped>
53
- .link-item {
54
- display: inline-flex;
55
- }
56
-
57
- .links {
58
- .link-items {
59
- display: flex;
60
- text-align: center;
61
- justify-content: center;
62
- flex-wrap: wrap;
63
-
29
+ <style lang="scss">
30
+ .yun-links {
31
+ .yun-link-items {
64
32
  padding-left: 0;
65
33
  }
66
34
 
67
- .link-url {
35
+ .yun-link-url {
68
36
  --smc-link-color: var(--primary-color);
69
37
 
70
38
  display: inline-flex;
@@ -82,7 +50,7 @@ function onError(e: Event) {
82
50
  box-shadow: 0 2px 20px var(--primary-color, gray);
83
51
  }
84
52
 
85
- .link {
53
+ .yun-link {
86
54
  &-left {
87
55
  line-height: 0;
88
56
  }
@@ -97,7 +65,7 @@ function onError(e: Event) {
97
65
  transition: 0.5s;
98
66
 
99
67
  &:hover {
100
- box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
68
+ box-shadow: 0 0 20px rgb(0 0 0 / 0.1);
101
69
  }
102
70
  }
103
71
 
@@ -111,7 +79,7 @@ function onError(e: Event) {
111
79
  }
112
80
  }
113
81
 
114
- .link-info {
82
+ .yun-link-info {
115
83
  display: inline-flex;
116
84
  flex-direction: column;
117
85
  justify-content: center;
@@ -0,0 +1,125 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, ref, watch } from 'vue'
3
+ import { useSiteConfig } from 'valaxy'
4
+ import { useRoute } from 'vue-router'
5
+ import { useYunAppStore } from '../stores'
6
+ // import { useThemeConfig } from '../composables'
7
+
8
+ // const app = useAppStore()
9
+ const yunApp = useYunAppStore()
10
+ const siteConfig = useSiteConfig()
11
+ // const themeConfig = useThemeConfig()
12
+
13
+ const showMenu = ref(false)
14
+ const route = useRoute()
15
+ onMounted(() => {
16
+ if (route.meta.layout === 'home') {
17
+ setTimeout(() => {
18
+ showMenu.value = true
19
+ }, 600)
20
+ }
21
+ else {
22
+ showMenu.value = true
23
+ }
24
+ })
25
+
26
+ const playAnimation = ref(false)
27
+ watch(() => yunApp.scrollY, () => {
28
+ if (yunApp.scrollY > 10)
29
+ playAnimation.value = true
30
+ else
31
+ playAnimation.value = false
32
+ })
33
+ </script>
34
+
35
+ <template>
36
+ <Transition
37
+ enter-active-class="animate-fade-in"
38
+ >
39
+ <div
40
+ v-if="showMenu"
41
+ class="yun-nav-menu z-$yun-z-nav-menu"
42
+ border="~ solid $va-c-text"
43
+ :class="{
44
+ play: playAnimation,
45
+ }"
46
+ >
47
+ <!-- -->
48
+ <ValaxyHamburger
49
+ :active="yunApp.fullscreenMenu.isOpen"
50
+ class="menu-btn sidebar-toggle leading-4 size-12"
51
+ inline-flex cursor="pointer"
52
+ hover="bg-white/80 dark:bg-black/80"
53
+ z="$yun-z-menu-btn"
54
+ @click="yunApp.fullscreenMenu.toggle()"
55
+ />
56
+ <YunNavMenuItem icon="i-ri-home-4-line" to="/" />
57
+
58
+ <div class="flex flex-1 flex-center">
59
+ <YunNavMenuTitle />
60
+ </div>
61
+
62
+ <div class="inline-flex-center">
63
+ <!-- <template v-if="!app.isMobile && themeConfig.nav">
64
+ <template v-for="item in themeConfig.nav" :key="item.text">
65
+ <AppLink
66
+ v-if="'link' in item"
67
+ :to="item.link"
68
+ class="menu-btn inline-flex-center p-2 transition text-$va-c-text"
69
+ inline-flex cursor="pointer"
70
+ hover="bg-white/80 dark:bg-black/80"
71
+ z="$yun-z-menu-btn"
72
+ >
73
+ {{ item.text }}
74
+ </AppLink>
75
+ <template v-else-if="'items' in item" />
76
+ </template>
77
+ </template> -->
78
+
79
+ <YunToggleDark class="rounded-none!" />
80
+ <YunSearchTrigger v-if="siteConfig.search.enable" />
81
+ </div>
82
+ </div>
83
+ </Transition>
84
+ </template>
85
+
86
+ <style lang="scss">
87
+ @use 'sass:map';
88
+ @use 'valaxy-theme-yun/styles/vars.scss' as *;
89
+ @use "valaxy/client/styles/mixins/index.scss" as *;
90
+
91
+ .yun-nav-menu {
92
+ position: fixed;
93
+
94
+ // safari not support
95
+ // animation-timeline: scroll();
96
+ // animation-range: 0 calc(30vh), exit;
97
+ background-color: transparent;
98
+ box-shadow: none;
99
+ display: flex;
100
+ top: var(--rect-margin);
101
+ left: var(--rect-margin);
102
+ right: var(--rect-margin);
103
+ align-items: center;
104
+ justify-content: space-between;
105
+ height: 50px;
106
+ transition: all 0.5s map.get($cubic-bezier, 'ease-in');
107
+
108
+ &.play {
109
+ top: 0;
110
+ left: 0;
111
+ right: 0;
112
+ background-color: var(--va-c-bg);
113
+ border-color: rgb(0 0 0 / 0.1);
114
+
115
+ --un-shadow: var(--un-shadow-inset) 0 20px 25px -5px var(--un-shadow-color, rgb(0 0 0 / 0.1)), var(--un-shadow-inset) 0 8px 10px -6px var(--un-shadow-color, rgb(0 0 0 / 0.1));
116
+
117
+ box-shadow: var(--un-ring-offset-shadow), var(--un-ring-shadow),
118
+ var(--un-shadow);
119
+ }
120
+
121
+ .vt-hamburger-top, .vt-hamburger-middle, .vt-hamburger-bottom {
122
+ background-color: var(--va-c-text);
123
+ }
124
+ }
125
+ </style>
@@ -11,9 +11,8 @@ const themeConfig = useThemeConfig()
11
11
  const container = ref()
12
12
  const marker = ref()
13
13
 
14
- useActiveAnchor(container, marker)
15
-
16
14
  const { headers, handleClick } = useOutline()
15
+ useActiveAnchor(container, marker)
17
16
  </script>
18
17
 
19
18
  <template>
@@ -0,0 +1,31 @@
1
+ <script lang="ts" setup>
2
+ withDefaults(defineProps<{
3
+ show: boolean
4
+ }>(), {
5
+ show: false,
6
+ })
7
+ </script>
8
+
9
+ <template>
10
+ <Transition name="fade">
11
+ <div v-if="show" class="yun-overlay z-$yun-z-overlay" />
12
+ </Transition>
13
+ </template>
14
+
15
+ <style lang="scss">
16
+ @use "sass:map";
17
+ @use "valaxy/client/styles/mixins/index.scss" as *;
18
+
19
+ .yun-overlay {
20
+ background-color: rgb(0 0 0 / 0.3);
21
+ position: fixed;
22
+ inset: 0;
23
+ transition: opacity 0.4s;
24
+ }
25
+
26
+ @include mobile {
27
+ .yun-overlay {
28
+ display: block;
29
+ }
30
+ }
31
+ </style>
@@ -1,37 +1,10 @@
1
1
  <script lang="ts" setup>
2
- import { useSiteConfig } from 'valaxy'
3
- import { useRouter } from 'vue-router'
4
-
5
- const siteConfig = useSiteConfig()
6
- const router = useRouter()
2
+ // overview
7
3
  </script>
8
4
 
9
5
  <template>
10
6
  <div class="sidebar-panel" p="2">
11
- <div class="site-info" m="t-6">
12
- <RouterLink class="site-author-avatar" to="/about">
13
- <img class="rounded-full" :src="siteConfig.author.avatar" alt="avatar">
14
- <span v-if="siteConfig.author.status.emoji" class="site-author-status" :title="siteConfig.author.status.message || undefined">{{ siteConfig.author.status.emoji }}</span>
15
- </RouterLink>
16
- <div
17
- class="site-author-name leading-6"
18
- m="t-0 b-4"
19
- >
20
- <RouterLink to="/about">
21
- {{ siteConfig.author.name }}
22
- </RouterLink>
23
- </div>
24
- <RouterLink v-if="router.hasRoute('/about/site')" to="/about/site" class="site-name">
25
- {{ siteConfig.title }}
26
- </RouterLink>
27
- <span v-else class="site-name">{{ siteConfig.title }}</span>
28
- <h4 v-if="siteConfig.subtitle" class="site-subtitle block" text="xs">
29
- {{ siteConfig.subtitle }}
30
- </h4>
31
- <div v-if="siteConfig.description" class="site-description my-1">
32
- {{ siteConfig.description }}
33
- </div>
34
- </div>
7
+ <YunSiteInfo />
35
8
 
36
9
  <YunSidebarNav />
37
10
  <hr m="t-4 b-2" op="20">
@@ -47,57 +20,12 @@ const router = useRouter()
47
20
  <style lang="scss">
48
21
  @use "valaxy/client/styles/mixins/index.scss" as *;
49
22
 
50
- .site-info {
51
- &.fix-top {
52
- margin-top: -1.5rem;
53
- }
54
- }
55
-
56
- .site-author-avatar {
57
- display: inline-block;
58
- line-height: 0;
59
- position: relative;
60
-
61
- img {
62
- height: 96px;
63
- width: 96px;
64
- max-width: 100%;
65
- margin: 0;
66
- padding: 4px;
67
- background-color: white;
68
- box-shadow: 0 0 10px rgba(black, 0.2);
69
- transition: 0.4s;
70
-
71
- &:hover {
72
- box-shadow: 0 0 30px rgba(var(--va-c-primary-rgb), 0.2);
73
- }
74
- }
75
- }
76
-
77
- .site-author-status {
78
- position: absolute;
79
- height: 1.8rem;
80
- width: 1.8rem;
81
- bottom: 0;
82
- right: 0;
83
- line-height: 1.8rem;
84
- border-radius: 50%;
85
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
86
- background-color: var(--va-c-bg-light);
87
- border: 1px solid rgba(255, 255, 255, 0.1);
88
- }
89
-
90
23
  .site-name {
91
24
  color: var(--va-c-text);
92
25
  font-family: get-css-var('font-serif');
93
26
  font-weight: 900;
94
27
  }
95
28
 
96
- .site-subtitle {
97
- color: get-css-var('c-gray');
98
- display: block;
99
- }
100
-
101
29
  .site-description {
102
30
  color: var(--va-c-text);
103
31
  font-size: 0.8rem;
@@ -11,7 +11,7 @@ defineProps<{
11
11
  </script>
12
12
 
13
13
  <template>
14
- <header class="post-header" m="t-16 sm:t-6">
14
+ <header class="post-header">
15
15
  <h1
16
16
  class="post-title flex-center" p="2" text="2xl center"
17
17
  font="serif black"
@@ -0,0 +1,105 @@
1
+ <script lang="ts" setup>
2
+ import { usePagination } from 'valaxy'
3
+
4
+ const props = defineProps<{
5
+ /**
6
+ * Total Pages
7
+ */
8
+ total: number
9
+ /**
10
+ * Page Size
11
+ */
12
+ pageSize: number
13
+ }>()
14
+
15
+ const { curPage, totalPages, showPage, getTo, surLen, prevTo, nextTo, showPrev, showNext } = usePagination({
16
+ total: props.total,
17
+ pageSize: props.pageSize,
18
+ })
19
+ </script>
20
+
21
+ <template>
22
+ <nav class="pagination">
23
+ <RouterLink v-if="showPrev" class="page-number" :to="prevTo" aria-label="prev">
24
+ <div i-ri-arrow-left-s-line />
25
+ </RouterLink>
26
+
27
+ <template v-for="i in totalPages">
28
+ <RouterLink
29
+ v-if="showPage(i)" :key="i" class="page-number"
30
+ :class="curPage === i && 'active'"
31
+ :to="getTo(i)"
32
+ >
33
+ {{ i }}
34
+ </RouterLink>
35
+ <span v-else-if="i === curPage - surLen" :key="`prev-space-${i}`" class="space" disabled>
36
+ ...
37
+ </span>
38
+ <span v-else-if="i === curPage + surLen" :key="`next-space-${i}`" class="space" disabled>
39
+ ...
40
+ </span>
41
+ </template>
42
+
43
+ <RouterLink v-if="showNext" class="page-number" :to="nextTo" aria-label="next">
44
+ <div i-ri-arrow-right-s-line />
45
+ </RouterLink>
46
+ </nav>
47
+ </template>
48
+
49
+ <style lang="scss">
50
+ :root {
51
+ --page-btn-bg-color: rgba(255, 255, 255, 0.5);
52
+ --page-btn-hover-bg-color: var(--va-c-primary-lighter);
53
+ --page-btn-active-bg-color: var(--va-c-primary-light);
54
+ }
55
+
56
+ .dark {
57
+ --page-btn-bg-color: var(--va-c-bg-light);
58
+ }
59
+
60
+ .pagination {
61
+ display: flex;
62
+ justify-content: center;
63
+ align-items: center;
64
+
65
+ .prev, .next, .page-number, .space {
66
+ display: inline-flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ width: 2rem;
70
+ height: 2rem;
71
+ margin: 0;
72
+ transition: background-color var(--va-transition-duration) ease;
73
+
74
+ // disabled attr
75
+ &[disabled] {
76
+ background-color: var(--va-c-bg-mute);
77
+ }
78
+ }
79
+
80
+ .prev, .next, .page-number {
81
+ cursor: pointer;
82
+ color: var(--va-c-text);
83
+ text-decoration: none;
84
+ background-color: var(--page-btn-bg-color);
85
+
86
+ &:hover {
87
+ color: var(--va-c-bg);
88
+ background: var(--page-btn-hover-bg-color);
89
+ }
90
+
91
+ &:active {
92
+ color: var(--va-c-bg);
93
+ background: var(--page-btn-active-bg-color);
94
+ }
95
+
96
+ &.active {
97
+ font-weight: normal;
98
+ background: var(--page-btn-active-bg-color);
99
+ color: var(--va-c-bg);
100
+ cursor: default;
101
+ }
102
+
103
+ }
104
+ }
105
+ </style>