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

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 (120) 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 +47 -58
  5. package/components/YunAdBoard.vue +4 -0
  6. package/components/YunAlbum.vue +13 -3
  7. package/components/YunAlbumList.vue +5 -11
  8. package/components/YunAside.vue +66 -43
  9. package/components/YunBackToTop.vue +11 -4
  10. package/components/YunBanner.vue +31 -15
  11. package/components/YunBg.vue +2 -0
  12. package/components/YunCard.vue +5 -1
  13. package/components/YunCategories.vue +15 -34
  14. package/components/YunCategory.vue +57 -40
  15. package/components/YunCategoryChildItem.vue +49 -0
  16. package/components/YunClassifyPopover.vue +59 -0
  17. package/components/YunCloud.vue +5 -10
  18. package/components/YunConfig.vue +2 -19
  19. package/components/YunDebug.vue +47 -0
  20. package/components/YunDock.vue +223 -0
  21. package/components/YunFooter.vue +56 -4
  22. package/components/YunFullscreenMenu.vue +57 -0
  23. package/components/YunGirlItem.vue +98 -0
  24. package/components/YunGirls.vue +2 -73
  25. package/components/YunGoDown.vue +8 -15
  26. package/components/YunLayoutPostTag.vue +11 -1
  27. package/components/YunLinkItem.vue +62 -0
  28. package/components/YunLinks.vue +15 -47
  29. package/components/YunNavMenu.vue +125 -0
  30. package/components/YunOutline.vue +1 -2
  31. package/components/YunOverlay.vue +31 -0
  32. package/components/YunOverview.vue +2 -79
  33. package/components/YunPageHeader.vue +1 -1
  34. package/components/YunPagination.vue +108 -0
  35. package/components/YunPostCard.vue +32 -3
  36. package/components/YunPostCategories.vue +3 -3
  37. package/components/YunPostCollapse.vue +12 -75
  38. package/components/YunPostCollapseItem.vue +137 -0
  39. package/components/YunPostDateMeta.vue +30 -0
  40. package/components/YunPostList.vue +6 -11
  41. package/components/YunPostMeta.vue +31 -39
  42. package/components/YunPostTags.vue +2 -2
  43. package/components/YunPostsInfo.vue +41 -0
  44. package/components/YunPrologue.vue +24 -0
  45. package/components/YunSearchBtn.vue +8 -6
  46. package/components/YunSelect.vue +1 -11
  47. package/components/YunSidebar.vue +7 -4
  48. package/components/YunSidebarCard.vue +10 -0
  49. package/components/YunSidebarNav.vue +0 -1
  50. package/components/YunSiteInfo.vue +72 -0
  51. package/components/YunSponsor.vue +21 -6
  52. package/components/animation/LineBurstEffects.vue +75 -0
  53. package/components/author/YunAuthorAvatar.vue +12 -0
  54. package/components/author/YunAuthorIntro.vue +11 -0
  55. package/components/author/YunAuthorName.vue +14 -0
  56. package/components/config/YunToggleDark.vue +37 -0
  57. package/components/layout/YunLayoutLeft.vue +12 -0
  58. package/components/layout/YunLayoutRight.vue +21 -0
  59. package/components/layout/YunLayoutWrapper.vue +13 -0
  60. package/components/menu/YunNavMenuItem.vue +22 -0
  61. package/components/menu/YunNavMenuTitle.vue +86 -0
  62. package/components/menu/YunPostClassifyNavItem.vue +30 -0
  63. package/components/page/YunPageHeaderGradient.vue +38 -0
  64. package/components/project/YunProjectCard.vue +120 -0
  65. package/components/project/YunProjectCollection.vue +15 -0
  66. package/components/project/YunProjectLinkItem.vue +60 -0
  67. package/components/project/YunProjectToggleButton.vue +17 -0
  68. package/components/project/YunProjects.vue +48 -0
  69. package/components/prologue/PrologueSocialIcon.vue +58 -0
  70. package/components/prologue/PrologueSocialLinks.vue +16 -0
  71. package/components/prologue/PrologueSquare.vue +145 -0
  72. package/components/prologue/YunAEFrame.vue +138 -0
  73. package/components/prologue/YunAERect.vue +127 -0
  74. package/components/site/YunFullscreenMenuItem.vue +26 -0
  75. package/components/site/YunFullscreenMenuList.vue +19 -0
  76. package/components/site/YunSiteDescription.vue +11 -0
  77. package/components/site/YunSiteLinkItem.vue +26 -0
  78. package/components/site/YunSiteLinks.vue +19 -0
  79. package/components/site/YunSiteSubtitle.vue +14 -0
  80. package/components/site/YunSiteTitle.vue +59 -0
  81. package/components/third/YunWalineMeta.vue +17 -5
  82. package/components/ui/YunDivider.vue +3 -0
  83. package/composables/animation.ts +33 -0
  84. package/docs/zh-CN/config.md +0 -3
  85. package/layouts/404.vue +1 -3
  86. package/layouts/albums.vue +25 -24
  87. package/layouts/archives.vue +32 -21
  88. package/layouts/categories.vue +47 -31
  89. package/layouts/default.vue +10 -5
  90. package/layouts/empty.vue +3 -0
  91. package/layouts/gallery.vue +31 -30
  92. package/layouts/home.vue +13 -12
  93. package/layouts/post.vue +23 -20
  94. package/layouts/posts.vue +10 -0
  95. package/layouts/projects.vue +25 -0
  96. package/layouts/tags.vue +51 -41
  97. package/node/config.ts +2 -5
  98. package/package.json +16 -7
  99. package/pages/page/[page].vue +3 -6
  100. package/pages/posts/index.vue +11 -0
  101. package/setup/main.ts +51 -9
  102. package/stores/app.ts +25 -3
  103. package/styles/animations/index.scss +73 -0
  104. package/styles/common/markdown.scss +4 -0
  105. package/styles/css-vars.scss +19 -1
  106. package/styles/global.scss +8 -0
  107. package/styles/index.scss +1 -0
  108. package/styles/layout/index.scss +2 -4
  109. package/styles/modules/prologue.scss +1 -0
  110. package/styles/primevue/index.ts +7 -0
  111. package/styles/primevue/tooltip.scss +55 -0
  112. package/styles/primevue/tooltip.ts +14 -0
  113. package/styles/vars.scss +23 -2
  114. package/styles/widgets/banner.scss +26 -6
  115. package/types/index.d.ts +53 -5
  116. package/types/projects.ts +48 -0
  117. package/unocss.config.ts +1 -2
  118. package/utils/animation.ts +35 -0
  119. package/utils/index.ts +2 -0
  120. package/valaxy.config.ts +1 -0
