@ansidev-oss/vitepress-theme-ansidev 1.0.10 → 1.0.11
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/dist/client/Sharing-ZrU7YF-x.js +190 -0
- package/dist/client/Swetrix-CM1mbD6X.js +450 -0
- package/dist/client/{VPAlgoliaSearchBox-DXE-LCVf.js → VPAlgoliaSearchBox-BAhNuo7n.js} +1 -1
- package/dist/client/{VPCarbonAds-Czmm53YE.js → VPCarbonAds-CSK7KnIu.js} +1 -1
- package/dist/client/{VPLocalSearchBox-ihwA4uH-.js → VPLocalSearchBox-TYbANUkJ.js} +1 -1
- package/dist/client/composables/index.d.ts +1 -1
- package/dist/client/{index-CZCdwVUW.js → index-C43AnX3f.js} +1623 -1573
- package/dist/client/index-DuYWs0vj.js +265 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.js +7 -2
- package/dist/client/plugins/medium-zoom/index.d.ts +14 -0
- package/dist/client/plugins/sharing/index.d.ts +59 -0
- package/dist/client/plugins/swetrix/index.d.ts +10 -0
- package/dist/client/styles.css +1 -1
- package/dist/client/types/index.d.ts +14 -1
- package/dist/node/composables/index.d.ts +3 -0
- package/dist/node/composables/markdown.d.ts +2 -0
- package/dist/node/composables/route.d.ts +15 -0
- package/dist/node/composables/slug.d.ts +7 -0
- package/dist/node/composables/types.d.ts +7 -0
- package/dist/node/composables.d.mts +4 -2
- package/dist/node/composables.mjs +4 -1
- package/dist/node/config.d.mts +90 -8
- package/dist/node/config.d.ts +45 -0
- package/dist/node/config.mjs +19 -10
- package/dist/shared/composables/index.d.ts +1 -0
- package/package.json +11 -3
- package/src/client/components/DonationWidget.vue +22 -0
- package/src/client/components/Footer.vue +12 -12
- package/src/client/components/SharingWidget.vue +19 -0
- package/src/client/composables/index.ts +1 -1
- package/src/client/index.ts +2 -8
- package/src/client/layouts/Layout.vue +48 -2
- package/src/client/plugins/medium-zoom/index.ts +30 -0
- package/src/client/plugins/sharing/components/Sharing.vue +81 -0
- package/src/client/plugins/sharing/components/SharingButton.vue +115 -0
- package/src/client/plugins/sharing/index.ts +76 -0
- package/src/client/plugins/swetrix/components/Swetrix.vue +43 -0
- package/src/client/plugins/swetrix/index.ts +11 -0
- package/src/client/types/index.ts +14 -1
- package/src/node/composables/slug.ts +3 -13
- package/src/node/config.ts +22 -13
- package/src/shared/composables/index.ts +1 -0
- /package/dist/{client/composables/slug.d.ts → shared/composables/useSlug.d.ts} +0 -0
- /package/src/{client/composables/slug.ts → shared/composables/useSlug.ts} +0 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { DefaultTheme } from 'vitepress/theme';
|
|
2
2
|
import type { DonationPluginConfig } from '../plugins/donation';
|
|
3
3
|
import type { GoogleAnalyticsOptions } from '../plugins/google-analytics';
|
|
4
|
+
import type { MediumZoomPluginConfig } from '../plugins/medium-zoom';
|
|
5
|
+
import type { SharingPluginConfig } from '../plugins/sharing';
|
|
6
|
+
import type { SwetrixOptions } from '../plugins/swetrix';
|
|
4
7
|
export interface ThemeConfig extends DefaultTheme.Config {
|
|
5
8
|
/**
|
|
6
9
|
* The site URL.
|
|
@@ -8,11 +11,21 @@ export interface ThemeConfig extends DefaultTheme.Config {
|
|
|
8
11
|
* @default process.env.VITE_BASE_URL
|
|
9
12
|
*/
|
|
10
13
|
siteURL?: string;
|
|
11
|
-
googleAnalytics?: GoogleAnalyticsOptions;
|
|
12
14
|
donation?: DonationPluginConfig;
|
|
15
|
+
googleAnalytics?: GoogleAnalyticsOptions;
|
|
16
|
+
mediumZoom?: MediumZoomPluginConfig;
|
|
17
|
+
sharing?: SharingPluginConfig;
|
|
18
|
+
swetrix?: SwetrixOptions;
|
|
19
|
+
/**
|
|
20
|
+
* The footer configuration.
|
|
21
|
+
*/
|
|
22
|
+
themeFooter?: DefaultTheme.Footer;
|
|
13
23
|
}
|
|
14
24
|
export type { DonationPluginConfig } from '../plugins/donation';
|
|
15
25
|
export type { GoogleAnalyticsOptions } from '../plugins/google-analytics';
|
|
26
|
+
export type { MediumZoomPluginConfig } from '../plugins/medium-zoom';
|
|
27
|
+
export type { SharingPluginConfig } from '../plugins/sharing';
|
|
28
|
+
export type { SwetrixOptions } from '../plugins/swetrix';
|
|
16
29
|
export interface Post {
|
|
17
30
|
type: string;
|
|
18
31
|
title: string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Pattern } from './types';
|
|
2
|
+
export declare const useMarkdownFrontmatterRoute: (pattern: Pattern, frontmatterKey: string, excerptSeparator?: string) => {
|
|
3
|
+
paths(): {
|
|
4
|
+
params: {
|
|
5
|
+
slug: string;
|
|
6
|
+
};
|
|
7
|
+
}[];
|
|
8
|
+
};
|
|
9
|
+
export declare const useArchiveRoute: (pattern: Pattern, excerptSeparator?: string) => {
|
|
10
|
+
paths(): {
|
|
11
|
+
params: {
|
|
12
|
+
slug: string;
|
|
13
|
+
};
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Pattern, StringOrFrontmatterToString } from './types';
|
|
2
|
+
export declare const useSlugFromMarkdownFrontMatter: (pattern: Pattern, frontmatterKeyOrMappingFn: StringOrFrontmatterToString, excerptSeparator?: string) => {
|
|
3
|
+
params: {
|
|
4
|
+
slug: string;
|
|
5
|
+
};
|
|
6
|
+
}[];
|
|
7
|
+
export { useSlug, useSlugFilter } from '../../shared/composables';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type Pattern = string | string[];
|
|
2
|
+
export type Frontmatter = Record<string, unknown> & {
|
|
3
|
+
date?: string;
|
|
4
|
+
excerpt?: string;
|
|
5
|
+
};
|
|
6
|
+
export type FrontmatterToString = (frontmatter: Frontmatter) => string;
|
|
7
|
+
export type StringOrFrontmatterToString = string | FrontmatterToString;
|
|
@@ -18,12 +18,14 @@ declare const useArchiveRoute: (pattern: Pattern, excerptSeparator?: string) =>
|
|
|
18
18
|
paths(): any;
|
|
19
19
|
};
|
|
20
20
|
//#endregion
|
|
21
|
-
//#region src/
|
|
21
|
+
//#region src/shared/composables/useSlug.d.ts
|
|
22
22
|
declare const useSlug: (str: string) => string;
|
|
23
23
|
declare const useSlugFilter: (slug: string) => (str: string) => boolean;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/node/composables/slug.d.ts
|
|
24
26
|
declare const useSlugFromMarkdownFrontMatter: (pattern: Pattern, frontmatterKeyOrMappingFn: StringOrFrontmatterToString, excerptSeparator?: string) => {
|
|
25
27
|
params: {
|
|
26
|
-
slug:
|
|
28
|
+
slug: any;
|
|
27
29
|
};
|
|
28
30
|
}[];
|
|
29
31
|
//#endregion
|
|
@@ -18,11 +18,14 @@ const useMarkdownFrontmatter = (pattern, excerptSeparator = "---") => {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
//#endregion
|
|
21
|
-
//#region src/
|
|
21
|
+
//#region src/shared/composables/useSlug.ts
|
|
22
22
|
const useSlug = (str) => {
|
|
23
23
|
return str.replace(/#/, "-sharp-").replace(/\./, "-dot-").replace(/-$/, "").toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/đ/g, "d").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
24
24
|
};
|
|
25
25
|
const useSlugFilter = (slug) => (str) => useSlug(str) === slug;
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/node/composables/slug.ts
|
|
26
29
|
const useSlugFromMarkdownFrontMatter = (pattern, frontmatterKeyOrMappingFn, excerptSeparator = "---") => {
|
|
27
30
|
const frontMatters = useMarkdownFrontmatter(pattern, excerptSeparator);
|
|
28
31
|
const _frontmatterMappingFn = typeof frontmatterKeyOrMappingFn === "string" ? (frontMatter) => frontMatter[frontmatterKeyOrMappingFn] : frontmatterKeyOrMappingFn;
|
package/dist/node/config.d.mts
CHANGED
|
@@ -1,8 +1,91 @@
|
|
|
1
|
+
import { UserConfig } from "vitepress";
|
|
2
|
+
import { DefaultTheme } from "vitepress/theme";
|
|
3
|
+
import * as Swetrix from "swetrix";
|
|
4
|
+
|
|
5
|
+
//#region src/client/plugins/donation/index.d.ts
|
|
6
|
+
declare interface DonationPluginConfig {
|
|
7
|
+
buymeacoffee?: string;
|
|
8
|
+
kofi?: string;
|
|
9
|
+
paypal?: string;
|
|
10
|
+
custom?: {
|
|
11
|
+
[key: string]: CustomDonationConfig;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
declare interface CustomDonationBaseConfig {
|
|
15
|
+
donationBaseUrl: string;
|
|
16
|
+
donationButtonImage: string;
|
|
17
|
+
donationButtonStyle?: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
declare interface CustomDonationConfig extends CustomDonationBaseConfig {
|
|
20
|
+
donationId: string;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/client/plugins/google-analytics/index.d.ts
|
|
24
|
+
interface GoogleAnalyticsOptions {
|
|
25
|
+
/**
|
|
26
|
+
* The Google Analytics ID.
|
|
27
|
+
*
|
|
28
|
+
* @default process.env.VITE_GA_ID
|
|
29
|
+
*/
|
|
30
|
+
id: string;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/client/plugins/medium-zoom/index.d.ts
|
|
34
|
+
declare module 'medium-zoom' {
|
|
35
|
+
interface Zoom {
|
|
36
|
+
refresh: (selector?: string) => void;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
type MediumZoomPluginConfig = {
|
|
40
|
+
selector: string;
|
|
41
|
+
zoomOptions?: string;
|
|
42
|
+
delay?: number;
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/client/plugins/sharing/index.d.ts
|
|
46
|
+
declare interface SharingPluginConfig {
|
|
47
|
+
networks?: string[];
|
|
48
|
+
displayMode?: string;
|
|
49
|
+
buttonSize?: number;
|
|
50
|
+
iconSize?: number;
|
|
51
|
+
iconStyle?: string;
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/client/plugins/swetrix/index.d.ts
|
|
55
|
+
interface SwetrixOptions {
|
|
56
|
+
/**
|
|
57
|
+
* The Swetrix ID.
|
|
58
|
+
*
|
|
59
|
+
* @default process.env.VITE_SWETRIX_ID
|
|
60
|
+
*/
|
|
61
|
+
id: string;
|
|
62
|
+
options?: Swetrix.LibOptions;
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/client/types/index.d.ts
|
|
66
|
+
interface ThemeConfig extends DefaultTheme.Config {
|
|
67
|
+
/**
|
|
68
|
+
* The site URL.
|
|
69
|
+
*
|
|
70
|
+
* @default process.env.VITE_BASE_URL
|
|
71
|
+
*/
|
|
72
|
+
siteURL?: string;
|
|
73
|
+
donation?: DonationPluginConfig;
|
|
74
|
+
googleAnalytics?: GoogleAnalyticsOptions;
|
|
75
|
+
mediumZoom?: MediumZoomPluginConfig;
|
|
76
|
+
sharing?: SharingPluginConfig;
|
|
77
|
+
swetrix?: SwetrixOptions;
|
|
78
|
+
/**
|
|
79
|
+
* The footer configuration.
|
|
80
|
+
*/
|
|
81
|
+
themeFooter?: DefaultTheme.Footer;
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
1
84
|
//#region src/node/config.d.ts
|
|
2
85
|
/**
|
|
3
86
|
* @type {import('vitepress').UserConfig}
|
|
4
87
|
*/
|
|
5
|
-
declare const
|
|
88
|
+
declare const baseConfig: {
|
|
6
89
|
themeConfig: {
|
|
7
90
|
siteURL: string;
|
|
8
91
|
googleAnalytics: {
|
|
@@ -34,13 +117,12 @@ declare const config: {
|
|
|
34
117
|
};
|
|
35
118
|
};
|
|
36
119
|
};
|
|
37
|
-
resolve: {
|
|
38
|
-
alias: {
|
|
39
|
-
find: RegExp;
|
|
40
|
-
replacement: string;
|
|
41
|
-
}[];
|
|
42
|
-
};
|
|
43
120
|
};
|
|
44
121
|
};
|
|
122
|
+
/**
|
|
123
|
+
* Helper function to define theme configuration with proper typing
|
|
124
|
+
* Note: TailwindCSS plugin should be added in vite.config.ts, not here
|
|
125
|
+
*/
|
|
126
|
+
declare function defineWithDefaultThemeConfig(config?: UserConfig<ThemeConfig>): UserConfig<ThemeConfig>;
|
|
45
127
|
//#endregion
|
|
46
|
-
export {
|
|
128
|
+
export { baseConfig as default, defineWithDefaultThemeConfig };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { UserConfig } from 'vitepress';
|
|
2
|
+
import type { ThemeConfig } from '../client/types';
|
|
3
|
+
/**
|
|
4
|
+
* @type {import('vitepress').UserConfig}
|
|
5
|
+
*/
|
|
6
|
+
declare const baseConfig: {
|
|
7
|
+
themeConfig: {
|
|
8
|
+
siteURL: string;
|
|
9
|
+
googleAnalytics: {
|
|
10
|
+
id: string;
|
|
11
|
+
};
|
|
12
|
+
search: {
|
|
13
|
+
provider: string;
|
|
14
|
+
options: {
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} src
|
|
17
|
+
* @param {import('vitepress').MarkdownEnv} env
|
|
18
|
+
* @param {import('markdown-it')} md
|
|
19
|
+
*/
|
|
20
|
+
_render(src: any, env: any, md: any): Promise<string>;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
vite: {
|
|
25
|
+
ssr: {
|
|
26
|
+
noExternal: string[];
|
|
27
|
+
};
|
|
28
|
+
optimizeDeps: {
|
|
29
|
+
exclude: string[];
|
|
30
|
+
};
|
|
31
|
+
css: {
|
|
32
|
+
preprocessorOptions: {
|
|
33
|
+
scss: {
|
|
34
|
+
api: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Helper function to define theme configuration with proper typing
|
|
42
|
+
* Note: TailwindCSS plugin should be added in vite.config.ts, not here
|
|
43
|
+
*/
|
|
44
|
+
export declare function defineWithDefaultThemeConfig(config?: UserConfig<ThemeConfig>): UserConfig<ThemeConfig>;
|
|
45
|
+
export default baseConfig;
|
package/dist/node/config.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { loadEnv } from "vitepress";
|
|
1
|
+
import { loadEnv, mergeConfig } from "vitepress";
|
|
3
2
|
|
|
4
3
|
//#region src/node/config.ts
|
|
5
4
|
process.env.VITE_EXTRA_EXTENSIONS = "rss";
|
|
@@ -12,11 +11,11 @@ const siteURL = env.VITE_BASE_URL;
|
|
|
12
11
|
*
|
|
13
12
|
* It runs in Node.js.
|
|
14
13
|
*/
|
|
15
|
-
const deps = ["vitepress-theme-ansidev"];
|
|
14
|
+
const deps = ["@ansidev-oss/vitepress-theme-ansidev"];
|
|
16
15
|
/**
|
|
17
16
|
* @type {import('vitepress').UserConfig}
|
|
18
17
|
*/
|
|
19
|
-
const
|
|
18
|
+
const baseConfig = {
|
|
20
19
|
themeConfig: {
|
|
21
20
|
siteURL,
|
|
22
21
|
googleAnalytics: { id: env.VITE_GA_ID },
|
|
@@ -35,13 +34,23 @@ const config = {
|
|
|
35
34
|
vite: {
|
|
36
35
|
ssr: { noExternal: deps },
|
|
37
36
|
optimizeDeps: { exclude: deps },
|
|
38
|
-
css: { preprocessorOptions: { scss: { api: "modern-compiler" } } }
|
|
39
|
-
resolve: { alias: [{
|
|
40
|
-
find: /^.*\/VPFooter\.vue$/,
|
|
41
|
-
replacement: fileURLToPath(new URL("./components/EmptyFooter.vue", import.meta.url))
|
|
42
|
-
}] }
|
|
37
|
+
css: { preprocessorOptions: { scss: { api: "modern-compiler" } } }
|
|
43
38
|
}
|
|
44
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Helper function to define theme configuration with proper typing
|
|
42
|
+
* Note: TailwindCSS plugin should be added in vite.config.ts, not here
|
|
43
|
+
*/
|
|
44
|
+
function defineWithDefaultThemeConfig(config = {}) {
|
|
45
|
+
if (config.themeConfig?.footer) {
|
|
46
|
+
config.themeConfig = {
|
|
47
|
+
...config.themeConfig,
|
|
48
|
+
themeFooter: config.themeConfig.footer
|
|
49
|
+
};
|
|
50
|
+
delete config.themeConfig.footer;
|
|
51
|
+
}
|
|
52
|
+
return mergeConfig(baseConfig, config);
|
|
53
|
+
}
|
|
45
54
|
|
|
46
55
|
//#endregion
|
|
47
|
-
export {
|
|
56
|
+
export { baseConfig as default, defineWithDefaultThemeConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useSlug';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ansidev-oss/vitepress-theme-ansidev",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "The VitePress theme for ansidev's blog",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/node/index.js",
|
|
@@ -55,12 +55,15 @@
|
|
|
55
55
|
"@types/node": "^25.2.3",
|
|
56
56
|
"@vitejs/plugin-vue": "^6.0.4",
|
|
57
57
|
"autoprefixer": "^10.4.24",
|
|
58
|
+
"concurrently": "^9.2.1",
|
|
58
59
|
"glob": "^13.0.5",
|
|
59
60
|
"gray-matter": "^4.0.3",
|
|
61
|
+
"medium-zoom": "^1.1.0",
|
|
60
62
|
"postcss": "^8.5.6",
|
|
61
63
|
"prettier": "^3.8.1",
|
|
62
64
|
"rimraf": "^6.1.3",
|
|
63
65
|
"rollup-plugin-copy": "^3.5.0",
|
|
66
|
+
"swetrix": "^4.1.0",
|
|
64
67
|
"tailwindcss": "^4.1.18",
|
|
65
68
|
"ts-node": "^10.9.2",
|
|
66
69
|
"tsdown": "^0.20.3",
|
|
@@ -71,6 +74,9 @@
|
|
|
71
74
|
"vue-tsc": "^3.2.4"
|
|
72
75
|
},
|
|
73
76
|
"peerDependencies": {
|
|
77
|
+
"@iconify/vue": "^5.0.0",
|
|
78
|
+
"medium-zoom": "^1.1.0",
|
|
79
|
+
"swetrix": "^4.1.0",
|
|
74
80
|
"vitepress": "^2.0.0-alpha.16",
|
|
75
81
|
"vue": "^3.5.28"
|
|
76
82
|
},
|
|
@@ -78,10 +84,12 @@
|
|
|
78
84
|
"typecheck": "tsc --noEmit",
|
|
79
85
|
"lint:check": "biome check",
|
|
80
86
|
"lint": "biome check --write",
|
|
81
|
-
"dev": "vite build --watch",
|
|
87
|
+
"dev:client": "vite build --watch",
|
|
88
|
+
"dev:node": "tsdown --watch",
|
|
89
|
+
"dev": "concurrently --kill-others \"pnpm dev:client\" \"pnpm dev:node\"",
|
|
82
90
|
"clean": "rimraf dist",
|
|
83
91
|
"build:client": "vite build && tsc --emitDeclarationOnly",
|
|
84
92
|
"build:node": "tsdown",
|
|
85
|
-
"build": "pnpm clean && pnpm build:client
|
|
93
|
+
"build": "pnpm clean && concurrently \"pnpm build:client\" \"pnpm build:node\""
|
|
86
94
|
}
|
|
87
95
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useData } from 'vitepress'
|
|
3
|
+
import { defineAsyncComponent } from 'vue'
|
|
4
|
+
|
|
5
|
+
const { theme } = useData()
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
direction?: 'horizontal' | 'vertical'
|
|
9
|
+
}>()
|
|
10
|
+
|
|
11
|
+
const directionCssClass = props.direction === 'vertical' ? 'space-y-4' : 'space-x-4'
|
|
12
|
+
|
|
13
|
+
const Donation = theme.value.donation
|
|
14
|
+
? defineAsyncComponent(() => import('../plugins/donation/components/Donation.vue'))
|
|
15
|
+
: () => null
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<div class="flex flex-wrap py-4 items-center justify-center" :class="directionCssClass">
|
|
20
|
+
<Donation :donation="theme.donation" />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -2,44 +2,44 @@
|
|
|
2
2
|
import { useData } from 'vitepress'
|
|
3
3
|
import { useLayout } from 'vitepress/theme'
|
|
4
4
|
import { computed, defineAsyncComponent } from 'vue'
|
|
5
|
+
import DonationWidget from './DonationWidget.vue'
|
|
5
6
|
|
|
6
7
|
const { theme, frontmatter } = useData()
|
|
7
|
-
const { hasSidebar } = useLayout()
|
|
8
|
+
const { hasSidebar, hasAside } = useLayout()
|
|
8
9
|
|
|
9
10
|
const copyright = computed(() => {
|
|
10
|
-
return typeof theme.value.
|
|
11
|
-
? theme.value.
|
|
12
|
-
: theme.value.
|
|
11
|
+
return typeof theme.value.themeFooter.copyright === 'string'
|
|
12
|
+
? theme.value.themeFooter.copyright.replace(/#\{present\}/g, new Date().getFullYear().toString())
|
|
13
|
+
: theme.value.themeFooter.copyright
|
|
13
14
|
})
|
|
14
15
|
|
|
15
16
|
const GoogleAnalytics = theme.value.googleAnalytics
|
|
16
17
|
? defineAsyncComponent(() => import('../plugins/google-analytics/components/GoogleAnalytics.vue'))
|
|
17
18
|
: () => null
|
|
18
19
|
|
|
19
|
-
const
|
|
20
|
-
? defineAsyncComponent(() => import('../plugins/
|
|
20
|
+
const Swetrix = theme.value.swetrix
|
|
21
|
+
? defineAsyncComponent(() => import('../plugins/swetrix/components/Swetrix.vue'))
|
|
21
22
|
: () => null
|
|
22
23
|
</script>
|
|
23
24
|
|
|
24
25
|
<template>
|
|
25
|
-
<
|
|
26
|
-
<Donation :donation="theme.donation" />
|
|
27
|
-
</div>
|
|
26
|
+
<DonationWidget v-if="!hasAside" direction="horizontal" />
|
|
28
27
|
<footer
|
|
29
|
-
v-if="theme.
|
|
28
|
+
v-if="theme.themeFooter && frontmatter.themeFooter !== false"
|
|
30
29
|
class="VPFooter"
|
|
31
30
|
:class="{ 'has-sidebar': hasSidebar }"
|
|
32
31
|
>
|
|
33
32
|
<div class="container">
|
|
34
33
|
<p
|
|
35
|
-
v-if="theme.
|
|
34
|
+
v-if="theme.themeFooter.message"
|
|
36
35
|
class="message"
|
|
37
|
-
v-html="theme.
|
|
36
|
+
v-html="theme.themeFooter.message"
|
|
38
37
|
></p>
|
|
39
38
|
<p v-if="copyright" class="copyright" v-html="copyright"></p>
|
|
40
39
|
</div>
|
|
41
40
|
</footer>
|
|
42
41
|
<GoogleAnalytics :google-analytics="theme.googleAnalytics" />
|
|
42
|
+
<Swetrix :swetrix="theme.swetrix" />
|
|
43
43
|
</template>
|
|
44
44
|
|
|
45
45
|
<style scoped>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useData, useRoute } from 'vitepress'
|
|
3
|
+
import { defineAsyncComponent } from 'vue'
|
|
4
|
+
|
|
5
|
+
const route = useRoute()
|
|
6
|
+
|
|
7
|
+
const { theme, frontmatter, page } = useData()
|
|
8
|
+
|
|
9
|
+
const Sharing = theme.value.sharing
|
|
10
|
+
? defineAsyncComponent(() => import('../plugins/sharing/components/Sharing.vue'))
|
|
11
|
+
: () => null
|
|
12
|
+
|
|
13
|
+
const postURL = new URL(route.path, theme.value.siteURL).href
|
|
14
|
+
const postTitle = frontmatter.value.title || page.value.title
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<Sharing :url="postURL" :text="postTitle" />
|
|
19
|
+
</template>
|
package/src/client/index.ts
CHANGED
|
@@ -31,13 +31,7 @@ const theme: Theme = {
|
|
|
31
31
|
},
|
|
32
32
|
} satisfies Theme
|
|
33
33
|
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
GoogleAnalyticsOptions,
|
|
37
|
-
Post,
|
|
38
|
-
PostDate,
|
|
39
|
-
Project,
|
|
40
|
-
ThemeConfig,
|
|
41
|
-
} from './types'
|
|
34
|
+
export * from './composables'
|
|
35
|
+
export type * from './types'
|
|
42
36
|
|
|
43
37
|
export default theme
|
|
@@ -1,11 +1,37 @@
|
|
|
1
1
|
<script setup lang='ts'>
|
|
2
|
-
import { useData } from 'vitepress'
|
|
2
|
+
import { useData, useRoute } from 'vitepress'
|
|
3
3
|
import DefaultTheme from 'vitepress/theme'
|
|
4
|
+
import { onMounted, watch } from 'vue'
|
|
5
|
+
import DonationWidget from '../components/DonationWidget.vue'
|
|
4
6
|
import Footer from '../components/Footer.vue'
|
|
5
7
|
import LocaleSwitcher from '../components/LocaleSwitcher.vue'
|
|
8
|
+
import SharingWidget from '../components/SharingWidget.vue'
|
|
9
|
+
import type { MediumZoomPluginConfig } from '../plugins/medium-zoom'
|
|
6
10
|
|
|
7
11
|
const { Layout: DefaultLayout } = DefaultTheme
|
|
8
|
-
const { frontmatter } = useData()
|
|
12
|
+
const { frontmatter, theme } = useData()
|
|
13
|
+
const route = useRoute()
|
|
14
|
+
let mediumZoomModule = null
|
|
15
|
+
if (theme.value.mediumZoom) {
|
|
16
|
+
mediumZoomModule = import('../plugins/medium-zoom')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const initMediumZoom = async () => {
|
|
20
|
+
if (mediumZoomModule) {
|
|
21
|
+
const { useMediumZoom } = await mediumZoomModule
|
|
22
|
+
useMediumZoom(theme.value.mediumZoom as MediumZoomPluginConfig)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
onMounted(initMediumZoom)
|
|
27
|
+
watch(
|
|
28
|
+
() => route.path,
|
|
29
|
+
(newPath, oldPath) => {
|
|
30
|
+
if (newPath !== oldPath) {
|
|
31
|
+
initMediumZoom()
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
)
|
|
9
35
|
</script>
|
|
10
36
|
|
|
11
37
|
<template>
|
|
@@ -18,8 +44,28 @@ const { frontmatter } = useData()
|
|
|
18
44
|
<template #nav-bar-content-after>
|
|
19
45
|
<LocaleSwitcher />
|
|
20
46
|
</template>
|
|
47
|
+
<template #aside-outline-after>
|
|
48
|
+
<SharingWidget />
|
|
49
|
+
</template>
|
|
50
|
+
<template #aside-ads-before>
|
|
51
|
+
<DonationWidget direction="vertical" />
|
|
52
|
+
</template>
|
|
21
53
|
<template #layout-bottom>
|
|
22
54
|
<Footer />
|
|
23
55
|
</template>
|
|
24
56
|
</DefaultLayout>
|
|
25
57
|
</template>
|
|
58
|
+
<style lang="css">
|
|
59
|
+
:root {
|
|
60
|
+
--vp-z-index-aside: 25;
|
|
61
|
+
}
|
|
62
|
+
.VPDoc.has-aside .aside-container {
|
|
63
|
+
z-index: var(--vp-z-index-aside);
|
|
64
|
+
}
|
|
65
|
+
.medium-zoom--opened .medium-zoom-overlay {
|
|
66
|
+
z-index: calc(var(--vp-z-index-aside) + 1);
|
|
67
|
+
}
|
|
68
|
+
.medium-zoom-image--opened {
|
|
69
|
+
z-index: calc(var(--vp-z-index-aside) + 2);
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import mediumZoom from 'medium-zoom'
|
|
2
|
+
|
|
3
|
+
declare module 'medium-zoom' {
|
|
4
|
+
interface Zoom {
|
|
5
|
+
refresh: (selector?: string) => void
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type MediumZoomPluginConfig = {
|
|
10
|
+
selector: string
|
|
11
|
+
zoomOptions?: string
|
|
12
|
+
delay?: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Inject medium zoom instance
|
|
17
|
+
*/
|
|
18
|
+
export const useMediumZoom = (config: MediumZoomPluginConfig): void => {
|
|
19
|
+
if (!config.selector) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const zoom = mediumZoom(config.zoomOptions)
|
|
24
|
+
zoom.refresh = (sel = config.selector) => {
|
|
25
|
+
zoom.detach()
|
|
26
|
+
zoom.attach(sel)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setTimeout(() => zoom.refresh(config.selector), config.delay || 1000)
|
|
30
|
+
}
|