@sugarat/theme 0.2.26 → 0.2.28
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/node.d.ts +17 -2
- package/node.js +16 -1
- package/package.json +3 -3
- package/src/components/BlogFooter.vue +40 -16
- package/src/composables/config/index.ts +15 -1
- package/src/hooks/useOml2d.ts +66 -1
- package/src/node.ts +16 -1
- package/src/utils/node/theme.ts +4 -0
package/node.d.ts
CHANGED
|
@@ -412,11 +412,24 @@ declare namespace Theme {
|
|
|
412
412
|
liClass?: string;
|
|
413
413
|
}
|
|
414
414
|
type RSSOptions = RSSPluginOptions;
|
|
415
|
+
interface FooterItem {
|
|
416
|
+
text: string;
|
|
417
|
+
link?: string;
|
|
418
|
+
icon?: boolean | string;
|
|
419
|
+
}
|
|
415
420
|
interface Footer {
|
|
416
421
|
/**
|
|
417
|
-
* 自定义补充信息(支持配置为HTML
|
|
422
|
+
* 自定义补充信息(支持配置为HTML),在内置的 footer 上方
|
|
418
423
|
*/
|
|
419
424
|
message?: string | string[];
|
|
425
|
+
/**
|
|
426
|
+
* 自定义补充信息(支持配置为HTML),在内置的 footer 下方
|
|
427
|
+
*/
|
|
428
|
+
bottomMessage?: string | string[];
|
|
429
|
+
/**
|
|
430
|
+
* 自定义补充信息(支持配置为HTML),紧随内置的后方
|
|
431
|
+
*/
|
|
432
|
+
list?: string | string[] | FooterItem | FooterItem[];
|
|
420
433
|
/**
|
|
421
434
|
* 是否展示主题版本信息
|
|
422
435
|
*/
|
|
@@ -468,4 +481,6 @@ declare function getThemeConfig(cfg?: Partial<Theme.BlogConfig>): any;
|
|
|
468
481
|
*/
|
|
469
482
|
declare function defineConfig(config: UserConfig<Theme.Config>): any;
|
|
470
483
|
|
|
471
|
-
|
|
484
|
+
declare function footerHTML(footerData: Theme.FooterItem | Theme.FooterItem[]): string;
|
|
485
|
+
|
|
486
|
+
export { defineConfig, footerHTML, getThemeConfig };
|
package/node.js
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var node_exports = {};
|
|
32
32
|
__export(node_exports, {
|
|
33
33
|
defineConfig: () => defineConfig,
|
|
34
|
+
footerHTML: () => footerHTML,
|
|
34
35
|
getThemeConfig: () => getThemeConfig,
|
|
35
36
|
tabsMarkdownPlugin: () => tabsPlugin
|
|
36
37
|
});
|
|
@@ -39,7 +40,7 @@ module.exports = __toCommonJS(node_exports);
|
|
|
39
40
|
// src/utils/node/mdPlugins.ts
|
|
40
41
|
var import_module = require("module");
|
|
41
42
|
|
|
42
|
-
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.
|
|
43
|
+
// ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.1_vue@3.4.21/node_modules/vitepress-plugin-tabs/dist/index.js
|
|
43
44
|
var tabsMarker = "=tabs";
|
|
44
45
|
var tabsMarkerLen = tabsMarker.length;
|
|
45
46
|
var ruleBlockTabs = (state, startLine, endLine, silent) => {
|
|
@@ -456,6 +457,8 @@ function patchVPThemeConfig(cfg, vpThemeConfig = {}) {
|
|
|
456
457
|
vpThemeConfig.sidebar = patchDefaultThemeSideBar(cfg)?.sidebar;
|
|
457
458
|
return vpThemeConfig;
|
|
458
459
|
}
|
|
460
|
+
function checkConfig(cfg) {
|
|
461
|
+
}
|
|
459
462
|
|
|
460
463
|
// src/utils/node/vitePlugins.ts
|
|
461
464
|
var import_node_path3 = __toESM(require("path"));
|
|
@@ -562,6 +565,7 @@ function coverImgTransform() {
|
|
|
562
565
|
|
|
563
566
|
// src/node.ts
|
|
564
567
|
function getThemeConfig(cfg) {
|
|
568
|
+
checkConfig(cfg);
|
|
565
569
|
const pagesData = getArticles(cfg);
|
|
566
570
|
const extraVPConfig = {};
|
|
567
571
|
const vitePlugins = getVitePlugins(cfg);
|
|
@@ -585,9 +589,20 @@ function getThemeConfig(cfg) {
|
|
|
585
589
|
function defineConfig(config) {
|
|
586
590
|
return config;
|
|
587
591
|
}
|
|
592
|
+
function footerHTML(footerData) {
|
|
593
|
+
const data = [footerData || []].flat();
|
|
594
|
+
return data.map((d) => {
|
|
595
|
+
const { icon, text, link } = d;
|
|
596
|
+
return `<span class="footer-item">
|
|
597
|
+
${icon ? `<i>${icon}</i>` : ""}
|
|
598
|
+
${link ? `<a href="${link}" target="_blank" rel="noopener noreferrer">${text}</a>` : `<span>${text}</span>`}
|
|
599
|
+
</span>`;
|
|
600
|
+
}).join("");
|
|
601
|
+
}
|
|
588
602
|
// Annotate the CommonJS export names for ESM import in node:
|
|
589
603
|
0 && (module.exports = {
|
|
590
604
|
defineConfig,
|
|
605
|
+
footerHTML,
|
|
591
606
|
getThemeConfig,
|
|
592
607
|
tabsMarkdownPlugin
|
|
593
608
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarat/theme",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.28",
|
|
4
4
|
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
|
|
5
5
|
"author": "sugar",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"gray-matter": "^4.0.3",
|
|
43
43
|
"markdown-it-task-checkbox": "^1.0.6",
|
|
44
44
|
"mermaid": "^10.2.4",
|
|
45
|
-
"oh-my-live2d": "^0.
|
|
45
|
+
"oh-my-live2d": "^0.13.0",
|
|
46
46
|
"swiper": "^11.0.5",
|
|
47
47
|
"vitepress-markdown-timeline": "^1.2.1",
|
|
48
48
|
"vitepress-plugin-mermaid": "2.0.13",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"pagefind": "1.0.3",
|
|
58
58
|
"sass": "^1.56.1",
|
|
59
59
|
"typescript": "^4.8.2",
|
|
60
|
-
"vitepress": "1.0.
|
|
60
|
+
"vitepress": "1.0.1",
|
|
61
61
|
"vue": "^3.4.21"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
@@ -3,6 +3,7 @@ import { computed } from 'vue'
|
|
|
3
3
|
import { useHomeFooterConfig } from '../composables/config/blog'
|
|
4
4
|
import packageJSON from '../../package.json'
|
|
5
5
|
import { copyrightSVG, icpSVG, themeSVG } from '../constants/svg'
|
|
6
|
+
import { vOuterHtml } from '../directives'
|
|
6
7
|
|
|
7
8
|
const footerData = useHomeFooterConfig()
|
|
8
9
|
|
|
@@ -12,14 +13,15 @@ const renderData = computed(() => {
|
|
|
12
13
|
}
|
|
13
14
|
const flatData = [footerData].flat()
|
|
14
15
|
return flatData.flat().map((footer, idx) => {
|
|
15
|
-
const { icpRecord, securityRecord, copyright, version, message } = footer
|
|
16
|
-
const data: {
|
|
16
|
+
const { icpRecord, securityRecord, copyright, version, message, bottomMessage, list } = footer
|
|
17
|
+
const data: ({
|
|
17
18
|
name: string
|
|
18
19
|
link?: string
|
|
19
20
|
icon?: string | boolean
|
|
20
|
-
}[] = []
|
|
21
|
+
} | string) [] = []
|
|
21
22
|
// message
|
|
22
|
-
const messageData
|
|
23
|
+
const messageData = [message || []].flat()
|
|
24
|
+
const bottomMessageData = [bottomMessage || []].flat()
|
|
23
25
|
|
|
24
26
|
// version
|
|
25
27
|
const isLast = idx === flatData.length - 1
|
|
@@ -58,9 +60,23 @@ const renderData = computed(() => {
|
|
|
58
60
|
...securityRecord
|
|
59
61
|
})
|
|
60
62
|
}
|
|
63
|
+
if (list) {
|
|
64
|
+
const listData = [list || []].flat()
|
|
65
|
+
data.push(...listData.map((v) => {
|
|
66
|
+
if (typeof v === 'string') {
|
|
67
|
+
return v
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
name: v.text,
|
|
71
|
+
icon: v.icon,
|
|
72
|
+
link: v.link
|
|
73
|
+
}
|
|
74
|
+
}))
|
|
75
|
+
}
|
|
61
76
|
return {
|
|
62
77
|
data,
|
|
63
|
-
messageData
|
|
78
|
+
messageData,
|
|
79
|
+
bottomMessageData
|
|
64
80
|
}
|
|
65
81
|
})
|
|
66
82
|
})
|
|
@@ -70,20 +86,27 @@ const renderData = computed(() => {
|
|
|
70
86
|
<footer v-if="renderData.length" class="blog-footer">
|
|
71
87
|
<!-- eslint-disable vue/require-v-for-key -->
|
|
72
88
|
<!-- see https://cn.vuejs.org/guide/essentials/list.html#v-for-on-template -->
|
|
73
|
-
<template v-for="({ data, messageData }) in renderData">
|
|
89
|
+
<template v-for="({ data, messageData, bottomMessageData }) in renderData">
|
|
90
|
+
<!-- 在内置footer上方渲染 -->
|
|
74
91
|
<p v-for="message in messageData" v-html="message" />
|
|
92
|
+
<!-- 内置的列表 -->
|
|
75
93
|
<p class="footer-item-list">
|
|
76
|
-
<
|
|
77
|
-
<
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
94
|
+
<template v-for="item in data">
|
|
95
|
+
<span v-if="typeof item !== 'string'" class="footer-item">
|
|
96
|
+
<i v-if="item.icon === 'security'">
|
|
97
|
+
<img src="./../styles/gongan.png" alt="公网安备">
|
|
98
|
+
</i>
|
|
99
|
+
<i v-else-if="item.icon" v-html="item.icon" />
|
|
100
|
+
<a v-if="item.link" :href="item.link" target="_blank" rel="noopener noreferrer">
|
|
101
|
+
{{ item.name }}
|
|
102
|
+
</a>
|
|
103
|
+
<span v-else>{{ item.name }}</span>
|
|
104
|
+
</span>
|
|
105
|
+
<span v-else v-outer-html="item" />
|
|
106
|
+
</template>
|
|
86
107
|
</p>
|
|
108
|
+
<!-- 在内置的footer下方渲染 -->
|
|
109
|
+
<p v-for="message in bottomMessageData" v-html="message" />
|
|
87
110
|
</template>
|
|
88
111
|
</footer>
|
|
89
112
|
</template>
|
|
@@ -124,6 +147,7 @@ footer.blog-footer {
|
|
|
124
147
|
|
|
125
148
|
i {
|
|
126
149
|
margin-right: 4px;
|
|
150
|
+
font-style: normal;
|
|
127
151
|
}
|
|
128
152
|
|
|
129
153
|
i :deep(svg) {
|
|
@@ -450,11 +450,25 @@ export namespace Theme {
|
|
|
450
450
|
|
|
451
451
|
export type RSSOptions = RSSPluginOptions
|
|
452
452
|
|
|
453
|
+
export interface FooterItem {
|
|
454
|
+
text: string
|
|
455
|
+
link?: string
|
|
456
|
+
icon?: boolean | string
|
|
457
|
+
}
|
|
458
|
+
|
|
453
459
|
export interface Footer {
|
|
454
460
|
/**
|
|
455
|
-
* 自定义补充信息(支持配置为HTML
|
|
461
|
+
* 自定义补充信息(支持配置为HTML),在内置的 footer 上方
|
|
456
462
|
*/
|
|
457
463
|
message?: string | string[]
|
|
464
|
+
/**
|
|
465
|
+
* 自定义补充信息(支持配置为HTML),在内置的 footer 下方
|
|
466
|
+
*/
|
|
467
|
+
bottomMessage?: string | string[]
|
|
468
|
+
/**
|
|
469
|
+
* 自定义补充信息(支持配置为HTML),紧随内置的后方
|
|
470
|
+
*/
|
|
471
|
+
list?: string | string[] | FooterItem | FooterItem[]
|
|
458
472
|
/**
|
|
459
473
|
* 是否展示主题版本信息
|
|
460
474
|
*/
|
package/src/hooks/useOml2d.ts
CHANGED
|
@@ -1,12 +1,77 @@
|
|
|
1
1
|
import { onMounted } from 'vue'
|
|
2
|
+
import type { Options } from 'oh-my-live2d'
|
|
2
3
|
import { useOml2dOptions } from '../composables/config/blog'
|
|
3
4
|
|
|
5
|
+
const defaultModelOptions: any = {
|
|
6
|
+
scale: 0.08,
|
|
7
|
+
position: [-30, 0],
|
|
8
|
+
stageStyle: {
|
|
9
|
+
width: 220
|
|
10
|
+
},
|
|
11
|
+
mobilePosition: [-10, 0],
|
|
12
|
+
mobileScale: 0.05,
|
|
13
|
+
mobileStageStyle: {
|
|
14
|
+
width: 150
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
const defaultOptions: Options = {
|
|
18
|
+
tips: {
|
|
19
|
+
copyTips: {
|
|
20
|
+
duration: 2000,
|
|
21
|
+
message: ['复制成功,感谢您的支持!'],
|
|
22
|
+
},
|
|
23
|
+
style: {
|
|
24
|
+
top: '-50px',
|
|
25
|
+
fontSize: '14px',
|
|
26
|
+
padding: '10px',
|
|
27
|
+
width: '200px'
|
|
28
|
+
},
|
|
29
|
+
mobileStyle: {
|
|
30
|
+
top: '-80px',
|
|
31
|
+
left: '80px',
|
|
32
|
+
fontSize: '14px',
|
|
33
|
+
padding: '4px 10px',
|
|
34
|
+
width: '110px'
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
4
38
|
export function useOml2d() {
|
|
5
39
|
const oml2dOptions = useOml2dOptions()
|
|
6
40
|
onMounted(async () => {
|
|
7
41
|
if (oml2dOptions) {
|
|
8
42
|
const { loadOml2d } = await import('oh-my-live2d')
|
|
9
|
-
loadOml2d(
|
|
43
|
+
loadOml2d({
|
|
44
|
+
...defaultOptions,
|
|
45
|
+
...oml2dOptions,
|
|
46
|
+
models: oml2dOptions?.models?.map(model => ({
|
|
47
|
+
...defaultModelOptions,
|
|
48
|
+
...model,
|
|
49
|
+
stageStyle: {
|
|
50
|
+
...defaultModelOptions.stageStyle,
|
|
51
|
+
...model.stageStyle
|
|
52
|
+
},
|
|
53
|
+
mobileStageStyle: {
|
|
54
|
+
...defaultModelOptions.mobileStageStyle,
|
|
55
|
+
...model.mobileStageStyle
|
|
56
|
+
}
|
|
57
|
+
})),
|
|
58
|
+
tips: {
|
|
59
|
+
...defaultOptions.tips,
|
|
60
|
+
...oml2dOptions.tips,
|
|
61
|
+
style: {
|
|
62
|
+
...defaultOptions?.tips?.style,
|
|
63
|
+
...oml2dOptions?.tips?.style
|
|
64
|
+
},
|
|
65
|
+
mobileStyle: {
|
|
66
|
+
...defaultOptions?.tips?.mobileStyle,
|
|
67
|
+
...oml2dOptions?.tips?.mobileStyle
|
|
68
|
+
},
|
|
69
|
+
copyTips: {
|
|
70
|
+
...defaultOptions?.tips?.copyTips,
|
|
71
|
+
...oml2dOptions?.tips?.copyTips
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
})
|
|
10
75
|
}
|
|
11
76
|
})
|
|
12
77
|
}
|
package/src/node.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
patchOptimizeDeps,
|
|
7
7
|
registerMdPlugins,
|
|
8
8
|
} from './utils/node/mdPlugins'
|
|
9
|
-
import { getArticles, patchVPThemeConfig } from './utils/node/theme'
|
|
9
|
+
import { checkConfig, getArticles, patchVPThemeConfig } from './utils/node/theme'
|
|
10
10
|
import { getVitePlugins, registerVitePlugins } from './utils/node/vitePlugins'
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -14,6 +14,9 @@ import { getVitePlugins, registerVitePlugins } from './utils/node/vitePlugins'
|
|
|
14
14
|
* @param cfg 主题配置
|
|
15
15
|
*/
|
|
16
16
|
export function getThemeConfig(cfg?: Partial<Theme.BlogConfig>) {
|
|
17
|
+
// 配置校验
|
|
18
|
+
checkConfig(cfg)
|
|
19
|
+
|
|
17
20
|
// 文章数据
|
|
18
21
|
const pagesData = getArticles(cfg)
|
|
19
22
|
const extraVPConfig: any = {}
|
|
@@ -53,3 +56,15 @@ export function defineConfig(config: UserConfig<Theme.Config>): any {
|
|
|
53
56
|
|
|
54
57
|
// 重新导包 tabsMarkdownPlugin 导出CJS格式支持
|
|
55
58
|
export { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
|
|
59
|
+
|
|
60
|
+
export function footerHTML(footerData: Theme.FooterItem | Theme.FooterItem[]) {
|
|
61
|
+
const data = [footerData || []].flat()
|
|
62
|
+
return data.map((d) => {
|
|
63
|
+
const { icon, text, link } = d
|
|
64
|
+
|
|
65
|
+
return `<span class="footer-item">
|
|
66
|
+
${icon ? `<i>${icon}</i>` : ''}
|
|
67
|
+
${link ? `<a href="${link}" target="_blank" rel="noopener noreferrer">${text}</a>` : `<span>${text}</span>`}
|
|
68
|
+
</span>`
|
|
69
|
+
}).join('')
|
|
70
|
+
}
|