@@ -1,14 +1,14 @@
1
1
  <script lang="ts" setup>
2
2
  import type { Post } from 'valaxy'
3
- import { formatDate, useSiteConfig } from 'valaxy'
3
+ import { useAppStore, useSiteConfig } from 'valaxy'
4
4
  import { useI18n } from 'vue-i18n'
5
- import { formatTimestamp } from '../utils'
6
5
 
7
6
  defineProps<{
8
7
  // FrontMatter
9
8
  frontmatter: Post
10
9
  }>()
11
10
 
11
+ const app = useAppStore()
12
12
  const { t } = useI18n()
13
13
 
14
14
  const siteConfig = useSiteConfig()
@@ -27,50 +27,42 @@ const siteConfig = useSiteConfig()
27
27
  </div>
28
28
 
29
29
  <div
30
- v-if="frontmatter" class="post-meta"
31
- flex="~ col" justify="center" items="center" text="sm" py="1"
30
+ v-if="frontmatter"
31
+ class="post-meta gap-4"
32
+ flex="~ center"
33
+ text="sm"
34
+ :class="{
35
+ 'flex-col gap-2!': app.isMobile || frontmatter.updated,
36
+ }"
32
37
  >
33
- <div v-if="frontmatter.date" class="post-time flex items-center">
34
- <span class="posted-time inline-flex-center" :title="t('post.posted') + formatTimestamp(frontmatter.date)">
35
- <div class="inline-block" i-ri-calendar-line />
36
- <time m="l-1">{{ formatDate(frontmatter.date) }}</time>
37
- </span>
38
+ <YunPostDateMeta :frontmatter="frontmatter" />
38
39
 
