valaxy-theme-yun 0.1.1 → 0.2.1

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 (41) hide show
  1. package/components/YunAlgoliaSearch.vue +10 -10
  2. package/components/YunBackToTop.vue +2 -3
  3. package/components/YunBase.vue +3 -0
  4. package/components/YunBoard.vue +23 -0
  5. package/components/YunCard.vue +1 -1
  6. package/components/YunCategories.vue +12 -7
  7. package/components/YunCategory.vue +25 -13
  8. package/components/YunConfig.vue +2 -10
  9. package/components/YunGirls.vue +2 -3
  10. package/components/YunGoDown.vue +3 -3
  11. package/components/YunOverview.vue +113 -0
  12. package/components/YunPostCollapse.vue +10 -10
  13. package/components/YunPostMeta.vue +23 -1
  14. package/components/YunPostNav.vue +2 -2
  15. package/components/YunSay.vue +6 -5
  16. package/components/YunSidebar.vue +24 -96
  17. package/components/YunSidebarNav.vue +8 -7
  18. package/components/YunSponsor.vue +3 -6
  19. package/components/YunToggleLocale.vue +25 -0
  20. package/components/YunTwikoo.vue +14 -0
  21. package/components/YunWaline.vue +3 -5
  22. package/composables/index.ts +6 -3
  23. package/config/index.ts +62 -4
  24. package/dist/index.d.ts +35 -1
  25. package/dist/index.js +1 -1
  26. package/dist/index.mjs +1 -1
  27. package/index.ts +31 -0
  28. package/layouts/archives.vue +4 -2
  29. package/layouts/base.vue +16 -7
  30. package/layouts/categories.vue +4 -2
  31. package/layouts/home.vue +11 -2
  32. package/layouts/post.vue +5 -1
  33. package/layouts/tags.vue +9 -4
  34. package/locales/en.yml +1 -0
  35. package/locales/zh-CN.yml +1 -0
  36. package/package.json +3 -3
  37. package/styles/css-vars.scss +17 -0
  38. package/styles/layout/index.scss +2 -2
  39. package/styles/layout/post.scss +10 -18
  40. package/styles/markdown.scss +14 -16
  41. package/styles/vars.scss +32 -6
@@ -1,111 +1,39 @@
1
1
  <script lang="ts" setup>
2
- import { useConfig } from 'valaxy'
3
- import { useRouter } from 'vue-router'
4
-
5
- const config = useConfig()
6
- const router = useRouter()
2
+ import { ref } from 'vue'
3
+ const showOverview = ref(false)
7
4
  </script>
8
5
 
9
6
  <template>
10
- <div class="sidebar-panel">
11
- <div class="site-info" m="t-6">
12
- <a class="site-author-avatar" href="/about">
13
- <img class="rounded-full" :src="config.author.avatar" alt="avatar">
14
- <span class="site-author-status">{{ config.author.status.emoji }}</span>
15
- </a>
16
- <div class="site-author-name">
17
- <a href="/about">
18
- {{ config.author.name }}
19
- </a>
20
- </div>
21
- <router-link v-if="router.hasRoute('about-site')" to="/about/site" class="site-name">
22
- {{ config.title }}
23
- </router-link>
24
- <span v-else class="site-name">{{ config.title }}</span>
25
- <h4 v-if="config.subtitle" class="site-subtitle block" text="xs">
26
- {{ config.subtitle }}
27
- </h4>
28
- <div v-if="config.description" class="site-description my-1">
29
- {{ config.description }}
30
- </div>
31
- </div>
7
+ <div v-if="$slots.default" class="sidebar-nav" m="t-6">
8
+ <button m="x-4" class="sidebar-nav-item yun-icon-btn" :class="showOverview && 'active'" @click="showOverview = true">
9
+ <div i-ri-passport-line />
10
+ </button>
11
+ <button m="x-4" class="sidebar-nav-item yun-icon-btn" :class="!showOverview && 'active'" @click="showOverview = false">
12
+ <div i-ri-list-ordered />
13
+ </button>
14
+ </div>
15
+
16
+ <div v-if="showOverview || !$slots.default" :class="$slots.default && '-mt-4'">
17
+ <YunOverview />
18
+ </div>
32
19
 
33
- <YunSidebarNav />
34
- <hr m="t-4 b-2">
35
- <YunSocialLinks />
36
- <hr m="y-2">
37
- <YunSidebarLinks />
38
- <br>
20
+ <div v-else>
21
+ <slot />
39
22
  </div>
40
23
  </template>
41
24
 
