valaxy-theme-yun 0.20.1 → 0.20.3

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 (43) hide show
  1. package/App.vue +8 -4
  2. package/components/ValaxyMain.vue +7 -4
  3. package/components/YunAside.vue +2 -2
  4. package/components/YunBanner.vue +31 -28
  5. package/components/YunConfig.vue +4 -1
  6. package/components/YunFullscreenMenu.vue +27 -15
  7. package/components/YunFuseSearch.vue +7 -54
  8. package/components/YunLinkItem.vue +9 -6
  9. package/components/YunLinks.vue +0 -1
  10. package/components/YunNavMenu.vue +3 -118
  11. package/components/YunOverlay.vue +1 -1
  12. package/components/YunSearchBtn.vue +2 -1
  13. package/components/YunSearchTrigger.vue +2 -11
  14. package/components/YunSidebarCard.vue +5 -1
  15. package/components/YunSidebarLinks.vue +1 -1
  16. package/components/YunSiteInfo.vue +1 -1
  17. package/components/YunSocialLinkItem.vue +25 -0
  18. package/components/YunSocialLinks.vue +4 -3
  19. package/components/config/YunToggleDark.vue +2 -1
  20. package/components/layout/YunLayoutLeft.vue +1 -1
  21. package/components/layout/YunLayoutWrapper.vue +12 -2
  22. package/components/menu/YunNavMenuTitle.vue +11 -4
  23. package/components/prologue/PrologueSquare.vue +7 -5
  24. package/components/site/YunFullscreenMenuItem.vue +1 -2
  25. package/components/site/YunFullscreenMenuList.vue +7 -2
  26. package/components/theme/nimbo/YunNimboBanner.vue +0 -0
  27. package/components/theme/nimbo/YunNimboNavMenu.vue +130 -0
  28. package/components/theme/strato/YunStratoApp.vue +10 -0
  29. package/components/theme/strato/YunStratoBanner.vue +0 -0
  30. package/components/theme/strato/YunStratoNavMenu.vue +81 -0
  31. package/components/{YunSidebar.vue → theme/strato/YunStratoSidebar.vue} +19 -16
  32. package/components/ui/YunBannerCharContainer.vue +24 -0
  33. package/components/ui/YunGradientDivider.vue +24 -0
  34. package/composables/helper.ts +16 -1
  35. package/composables/useYunBanner.ts +21 -0
  36. package/layouts/collection.vue +9 -12
  37. package/layouts/collections.vue +12 -15
  38. package/layouts/home.vue +4 -1
  39. package/node/config.ts +1 -1
  40. package/package.json +5 -5
  41. package/stores/app.ts +11 -0
  42. package/styles/css-vars.scss +5 -0
  43. package/styles/vars.scss +4 -2