39
- <span
40
- v-if="frontmatter.updated && frontmatter.updated !== frontmatter.date"
41
- class="edited-time inline-flex-center" :title="t('post.edited') + formatTimestamp(frontmatter.updated)"
40
+ <div class="inline-flex-center gap-4">
41
+ <div
42
+ v-if="siteConfig.statistics.enable"
43
+ class="inline-flex-center post-counter gap-4"
42
44
  >
43
- <span m="x-2">-</span>
44
- <div i-ri-calendar-2-line />
45
- <time m="l-1">{{ formatDate(frontmatter.updated) }}</time>
46
- </span>
47
- </div>
45
+ <span
46
+ v-if="frontmatter.wordCount"
47
+ class="word-count inline-flex-center gap-1" :title="t('statistics.word')"
48
+ >
49
+ <div class="inline-block" i-ri-file-word-line />
50
+ <span class="op-80">{{ frontmatter.wordCount }}</span>
51
+ </span>
48
52
 
49
- <div
50
- v-if="siteConfig.statistics.enable"
51
- class="post-counter flex items-center" mt="2"
52
- >
53
- <span
54
- v-if="frontmatter.wordCount"
55
- class="word-count inline-flex-center" :title="t('statistics.word')"
56
- >
57
- <div class="inline-block" i-ri-file-word-line />
58
- <span m="l-1">{{ frontmatter.wordCount }}</span>
59
- </span>
53
+ <span
54
+ v-if="frontmatter.readingTime"
55
+ class="reading-time inline-flex-center gap-1"
56
+ :title="t('statistics.time')"
57
+ >
58
+ <div i-ri-timer-line />
59
+ <time class="op-80">{{ frontmatter.readingTime }}m</time>
60
+ </span>
61
+ </div>
60
62
 
61
- <span
62
- v-if="frontmatter.readingTime"
63
- class="reading-time inline-flex-center"
64
- :title="t('statistics.time')"
65
- >
66
- <span m="x-2">-</span>
67
- <div i-ri-timer-line />
68
- <time m="l-1">{{ frontmatter.readingTime }}m</time>
69
- </span>
63
+ <YunWalineMeta />
70
64
  </div>
71
65
  </div>
72
-
73
- <slot />
74
66
  </template>
75
67
 
76
68
  <style>