42
25
  <style lang="scss">
43
- @use "~/styles/mixins" as *;
26
+ .sidebar-nav {
27
+ .sidebar-nav-item {
28
+ color: var(--va-c-primary);
29
+ border: 1px solid var(--va-c-primary);
44
30
 
45
- .sidebar-panel {
46
- padding: 0.5rem;
47
- }
31
+ &.active {
32
+ border: 1px solid var(--va-c-primary);
48
33
 
49
- .site-info {
50
- &.fix-top {
51
- margin-top: -1.5rem;
52
- }
53
- }
54
-
55
- .site-author-avatar {
56
- display: inline-block;
57
- line-height: 0;
58
- position: relative;
59
-
60
- img {
61
- height: 96px;
62
- width: 96px;
63
- max-width: 100%;
64
- margin: 0px;
65
- padding: 4px;
66
- background-color: white;
67
- box-shadow: 0 0 10px rgba(black, 0.2);
68
- transition: 0.4s;
69
-
70
- &:hover {
71
- box-shadow: 0 0 30px rgba(var(--yun-c-primary-rgb), 0.2);
34
+ color: white;
35
+ background-color: var(--va-c-primary);
72
36
  }
73
37
  }
74
38
  }
75
-
76
- .site-author-name {
77
- margin-top: 0;
78
- margin-bottom: 1rem;
79
- line-height: 1.5;
80
- }
81
-
82
- .site-author-status {
83
- position: absolute;
84
- height: 1.8rem;
85
- width: 1.8rem;
86
- bottom: 0;
87
- right: 0;
88
- line-height: 1.8rem;
89
- border-radius: 50%;
90
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
91
- background-color: var(--yun-c-bg-light);
92
-
93
- border: 1px solid rgba(255, 255, 255, 0.1);
94
- }
95
-
96
- .site-name {
97
- color: var(--yun-c-text);
98
- font-family: get-css-var('font-serif');
99
- font-weight: get-css-var('font-serif-weight');
100
- }
101
-
102
- .site-subtitle {
103
- color: get-css-var('c-gray');
104
- display: block;
105
- }
106
-
107
- .site-description {
108
- color: var(--yun-c-text);
109
- font-size: 0.8rem;
110
- }
111
39
  </style>
@@ -1,9 +1,10 @@
1
1
  <script lang="ts" setup>
2
- import { useCategory, usePostList, useTag } from 'valaxy'
2
+ import { useCategory, usePostList, useTag, useThemeConfig } from 'valaxy'
3
3
  import { useI18n } from 'vue-i18n'
4
4
 
5
5
  const { t } = useI18n()
6
6
 
7
+ const themeConfig = useThemeConfig()
7
8
  const posts = usePostList()
8
9
  const categories = useCategory()
9
10
  const tags = useTag()
@@ -28,8 +29,8 @@ const tags = useTag()
28
29
  <span class="count">{{ Array.from(tags).length }}</span>
29
30
  </router-link>
30
31
 
31
- <router-link class="site-link-item yun-icon-btn" to="/about" :title="t('button.about')">
32
- <div i-ri-clipboard-line />
32
+ <router-link class="site-link-item yun-icon-btn" :to="themeConfig.menu.custom.url" :title="t(themeConfig.menu.custom.title)">
33
+ <div :class="themeConfig.menu.custom.icon" />
33
34
  </router-link>
34
35
  </nav>
35
36
  </template>
@@ -55,7 +56,7 @@ const tags = useTag()
55
56
 
56
57
  flex-direction: column;
57
58
 
58
- color: var(--yun-c-text);
59
+ color: var(--va-c-text);
59
60
 
60
61
  &:first-child, &:last-child {
61
62
  line-height: 1;
@@ -76,8 +77,8 @@ const tags = useTag()
76
77
  }
77
78
 
78
79
  .count {
79
- color: var(--yun-c-text);
80
- font-family: var(--yun-font-sans);
80
+ color: var(--va-c-text);
81
+ font-family: var(--va-font-sans);
81
82
  display: block;
82
83
  text-align: center;
83
84
  font-size: 1rem;
@@ -88,7 +89,7 @@ const tags = useTag()
88
89
  height: 1.5rem;
89
90
 
90
91
  &:hover {
91
- color: var(--yun-c-primary-light);
92
+ color: var(--va-c-primary-light);
92
93
  }
93
94
  }
94
95
  }
@@ -11,9 +11,6 @@ const showQr = ref(false)
11
11
 
12
12
  <template>
13
13
  <div class="yun-sponsor-container flex justify-center items-center flex-col">
14
- <!-- <a href="" :title="t('reward.donate')">
15
-
16
- </a> -->
17
14
  <button class="sponsor-button yun-icon-btn shadow hover:shadow-md" :title="t('reward.donate')" text="red-400" @click="showQr = !showQr">
18
15
  <div i-ri-heart-line />
19
16
  </button>
@@ -26,7 +23,7 @@ const showQr = ref(false)
26
23
  :href="method.url" target="_blank"
27
24
  :style="`color:${method.color}`"
28
25
  >
29
- <img w="full" class="sponsor-method-img" border="~ rounded" p="1" loading="lazy" :src="method.url" :title="method.name">
26
+ <img class="sponsor-method-img" border="~ rounded" p="1" loading="lazy" :src="method.url" :title="method.name">
30
27
  <div text="xl" m="2" :class="method.icon" />
31
28
  </a>
32
29
  </div>
@@ -39,7 +36,7 @@ const showQr = ref(false)
39
36
 
40
37
  div {
41
38
  transform: scale(1.1);
42
- transition: transform var(--yun-transition-duration) ease-in-out;
39
+ transition: transform var(--va-transition-duration) ease-in-out;
43
40
  }
44
41
  &:hover {
45
42
  background-color: rgba(255, 255, 255, 0.9);
@@ -60,7 +57,7 @@ const showQr = ref(false)
60
57
  overflow: hidden;
61
58
  height: 0;
62
59
 
63
- transition: height var(--yun-transition-duration) ease-in-out;
60
+ transition: height var(--va-transition-duration) ease-in-out;
64
61
 
65
62
  &.show {
66
63
  height: 220px;
@@ -0,0 +1,25 @@
1
+ <script lang="ts" setup>
2
+ import { isClient, useStorage } from '@vueuse/core'
3
+ import { useI18n } from 'vue-i18n'
4
+ const { t, availableLocales, locale } = useI18n()
5
+
6
+ const lang = useStorage('valaxy-locale', locale.value)
7
+
8
+ const toggleLocales = () => {
9
+ // change to some real logic
10
+ const locales = availableLocales
11
+
12
+ locale.value = locales[(locales.indexOf(locale.value) + 1) % locales.length]
13
+ // for localStorage
14
+ lang.value = locale.value
15
+
16
+ if (isClient)
17
+ document.documentElement.setAttribute('lang', locale.value)
18
+ }
19
+ </script>
20
+
21
+ <template>
22
+ <button class="yun-icon-btn" :title="t('button.toggle_langs')" style="color:var(--va-c-text)" @click="toggleLocales">
23
+ <div i-ri-translate class="transition transform" :class="locale === 'en' ? 'rotate-y-180' : ''" />
24
+ </button>
25
+ </template>
@@ -0,0 +1,14 @@
1
+ <script lang="ts" setup>
2
+ import { useConfig, useTwikoo } from 'valaxy'
3
+
4
+ const config = useConfig()
5
+ useTwikoo(config.value.comment.twikoo)
6
+ </script>
7
+
8
+ <template>
9
+ <div id="tcomment" w="full" />
10
+ </template>
11
+
12
+ <style lang="scss">
13
+ // custom twikoo style
14
+ </style>
@@ -2,9 +2,7 @@
2
2
  import { useConfig, useWaline } from 'valaxy'
3
3
 
4
4
  const config = useConfig()
5
- useWaline({
6
- serverURL: config.value.comment.waline.serverURL,
7
- })
5
+ useWaline(config.value.comment.waline)
8
6
  </script>
9
7
 
10
8
  <template>
@@ -13,8 +11,8 @@ useWaline({
13
11
 
14
12
  <style lang="scss">
15
13
  #waline {
16
- --waline-theme-color: var(--yun-c-primary);
17
- --waline-active-color: var(--yun-c-primary-light);
14
+ --waline-theme-color: var(--va-c-primary);
15
+ --waline-active-color: var(--va-c-primary-light);
18
16
 
19
17
  .v[data-class=v] {
20
18
  .veditor {
@@ -1,4 +1,5 @@
1
1
  import { ref, watch } from 'vue'
2
+ import { isClient } from '@vueuse/core'
2
3
 
3
4
  /**
4
5
  * fetch data from source, and random
@@ -11,10 +12,12 @@ export function useRandomData<T>(source: string | T[], random = false) {
11
12
 
12
13
  watch(() => source, async() => {
13
14
  let rawData: T[]
14
- if (typeof source === 'string')
15
+ if (typeof source === 'string') {
16
+ if (!isClient)
17
+ return
15
18
  rawData = await fetch(source).then(res => res.json()) as T[]
16
- else
17
- rawData = source
19
+ }
20
+ else { rawData = source }
18
21
 
19
22
  data.value = random ? Array.from(rawData).sort(() => Math.random() - 0.5) : rawData
20
23
  }, { immediate: true })
package/config/index.ts CHANGED
@@ -4,6 +4,16 @@ export const anonymousImage = 'https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/ava
4
4
  * Theme Config
5
5
  */
6
6
  export interface ThemeConfig {
7
+ // for unocss
8
+ safelist: string[]
9
+ colors: {
10
+ /**
11
+ * primary color
12
+ * @default '#0078E7'
13
+ */
14
+ primary: string
15
+ }
16
+
7
17
  /**
8
18
  * 首页标语
9
19
  */
@@ -92,6 +102,17 @@ export interface ThemeConfig {
92
102
  color: string
93
103
  icon: string
94
104
  }>
105
+
106
+ /**
107
+ * 菜单栏
108
+ */
109
+ menu: {
110
+ custom: {
111
+ title: string
112
+ url: string
113
+ icon: string
114
+ }
115
+ }
95
116
  }
96
117
 
97
118
  export type ThemeUserConfig = Partial<ThemeConfig>
@@ -100,6 +121,10 @@ export type ThemeUserConfig = Partial<ThemeConfig>
100
121
  * Default Config
101
122
  */
102
123
  export const defaultThemeConfig: ThemeConfig = {
124
+ safelist: ['i-ri-clipboard-line'],
125
+ colors: {
126
+ primary: '#0078E7',
127
+ },
103
128
  banner: {
104
129
  enable: true,
105
130
  title: '云游君的小站',
@@ -128,7 +153,7 @@ export const defaultThemeConfig: ThemeConfig = {
128
153
  icon: {
129
154
  name: 'i-ri-cloud-line',
130
155
  animated: true,
131
- color: 'var(--yun-c-primary)',
156
+ color: 'var(--va-c-primary)',
132
157
  url: 'https://sponsors.yunyoujun.cn',
133
158
  title: 'Sponsor YunYouJun',
134
159
  },
@@ -143,7 +168,7 @@ export const defaultThemeConfig: ThemeConfig = {
143
168
 
144
169
  types: {
145
170
  'link': {
146
- color: 'var(--yun-c-primary)',
171
+ color: 'var(--va-c-primary)',
147
172
  icon: 'i-ri-external-link-line',
148
173
  },
149
174
  'bilibili': {
@@ -155,7 +180,7 @@ export const defaultThemeConfig: ThemeConfig = {
155
180
  icon: 'i-ri-douban-line',
156
181
  },
157
182
  'github': {
158
- color: 'var(--yun-c-text)',
183
+ color: 'var(--va-c-text)',
159
184
  icon: 'i-ri-github-line',
160
185
  },
161
186
  'netease-cloud-music': {
@@ -163,7 +188,7 @@ export const defaultThemeConfig: ThemeConfig = {
163
188
  icon: 'i-ri-netease-cloud-music-line',
164
189
  },
165
190
  'notion': {
166
- color: 'var(--yun-c-text)',
191
+ color: 'var(--va-c-text)',
167
192
  icon: 'i-simple-icons-notion',
168
193
  },
169
194
  'twitter': {
@@ -187,6 +212,39 @@ export const defaultThemeConfig: ThemeConfig = {
187
212
  icon: 'i-ri-zhihu-line',
188
213
  },
189
214
  },
215
+
216
+ menu: {
217
+ custom: {
218
+ title: 'button.about',
219
+ icon: 'i-ri-clipboard-line',
220
+ url: '/about',
221
+ },
222
+ },
190
223
  }
191
224
 
225
+ defaultThemeConfig.safelist = defaultThemeConfig.safelist.concat(generateSafelist(defaultThemeConfig))
226
+
192
227
  export default defaultThemeConfig
228
+
229
+ /**
230
+ * generateSafelist by config
231
+ * @param themeConfig
232
+ * @returns
233
+ */
234
+ export function generateSafelist(themeConfig: ThemeUserConfig) {
235
+ const safelist = []
236
+
237
+ const types = themeConfig.types
238
+ if (types) {
239
+ for (const type in types)
240
+ safelist.push(types[type].icon)
241
+ }
242
+
243
+ if (themeConfig.footer?.icon?.name)
244
+ safelist.push(themeConfig.footer?.icon?.name)
245
+
246
+ if (themeConfig.menu?.custom?.icon)
247
+ safelist.push(themeConfig.menu?.custom?.icon)
248
+
249
+ return safelist
250
+ }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,18 @@
1
+ import { Plugin } from 'vite';
2
+
1
3
  declare const anonymousImage = "https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg";
2
4
  /**
3
5
  * Theme Config
4
6
  */
5
7
  interface ThemeConfig {
8
+ safelist: string[];
9
+ colors: {
10
+ /**
11
+ * primary color
12
+ * @default '#0078E7'
13
+ */
14
+ primary: string;
15
+ };
6
16
  /**
7
17
  * 首页标语
8
18
  */
@@ -83,6 +93,16 @@ interface ThemeConfig {
83
93
  color: string;
84
94
  icon: string;
85
95
  }>;
96
+ /**
97
+ * 菜单栏
98
+ */
99
+ menu: {
100
+ custom: {
101
+ title: string;
102
+ url: string;
103
+ icon: string;
104
+ };
105
+ };
86
106
  }
87
107
  declare type ThemeUserConfig = Partial<ThemeConfig>;
88
108
  /**
@@ -90,4 +110,18 @@ declare type ThemeUserConfig = Partial<ThemeConfig>;
90
110
  */
91
111
  declare const defaultThemeConfig: ThemeConfig;
92
112
 
93
- export { ThemeConfig, ThemeUserConfig, anonymousImage, defaultThemeConfig };
113
+ /**
114
+ * generateSafelist by config
115
+ * @param themeConfig
116
+ * @returns
117
+ */
118
+ declare function generateSafelist(themeConfig: ThemeUserConfig): string[];
119
+
120
+ interface UserOptions {
121
+ colors: {
122
+ primary: string;
123
+ };
124
+ }
125
+ declare function yunPlugin(userOptions?: Partial<ThemeConfig>): Plugin;
126
+
127
+ export { ThemeConfig, ThemeUserConfig, UserOptions, anonymousImage, yunPlugin as default, defaultThemeConfig, generateSafelist, yunPlugin };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var n="https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg",e= exports.defaultThemeConfig ={banner:{enable:!0,title:"\u4E91\u6E38\u541B\u7684\u5C0F\u7AD9"},bg_image:{enable:!0,url:"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/bg/stars-timing-0-blur-30px.jpg",dark:"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/bg/galaxy.jpg",opacity:1},say:{enable:!0,api:"https://el-bot-api.vercel.app/api/words/young",hitokoto:{enable:!1,api:"https://v1.hitokoto.cn"}},pages:[],footer:{since:2022,icon:{name:"i-ri-cloud-line",animated:!0,color:"var(--yun-c-primary)",url:"https://sponsors.yunyoujun.cn",title:"Sponsor YunYouJun"},powered:!0,beian:{enable:!1,icp:""}},types:{link:{color:"var(--yun-c-primary)",icon:"i-ri-external-link-line"},bilibili:{color:"#FF8EB3",icon:"i-ri-bilibili-line"},douban:{color:"#007722",icon:"i-ri-douban-line"},github:{color:"var(--yun-c-text)",icon:"i-ri-github-line"},"netease-cloud-music":{color:"#C10D0C",icon:"i-ri-netease-cloud-music-line"},notion:{color:"var(--yun-c-text)",icon:"i-simple-icons-notion"},twitter:{color:"#1da1f2",icon:"i-ri-twitter-line"},wechat:{color:"#1AAD19",icon:"i-ri-wechat-2-line"},weibo:{color:"#E6162D",icon:"i-ri-weibo-line"},yuque:{color:"#25b864",icon:"i-ant-design-yuque-outlined"},zhihu:{color:"#0084FF",icon:"i-ri-zhihu-line"}}};exports.anonymousImage = n; exports.defaultThemeConfig = e;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var d="https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg",n= exports.defaultThemeConfig ={safelist:["i-ri-clipboard-line"],colors:{primary:"#0078E7"},banner:{enable:!0,title:"\u4E91\u6E38\u541B\u7684\u5C0F\u7AD9"},bg_image:{enable:!0,url:"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/bg/stars-timing-0-blur-30px.jpg",dark:"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/bg/galaxy.jpg",opacity:1},say:{enable:!0,api:"https://el-bot-api.vercel.app/api/words/young",hitokoto:{enable:!1,api:"https://v1.hitokoto.cn"}},pages:[],footer:{since:2022,icon:{name:"i-ri-cloud-line",animated:!0,color:"var(--va-c-primary)",url:"https://sponsors.yunyoujun.cn",title:"Sponsor YunYouJun"},powered:!0,beian:{enable:!1,icp:""}},types:{link:{color:"var(--va-c-primary)",icon:"i-ri-external-link-line"},bilibili:{color:"#FF8EB3",icon:"i-ri-bilibili-line"},douban:{color:"#007722",icon:"i-ri-douban-line"},github:{color:"var(--va-c-text)",icon:"i-ri-github-line"},"netease-cloud-music":{color:"#C10D0C",icon:"i-ri-netease-cloud-music-line"},notion:{color:"var(--va-c-text)",icon:"i-simple-icons-notion"},twitter:{color:"#1da1f2",icon:"i-ri-twitter-line"},wechat:{color:"#1AAD19",icon:"i-ri-wechat-2-line"},weibo:{color:"#E6162D",icon:"i-ri-weibo-line"},yuque:{color:"#25b864",icon:"i-ant-design-yuque-outlined"},zhihu:{color:"#0084FF",icon:"i-ri-zhihu-line"}},menu:{custom:{title:"button.about",icon:"i-ri-clipboard-line",url:"/about"}}};n.safelist=n.safelist.concat(b(n));function b(i){var t,r,a,l,s,c,u,p;let e=[],o=i.types;if(o)for(let g in o)e.push(o[g].icon);return(r=(t=i.footer)==null?void 0:t.icon)!=null&&r.name&&e.push((l=(a=i.footer)==null?void 0:a.icon)==null?void 0:l.name),(c=(s=i.menu)==null?void 0:s.custom)!=null&&c.icon&&e.push((p=(u=i.menu)==null?void 0:u.custom)==null?void 0:p.icon),e}function f(i=n){return{name:"valaxy-theme-yun",enforce:"pre",config(){var e;return{css:{preprocessorOptions:{scss:{additionalData:`$c-primary: ${((e=i.colors)==null?void 0:e.primary)||"#0078E7"} !default;`}}}}}}}var v=f;exports.anonymousImage = d; exports.default = v; exports.defaultThemeConfig = n; exports.generateSafelist = b; exports.yunPlugin = f;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var e="https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg",o={banner:{enable:!0,title:"\u4E91\u6E38\u541B\u7684\u5C0F\u7AD9"},bg_image:{enable:!0,url:"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/bg/stars-timing-0-blur-30px.jpg",dark:"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/bg/galaxy.jpg",opacity:1},say:{enable:!0,api:"https://el-bot-api.vercel.app/api/words/young",hitokoto:{enable:!1,api:"https://v1.hitokoto.cn"}},pages:[],footer:{since:2022,icon:{name:"i-ri-cloud-line",animated:!0,color:"var(--yun-c-primary)",url:"https://sponsors.yunyoujun.cn",title:"Sponsor YunYouJun"},powered:!0,beian:{enable:!1,icp:""}},types:{link:{color:"var(--yun-c-primary)",icon:"i-ri-external-link-line"},bilibili:{color:"#FF8EB3",icon:"i-ri-bilibili-line"},douban:{color:"#007722",icon:"i-ri-douban-line"},github:{color:"var(--yun-c-text)",icon:"i-ri-github-line"},"netease-cloud-music":{color:"#C10D0C",icon:"i-ri-netease-cloud-music-line"},notion:{color:"var(--yun-c-text)",icon:"i-simple-icons-notion"},twitter:{color:"#1da1f2",icon:"i-ri-twitter-line"},wechat:{color:"#1AAD19",icon:"i-ri-wechat-2-line"},weibo:{color:"#E6162D",icon:"i-ri-weibo-line"},yuque:{color:"#25b864",icon:"i-ant-design-yuque-outlined"},zhihu:{color:"#0084FF",icon:"i-ri-zhihu-line"}}};export{e as anonymousImage,o as defaultThemeConfig};
1
+ var h="https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg",n={safelist:["i-ri-clipboard-line"],colors:{primary:"#0078E7"},banner:{enable:!0,title:"\u4E91\u6E38\u541B\u7684\u5C0F\u7AD9"},bg_image:{enable:!0,url:"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/bg/stars-timing-0-blur-30px.jpg",dark:"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/bg/galaxy.jpg",opacity:1},say:{enable:!0,api:"https://el-bot-api.vercel.app/api/words/young",hitokoto:{enable:!1,api:"https://v1.hitokoto.cn"}},pages:[],footer:{since:2022,icon:{name:"i-ri-cloud-line",animated:!0,color:"var(--va-c-primary)",url:"https://sponsors.yunyoujun.cn",title:"Sponsor YunYouJun"},powered:!0,beian:{enable:!1,icp:""}},types:{link:{color:"var(--va-c-primary)",icon:"i-ri-external-link-line"},bilibili:{color:"#FF8EB3",icon:"i-ri-bilibili-line"},douban:{color:"#007722",icon:"i-ri-douban-line"},github:{color:"var(--va-c-text)",icon:"i-ri-github-line"},"netease-cloud-music":{color:"#C10D0C",icon:"i-ri-netease-cloud-music-line"},notion:{color:"var(--va-c-text)",icon:"i-simple-icons-notion"},twitter:{color:"#1da1f2",icon:"i-ri-twitter-line"},wechat:{color:"#1AAD19",icon:"i-ri-wechat-2-line"},weibo:{color:"#E6162D",icon:"i-ri-weibo-line"},yuque:{color:"#25b864",icon:"i-ant-design-yuque-outlined"},zhihu:{color:"#0084FF",icon:"i-ri-zhihu-line"}},menu:{custom:{title:"button.about",icon:"i-ri-clipboard-line",url:"/about"}}};n.safelist=n.safelist.concat(f(n));function f(i){var t,r,a,l,s,c,u,p;let e=[],o=i.types;if(o)for(let g in o)e.push(o[g].icon);return(r=(t=i.footer)==null?void 0:t.icon)!=null&&r.name&&e.push((l=(a=i.footer)==null?void 0:a.icon)==null?void 0:l.name),(c=(s=i.menu)==null?void 0:s.custom)!=null&&c.icon&&e.push((p=(u=i.menu)==null?void 0:u.custom)==null?void 0:p.icon),e}function d(i=n){return{name:"valaxy-theme-yun",enforce:"pre",config(){var e;return{css:{preprocessorOptions:{scss:{additionalData:`$c-primary: ${((e=i.colors)==null?void 0:e.primary)||"#0078E7"} !default;`}}}}}}}var x=d;export{h as anonymousImage,x as default,n as defaultThemeConfig,f as generateSafelist,d as yunPlugin};
package/index.ts CHANGED
@@ -1 +1,32 @@
1
+ import type { Plugin } from 'vite'
2
+ import type { ThemeConfig } from './config'
3
+ import { defaultThemeConfig } from './config'
4
+
1
5
  export * from './config'
6
+
7
+ export interface UserOptions {
8
+ colors: {
9
+ primary: string
10
+ }
11
+ }
12
+
13
+ export function yunPlugin(userOptions: Partial<ThemeConfig> = defaultThemeConfig): Plugin {
14
+ return {
15
+ name: 'valaxy-theme-yun',
16
+ enforce: 'pre',
17
+
18
+ config() {
19
+ return {
20
+ css: {
21
+ preprocessorOptions: {
22
+ scss: {
23
+ additionalData: `$c-primary: ${userOptions.colors?.primary || '#0078E7'} !default;`,
24
+ },
25
+ },
26
+ },
27
+ }
28
+ },
29
+ }
30
+ }
31
+
32
+ export default yunPlugin
@@ -1,17 +1,19 @@
1
1
  <script lang="ts" setup>
2
- import { useFrontmatter, usePostList } from 'valaxy'
2
+ import { useFrontmatter, usePostList, usePostTitle } from 'valaxy'
3
3
  import { useI18n } from 'vue-i18n'
4
4
 
5
5
  const { t } = useI18n()
6
6
 
7
7
  const frontmatter = useFrontmatter()
8
8
  const postList = usePostList()
9
+
10
+ const title = usePostTitle(frontmatter)
9
11
  </script>
10
12
 
11
13
  <template>
12
14
  <YunBase>
13
15
  <template #header>
14
- <YunPageHeader :title="frontmatter.title || t('menu.archives')" :icon="frontmatter.icon || 'i-ri-archive-line'" :color="frontmatter.color" />
16
+ <YunPageHeader :title="title || t('menu.archives')" :icon="frontmatter.icon || 'i-ri-archive-line'" :color="frontmatter.color" />
15
17
  </template>
16
18
  <template #content>
17
19
  <router-view />
package/layouts/base.vue CHANGED
@@ -1,20 +1,28 @@
1
1
  <script lang="ts" setup>
2
- import { useConfig, useFrontmatter, usePostProperty } from 'valaxy'
2
+ import { useConfig, useFrontmatter, usePostProperty, usePostTitle } from 'valaxy'
3
3
  const frontmatter = useFrontmatter()
4
4
 
5
5
  const config = useConfig()
6
6
 
7
7
  const { styles, icon, color } = usePostProperty(frontmatter.value.type)
8
+ const title = usePostTitle(frontmatter)
8
9
  </script>
9
10
 
10
11
  <template>
11
- <ValaxySidebar />
12
+ <ValaxySidebar>
13
+ <slot name="sidebar">
14
+ <YunSidebar v-if="$slots['sidebar-child']">
15
+ <slot name="sidebar-child" />
16
+ </YunSidebar>
17
+ <YunSidebar v-else />
18
+ </slot>
19
+ </ValaxySidebar>
12
20
 
13
21
  <main class="yun-main flex lt-md:ml-0">
14
22
  <div flex="~ 1 col" w="full" p="l-4 lt-md:0">
15
- <YunCard m="0" p="4" class="page-card sm:p-6 lg:px-12 xl:px-16" :style="styles">
23
+ <YunCard m="0" p="4" class="relative page-card sm:p-6 lg:px-12 xl:px-16" :style="styles">
16
24
  <slot name="header">
17
- <YunPageHeader :title="frontmatter.title" :icon="frontmatter.icon || icon" :color="frontmatter.color || color" />
25
+ <YunPageHeader :title="title" :icon="frontmatter.icon || icon" :color="frontmatter.color || color" />
18
26
  </slot>
19
27
  <template #content>
20
28
  <slot name="content">
@@ -30,8 +38,9 @@ const { styles, icon, color } = usePostProperty(frontmatter.value.type)
30
38
  </slot>
31
39
 
32
40
  <slot v-if="frontmatter.comment !== false" name="comment">
33
- <YunCard v-if="config.comment.waline.enable" w="full" p="4" class="comment sm:p-8 lg:px-12 xl:px-16" :class="frontmatter.nav === false ? 'mt-4' : 0">
34
- <YunWaline />
41
+ <YunCard w="full" p="4" class="comment sm:p-8 lg:px-12 xl:px-16" :class="frontmatter.nav === false ? 'mt-4' : 0">
42
+ <YunWaline v-if="config.comment.waline.enable" />
43
+ <YunTwikoo v-if="config.comment.twikoo.enable" />
35
44
  </YunCard>
36
45
  </slot>
37
46
 
@@ -58,7 +67,7 @@ const { styles, icon, color } = usePostProperty(frontmatter.value.type)
58
67
  @include xl {
59
68
  .page-card {
60
69
  // 8px scrollbar width
61
- max-width: calc(100vw - 2 * var(--yun-sidebar-width-mobile) - 2rem - 8px);
70
+ max-width: calc(100vw - 2 * var(--va-sidebar-width-mobile) - 2rem - 8px);
62
71
  }
63
72
  }
64
73
  </style>
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed, ref } from 'vue'
3
- import { useCategory, useFrontmatter, useInvisibleElement, usePostList } from 'valaxy'
3
+ import { useCategory, useFrontmatter, useInvisibleElement, usePostList, usePostTitle } from 'valaxy'
4
4
  import { useI18n } from 'vue-i18n'
5
5
  import { useRoute, useRouter } from 'vue-router'
6
6
 
@@ -39,13 +39,15 @@ const displayCategory = (category: string) => {
39
39
 
40
40
  show()
41
41
  }
42
+
43
+ const title = usePostTitle(frontmatter)
42
44
  </script>
43
45
 
44
46
  <template>
45
47
  <YunBase>
46
48
  <template #header>
47
49
  <YunPageHeader
48
- :title="frontmatter.title || t('menu.categories')"
50
+ :title="title || t('menu.categories')"
49
51
  :icon="frontmatter.icon || 'i-ri-folder-2-line'"
50
52
  :color="frontmatter.color"
51
53
  />
package/layouts/home.vue CHANGED
@@ -12,11 +12,20 @@ const isHome = useLayout('home')
12
12
 
13
13
  <template>
14
14
  <main class="yun-main justify-center items-center" :class="(isHome && !app.isSidebarOpen) && 'pl-0'" flex="~ col" w="full">
15
- <ValaxySidebar />
15
+ <ValaxySidebar>
16
+ <slot name="sidebar">
17
+ <YunSidebar />
18
+ </slot>
19
+ </ValaxySidebar>
20
+
16
21
  <YunBanner />
17
22
  <YunSay w="full" />
18
23
 
19
- <router-view />
24
+ <slot name="board" />
25
+
26
+ <slot>
27
+ <router-view />
28
+ </slot>
20
29
 
21
30
  <ValaxyFooter>
22
31
  <slot name="footer" />