valaxy-theme-yun 0.7.3 → 0.7.4
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.
- package/components/ValaxyMain.vue +4 -3
- package/components/YunBanner.vue +1 -1
- package/components/YunBg.vue +51 -0
- package/components/YunCard.vue +0 -2
- package/components/YunFooter.vue +54 -0
- package/components/YunGirls.vue +1 -1
- package/components/YunPostCard.vue +81 -0
- package/components/YunPostList.vue +46 -0
- package/components/YunSay.vue +1 -1
- package/components/YunSidebarLinks.vue +1 -1
- package/components/YunSidebarNav.vue +2 -1
- package/components/YunToc.vue +1 -1
- package/composables/config.ts +12 -0
- package/composables/helper.ts +28 -0
- package/composables/index.ts +3 -28
- package/composables/post.ts +37 -0
- package/config/index.ts +3 -134
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/layouts/base.vue +1 -1
- package/layouts/home.vue +3 -3
- package/layouts/tags.vue +2 -11
- package/{index.ts → node/index.ts} +4 -3
- package/package.json +16 -5
- package/pages/index.vue +8 -0
- package/pages/page/[page].vue +12 -0
- package/styles/layout/post.scss +9 -0
- package/tsup.config.ts +5 -2
- package/types/index.ts +127 -0
- package/unocss.config.ts +8 -0
@@ -1,7 +1,8 @@
|
|
1
1
|
<script lang="ts" setup>
|
2
2
|
import type { PageData, Post } from 'valaxy'
|
3
|
-
import { useConfig,
|
3
|
+
import { useConfig, usePostTitle } from 'valaxy'
|
4
4
|
import { computed } from 'vue'
|
5
|
+
import { usePostProperty } from '../composables'
|
5
6
|
|
6
7
|
const props = defineProps<{
|
7
8
|
frontmatter: Post
|
@@ -51,9 +52,9 @@ const title = usePostTitle(computed(() => props.frontmatter))
|
|
51
52
|
</YunCard>
|
52
53
|
</slot>
|
53
54
|
|
54
|
-
<
|
55
|
+
<YunFooter>
|
55
56
|
<slot name="footer" />
|
56
|
-
</
|
57
|
+
</YunFooter>
|
57
58
|
</div>
|
58
59
|
</slot>
|
59
60
|
|
package/components/YunBanner.vue
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { computed } from 'vue'
|
3
|
+
import { useThemeConfig } from 'valaxy-theme-yun/composables'
|
4
|
+
import { useCssVar } from '@vueuse/core'
|
5
|
+
import { isDark } from '~/composables'
|
6
|
+
|
7
|
+
const themeConfig = useThemeConfig()
|
8
|
+
|
9
|
+
const bgImgOpacity = useCssVar('--va-bg-img-opacity')
|
10
|
+
if (themeConfig.value.bg_image.opacity)
|
11
|
+
bgImgOpacity.value = themeConfig.value.bg_image.opacity.toString() || '1'
|
12
|
+
|
13
|
+
const styles = computed(() => {
|
14
|
+
return {
|
15
|
+
backgroundImage: `url('${isDark.value
|
16
|
+
? themeConfig.value.bg_image.dark
|
17
|
+
: themeConfig.value.bg_image.url
|
18
|
+
}')`,
|
19
|
+
}
|
20
|
+
})
|
21
|
+
</script>
|
22
|
+
|
23
|
+
<template>
|
24
|
+
<div class="va-bg" :style="styles" />
|
25
|
+
</template>
|
26
|
+
|
27
|
+
<style lang="scss">
|
28
|
+
.va-bg {
|
29
|
+
position: fixed;
|
30
|
+
width: 100%;
|
31
|
+
height: 100%;
|
32
|
+
z-index: -1;
|
33
|
+
background-image: var(--va-bg-image);
|
34
|
+
background-size: cover;
|
35
|
+
background-position: center;
|
36
|
+
background-repeat: no-repeat;
|
37
|
+
animation-name: bgFadeIn;
|
38
|
+
animation-duration: 2s;
|
39
|
+
opacity: var(--va-bg-img-opacity, 1);
|
40
|
+
}
|
41
|
+
|
42
|
+
@keyframes bgFadeIn {
|
43
|
+
from {
|
44
|
+
opacity: 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
to {
|
48
|
+
opacity: var(--va-bg-img-opacity, 1);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
</style>
|
package/components/YunCard.vue
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { capitalize, computed } from 'vue'
|
3
|
+
import { useConfig } from 'valaxy'
|
4
|
+
import { useI18n } from 'vue-i18n'
|
5
|
+
|
6
|
+
import pkg from 'valaxy/package.json'
|
7
|
+
import { useThemeConfig } from '../composables'
|
8
|
+
|
9
|
+
const { t } = useI18n()
|
10
|
+
|
11
|
+
const config = useConfig()
|
12
|
+
const themeConfig = useThemeConfig()
|
13
|
+
|
14
|
+
const year = new Date().getFullYear()
|
15
|
+
|
16
|
+
const isThisYear = computed(() => {
|
17
|
+
return year === themeConfig.value.footer.since
|
18
|
+
})
|
19
|
+
|
20
|
+
const poweredHtml = computed(() => t('footer.powered', [`<a href="${pkg.repository}" target="_blank" rel="noopener">Valaxy</a> v${pkg.version}`]))
|
21
|
+
const footerIcon = computed(() => themeConfig.value.footer.icon!)
|
22
|
+
</script>
|
23
|
+
|
24
|
+
<template>
|
25
|
+
<footer class="va-footer p-4" text="center sm" style="color:var(--va-c-text-light)">
|
26
|
+
<div v-if="themeConfig.footer.beian?.enable && themeConfig.footer.beian.icp" class="beian" m="y-2">
|
27
|
+
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">
|
28
|
+
{{ themeConfig.footer.beian.icp }}
|
29
|
+
</a>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<div class="copyright flex justify-center items-center" p="1">
|
33
|
+
<span>
|
34
|
+
©
|
35
|
+
<template v-if="!isThisYear">
|
36
|
+
{{ themeConfig.footer.since }} -
|
37
|
+
</template>
|
38
|
+
{{ year }}
|
39
|
+
</span>
|
40
|
+
|
41
|
+
<a m="x-2" class="inline-flex animate-pulse" :href="footerIcon.url" target="_blank" :title="footerIcon.title">
|
42
|
+
<div :class="footerIcon.name" />
|
43
|
+
</a>
|
44
|
+
|
45
|
+
<span>{{ config.author.name }}</span>
|
46
|
+
</div>
|
47
|
+
|
48
|
+
<div v-if="themeConfig.footer.powered" class="powered" m="2">
|
49
|
+
<span v-html="poweredHtml" /> | <span>{{ t('footer.theme') }} - <a :href="themeConfig.pkg.homepage" :title="`valaxy-theme-${config.theme}`" target="_blank">{{ capitalize(config.theme) }}</a> v{{ themeConfig.pkg.version }}</span>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
<slot />
|
53
|
+
</footer>
|
54
|
+
</template>
|
package/components/YunGirls.vue
CHANGED
@@ -0,0 +1,81 @@
|
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { useI18n } from 'vue-i18n'
|
3
|
+
import type { Post } from 'valaxy'
|
4
|
+
import { usePostProperty } from '../composables'
|
5
|
+
|
6
|
+
const props = defineProps<{
|
7
|
+
post: Post
|
8
|
+
}>()
|
9
|
+
|
10
|
+
const { t } = useI18n()
|
11
|
+
|
12
|
+
const { icon, styles } = usePostProperty(props.post.type)
|
13
|
+
</script>
|
14
|
+
|
15
|
+
<template>
|
16
|
+
<YunCard m="y-4 auto" :class="post.cover ? 'post-card-image' : 'post-card'" :style="styles">
|
17
|
+
<div class="flex flex-1 of-hidden justify-start items-start post-card-info" w="full">
|
18
|
+
<img
|
19
|
+
v-if="post.cover"
|
20
|
+
:src="post.cover"
|
21
|
+
:alt="t('post.cover')"
|
22
|
+
width="320" height="180"
|
23
|
+
w="40%" h="54"
|
24
|
+
class="cover object-cover object-center md:shadow"
|
25
|
+
>
|
26
|
+
|
27
|
+
<div class="flex flex-col flex-1 items-center" :class="post.cover && 'max-h-54'" w="full">
|
28
|
+
<AppLink
|
29
|
+
class="post-title-link"
|
30
|
+
:to="post.path || ''"
|
31
|
+
m="t-3"
|
32
|
+
>
|
33
|
+
<div class="flex justify-center items-center title text-2xl" font="serif black">
|
34
|
+
<div v-if="post.type" class="inline-flex" m="r-1" :class="icon" />{{ post.title }}
|
35
|
+
</div>
|
36
|
+
</AppLink>
|
37
|
+
|
38
|
+
<YunPostMeta :frontmatter="post" />
|
39
|
+
|
40
|
+
<div v-if="post.excerpt" class="markdown-body" text="left" w="full" p="x-6 lt-sm:4" v-html="post.excerpt" />
|
41
|
+
<div m="b-5" />
|
42
|
+
|
43
|
+
<a
|
44
|
+
v-if="post.url"
|
45
|
+
:href="post.url"
|
46
|
+
class="post-link-btn shadow hover:shadow-md"
|
47
|
+
rounded
|
48
|
+
target="_blank"
|
49
|
+
m="b-4"
|
50
|
+
>
|
51
|
+
{{ t('post.view_link') }}
|
52
|
+
</a>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<!-- always show -->
|
57
|
+
<div w="full" class="yun-card-actions flex justify-between" border="t" text="sm">
|
58
|
+
<div class="inline-flex">
|
59
|
+
<router-link
|
60
|
+
:to="{
|
61
|
+
path: '/categories/',
|
62
|
+
query: { category: Array.isArray(post.categories) ? post.categories[post.categories.length - 1] : post.categories },
|
63
|
+
}"
|
64
|
+
class="post-categories inline-flex justify-center items-center" m="l-2"
|
65
|
+
>
|
66
|
+
<div m="x-1" i-ri-folder-2-line />
|
67
|
+
{{ Array.isArray(post.categories) ? post.categories.join(' > ') : post.categories }}
|
68
|
+
</router-link>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<div class="post-tags inline-flex" m="r-2">
|
72
|
+
<template v-if="post.tags">
|
73
|
+
<router-link v-for="tag, i in post.tags" :key="i" :to="{ path: '/tags/', query: { tag } }" m="x-1" class="post-tag inline-flex justify-center items-center">
|
74
|
+
<div m="r-1" i-ri-price-tag-3-line />
|
75
|
+
{{ tag }}
|
76
|
+
</router-link>
|
77
|
+
</template>
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
</YunCard>
|
81
|
+
</template>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<script setup lang="ts">
|
2
|
+
import { computed, ref } from 'vue'
|
3
|
+
import type { Post } from 'valaxy'
|
4
|
+
import { usePostList } from '~/composables'
|
5
|
+
|
6
|
+
const props = withDefaults(defineProps<{
|
7
|
+
type?: string
|
8
|
+
posts?: Post[]
|
9
|
+
curPage?: number
|
10
|
+
}>(), {
|
11
|
+
curPage: 1,
|
12
|
+
})
|
13
|
+
|
14
|
+
const pageSize = ref(7)
|
15
|
+
|
16
|
+
const routes = usePostList({ type: props.type || '' })
|
17
|
+
const posts = computed(() => props.posts || routes.value)
|
18
|
+
const displayedPosts = computed(() => posts.value.slice((props.curPage - 1) * pageSize.value, props.curPage * pageSize.value))
|
19
|
+
</script>
|
20
|
+
|
21
|
+
<template>
|
22
|
+
<div w="full" p="x-4 lt-sm:0">
|
23
|
+
<template v-if="!displayedPosts.length">
|
24
|
+
<div py2 op50>
|
25
|
+
博主还什么都没写哦~
|
26
|
+
</div>
|
27
|
+
</template>
|
28
|
+
|
29
|
+
<Transition v-for="route, i in displayedPosts" :key="i" name="fade">
|
30
|
+
<YunPostCard :post="route" />
|
31
|
+
</Transition>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<ValaxyPagination :cur-page="curPage" :page-size="pageSize" :total="posts.length" />
|
35
|
+
</template>
|
36
|
+
|
37
|
+
<style>
|
38
|
+
.yun-card-actions {
|
39
|
+
border-top: 1px solid rgba(122, 122, 122, 0.15);
|
40
|
+
min-height: 2.5rem;
|
41
|
+
}
|
42
|
+
|
43
|
+
.post-categories {
|
44
|
+
color: var(--va-c-text);
|
45
|
+
}
|
46
|
+
</style>
|
package/components/YunSay.vue
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
<script lang="ts" setup>
|
2
|
-
import { useCategory, usePostList, useTag
|
2
|
+
import { useCategory, usePostList, useTag } from 'valaxy'
|
3
3
|
import { useI18n } from 'vue-i18n'
|
4
|
+
import { useThemeConfig } from '../composables'
|
4
5
|
|
5
6
|
const { t } = useI18n()
|
6
7
|
|
package/components/YunToc.vue
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
import { computed, ref } from 'vue'
|
3
3
|
import { useI18n } from 'vue-i18n'
|
4
4
|
import type { Header } from 'valaxy'
|
5
|
-
import { useThemeConfig } from '
|
5
|
+
import { useThemeConfig } from '../composables'
|
6
6
|
import { useFrontmatter } from '~/composables'
|
7
7
|
import {
|
8
8
|
resolveHeaders,
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { computed } from 'vue'
|
2
|
+
import { useConfig } from 'valaxy'
|
3
|
+
import type { YunTheme } from '../types'
|
4
|
+
|
5
|
+
/**
|
6
|
+
* getThemeConfig
|
7
|
+
* @returns
|
8
|
+
*/
|
9
|
+
export function useThemeConfig<ThemeConfig = YunTheme.Config>() {
|
10
|
+
const config = useConfig<ThemeConfig>()
|
11
|
+
return computed(() => config!.value.themeConfig)
|
12
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { ref, watch } from 'vue'
|
2
|
+
import { isClient } from '@vueuse/core'
|
3
|
+
|
4
|
+
/**
|
5
|
+
* fetch data from source, and random
|
6
|
+
* @param source
|
7
|
+
* @param random
|
8
|
+
* @returns
|
9
|
+
*/
|
10
|
+
export function useRandomData<T>(source: string | T[], random = false) {
|
11
|
+
const data = ref<T[]>()
|
12
|
+
|
13
|
+
watch(() => source, async () => {
|
14
|
+
let rawData: T[]
|
15
|
+
if (typeof source === 'string') {
|
16
|
+
if (!isClient)
|
17
|
+
return
|
18
|
+
rawData = await fetch(source).then(res => res.json()) as T[]
|
19
|
+
}
|
20
|
+
else { rawData = source }
|
21
|
+
|
22
|
+
data.value = random ? Array.from(rawData).sort(() => Math.random() - 0.5) : rawData
|
23
|
+
}, { immediate: true })
|
24
|
+
|
25
|
+
return {
|
26
|
+
data,
|
27
|
+
}
|
28
|
+
}
|
package/composables/index.ts
CHANGED
@@ -1,28 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
/**
|
5
|
-
* fetch data from source, and random
|
6
|
-
* @param source
|
7
|
-
* @param random
|
8
|
-
* @returns
|
9
|
-
*/
|
10
|
-
export function useRandomData<T>(source: string | T[], random = false) {
|
11
|
-
const data = ref<T[]>()
|
12
|
-
|
13
|
-
watch(() => source, async () => {
|
14
|
-
let rawData: T[]
|
15
|
-
if (typeof source === 'string') {
|
16
|
-
if (!isClient)
|
17
|
-
return
|
18
|
-
rawData = await fetch(source).then(res => res.json()) as T[]
|
19
|
-
}
|
20
|
-
else { rawData = source }
|
21
|
-
|
22
|
-
data.value = random ? Array.from(rawData).sort(() => Math.random() - 0.5) : rawData
|
23
|
-
}, { immediate: true })
|
24
|
-
|
25
|
-
return {
|
26
|
-
data,
|
27
|
-
}
|
28
|
-
}
|
1
|
+
export * from './config'
|
2
|
+
export * from './helper'
|
3
|
+
export * from './post'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import type { StyleValue } from 'vue'
|
2
|
+
import { computed } from 'vue'
|
3
|
+
import { useThemeConfig } from './config'
|
4
|
+
|
5
|
+
/**
|
6
|
+
* get type card property
|
7
|
+
* todo: test reactive
|
8
|
+
*/
|
9
|
+
export function usePostProperty(type?: string) {
|
10
|
+
if (!type) {
|
11
|
+
return {
|
12
|
+
color: '',
|
13
|
+
icon: '',
|
14
|
+
styles: {},
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
const themeConfig = useThemeConfig()
|
19
|
+
|
20
|
+
if (!(type in themeConfig.value.types))
|
21
|
+
type = 'link'
|
22
|
+
|
23
|
+
const color = themeConfig.value.types[type].color
|
24
|
+
const icon = themeConfig.value.types[type].icon
|
25
|
+
|
26
|
+
const styles = computed(() => {
|
27
|
+
return {
|
28
|
+
'--card-c-primary': type && color,
|
29
|
+
} as StyleValue
|
30
|
+
})
|
31
|
+
|
32
|
+
return {
|
33
|
+
color,
|
34
|
+
icon,
|
35
|
+
styles,
|
36
|
+
}
|
37
|
+
}
|
package/config/index.ts
CHANGED
@@ -1,141 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
export namespace YunTheme {
|
4
|
-
export type Config = ThemeConfig
|
5
|
-
export type Sidebar = any
|
6
|
-
}
|
7
|
-
|
8
|
-
/**
|
9
|
-
* Theme Config
|
10
|
-
*/
|
11
|
-
export interface ThemeConfig {
|
12
|
-
/**
|
13
|
-
* toc title
|
14
|
-
* @default 'On this page'
|
15
|
-
*/
|
16
|
-
outlineTitle: string
|
17
|
-
|
18
|
-
// for unocss
|
19
|
-
safelist: string[]
|
20
|
-
colors: {
|
21
|
-
/**
|
22
|
-
* primary color
|
23
|
-
* @default '#0078E7'
|
24
|
-
*/
|
25
|
-
primary: string
|
26
|
-
}
|
27
|
-
|
28
|
-
/**
|
29
|
-
* 首页标语
|
30
|
-
*/
|
31
|
-
banner: {
|
32
|
-
enable: boolean
|
33
|
-
/**
|
34
|
-
* 标题
|
35
|
-
*/
|
36
|
-
title: string
|
37
|
-
}
|
38
|
-
|
39
|
-
bg_image: {
|
40
|
-
enable: boolean
|
41
|
-
url: string
|
42
|
-
dark?: string
|
43
|
-
opacity?: number
|
44
|
-
}
|
45
|
-
|
46
|
-
/**
|
47
|
-
* say something
|
48
|
-
* https://say.elpsy.cn
|
49
|
-
*/
|
50
|
-
say: {
|
51
|
-
enable: boolean
|
52
|
-
api: string
|
53
|
-
hitokoto: {
|
54
|
-
enable: boolean
|
55
|
-
api: string
|
56
|
-
}
|
57
|
-
}
|
1
|
+
import type { ThemeConfig, ThemeUserConfig } from '../types'
|
58
2
|
|
59
|
-
|
60
|
-
name: string
|
61
|
-
url: string
|
62
|
-
icon: string
|
63
|
-
color: string
|
64
|
-
}[]
|
65
|
-
|
66
|
-
sidebar: YunTheme.Sidebar
|
67
|
-
|
68
|
-
/**
|
69
|
-
* footer
|
70
|
-
*/
|
71
|
-
footer: {
|
72
|
-
/**
|
73
|
-
* 建站于
|
74
|
-
*/
|
75
|
-
since: number
|
76
|
-
|
77
|
-
/**
|
78
|
-
* Icon between year and copyright info.
|
79
|
-
*/
|
80
|
-
icon: {
|
81
|
-
/**
|
82
|
-
* icon name, i-xxx
|
83
|
-
*/
|
84
|
-
name: string
|
85
|
-
animated: boolean
|
86
|
-
color: string
|
87
|
-
url: string
|
88
|
-
title: string
|
89
|
-
}
|
90
|
-
|
91
|
-
/**
|
92
|
-
* Powered by valaxy & valaxy-theme-${name}, default is yun
|
93
|
-
*/
|
94
|
-
powered: boolean
|
95
|
-
|
96
|
-
/**
|
97
|
-
* Chinese Users | 中国用户
|
98
|
-
* 备案 ICP
|
99
|
-
* 国内用户需要在网站页脚展示备案 ICP 号
|
100
|
-
* https://beian.miit.gov.cn/
|
101
|
-
*/
|
102
|
-
beian: {
|
103
|
-
enable: boolean
|
104
|
-
/**
|
105
|
-
* 苏ICP备xxxxxxxx号
|
106
|
-
*/
|
107
|
-
icp: string
|
108
|
-
}
|
109
|
-
}
|
110
|
-
|
111
|
-
/**
|
112
|
-
* post card types
|
113
|
-
*/
|
114
|
-
types: Record<string, {
|
115
|
-
color: string
|
116
|
-
icon: string
|
117
|
-
}>
|
118
|
-
|
119
|
-
/**
|
120
|
-
* 菜单栏
|
121
|
-
*/
|
122
|
-
menu: {
|
123
|
-
custom: {
|
124
|
-
title: string
|
125
|
-
url: string
|
126
|
-
icon: string
|
127
|
-
}
|
128
|
-
}
|
129
|
-
}
|
130
|
-
|
131
|
-
export type ThemeUserConfig = Partial<ThemeConfig>
|
3
|
+
export const anonymousImage = 'https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg'
|
132
4
|
|
133
5
|
/**
|
134
6
|
* Default Config
|
135
7
|
*/
|
136
8
|
export const defaultThemeConfig: ThemeConfig = {
|
137
9
|
outlineTitle: 'On this page',
|
138
|
-
safelist: ['i-ri-clipboard-line'],
|
139
10
|
colors: {
|
140
11
|
primary: '#0078E7',
|
141
12
|
},
|
@@ -236,8 +107,6 @@ export const defaultThemeConfig: ThemeConfig = {
|
|
236
107
|
},
|
237
108
|
}
|
238
109
|
|
239
|
-
defaultThemeConfig.safelist = defaultThemeConfig.safelist.concat(generateSafelist(defaultThemeConfig))
|
240
|
-
|
241
110
|
export default defaultThemeConfig
|
242
111
|
|
243
112
|
/**
|
@@ -251,7 +120,7 @@ export function generateSafelist(themeConfig: ThemeUserConfig) {
|
|
251
120
|
const types = themeConfig.types
|
252
121
|
if (types) {
|
253
122
|
for (const type in types)
|
254
|
-
safelist.push(types[type]
|
123
|
+
safelist.push(types[type]?.icon)
|
255
124
|
}
|
256
125
|
|
257
126
|
if (themeConfig.footer?.icon?.name)
|
package/dist/index.d.ts
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import { Plugin } from 'vite';
|
2
2
|
|
3
|
-
declare const anonymousImage = "https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg";
|
4
3
|
declare namespace YunTheme {
|
5
4
|
type Config = ThemeConfig;
|
6
5
|
type Sidebar = any;
|
@@ -14,7 +13,6 @@ interface ThemeConfig {
|
|
14
13
|
* @default 'On this page'
|
15
14
|
*/
|
16
15
|
outlineTitle: string;
|
17
|
-
safelist: string[];
|
18
16
|
colors: {
|
19
17
|
/**
|
20
18
|
* primary color
|
@@ -60,7 +58,7 @@ interface ThemeConfig {
|
|
60
58
|
/**
|
61
59
|
* footer
|
62
60
|
*/
|
63
|
-
footer: {
|
61
|
+
footer: Partial<{
|
64
62
|
/**
|
65
63
|
* 建站于
|
66
64
|
*/
|
@@ -95,7 +93,7 @@ interface ThemeConfig {
|
|
95
93
|
*/
|
96
94
|
icp: string;
|
97
95
|
};
|
98
|
-
}
|
96
|
+
}>;
|
99
97
|
/**
|
100
98
|
* post card types
|
101
99
|
*/
|
@@ -115,6 +113,8 @@ interface ThemeConfig {
|
|
115
113
|
};
|
116
114
|
}
|
117
115
|
declare type ThemeUserConfig = Partial<ThemeConfig>;
|
116
|
+
|
117
|
+
declare const anonymousImage = "https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg";
|
118
118
|
/**
|
119
119
|
* Default Config
|
120
120
|
*/
|
package/dist/index.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
"use strict";Object.defineProperty(
|
1
|
+
"use strict";var r=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var v=(e,i)=>{for(var o in i)r(e,o,{get:i[o],enumerable:!0})},x=(e,i,o,t)=>{if(i&&typeof i=="object"||typeof i=="function")for(let n of h(i))!y.call(e,n)&&n!==o&&r(e,n,{get:()=>i[n],enumerable:!(t=b(i,n))||t.enumerable});return e};var T=e=>x(r({},"__esModule",{value:!0}),e);var C={};v(C,{anonymousImage:()=>w,default:()=>j,defaultThemeConfig:()=>a,generateSafelist:()=>Y,yunPlugin:()=>g});module.exports=T(C);var w="https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg",a={outlineTitle:"On this page",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"},say:{enable:!0,api:"https://el-bot-api.vercel.app/api/words/young",hitokoto:{enable:!1,api:"https://v1.hitokoto.cn"}},pages:[],sidebar:null,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"}}};function Y(e){var t,n,l,c,u,s,p,m,f;let i=[],o=e.types;if(o)for(let d in o)i.push((t=o[d])==null?void 0:t.icon);return(l=(n=e.footer)==null?void 0:n.icon)!=null&&l.name&&i.push((u=(c=e.footer)==null?void 0:c.icon)==null?void 0:u.name),(p=(s=e.menu)==null?void 0:s.custom)!=null&&p.icon&&i.push((f=(m=e.menu)==null?void 0:m.custom)==null?void 0:f.icon),i}function g(e=a){return{name:"valaxy-theme-yun",enforce:"pre",config(){var i;return{css:{preprocessorOptions:{scss:{additionalData:`$c-primary: ${((i=e.colors)==null?void 0:i.primary)||"#0078E7"} !default;`}}}}}}}var j=g;0&&(module.exports={anonymousImage,defaultThemeConfig,generateSafelist,yunPlugin});
|
package/dist/index.mjs
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var
|
1
|
+
var d="https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg",m={outlineTitle:"On this page",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"},say:{enable:!0,api:"https://el-bot-api.vercel.app/api/words/young",hitokoto:{enable:!1,api:"https://v1.hitokoto.cn"}},pages:[],sidebar:null,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"}}};function b(i){var n,t,r,a,l,c,u,s,p;let e=[],o=i.types;if(o)for(let f in o)e.push((n=o[f])==null?void 0:n.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),(u=(c=i.menu)==null?void 0:c.custom)!=null&&u.icon&&e.push((p=(s=i.menu)==null?void 0:s.custom)==null?void 0:p.icon),e}function g(i=m){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=g;export{d as anonymousImage,v as default,m as defaultThemeConfig,b as generateSafelist,g as yunPlugin};
|
package/layouts/base.vue
CHANGED
package/layouts/home.vue
CHANGED
@@ -11,7 +11,7 @@ const isHome = useLayout('home')
|
|
11
11
|
</script>
|
12
12
|
|
13
13
|
<template>
|
14
|
-
<
|
14
|
+
<YunBg v-if="config.themeConfig.bg_image.enable" />
|
15
15
|
|
16
16
|
<main class="yun-main justify-center items-center" :class="(isHome && !app.isSidebarOpen) && 'pl-0'" flex="~ col" w="full">
|
17
17
|
<ValaxySidebar>
|
@@ -29,9 +29,9 @@ const isHome = useLayout('home')
|
|
29
29
|
<router-view />
|
30
30
|
</slot>
|
31
31
|
|
32
|
-
<
|
32
|
+
<YunFooter>
|
33
33
|
<slot name="footer" />
|
34
|
-
</
|
34
|
+
</YunFooter>
|
35
35
|
</main>
|
36
36
|
|
37
37
|
<YunSearch v-if="config.search.enable" />
|
package/layouts/tags.vue
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
<script lang="ts" setup>
|
2
|
-
import { useFrontmatter, useInvisibleElement, usePostList, usePostTitle, useTags
|
2
|
+
import { useFrontmatter, useInvisibleElement, usePostList, usePostTitle, useTags } from 'valaxy'
|
3
3
|
import { useI18n } from 'vue-i18n'
|
4
4
|
import { computed, ref } from 'vue'
|
5
5
|
import { useRoute, useRouter } from 'vue-router'
|
6
|
+
import { useThemeConfig } from '../composables'
|
6
7
|
|
7
8
|
const route = useRoute()
|
8
9
|
const router = useRouter()
|
@@ -78,13 +79,3 @@ const title = usePostTitle(frontmatter)
|
|
78
79
|
</template>
|
79
80
|
</Base>
|
80
81
|
</template>
|
81
|
-
|
82
|
-
<style lang="scss">
|
83
|
-
.post-tag {
|
84
|
-
color: var(--yun-tag-color);
|
85
|
-
|
86
|
-
&:hover {
|
87
|
-
color: var(--va-c-primary);
|
88
|
-
}
|
89
|
-
}
|
90
|
-
</style>
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import type { Plugin } from 'vite'
|
2
|
-
import type { ThemeConfig } from '
|
3
|
-
import { defaultThemeConfig } from '
|
2
|
+
import type { ThemeConfig } from '../types'
|
3
|
+
import { defaultThemeConfig } from '../config'
|
4
4
|
|
5
|
-
export * from '
|
5
|
+
export * from '../config'
|
6
|
+
export * from '../types'
|
6
7
|
|
7
8
|
export interface UserOptions {
|
8
9
|
colors: {
|
package/package.json
CHANGED
@@ -1,27 +1,38 @@
|
|
1
1
|
{
|
2
2
|
"name": "valaxy-theme-yun",
|
3
|
-
"version": "0.7.
|
3
|
+
"version": "0.7.4",
|
4
4
|
"author": {
|
5
5
|
"email": "me@yunyoujun.cn",
|
6
6
|
"name": "YunYouJun",
|
7
7
|
"url": "https://www.yunyoujun.cn"
|
8
8
|
},
|
9
|
-
"homepage": "https://valaxy.
|
9
|
+
"homepage": "https://yun.valaxy.site",
|
10
10
|
"repository": {
|
11
11
|
"type": "git",
|
12
12
|
"url": "https://github.com/YunYouJun/valaxy/tree/main/packages/valaxy-theme-yun"
|
13
13
|
},
|
14
|
+
"exports": {
|
15
|
+
".": {
|
16
|
+
"require": "./dist/index.js",
|
17
|
+
"import": "./dist/index.mjs"
|
18
|
+
},
|
19
|
+
"./*": "./*"
|
20
|
+
},
|
14
21
|
"main": "dist/index.js",
|
22
|
+
"module": "dist/index.mjs",
|
15
23
|
"types": "dist/index.d.ts",
|
24
|
+
"peerDependencies": {
|
25
|
+
"valaxy": "0.7.4"
|
26
|
+
},
|
16
27
|
"dependencies": {
|
17
28
|
"@iconify-json/ant-design": "^1.1.3",
|
18
|
-
"@iconify-json/simple-icons": "^1.1.
|
29
|
+
"@iconify-json/simple-icons": "^1.1.19"
|
19
30
|
},
|
20
31
|
"devDependencies": {
|
21
|
-
"valaxy": "0.7.
|
32
|
+
"valaxy": "0.7.4"
|
22
33
|
},
|
23
34
|
"scripts": {
|
24
|
-
"build": "tsup",
|
35
|
+
"build": "rimraf dist && tsup",
|
25
36
|
"dev": "tsup --watch"
|
26
37
|
}
|
27
38
|
}
|
package/pages/index.vue
ADDED
package/styles/layout/post.scss
CHANGED
package/tsup.config.ts
CHANGED
@@ -2,12 +2,15 @@ import { defineConfig } from 'tsup'
|
|
2
2
|
|
3
3
|
export default defineConfig((options) => {
|
4
4
|
return {
|
5
|
-
entry: ['index.ts'],
|
6
|
-
splitting: true,
|
5
|
+
entry: ['node/index.ts'],
|
7
6
|
// disable for dev watch before valaxy watch
|
8
7
|
clean: !options.watch,
|
9
8
|
dts: true,
|
10
9
|
format: ['cjs', 'esm'],
|
11
10
|
minify: !options.watch,
|
11
|
+
external: [
|
12
|
+
'valaxy',
|
13
|
+
'vite',
|
14
|
+
],
|
12
15
|
}
|
13
16
|
})
|
package/types/index.ts
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
export namespace YunTheme {
|
2
|
+
export type Config = ThemeConfig
|
3
|
+
export type Sidebar = any
|
4
|
+
}
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Theme Config
|
8
|
+
*/
|
9
|
+
export interface ThemeConfig {
|
10
|
+
/**
|
11
|
+
* toc title
|
12
|
+
* @default 'On this page'
|
13
|
+
*/
|
14
|
+
outlineTitle: string
|
15
|
+
|
16
|
+
colors: {
|
17
|
+
/**
|
18
|
+
* primary color
|
19
|
+
* @default '#0078E7'
|
20
|
+
*/
|
21
|
+
primary: string
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* 首页标语
|
26
|
+
*/
|
27
|
+
banner: {
|
28
|
+
enable: boolean
|
29
|
+
/**
|
30
|
+
* 标题
|
31
|
+
*/
|
32
|
+
title: string
|
33
|
+
}
|
34
|
+
|
35
|
+
bg_image: {
|
36
|
+
enable: boolean
|
37
|
+
url: string
|
38
|
+
dark?: string
|
39
|
+
opacity?: number
|
40
|
+
}
|
41
|
+
|
42
|
+
/**
|
43
|
+
* say something
|
44
|
+
* https://say.elpsy.cn
|
45
|
+
*/
|
46
|
+
say: {
|
47
|
+
enable: boolean
|
48
|
+
api: string
|
49
|
+
hitokoto: {
|
50
|
+
enable: boolean
|
51
|
+
api: string
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
pages: {
|
56
|
+
name: string
|
57
|
+
url: string
|
58
|
+
icon: string
|
59
|
+
color: string
|
60
|
+
}[]
|
61
|
+
|
62
|
+
sidebar: YunTheme.Sidebar
|
63
|
+
|
64
|
+
/**
|
65
|
+
* footer
|
66
|
+
*/
|
67
|
+
footer: Partial<{
|
68
|
+
/**
|
69
|
+
* 建站于
|
70
|
+
*/
|
71
|
+
since: number
|
72
|
+
|
73
|
+
/**
|
74
|
+
* Icon between year and copyright info.
|
75
|
+
*/
|
76
|
+
icon: {
|
77
|
+
/**
|
78
|
+
* icon name, i-xxx
|
79
|
+
*/
|
80
|
+
name: string
|
81
|
+
animated: boolean
|
82
|
+
color: string
|
83
|
+
url: string
|
84
|
+
title: string
|
85
|
+
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Powered by valaxy & valaxy-theme-${name}, default is yun
|
89
|
+
*/
|
90
|
+
powered: boolean
|
91
|
+
|
92
|
+
/**
|
93
|
+
* Chinese Users | 中国用户
|
94
|
+
* 备案 ICP
|
95
|
+
* 国内用户需要在网站页脚展示备案 ICP 号
|
96
|
+
* https://beian.miit.gov.cn/
|
97
|
+
*/
|
98
|
+
beian: {
|
99
|
+
enable: boolean
|
100
|
+
/**
|
101
|
+
* 苏ICP备xxxxxxxx号
|
102
|
+
*/
|
103
|
+
icp: string
|
104
|
+
}
|
105
|
+
}>
|
106
|
+
|
107
|
+
/**
|
108
|
+
* post card types
|
109
|
+
*/
|
110
|
+
types: Record<string, {
|
111
|
+
color: string
|
112
|
+
icon: string
|
113
|
+
}>
|
114
|
+
|
115
|
+
/**
|
116
|
+
* 菜单栏
|
117
|
+
*/
|
118
|
+
menu: {
|
119
|
+
custom: {
|
120
|
+
title: string
|
121
|
+
url: string
|
122
|
+
icon: string
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
export type ThemeUserConfig = Partial<ThemeConfig>
|