@@ -13,11 +13,11 @@ defineProps<{
13
13
  >
14
14
  <RouterLink
15
15
  v-for="tag, i in tags" :key="i" :to="{ path: '/tags/', query: { tag } }"
16
- class="transition post-tag inline-flex-center text-xs border-$va-c-divider hover:(text-blue-500 border-blue-500)"
16
+ class="transition post-tag inline-flex-center text-xs border-$va-c-divider"
17
17
  px-2 h="7"
18
18
  rounded-full
19
19
  border
20
- bg="hover:(blue-500 opacity-10)"
20
+ hover="bg-blue-500 text-white"
21
21
  >
22
22
  <span>{{ tag }}</span>
23
23
  </RouterLink>
@@ -0,0 +1,41 @@
1
+ <script lang="ts" setup>
2
+ import { useCategories, useSiteStore, useTags } from 'valaxy'
3
+ import { useI18n } from 'vue-i18n'
4
+
5
+ const { t } = useI18n()
6
+
7
+ const site = useSiteStore()
8
+
9
+ const categories = useCategories()
10
+ const tags = useTags()
11
+ </script>
12
+
13
+ <template>
14
+ <nav class="site-nav" text-xl mt-2>
15
+ <YunPostClassifyNavItem
16
+ to="/archives/" icon="i-ri-archive-line" :title="t('menu.archives')"
17
+ :total="site.postList.length"
18
+ />
19
+ <YunPostClassifyNavItem
20
+ to="/categories/" icon="i-ri-folder-2-line" :title="t('menu.categories')"
21
+ :total="Array.from(categories.children).length"
22
+ />
23
+ <YunPostClassifyNavItem
24
+ to="/tags/" icon="i-ri-price-tag-3-line" :title="t('menu.tags')"
25
+ :total="Array.from(tags).length"
26
+ />
27
+ </nav>
28
+ </template>
29
+
30
+ <style lang="scss">
31
+ @use "valaxy/client/styles/mixins/index.scss" as *;
32
+
33
+ .site-nav {
34
+ display: flex;
35
+ justify-content: center;
36
+ overflow: hidden;
37
+ line-height: 1.5;
38
+ white-space: nowrap;
39
+ text-align: center;
40
+ }
41
+ </style>
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <div class="grid-bg">
3
+ <YunAEFrame />
4
+ <YunAERect />
5
+
6
+ <div
7
+ flex="~ col"
8
+ class="justify-center items-center absolute bottom-5 md:bottom-12 left-0 right-0"
9
+ >
10
+ <PrologueSocialLinks />
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <style lang="scss">
16
+ .grid-bg {
17
+ --size: 40px;
18
+
19
+ background:
20
+ linear-gradient(90deg, rgb(255 255 255 / .1) 1px, transparent 1px),
21
+ linear-gradient(rgb(255 255 255 / .1) 1px, transparent 1px);
22
+ background-size: var(--size) var(--size);
23
+ }
24
+ </style>
@@ -20,18 +20,20 @@ function onClick() {
20
20
  </script>
21
21
 
22
22
  <template>
23
- <button class="yun-search-btn popup-trigger yun-icon-btn" :title="t('menu.search')" @click="onClick">
24
- <div v-if="!open" i-ri-search-line />
23
+ <button
24
+ class="yun-search-btn popup-trigger size-12 inline-flex justify-center items-center"
25
+ text="xl $va-c-text"
26
+ hover="bg-white/80 dark:bg-black/80"
27
+ :title="t('menu.search')"
28
+ @click="onClick"
29
+ >
30
+ <div v-if="!open" i-ri-search-line op-80 hover="op-100" />
25
31
  <div v-else text="!2xl" i-ri-close-line />
26
32
  </button>
27
33
  </template>
28
34
 
29
35
  <style lang="scss">
30
36
  .yun-search-btn {
31
- position: fixed;
32
- top: 0.6rem;
33
- right: 0.8rem;
34
- color: var(--va-c-primary);
35
37
  z-index: var(--yun-z-search-btn);
36
38
  }
37
39
  </style>
@@ -22,7 +22,7 @@ function toggleOptionVisible(e: MouseEvent) {
22
22
  </script>
23
23
 
24
24
  <template>
25
- <div class="relative h-8 w-30 text-$va-c-text-2 z-10" @mousedown.stop>
25
+ <div class="relative h-8 w-30 text-$va-c-text-2 z-$yun-z-select" @mousedown.stop>
26
26
  <button
27
27
  class="flex h-full w-full px-2 items-center justify-between rounded transition"
28
28
  border="~ gray op-30"
@@ -55,14 +55,4 @@ function toggleOptionVisible(e: MouseEvent) {
55
55
  .select-options {
56
56
  margin: 0;
57
57
  }
58
-
59
- .v-enter-active,
60
- .v-leave-active {
61
- transition: opacity .2s ease;
62
- }
63
-
64
- .v-enter-from,
65
- .v-leave-to {
66
- opacity: 0;
67
- }
68
58
  </style>
@@ -13,13 +13,13 @@ const showOverview = ref(false)
13
13
  <template>
14
14
  <ValaxyOverlay class="md:hidden" :show="yunStore.leftSidebar.isOpen" @click="yunStore.leftSidebar.toggle()" />
15
15
 
16
- <ValaxyHamburger
16
+ <!-- <ValaxyHamburger
17
17
  :active="yunStore.leftSidebar.isOpen"
18
18
  class="menu-btn sidebar-toggle yun-icon-btn leading-4 fixed left-0.8rem top-0.6rem"
19
19
  inline-flex cursor="pointer" z="$yun-z-menu-btn"
20
20
  :class="showHamburger ? '' : 'md:hidden'"
21
21
  @click="yunStore.leftSidebar.toggle()"
22
- />
22
+ /> -->
23
23
 
24
24
  <aside
25
25
  class="va-card transition sidebar fixed inset-y-0 left-0 overflow-y-auto"
@@ -55,6 +55,9 @@ const showOverview = ref(false)
55
55
  </template>
56
56
 
57
57
  <style lang="scss">
58
+ @use 'sass:map';
59
+ @use 'valaxy-theme-yun/styles/vars.scss' as *;
60
+
58
61
  .sidebar {
59
62
  width: calc(100vw - 64px);
60
63
  max-width: var(--va-sidebar-width);
@@ -62,8 +65,8 @@ const showOverview = ref(false)
62
65
  background-position: bottom 1rem center;
63
66
  transform: translateX(-100%);
64
67
  transition: box-shadow var(--va-transition-duration),
65
- background-color var(--va-transition-duration), opacity 0.25s,
66
- transform var(--va-transition-duration) cubic-bezier(0.19, 1, 0.22, 1) !important;
68
+ background-color var(--va-transition-duration), opacity var(--va-transition-duration),
69
+ transform var(--va-transition-duration) map.get($cubic-bezier, 'ease-in-out') !important;
67
70
 
68
71
  &.open {
69
72
  transform: translateX(0);
@@ -0,0 +1,10 @@
1
+ <script setup lang="ts">
2
+ // new sidebar card
3
+ </script>
4
+
5
+ <template>
6
+ <YunCard class="p-4 min-h-sm">
7
+ <YunSiteInfo class="text-center" />
8
+ <YunPostsInfo />
9
+ </YunCard>
10
+ </template>
@@ -47,7 +47,6 @@ const tags = useTags()
47
47
  line-height: 1.5;
48
48
  white-space: nowrap;
49
49
  text-align: center;
50
- margin-top: 1rem;
51
50
  }
52
51
 
53
52
  .site-link-item {
@@ -0,0 +1,72 @@
1
+ <script lang="ts" setup>
2
+ import { useSiteConfig } from 'valaxy'
3
+
4
+ const siteConfig = useSiteConfig()
5
+ </script>
6
+
7
+ <template>
8
+ <div class="site-info gap-1 items-center" flex="~ col" m="t-4">
9
+ <RouterLink
10
+ class="site-author-avatar inline-flex-center" to="/about"
11
+ >
12
+ <img class="rounded-full" :src="siteConfig.author.avatar" alt="avatar">
13
+ <!-- <span
14
+ v-if="siteConfig.author.status.emoji"
15
+ class="site-author-status absolute"
16
+ :title="siteConfig.author.status.message || undefined"
17
+ >{{ siteConfig.author.status.emoji }}</span> -->
18
+ </RouterLink>
19
+ <YunAuthorName />
20
+ <YunSiteTitle />
21
+ <h4
22
+ v-if="siteConfig.subtitle"
23
+ class="site-subtitle block"
24
+ text="xs"
25
+ >
26
+ {{ siteConfig.subtitle }}
27
+ </h4>
28
+ <div v-if="siteConfig.description" class="site-description">
29
+ {{ siteConfig.description }}
30
+ </div>
31
+ </div>
32
+ </template>
33
+
34
+ <style lang="scss">
35
+ .site-author-avatar {
36
+ position: relative;
37
+ line-height: 0;
38
+
39
+ img {
40
+ height: 96px;
41
+ width: 96px;
42
+ max-width: 100%;
43
+ margin: 0;
44
+ padding: 4px;
45
+ background-color: white;
46
+ box-shadow: 0 0 10px rgba(black, 0.2);
47
+ transition: 0.4s;
48
+
49
+ &:hover {
50
+ box-shadow: 0 0 30px rgba(var(--va-c-primary-rgb), 0.2);
51
+ }
52
+ }
53
+ }
54
+
55
+ .site-author-status {
56
+ height: 1.8rem;
57
+ width: 1.8rem;
58
+ bottom: 0;
59
+ right: 0;
60
+ line-height: 1.8rem;
61
+ border-radius: 50%;
62
+ box-shadow: 0 1px 2px rgb(0 0 0 / 0.2);
63
+ background-color: var(--va-c-bg-light);
64
+ border: 1px solid rgb(255 255 255 / 0.1);
65
+ }
66
+
67
+ .site-info {
68
+ &.fix-top {
69
+ margin-top: -1.5rem;
70
+ }
71
+ }
72
+ </style>
@@ -18,10 +18,13 @@ const sponsorBtnTitle = computed(() => {
18
18
  class="sponsor-button yun-icon-btn shadow hover:shadow-md"
19
19
  :title="sponsorBtnTitle" text="red-400" @click="showQr = !showQr"
20
20
  >
21
- <div i-ri-heart-line />
21
+ <div class="mt-2px" i-ri-heart-fill />
22
22
  </button>
23
23
 
24
- <div class="qrcode-container qrcode flex-center flex-col" m="y-4" :class="showQr && 'show'">
24
+ <div
25
+ class="qrcode-container qrcode flex-center flex-col" m="y-4"
26
+ :class="showQr && 'show'"
27
+ >
25
28
  <div v-if="siteConfig.sponsor.description" class="sponsor-description" mb="4" text="sm">
26
29
  {{ siteConfig.sponsor.description }}
27
30
  </div>
@@ -41,10 +44,12 @@ const sponsorBtnTitle = computed(() => {
41
44
  </template>
42
45
 
43
46
  <style lang="scss">
47
+ @use 'sass:map';
48
+ @use 'valaxy-theme-yun/styles/vars.scss' as *;
44
49
  @use "valaxy/client/styles/mixins/index.scss" as *;
45
50
 
46
51
  .sponsor-button {
47
- background-color: rgba(255, 255, 255, 0.1);
52
+ background-color: rgb(255 255 255 / 0.1);
48
53
 
49
54
  div {
50
55
  transform: scale(1.1);
@@ -52,7 +57,7 @@ const sponsorBtnTitle = computed(() => {
52
57
  }
53
58
 
54
59
  &:hover {
55
- background-color: rgba(255, 255, 255, 0.9);
60
+ background-color: rgb(255 255 255 / 0.9);
56
61
 
57
62
  div {
58
63
  transform: scale(1.2);
@@ -67,12 +72,22 @@ const sponsorBtnTitle = computed(() => {
67
72
  }
68
73
 
69
74
  .qrcode-container {
75
+ --height: 200px;
76
+
70
77
  overflow: hidden;
71
78
  height: 0;
72
- transition: height var(--va-transition-duration) ease-in-out;
79
+ opacity: 0;
80
+ transition: all var(--va-transition-duration) map.get($cubic-bezier, 'ease-in-out');
73
81
 
74
82
  &.show {
75
- height: 260px;
83
+ height: var(--height);
84
+ opacity: 1;
85
+ }
86
+ }
87
+
88
+ @include screen('md') {
89
+ .qrcode-container {
90
+ --height: 260px;
76
91
  }
77
92
  }
78
93
 
@@ -0,0 +1,75 @@
1
+ <script setup lang="ts">
2
+ // 播放完销毁 css 动画
3
+ import { onMounted, ref } from 'vue'
4
+
5
+ const props = defineProps<{
6
+ duration: number
7
+ }>()
8
+
9
+ const destroy = ref(false)
10
+ onMounted(() => {
11
+ setTimeout(() => {
12
+ destroy.value = true
13
+ }, props.duration)
14
+ })
15
+ </script>
16
+
17
+ <template>
18
+ <div
19
+ v-if="!destroy"
20
+ class="line-burst-effects absolute"
21
+ >
22
+ <div v-for="i in 8" :key="i" class="line">
23
+ <div>
24
+ <span />
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <style lang="scss">
31
+ .line-burst-effects {
32
+ .line {
33
+ position: absolute;
34
+ top: 0;
35
+ left: calc(50% - 2px);
36
+ width: 4px;
37
+ height: 100%;
38
+ }
39
+
40
+ @for $i from 1 through 8 {
41
+ .line:nth-child(#{$i}) {
42
+ transform: rotate($i * 45deg);
43
+
44
+ div {
45
+ position: absolute;
46
+ top: 0;
47
+ left: 0;
48
+ width: 100%;
49
+ height: 20%;
50
+ overflow: hidden;
51
+ }
52
+
53
+ span {
54
+ display: block;
55
+ background-color: white;
56
+ content: '';
57
+ width: 100%;
58
+ height: 100%;
59
+ transform: translateY(100%);
60
+ animation: line-burst 0.8s forwards;
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ @keyframes line-burst {
67
+ 0% {
68
+ transform: translateY(100%);
69
+ }
70
+
71
+ 100% {
72
+ transform: translateY(-100%);
73
+ }
74
+ }
75
+ </style>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import { useSiteConfig } from 'valaxy'
3
+
4
+ const siteConfig = useSiteConfig()
5
+ </script>
6
+
7
+ <template>
8
+ <img
9
+ class="rounded-full size-full"
10
+ :src="siteConfig.author.avatar" alt="avatar"
11
+ >
12
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ import { useSiteConfig } from 'valaxy'
3
+
4
+ const siteConfig = useSiteConfig()
5
+ </script>
6
+
7
+ <template>
8
+ <div v-if="siteConfig.author.intro" class="site-author-intro" m="t-0 b-4">
9
+ {{ siteConfig.author.intro }}
10
+ </div>
11
+ </template>
@@ -0,0 +1,14 @@
1
+ <script setup lang="ts">
2
+ import { useSiteConfig } from 'valaxy'
3
+
4
+ const siteConfig = useSiteConfig()
5
+ </script>
6
+
7
+ <template>
8
+ <RouterLink
9
+ class="site-author-name font-black font-serif text-$va-c-text op-80 hover:op-100 flex-center"
10
+ to="/about"
11
+ >
12
+ {{ siteConfig.author.name }}
13
+ </RouterLink>
14
+ </template>
@@ -0,0 +1,37 @@
1
+ <script lang="ts" setup>
2
+ import { useI18n } from 'vue-i18n'
3
+ import { computed } from 'vue'
4
+ import { useAppStore } from 'valaxy'
5
+
6
+ const props = defineProps<{
7
+ transition?: boolean
8
+ }>()
9
+
10
+ const appStore = useAppStore()
11
+ const { t } = useI18n()
12
+
13
+ const themeTitle = computed(() => {
14
+ return appStore.isDark ? t('button.toggle_light') : t('button.toggle_dark')
15
+ })
16
+
17
+ const styles = computed(() => {
18
+ return {
19
+ color: appStore.isDark ? '' : '#f1cb64',
20
+ }
21
+ })
22
+
23
+ function toggle(e: MouseEvent) {
24
+ props.transition ? appStore.toggleDarkWithTransition(e) : appStore.toggleDark()
25
+ }
26
+ </script>
27
+
28
+ <template>
29
+ <button
30
+ class="yun-icon-btn"
31
+ :title="themeTitle"
32
+ :style="styles" @mousedown.prevent="() => { console.log('yes') }"
33
+ @click="toggle"
34
+ >
35
+ <div i="ri-sun-line dark:ri-moon-line" />
36
+ </button>
37
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import { useYunAppStore } from '../../stores'
3
+
4
+ const yun = useYunAppStore()
5
+ </script>
6
+
7
+ <template>
8
+ <div v-if="yun.size.isLg" flex="~ col" class="gap-4 sticky top-68px w-80">
9
+ <YunSidebarCard />
10
+ <YunAdBoard />
11
+ </div>
12
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { useFrontmatter } from 'valaxy'
3
+ import { useYunAppStore } from '../../stores'
4
+
5
+ const fm = useFrontmatter()
6
+ const yun = useYunAppStore()
7
+ </script>
8
+
9
+ <template>
10
+ <button
11
+ v-if="fm.aside !== false"
12
+ class="xl:hidden toc-btn shadow-md fixed yun-icon-btn z-350 bg-$va-c-bg-soft"
13
+ opacity="75" right="2" bottom="19"
14
+ @click="yun.rightSidebar.toggle()"
15
+ >
16
+ <div i-ri-file-list-line />
17
+ </button>
18
+
19
+ <YunOverlay :show="yun.rightSidebar.isOpen" @click="yun.rightSidebar.toggle()" />
20
+ <YunAside />
21
+ </template>
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ // common layout
3
+ </script>
4
+
5
+ <template>
6
+ <div
7
+ flex="~"
8
+ m="t-24 md:t-36"
9
+ class="w-full max-w-screen-2xl m-auto justify-center items-start gap-4"
10
+ >
11
+ <slot />
12
+ </div>
13
+ </template>
@@ -0,0 +1,22 @@
1
+ <script setup lang="ts">
2
+ import { useRouter } from 'vue-router'
3
+
4
+ defineProps<{
5
+ icon: string
6
+ to?: string
7
+ }>()
8
+
9
+ const router = useRouter()
10
+ </script>
11
+
12
+ <template>
13
+ <div
14
+ class="size-12 inline-flex-center cursor-pointer z-$yun-z-nav-menu"
15
+ text="$va-c-text"
16
+ hover="bg-white/80 dark:bg-black/80 op-100"
17
+ op-80
18
+ @click="to && router.push(to)"
19
+ >
20
+ <div class="size-6" :class="icon" />
21
+ </div>
22
+ </template>