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,11 +1,13 @@
1
1
  <script lang="ts" setup>
2
- import { computed, onMounted, ref } from 'vue'
2
+ import { onMounted, ref } from 'vue'
3
3
  import type { CategoryList, Post } from 'valaxy'
4
- import { isCategoryList, useInvisibleElement } from 'valaxy'
4
+ import { useInvisibleElement } from 'valaxy'
5
5
  import { useI18n } from 'vue-i18n'
6
- import { useRoute, useRouter } from 'vue-router'
6
+ import { useRouter } from 'vue-router'
7
+ import { useYunSpringAnimation } from '../composables/animation'
7
8
 
8
9
  const props = withDefaults(defineProps<{
10
+ i?: number
9
11
  parentKey: string
10
12
  // to eliminate the warning
11
13
  category: Post | CategoryList
@@ -20,24 +22,10 @@ const props = withDefaults(defineProps<{
20
22
  })
21
23
 
22
24
  const router = useRouter()
23
- const route = useRoute()
24
- const categoryList = computed(() => {
25
- const c = (route.query.category as string) || ''
26
- return Array.isArray(c) ? [c] : c.split('/')
27
- })
28
25
 
29
26
  const collapse = ref(props.collapsable)
30
27
  const { t } = useI18n()
31
28
 
32
- /**
33
- * i18n
34
- */
35
- const { locale } = useI18n()
36
- function getTitle(post: Post | any) {
37
- const lang = locale.value === 'zh-CN' ? 'zh' : locale.value
38
- return post[`title_${lang}`] ? post[`title_${lang}`] : post.title
39
- }
40
-
41
29
  const postCollapseElRef = ref<HTMLElement>()
42
30
  const { show } = useInvisibleElement(postCollapseElRef)
43
31
  /**
@@ -45,6 +33,8 @@ const { show } = useInvisibleElement(postCollapseElRef)
45
33
  * @param category
46
34
  */
47
35
  function jumpToDisplayCategory(category: string) {
36
+ collapse.value = false
37
+
48
38
  router.push({
49
39
  query: {
50
40
  category,
@@ -59,37 +49,64 @@ onMounted(() => {
59
49
  if (postCollapseEl)
60
50
  postCollapseElRef.value = postCollapseEl
61
51
  })
52
+
53
+ const categoryRef = ref<HTMLElement>()
54
+ if (props.level === 1) {
55
+ useYunSpringAnimation(categoryRef, {
56
+ i: props.i || 0,
57
+ y: 20,
58
+ duration: 200,
59
+ })
60
+ }
62
61
  </script>
63
62
 
64
63
  <template>
65
- <li class="category-list-item inline-flex items-center cursor-pointer">
66
- <span class="folder-action inline-flex" @click="collapse = !collapse">
64
+ <li
65
+ ref="categoryRef"
66
+ class="category-list-item inline-flex items-center cursor-pointer w-full gap-2 px-3 py-2 rounded"
67
+ hover="bg-black/5"
68
+ >
69
+ <span
70
+ class="folder-action inline-flex"
71
+ hover="text-$va-c-primary-lighter"
72
+ @click="collapse = !collapse"
73
+ >
67
74
  <div v-if="collapse" i-ri-folder-add-line />
68
- <div v-else style="color:var(--va-c-primary)" i-ri-folder-reduce-line />
75
+ <div v-else class="text-$va-c-primary dark:text-$va-c-primary-lighter" i-ri-folder-reduce-line />
69
76
  </span>
70
- <span class="category-name" m="l-1" @click="jumpToDisplayCategory(parentKey)">
71
- {{ category.name === 'Uncategorized' ? t('category.uncategorized') : category.name }} [{{ category.total }}]
77
+ <span
78
+ class="category-name inline-flex items-center gap-2 w-full"
79
+ @click="jumpToDisplayCategory(parentKey)"
80
+ >
81
+ <span>
82
+ {{ category.name === 'Uncategorized' ? t('category.uncategorized') : category.name }}
83
+ </span>
84
+ <span class="rounded-full px-1.5 bg-black/5 shadow-sm" text="xs black/55">
85
+ {{ category.total }}
86
+ </span>
72
87
  </span>
73
88
  </li>
74
89
 
75
- <template v-if="!collapse">
76
- <ul>
77
- <li v-for="categoryItem, i in category.children.values()" :key="i" class="post-list-item" m="l-4">
78
- <template v-if="isCategoryList(categoryItem)">
79
- <YunCategory
80
- :parent-key="parentKey ? `${parentKey}/${categoryItem.name}` : categoryItem.name"
81
- :category="categoryItem"
82
- :collapsable="!categoryList.includes(categoryItem.name)"
83
- />
84
- </template>
85
-
86
- <template v-else>
87
- <RouterLink v-if="categoryItem.title" :to="categoryItem.path || ''" class="inline-flex items-center">
88
- <div i-ri-file-text-line />
89
- <span m="l-1" font="serif black">{{ getTitle(categoryItem) }}</span>
90
- </RouterLink>
91
- </template>
90
+ <Transition
91
+ enter-active-class="v-enter-active"
92
+ enter-from-class="v-enter-from"
93
+ leave-active-class="v-leave-active"
94
+ leave-to-class="v-leave-to"
95
+ :duration="{ enter: 200, leave: 0 }"
96
+ >
97
+ <ul v-if="!collapse">
98
+ <li
99
+ v-for="categoryItem, cI in category.children.values()"
100
+ :key="cI"
101
+ class="post-list-item text-$va-c-text" m="l-4"
102
+ hover="text-$va-c-primary-lighter"
103
+ >
104
+ <YunCategoryChildItem
105
+ :i="cI"
106
+ :category-item="categoryItem"
107
+ :parent-key="parentKey"
108
+ />
92
109
  </li>
93
110
  </ul>
94
- </template>
111
+ </Transition>
95
112
  </template>
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ import type { Post } from 'valaxy'
3
+ import { isCategoryList } from 'valaxy'
4
+ import { computed } from 'vue'
5
+ import { useRoute } from 'vue-router'
6
+ import { useI18n } from 'vue-i18n'
7
+
8
+ defineProps<{
9
+ i?: number
10
+ categoryItem: any
11
+ parentKey?: string
12
+ }>()
13
+
14
+ /**
15
+ * i18n
16
+ */
17
+ const { locale } = useI18n()
18
+ function getTitle(post: Post | any) {
19
+ const lang = locale.value === 'zh-CN' ? 'zh' : locale.value
20
+ return post[`title_${lang}`] ? post[`title_${lang}`] : post.title
21
+ }
22
+ const route = useRoute()
23
+ const categoryList = computed(() => {
24
+ const c = (route.query.category as string) || ''
25
+ return Array.isArray(c) ? [c] : c.split('/')
26
+ })
27
+ </script>
28
+
29
+ <template>
30
+ <template v-if="isCategoryList(categoryItem)">
31
+ <YunCategory
32
+ :parent-key="parentKey ? `${parentKey}/${categoryItem.name}` : categoryItem.name"
33
+ :category="categoryItem"
34
+ :collapsable="!categoryList.includes(categoryItem.name)"
35
+ />
36
+ </template>
37
+
38
+ <template v-else>
39
+ <RouterLink
40
+ v-if="categoryItem.title"
41
+ :to="categoryItem.path || ''"
42
+ class="inline-flex items-center gap-2 px-3 py-2 w-full rounded"
43
+ hover="bg-black/5"
44
+ >
45
+ <div i-ri-file-text-line />
46
+ <span font="serif black">{{ getTitle(categoryItem) }}</span>
47
+ </RouterLink>
48
+ </template>
49
+ </template>
@@ -0,0 +1,59 @@
1
+ <script setup lang="ts">
2
+ import { useMotion } from '@vueuse/motion'
3
+ import Popover from 'primevue/popover'
4
+ import { onMounted, ref } from 'vue'
5
+
6
+ const op = ref<typeof Popover>()
7
+
8
+ const pContentRef = ref<HTMLElement>()
9
+ const motion = useMotion(pContentRef, {
10
+ initial: {
11
+ opacity: 0,
12
+ translateY: 30,
13
+ },
14
+ enter: {
15
+ opacity: 1,
16
+ translateY: 0,
17
+ transition: {
18
+ type: 'spring',
19
+ duration: 200,
20
+ damping: 9,
21
+ },
22
+ },
23
+ })
24
+
25
+ onMounted(() => {
26
+ motion.variant.value = 'initial'
27
+
28
+ // 滚动时隐藏
29
+ window.addEventListener('scroll', () => {
30
+ motion.variant.value = 'initial'
31
+ setTimeout(() => {
32
+ op.value?.hide()
33
+ }, 200)
34
+ })
35
+ })
36
+
37
+ function toggle(event: Event) {
38
+ op.value?.toggle(event)
39
+ motion.variant.value = op.value?.visible ? 'enter' : 'initial'
40
+ }
41
+ </script>
42
+
43
+ <template>
44
+ <YunNavMenuItem
45
+ icon="i-ri-mind-map" @click="toggle"
46
+ />
47
+ <Popover
48
+ ref="op"
49
+ >
50
+ <div
51
+ ref="pContentRef"
52
+ class="p-4 shadow-xl"
53
+ bg="$va-c-bg-light"
54
+ >
55
+ <YunSiteInfo class="text-center" />
56
+ <YunPostsInfo />
57
+ </div>
58
+ </Popover>
59
+ </template>
@@ -17,26 +17,21 @@
17
17
  <style lang="scss">
18
18
  @use 'valaxy/client/styles/mixins/index.scss' as *;
19
19
 
20
+ .dark .yun-cloud {
21
+ --yun-c-cloud: var(--va-c-bg-soft);
22
+ }
23
+
20
24
  .yun-cloud {
21
25
  display: flex;
22
26
  width: 100%;
23
- position: absolute;
24
- bottom: 0;
25
- left: 0;
26
- right: 0;
27
27
  z-index: var(--yun-z-cloud);
28
28
  box-sizing: border-box;
29
- mix-blend-mode: overlay;
30
29
 
31
30
  .waves {
32
31
  display: flex;
33
32
  position: relative;
34
33
  width: 100%;
35
- height: 100px;
36
-
37
- @include screen('md') {
38
- height: 40px;
39
- }
34
+ height: 40px;
40
35
  }
41
36
 
42
37
  .parallax {
@@ -1,27 +1,10 @@
1
1
  <script lang="ts" setup>
2
- import { useI18n } from 'vue-i18n'
3
- import { computed } from 'vue'
4
- import { useAppStore } from 'valaxy'
5
-
6
- const appStore = useAppStore()
7
- const { t } = useI18n()
8
-
9
- const themeTitle = computed(() => {
10
- return appStore.isDark ? t('button.toggle_light') : t('button.toggle_dark')
11
- })
12
-
13
- const styles = computed(() => {
14
- return {
15
- color: appStore.isDark ? '' : '#f1cb64',
16
- }
17
- })
2
+ // sidebar config
18
3
  </script>
19
4
 
20
5
  <template>
21
6
  <div>
22
- <button class="yun-icon-btn" :title="themeTitle" :style="styles" @click="appStore.toggleDarkWithTransition">
23
- <div i="ri-sun-line dark:ri-moon-line" />
24
- </button>
7
+ <YunToggleDark />
25
8
 
26
9
  <YunToggleLocale />
27
10
  </div>
@@ -0,0 +1,47 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { useYunAppStore } from '../stores'
4
+
5
+ const yun = useYunAppStore()
6
+
7
+ const infoList = computed(() => {
8
+ return [
9
+ {
10
+ label: 'xs',
11
+ value: yun.size.isXs,
12
+ },
13
+ {
14
+ label: 'sm',
15
+ value: yun.size.isSm,
16
+ },
17
+ {
18
+ label: 'md',
19
+ value: yun.size.isMd,
20
+ },
21
+ {
22
+ label: 'lg',
23
+ value: yun.size.isLg,
24
+ },
25
+ {
26
+ label: 'xl',
27
+ value: yun.size.isXl,
28
+ },
29
+ {
30
+ label: '2xl',
31
+ value: yun.size.is2xl,
32
+ },
33
+ ]
34
+ })
35
+ </script>
36
+
37
+ <template>
38
+ <div
39
+ class="bg-black/50 fixed bottom-2 left-2 p-2 gap-1 rounded z-9999"
40
+ text="xs white" flex="~ col"
41
+ >
42
+ <div v-for="item in infoList" :key="item.label" class="gap-2 inline-flex">
43
+ <span class="w-6" font="bold">{{ item.label }}: </span>
44
+ <span>{{ item.value ? '✅' : '❌' }}</span>
45
+ </div>
46
+ </div>
47
+ </template>
@@ -0,0 +1,223 @@
1
+ <script setup>
2
+ import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
3
+ import { useToast } from 'primevue/usetoast'
4
+ import TerminalService from 'primevue/terminalservice'
5
+ import Dock from 'primevue/dock'
6
+ import Toast from 'primevue/toast'
7
+ import { useYunAppStore } from '../stores'
8
+
9
+ onMounted(() => {
10
+ TerminalService.on('command', commandHandler)
11
+ })
12
+
13
+ onBeforeUnmount(() => {
14
+ TerminalService.off('command', commandHandler)
15
+ })
16
+
17
+ const yunApp = useYunAppStore()
18
+ const showDock = ref(false)
19
+ watch(() => yunApp.scrollY, () => {
20
+ if (yunApp.scrollY > 10)
21
+ showDock.value = true
22
+ else
23
+ showDock.value = false
24
+ })
25
+
26
+ const displayFinder = ref(false)
27
+ const displayTerminal = ref(false)
28
+ const displayPhotos = ref(false)
29
+ const toast = useToast()
30
+ const items = ref([
31
+ {
32
+ label: 'Finder',
33
+ icon: 'https://primefaces.org/cdn/primevue//images/dock/finder.svg',
34
+ command: () => {
35
+ displayFinder.value = true
36
+ },
37
+ },
38
+ {
39
+ label: 'Terminal',
40
+ icon: 'https://primefaces.org/cdn/primevue//images/dock/terminal.svg',
41
+ command: () => {
42
+ displayTerminal.value = true
43
+ },
44
+ },
45
+ {
46
+ label: 'App Store',
47
+ icon: 'https://primefaces.org/cdn/primevue//images/dock/appstore.svg',
48
+ command: () => {
49
+ toast.add({ severity: 'error', summary: 'An unexpected error occurred while signing in.', detail: 'UNTRUSTED_CERT_TITLE', group: 'tc', life: 3000 })
50
+ },
51
+ },
52
+ {
53
+ label: 'Safari',
54
+ icon: 'https://primefaces.org/cdn/primevue//images/dock/safari.svg',
55
+ command: () => {
56
+ toast.add({ severity: 'warn', summary: 'Safari has stopped working', group: 'tc', life: 3000 })
57
+ },
58
+ },
59
+ {
60
+ label: 'Photos',
61
+ icon: 'https://primefaces.org/cdn/primevue//images/dock/photos.svg',
62
+ command: () => {
63
+ displayPhotos.value = true
64
+ },
65
+ },
66
+ {
67
+ label: 'GitHub',
68
+ icon: 'https://primefaces.org/cdn/primevue//images/dock/github.svg',
69
+ },
70
+ {
71
+ label: 'Trash',
72
+ icon: 'https://primefaces.org/cdn/primevue//images/dock/trash.png',
73
+ command: () => {
74
+ toast.add({ severity: 'info', summary: 'Empty Trash', life: 3000 })
75
+ },
76
+ },
77
+ ])
78
+
79
+ function onDockItemClick(event, item) {
80
+ if (item.command)
81
+ item.command()
82
+
83
+ event.preventDefault()
84
+ }
85
+
86
+ function commandHandler(text) {
87
+ let response
88
+ const argsIndex = text.indexOf(' ')
89
+ const command = argsIndex !== -1 ? text.substring(0, argsIndex) : text
90
+
91
+ switch (command) {
92
+ case 'date':
93
+ response = `Today is ${new Date().toDateString()}`
94
+ break
95
+
96
+ case 'greet':
97
+ response = `Hola ${text.substring(argsIndex + 1)}`
98
+ break
99
+
100
+ case 'random':
101
+ response = Math.floor(Math.random() * 100)
102
+ break
103
+
104
+ default:
105
+ response = `Unknown command: ${command}`
106
+ }
107
+
108
+ TerminalService.emit('response', response)
109
+ }
110
+ </script>
111
+
112
+ <template>
113
+ <Toast position="top-center" group="tc" />
114
+
115
+ <!-- yun-dock slide in -->
116
+ <Transition
117
+ name="custom-classes"
118
+ enter-from-class="opacity-0 translate-y-10"
119
+ enter-to-class="opacity-100 translate-y-0"
120
+ leave-from-class="opacity-100 translate-y-0"
121
+ leave-to-class="opacity-0 translate-y-10"
122
+ >
123
+ <Dock
124
+ v-show="showDock"
125
+ class="fixed bottom-0 left-0 right-0 z-99 transition" flex="~"
126
+ :model="items"
127
+ >
128
+ <template #item="{ item }">
129
+ <a
130
+ v-tooltip.top="item.label" href="#"
131
+ class="yun-dock-item-link" @click="onDockItemClick($event, item)"
132
+ >
133
+ <img :alt="item.label" :src="item.icon" style="width: 100%">
134
+ </a>
135
+ </template>
136
+ </Dock>
137
+ </Transition>
138
+
139
+ <!-- <div class="dock-window dock-advanced">
140
+ <Dialog v-model:visible="displayTerminal" header="Terminal" :breakpoints="{ '960px': '50vw' }" :style="{ width: '40vw' }" :maximizable="true">
141
+ <Terminal welcome-message="Welcome to PrimeVue(cmd: 'date', 'greet {0}' and 'random')" prompt="primevue $" />
142
+ </Dialog>
143
+
144
+ <Dialog v-model:visible="displayFinder" header="Finder" :breakpoints="{ '960px': '50vw' }" :style="{ width: '40vw' }" :maximizable="true">
145
+ <Tree :value="nodes" />
146
+ </Dialog>
147
+
148
+ <Galleria v-model:visible="displayPhotos" :value="images" :responsive-options="responsiveOptions" :num-visible="2" container-style="width: 400px" :circular="true" :full-screen="true" :show-thumbnails="false" :show-item-navigators="true">
149
+ <template #item="slotProps">
150
+ <img :src="slotProps.item.itemImageSrc" :alt="slotProps.item.alt" style="width: 100%">
151
+ </template>
152
+ </Galleria>
153
+ </div> -->
154
+ </template>
155
+
156
+ <style lang="scss">
157
+ :root {
158
+ --p-dock-background: rgb(255 255 255 / 0.1);
159
+ --p-dock-border-color: rgb(255 255 255 / 0.2);
160
+ --p-dock-padding: 0.5rem;
161
+ --p-dock-border-radius: var(--p-border-radius-xl);
162
+ --p-dock-item-border-radius: var(--p-content-border-radius);
163
+ --p-dock-item-padding: 0.5rem;
164
+ --p-dock-item-size: 3rem;
165
+ --p-dock-item-focus-ring-width: var(--p-focus-ring-width);
166
+ --p-dock-item-focus-ring-style: var(--p-focus-ring-style);
167
+ --p-dock-item-focus-ring-color: var(--p-focus-ring-color);
168
+ --p-dock-item-focus-ring-offset: var(--p-focus-ring-offset);
169
+ --p-dock-item-focus-ring-shadow: var(--p-focus-ring-shadow);
170
+ }
171
+
172
+ .yun-dock {
173
+ position: fixed;
174
+ display: flex;
175
+ justify-content: center;
176
+ align-items: center;
177
+ z-index: var(--yun-z-dock);
178
+
179
+ &-bottom {
180
+ left: 0;
181
+ bottom: 0;
182
+ width: 100%;
183
+ }
184
+
185
+ .yun-dock-list-container {
186
+ display: flex;
187
+ pointer-events: auto;
188
+ background: var(--p-dock-background);
189
+ border: 1px solid var(--p-dock-border-color);
190
+ padding: var(--p-dock-padding);
191
+ border-radius: var(--p-dock-border-radius);
192
+ }
193
+ }
194
+
195
+ .yun-dock-list {
196
+ margin: 0;
197
+ padding: 0;
198
+ list-style: none;
199
+ display: flex;
200
+ align-items: center;
201
+ justify-content: center;
202
+ outline: 0 none;
203
+ }
204
+
205
+ .yun-dock-item {
206
+ transition: all 0.2s cubic-bezier(0.4,0,0.2,1);
207
+ will-change: transform;
208
+ padding: var(--p-dock-item-padding);
209
+ border-radius: var(--p-dock-item-border-radius);
210
+ }
211
+
212
+ .yun-dock-item-link {
213
+ display: flex;
214
+ flex-direction: column;
215
+ align-items: center;
216
+ justify-content: center;
217
+ position: relative;
218
+ overflow: hidden;
219
+ cursor: pointer;
220
+ width: var(--p-dock-item-size);
221
+ height: var(--p-dock-item-size);
222
+ }
223
+ </style>
@@ -1,10 +1,25 @@
1
1
  <script lang="ts" setup>
2
2
  import { capitalize, computed } from 'vue'
3
- import { useSiteConfig, useValaxyConfig } from 'valaxy'
3
+ import { useSiteConfig, useValaxyConfig, useValaxyDark } from 'valaxy'
4
4
  import { useI18n } from 'vue-i18n'
5
5
  import pkg from 'valaxy/package.json'
6
6
  import { useThemeConfig } from '../composables'
7
7
 
8
+ // background-image: linear-gradient(120deg, #a1c4fd 0%, #c2e9fb 100%);
9
+ const { isDark } = useValaxyDark()
10
+ const gradientStyles = computed(() => {
11
+ if (isDark.value) {
12
+ return {
13
+ '--gradient-from': '0 0 0',
14
+ '--gradient-to': '0 0 0',
15
+ }
16
+ }
17
+ return {
18
+ '--gradient-from': '161 196 253',
19
+ '--gradient-to': '194 233 251',
20
+ }
21
+ })
22
+
8
23
  const { t } = useI18n()
9
24
  const config = useValaxyConfig()
10
25
  const siteConfig = useSiteConfig()
@@ -15,7 +30,7 @@ const isThisYear = computed(() => {
15
30
  return year === themeConfig.value.footer.since
16
31
  })
17
32
 
18
- const poweredHtml = computed(() => t('footer.powered', [`<a href="${pkg.repository.url}" target="_blank" rel="noopener">Valaxy</a> v${pkg.version}`]))
33
+ const poweredHtml = computed(() => t('footer.powered', [`<a href="${pkg.repository.url}" target="_blank" rel="noopener">Valaxy</a> <span class="op-60">v${pkg.version}</span>`]))
19
34
  const footerIcon = computed(() => themeConfig.value.footer.icon || {
20
35
  url: pkg.repository.url,
21
36
  name: 'i-ri-cloud-line',
@@ -24,7 +39,14 @@ const footerIcon = computed(() => themeConfig.value.footer.icon || {
24
39
  </script>
25
40
 
26
41
  <template>
27
- <footer class="va-footer p-4 text-$va-c-text-light" text="center sm">
42
+ <footer
43
+ flex="~ col"
44
+ class="relative yun-footer va-footer px-4 py-4 pt-0 text-$va-c-text-light w-full mt-14"
45
+ bg="white dark:$va-c-bg-soft"
46
+ text="center sm"
47
+ >
48
+ <YunCloud class="absolute top--10 left-0 right-0" />
49
+
28
50
  <div v-if="themeConfig.footer.beian?.enable && themeConfig.footer.beian.icp" class="beian" m="y-2">
29
51
  <a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">
30
52
  {{ themeConfig.footer.beian.icp }}
@@ -54,9 +76,39 @@ const footerIcon = computed(() => themeConfig.value.footer.icon || {
54
76
  </div>
55
77
 
56
78
  <div v-if="themeConfig.footer.powered" class="powered" m="2">
57
- <span v-html="poweredHtml" /> | <span>{{ t('footer.theme') }} - <a :href="themeConfig.pkg.repository.url" :title="themeConfig.pkg.name" target="_blank">{{ capitalize(config.theme) }}</a> v{{ themeConfig.pkg.version }}</span>
79
+ <span v-html="poweredHtml" />
80
+ <span mx-1>|</span>
81
+ <span>
82
+ <span>{{ t('footer.theme') }}</span>
83
+ <span mx-1>-</span>
84
+ <a :href="themeConfig.pkg.repository.url" :title="themeConfig.pkg.name" target="_blank">{{ capitalize(config.theme) }}</a>
85
+ <span class="ml-1 op-60">v{{ themeConfig.pkg.version }}</span>
86
+ </span>
58
87
  </div>
59
88
 
60
89
  <slot />
90
+
91
+ <div class="yun-footer-gradient" :style="gradientStyles" />
61
92
  </footer>
62
93
  </template>
94
+
95
+ <style lang="scss">
96
+ .yun-footer {
97
+ letter-spacing: 0.05rem;
98
+ line-height: 1.8;
99
+ }
100
+
101
+ .yun-footer-gradient {
102
+ position: absolute;
103
+ bottom: 0;
104
+ left: 0;
105
+ right: 0;
106
+ width: 100%;
107
+ height: 300px;
108
+ z-index: 999;
109
+ pointer-events: none;
110
+ background: linear-gradient(to right,rgb(var(--gradient-from) / 0.2) 0,rgb(var(--gradient-to) / .2) 100%);
111
+ mask-image: linear-gradient(#fff0,#000 70%);
112
+ animation: fade-in 2s;
113
+ }
114
+ </style>