package/App.vue CHANGED
@@ -31,16 +31,16 @@ useHead({
31
31
  const themeConfig = useThemeConfig()
32
32
 
33
33
  const app = useAppStore()
34
- const yunStore = useYunAppStore()
34
+ const yun = useYunAppStore()
35
35
  const route = useRoute()
36
36
 
37
37
  watch(
38
38
  () => route.meta.layout,
39
39
  () => {
40
40
  if (route.meta.layout === 'home' || app.isMobile)
41
- yunStore.leftSidebar.isOpen = false
41
+ yun.leftSidebar.isOpen = false
42
42
  else
43
- yunStore.leftSidebar.isOpen = true
43
+ yun.leftSidebar.isOpen = false
44
44
  },
45
45
  { immediate: true },
46
46
  )
@@ -55,11 +55,15 @@ const isDev = import.meta.env.DEV
55
55
  </script>
56
56
 
57
57
  <template>
58
+ <YunStratoApp v-if="yun.isStrato" />
58
59
  <YunDebug v-if="isDev" />
59
60
 
60
61
  <YunPageHeaderGradient />
61
62
  <YunNavMenu />
62
- <YunFullscreenMenu />
63
+
64
+ <YunFullscreenMenu v-if="yun.isNimbo" />
65
+ <YunStratoSidebar v-if="yun.isStrato" />
66
+
63
67
  <YunFireworks v-if="themeConfig.fireworks.enable" />
64
68
  <slot name="bg">
65
69
  <YunBg v-if="themeConfig.bg_image.enable" />
@@ -10,7 +10,6 @@ const props = defineProps<{
10
10
  frontmatter: Post
11
11
  data?: PageData
12
12
  }>()
13
-
14
13
  const siteConfig = useSiteConfig()
15
14
 
16
15
  const { styles, icon, color } = usePostProperty(props.frontmatter.type)
@@ -37,12 +36,16 @@ onContentUpdated(() => {
37
36
  </script>
38
37
 
39
38
  <template>
40
- <main class="yun-main lt-md:w-full" flex="~ center">
39
+ <main
40
+ class="yun-main lt-md:w-full" flex="~ center"
41
+ >
41
42
  <slot name="main">
42
43
  <div
43
- class="content w-full md:w-3xl lg:w-2xl xl:w-2xl 2xl:w-4xl" :class="{
44
+ class="content w-full md:w-3xl lg:w-2xl xl:w-2xl 2xl:w-4xl"
45
+ :class="{
44
46
  'no-aside': !aside,
45
- }" flex="~ col grow"
47
+ }"
48
+ flex="~ col grow"
46
49
  p="lt-md:0"
47
50
  >
48
51
  <YunCard :cover="frontmatter.cover" m="0" class="relative" :style="styles as StyleValue">
@@ -28,7 +28,7 @@ watch(() => [yun.rightSidebar.isOpen, yun.size.isXl], async () => {
28
28
  <template>
29
29
  <aside
30
30
  flex="~ col"
31
- class="va-card yun-aside sticky top-0 lg:top-68px min-h-sm"
31
+ class="va-card yun-aside sticky top-0 lg:top-$yun-margin-top min-h-sm"
32
32
  :class="{
33
33
  float: isAsideFloat,
34
34
  show,
@@ -70,7 +70,7 @@ watch(() => [yun.rightSidebar.isOpen, yun.size.isXl], async () => {
70
70
  width: 0;
71
71
  transform: translateX(100%);
72
72
  transition: all 0.2s map.get($cubic-bezier, 'ease-in-out');
73
- max-height: calc(100vh - 68px);
73
+ max-height: calc(100vh - var(--yun-margin-top));
74
74
 
75
75
  // float panel
76
76
  &.float {
@@ -7,28 +7,28 @@
7
7
 
8
8
  import type { CSSProperties } from 'vue'
9
9
  import { computed, onMounted, ref } from 'vue'
10
- import { random, sleep } from 'valaxy'
10
+ import { sleep } from 'valaxy'
11
11
  import { useThemeConfig } from '../composables'
12
+ import { useYunAppStore } from '../stores'
13
+ import { useYunBanner } from '../composables/useYunBanner'
12
14
 
15
+ const yun = useYunAppStore()
13
16
  const themeConfig = useThemeConfig()
14
17
 
15
- const chars = computed(() => {
16
- const arr = []
17
- for (let i = 0; i < themeConfig.value.banner.title.length; i++) {
18
- const rn = random(1.5, 3.5)
19
- arr.push(rn)
20
- }
21
- return arr
22
- })
23
18
  // height of top/bottom line
24
- const totalCharHeight = computed(() => chars.value.reduce((a, b) => a + b, 0))
19
+
20
+ const { totalCharHeight, chars } = useYunBanner(themeConfig.value.banner)
25
21
 
26
22
  const bannerStyles = computed<CSSProperties>(() => {
27
- return {
23
+ const styles: CSSProperties = {
28
24
  '--total-char-height': `${totalCharHeight.value}rem`,
29
25
  '--banner-line-height': `calc(var(--banner-height, 100 * var(--vh)) / 2 - ${totalCharHeight.value / 2}rem)`,
30
26
  'justify-content': 'space-between',
31
27
  }
28
+ if (yun.isStrato)
29
+ styles.borderBottom = `1px solid var(--banner-line-color)`
30
+
31
+ return styles
32
32
  })
33
33
 
34
34
  const lineStatus = ref<
@@ -43,10 +43,12 @@ const animationStatus = ref('banner')
43
43
  onMounted(async () => {
44
44
  await sleep(500)
45
45
  lineStatus.value = 'active'
46
- await sleep(500)
47
- lineStatus.value = 'exit'
46
+ if (yun.isNimbo) {
47
+ await sleep(500)
48
+ lineStatus.value = 'exit'
48
49
 
49
- animationStatus.value = 'prologue'
50
+ animationStatus.value = 'prologue'
51
+ }
50
52
  })
51
53
  </script>
52
54
 
@@ -58,20 +60,21 @@ onMounted(async () => {
58
60
  :class="lineStatusClass"
59
61
  />
60
62
  </div>
61
- <div v-if="animationStatus === 'banner'" class="banner-char-container">
62
- <div v-for="c, i in themeConfig.banner.title" :key="i" class="char-box">
63
- <span
64
- :class="[i % 2 !== 0 ? 'char-right' : 'char-left']" :style="{
65
- '--banner-char-size': `${chars[i]}rem`,
66
- } as CSSProperties"
67
- >
68
- <span class="char">
69
- {{ c }}
70
- </span>
71
- </span>
72
- </div>
73
- </div>
74
- <PrologueSquare v-else class="z-1" />
63
+
64
+ <template v-if="yun.isNimbo">
65
+ <YunBannerCharContainer
66
+ v-if="animationStatus === 'banner'"
67
+ :title="themeConfig.banner.title"
68
+ :chars="chars"
69
+ />
70
+ <PrologueSquare v-else class="z-1" />
71
+ </template>
72
+ <template v-if="yun.isStrato">
73
+ <YunBannerCharContainer
74
+ :title="themeConfig.banner.title"
75
+ :chars="chars"
76
+ />
77
+ </template>
75
78
 
76
79
  <div class="banner-line-container bottom">
77
80
  <div
@@ -1,11 +1,14 @@
1
1
  <script lang="ts" setup>
2
+ import { useAppStore } from 'valaxy'
3
+
2
4
  // sidebar config
5
+ const app = useAppStore()
3
6
  </script>
4
7
 
5
8
  <template>
6
9
  <div>
7
10
  <YunToggleDark />
8
11
 
9
- <YunToggleLocale />
12
+ <YunToggleLocale v-if="app.showToggleLocale" />
10
13
  </div>
11
14
  </template>
@@ -1,38 +1,42 @@
1
1
  <script setup lang="ts">
2
2
  import { ref } from 'vue'
3
+ import { useAppStore } from 'valaxy'
3
4
  import { useYunAppStore } from '../stores'
4
5
 
5
6
  const yunApp = useYunAppStore()
6
7
  const fullscreenMenuRef = ref<HTMLElement>()
8
+
9
+ const app = useAppStore()
7
10
  </script>
8
11
 
9
12
  <template>
10
- <Transition name="slide-down">
13
+ <Transition :name="app.isMobile ? 'slide-down' : 'slide-left'">
11
14
  <div
12
15
  v-if="yunApp.fullscreenMenu.isOpen"
13
16
  ref="fullscreenMenuRef"
14
17
  p="t-20 md:t-26"
15
18
  class="yun-fullscreen-menu fixed left-0 right-0 bottom-0 top-0 bg-$va-c-bg-soft z-$yun-z-fullscreen-menu overflow-auto"
16
19
  >
17
- <div class="flex-center gap-2">
20
+ <!-- <div v-if="app.isMobile" class="flex-center gap-2">
18
21
  <YunToggleDark transition />
19
- <YunToggleLocale />
20
- </div>
22
+ <YunToggleLocale v-if="app.showToggleLocale" />
23
+ </div> -->
21
24
 
22
- <YunFullscreenMenuList>
23
- <YunFullscreenMenuItem
24
- :page="{
25
- name: '站点主页',
26
- icon: 'i-ri-home-2-line',
27
- url: '/',
28
- }"
29
- />
30
- </YunFullscreenMenuList>
31
-
32
- <div v-if="!yunApp.size.isLg" class="mt-4">
25
+ <div v-if="!yunApp.size.isLg" class="my-4">
33
26
  <YunSiteInfo class="text-center" />
27
+
28
+ <YunGradientDivider class="my-2 op-20" />
29
+
34
30
  <YunPostsInfo />
35
31
  </div>
32
+ <YunGradientDivider v-if="!yunApp.size.isLg" class="my-2 op-20" />
33
+
34
+ <YunFullscreenMenuList />
35
+
36
+ <YunGradientDivider v-if="!yunApp.size.isLg" class="my-2 op-20" />
37
+ <div v-if="!yunApp.size.isLg" class="flex-center">
38
+ <YunConfig />
39
+ </div>
36
40
  </div>
37
41
  </Transition>
38
42
  </template>
@@ -41,6 +45,8 @@ const fullscreenMenuRef = ref<HTMLElement>()
41
45
  @use 'sass:map';
42
46
  @use 'valaxy-theme-yun/styles/vars.scss' as *;
43
47
 
48
+ .slide-left-enter-active,
49
+ .slide-left-leave-active,
44
50
  .slide-down-enter-active,
45
51
  .slide-down-leave-active {
46
52
  opacity: 1;
@@ -54,4 +60,10 @@ const fullscreenMenuRef = ref<HTMLElement>()
54
60
  opacity: 0;
55
61
  transform: translateY(-100%);
56
62
  }
63
+
64
+ .slide-left-enter-from,
65
+ .slide-left-leave-to {
66
+ opacity: 0;
67
+ transform: translateX(-100%);
68
+ }
57
69
  </style>
@@ -1,70 +1,23 @@
1
1
  <script lang="ts" setup>
2
- import type { UseFuseOptions } from '@vueuse/integrations/useFuse'
3
- import { useFuse } from '@vueuse/integrations/useFuse'
4
- import { computed, ref, watch } from 'vue'
2
+ import { ref } from 'vue'
5
3
  import { useI18n } from 'vue-i18n'
6
- import { useSiteConfig } from 'valaxy'
7
- import type { FuseListItem } from 'valaxy/types'
4
+ import { useFuseSearch } from 'valaxy'
8
5
 
9
6
  import { isClient, onClickOutside, useScrollLock } from '@vueuse/core'
10
7
 
11
- const props = defineProps<{
8
+ defineProps<{
12
9
  open: boolean
13
10
  }>()
14
11
  const emit = defineEmits(['close'])
15
12
 
16
- const searchContainer = ref<HTMLElement>()
17
-
18
- const isLocked = useScrollLock(isClient ? document.body : null)
19
-
20
- const { t } = useI18n()
21
-
22
- const fuseListData = ref<FuseListItem[]>([])
23
-
24
- const siteConfig = useSiteConfig()
25
- const keys = computed(() => {
26
- const ks = siteConfig.value.fuse.options.keys || []
27
- return ks.length === 0
28
- ? ['title', 'tags', 'categories', 'excerpt']
29
- : ks
30
- })
31
-
32
13
  const input = ref('')
33
- // todo export options
34
- const useFuseOptions = computed<UseFuseOptions<FuseListItem>>(() => ({
35
- fuseOptions: {
36
- includeMatches: true,
37
- findAllMatches: true,
38
14
 
39
- ...siteConfig.value.fuse.options,
40
- keys: keys.value,
41
-
42
- // threshold: 0.99,
43
- // ignoreLocation: true,
44
- },
45
- // resultLimit: resultLimit.value,
46
- // matchAllWhenSearchEmpty: matchAllWhenSearchEmpty.value,
47
- }))
48
- const { results } = useFuse(input, fuseListData, useFuseOptions)
15
+ const isLocked = useScrollLock(isClient ? document.documentElement : null)
16
+ const { t } = useI18n()
17
+ const { results } = useFuseSearch(input)
49
18
 
50
19
  const searchInputRef = ref<HTMLInputElement>()
51
-
52
- watch(() => props.open, async () => {
53
- if (!props.open)
54
- return
55
-
56
- const fuseListDataPath = siteConfig.value.fuse.dataPath.startsWith('http')
57
- ? siteConfig.value.fuse.dataPath
58
- : `${import.meta.env.BASE_URL}${siteConfig.value.fuse.dataPath}`
59
- fetch(fuseListDataPath)
60
- .then(res => res.json())
61
- .then((data) => {
62
- if (Array.isArray(data))
63
- fuseListData.value = data
64
-
65
- searchInputRef.value?.focus()
66
- })
67
- })
20
+ const searchContainer = ref<HTMLElement>()
68
21
 
69
22
  onClickOutside(searchInputRef, () => {
70
23
  // emit('close')
@@ -47,12 +47,15 @@ useMotion(itemRef, {
47
47
  alt="portrait" rel="friend" target="_blank"
48
48
  >
49
49
  <div class="yun-link-left">
50
- <img
51
- class="yun-link-avatar w-16 h-16 aspect-ratio-1" width="64" height="64"
52
- loading="lazy"
53
- :src="link.avatar" :alt="link.name"
54
- @error="onError"
55
- >
50
+ <div class="yun-link-avatar size-16 overflow-hidden flex-center">
51
+ <img
52
+ class="size-16 object-center object-cover m-0!"
53
+ width="64" height="64"
54
+ loading="lazy"
55
+ :src="link.avatar" :alt="link.name"
56
+ @error="onError"
57
+ >
58
+ </div>
56
59
  </div>
57
60
  <div class="yun-link-info" m="l-2">
58
61
  <div class="yun-link-blog" font="serif black">{{ link.blog }}</div>
@@ -58,7 +58,6 @@ const { data } = useRandomData(props.links, props.random)
58
58
  &-avatar {
59
59
  margin: 0;
60
60
  display: inline-flex;
61
- max-width: 100%;
62
61
  border-radius: 50%;
63
62
  background-color: #fff;
64
63
  border: 1px solid var(--primary-color, gray);
@@ -1,125 +1,10 @@
1
1
  <script setup lang="ts">
2
- import { onMounted, ref, watch } from 'vue'
3
- import { useSiteConfig } from 'valaxy'
4
- import { useRoute } from 'vue-router'
5
2
  import { useYunAppStore } from '../stores'
6
- // import { useThemeConfig } from '../composables'
7
3
 
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
- })
4
+ const yun = useYunAppStore()
33
5
  </script>
34
6
 
35
7
  <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>
8
+ <YunStratoNavMenu v-if="yun.isStrato" />
9
+ <YunNimboNavMenu v-else-if="yun.isNimbo" />
84
10
  </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>
@@ -17,7 +17,7 @@ withDefaults(defineProps<{
17
17
  @use "valaxy/client/styles/mixins/index.scss" as *;
18
18
 
19
19
  .yun-overlay {
20
- background-color: rgb(0 0 0 / 0.3);
20
+ background-color: rgb(0 0 0 / 0.5);
21
21
  position: fixed;
22
22
  inset: 0;
23
23
  transition: opacity 0.4s;
@@ -22,8 +22,8 @@ function onClick() {
22
22
  <template>
23
23
  <button
24
24
  class="yun-search-btn popup-trigger size-12 inline-flex justify-center items-center"
25
+ :class="!open && 'hover-bg-white/80 hover:bg-black/80'"
25
26
  text="xl $va-c-text"
26
- hover="bg-white/80 dark:bg-black/80"
27
27
  :title="t('menu.search')"
28
28
  @click="onClick"
29
29
  >
@@ -35,5 +35,6 @@ function onClick() {
35
35
  <style lang="scss">
36
36
  .yun-search-btn {
37
37
  z-index: var(--yun-z-search-btn);
38
+ transition: background-color var(--va-transition-duration);
38
39
  }
39
40
  </style>
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" setup>
2
2
  import { useSiteConfig } from 'valaxy'
3
3
  import { computed, defineAsyncComponent, onMounted, ref } from 'vue'
4
- import { useEventListener } from '@vueuse/core'
4
+ import { useHotKey } from '../composables'
5
5
 
6
6
  const siteConfig = useSiteConfig()
7
7
 
@@ -14,20 +14,11 @@ function togglePopup() {
14
14
  open.value = !open.value
15
15
  }
16
16
 
17
- function handleSearchHotKey(event: KeyboardEvent) {
18
- if (
19
- (event.key.toLowerCase() === 'k' && (event.metaKey || event.ctrlKey))
20
- ) {
21
- event.preventDefault()
22
- togglePopup()
23
- }
24
- }
25
-
26
17
  const algoliaRef = ref()
27
18
  onMounted(() => {
28
19
  // algolia has its own hotkey
29
20
  if (isFuse.value)
30
- useEventListener('keydown', handleSearchHotKey)
21
+ useHotKey('k', togglePopup)
31
22
  })
32
23
 
33
24
  function openSearch() {
@@ -3,8 +3,12 @@
3
3
  </script>
4
4
 
5
5
  <template>
6
- <YunCard class="p-4 min-h-sm">
6
+ <YunCard class="p-4 min-h-sm" flex="~ col gap-1">
7
7
  <YunSiteInfo class="text-center" />
8
8
  <YunPostsInfo />
9
+ <YunGradientDivider class="my-2 op-20" />
10
+ <YunSocialLinks />
11
+ <YunGradientDivider class="my-2 op-20" />
12
+ <YunSidebarLinks />
9
13
  </YunCard>
10
14
  </template>
@@ -12,7 +12,7 @@ const themeConfig = useThemeConfig()
12
12
  :to="item.url" :title="item.name"
13
13
  :style="`color:${item.color}`"
14
14
  >
15
- <div :class="item.icon" class="icon w-8 h-8" />
15
+ <div :class="item.icon" class="icon size-6" />
16
16
  </AppLink>
17
17
  </div>
18
18
  </template>
@@ -5,7 +5,7 @@ const siteConfig = useSiteConfig()
5
5
  </script>
6
6
 
7
7
  <template>
8
- <div class="site-info gap-1 items-center" flex="~ col" m="t-4">
8
+ <div class="site-info gap-1 items-center" flex="~ col" p="t-8">
9
9
  <RouterLink
10
10
  class="site-author-avatar inline-flex-center" to="/about"
11
11
  >
@@ -0,0 +1,25 @@
1
+ <script setup lang="ts">
2
+ import { useAppStore } from 'valaxy'
3
+ import type { SocialLink } from 'valaxy/types'
4
+ import { computed } from 'vue'
5
+
6
+ const props = defineProps<{
7
+ social: SocialLink
8
+ }>()
9
+
10
+ const appStore = useAppStore()
11
+ const color = computed(() => {
12
+ return (appStore.isDark && props.social.color === 'black') ? 'white' : props.social.color
13
+ })
14
+ </script>
15
+
16
+ <template>
17
+ <a
18
+ class="links-of-author-item yun-icon-btn"
19
+ rel="noopener" :href="social.link" :title="social.name"
20
+ target="_blank"
21
+ :style="`color:${color}`"
22
+ >
23
+ <div class="icon" :class="social.icon" />
24
+ </a>
25
+ </template>
@@ -6,9 +6,10 @@ const siteConfig = useSiteConfig()
6
6
 
7
7
  <template>
8
8
  <div class="links-of-author">
9
- <a v-for="item, i in siteConfig.social" :key="i" class="links-of-author-item yun-icon-btn" rel="noopener" :href="item.link" :title="item.name" target="_blank" :style="`color:${item.color}`">
10
- <div class="icon" :class="item.icon" />
11
- </a>
9
+ <YunSocialLinkItem
10
+ v-for="item, i in siteConfig.social" :key="i"
11
+ :social="item"
12
+ />
12
13
  </div>
13
14
  </template>
14
15
 
@@ -29,7 +29,8 @@ function toggle(e: MouseEvent) {
29
29
  <button
30
30
  class="yun-icon-btn"
31
31
  :title="themeTitle"
32
- :style="styles" @mousedown.prevent="() => { console.log('yes') }"
32
+ :style="styles"
33
+ @mousedown.prevent="() => {}"
33
34
  @click="toggle"
34
35
  >
35
36
  <div i="ri-sun-line dark:ri-moon-line" />
@@ -5,7 +5,7 @@ const yun = useYunAppStore()
5
5
  </script>
6
6
 
7
7
  <template>
8
- <div v-if="yun.size.isLg" flex="~ col" class="gap-4 sticky top-68px w-80">
8
+ <div v-if="yun.size.isLg" flex="~ col" class="gap-4 sticky top-$yun-margin-top w-80">
9
9
  <YunSidebarCard />
10
10
  <YunAdBoard />
11
11
  </div>