vitepress-plugin-announcement 0.1.2 → 0.1.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/README.md +44 -0
- package/dist/components/Announcement.vue +51 -29
- package/dist/index.d.mts +20 -0
- package/dist/index.d.ts +20 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -104,6 +104,7 @@ AnnouncementPlugin({
|
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
### 修改样式
|
|
107
|
+
行内样式
|
|
107
108
|
```js
|
|
108
109
|
AnnouncementPlugin({
|
|
109
110
|
title: '公告',
|
|
@@ -119,12 +120,50 @@ AnnouncementPlugin({
|
|
|
119
120
|
})
|
|
120
121
|
```
|
|
121
122
|
|
|
123
|
+
内部样式表
|
|
124
|
+
```js
|
|
125
|
+
AnnouncementPlugin({
|
|
126
|
+
style: `.theme-blog-popover a {
|
|
127
|
+
color: var(--vp-c-brand-2);
|
|
128
|
+
}
|
|
129
|
+
`
|
|
130
|
+
})
|
|
131
|
+
```
|
|
132
|
+
### markdown
|
|
133
|
+
`content`,`title` 字段支持基础 markdown 语法
|
|
134
|
+
* `#` 标题
|
|
135
|
+
* `[链接](url)` 链接
|
|
136
|
+
* `**strong**` 加粗
|
|
137
|
+
* `*italic*` 斜体
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
AnnouncementPlugin({
|
|
141
|
+
title: '公告',
|
|
142
|
+
body: [
|
|
143
|
+
{
|
|
144
|
+
type: 'text',
|
|
145
|
+
content: '**加粗的内容 *斜体[链接](url)***'
|
|
146
|
+
},
|
|
147
|
+
]
|
|
148
|
+
})
|
|
149
|
+
```
|
|
150
|
+
|
|
122
151
|
## 完整配置
|
|
123
152
|
```ts
|
|
124
153
|
import type { Ref } from 'vue'
|
|
125
154
|
import type { Route } from 'vitepress'
|
|
126
155
|
|
|
127
156
|
export interface AnnouncementOptions {
|
|
157
|
+
/**
|
|
158
|
+
* 自定义样式类名
|
|
159
|
+
* @example
|
|
160
|
+
* ```css
|
|
161
|
+
* .theme-blog-popover a {
|
|
162
|
+
* color: var(--vp-c-brand-2);
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
style?: string
|
|
128
167
|
/**
|
|
129
168
|
* 公告标题
|
|
130
169
|
*/
|
|
@@ -188,6 +227,11 @@ export interface AnnouncementOptions {
|
|
|
188
227
|
* @param to 切换到的目标路由
|
|
189
228
|
*/
|
|
190
229
|
onRouteChanged?: (to: Route, show: Ref<boolean>) => void
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* 国际化
|
|
233
|
+
*/
|
|
234
|
+
locales?: Record<string, Omit<AnnouncementOptions, 'locales'>>
|
|
191
235
|
}
|
|
192
236
|
|
|
193
237
|
export declare namespace Announcement {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { computed, h,
|
|
3
|
-
import { useRoute, useRouter } from 'vitepress'
|
|
2
|
+
import { computed, h, ref, watch } from 'vue'
|
|
3
|
+
import { useData, useRoute, useRouter } from 'vitepress'
|
|
4
4
|
import type { Announcement, AnnouncementOptions } from 'vitepress-plugin-announcement'
|
|
5
5
|
|
|
6
6
|
// @ts-expect-error
|
|
@@ -9,26 +9,28 @@ import AnnouncementButton from './AnnouncementButton.vue'
|
|
|
9
9
|
import AnnouncementIcon from './AnnouncementIcon.vue'
|
|
10
10
|
import { inBrowser, parseStringStyle, useDebounceFn, useWindowSize } from './util'
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const { localeIndex } = useData()
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const popoverProps = computed<AnnouncementOptions>(() => ({ ...announcementOptions, ...announcementOptions?.locales?.[localeIndex.value] }))
|
|
15
|
+
|
|
16
|
+
const show = ref((popoverProps.value?.duration ?? 0) >= 0)
|
|
15
17
|
|
|
16
18
|
const bodyContent = computed(() => {
|
|
17
|
-
return popoverProps?.body || []
|
|
19
|
+
return popoverProps.value?.body || []
|
|
18
20
|
})
|
|
19
21
|
|
|
20
22
|
const footerContent = computed(() => {
|
|
21
|
-
return popoverProps?.footer || []
|
|
23
|
+
return popoverProps.value?.footer || []
|
|
22
24
|
})
|
|
23
|
-
const storageKey =
|
|
24
|
-
const closeFlag = `${storageKey}-close`
|
|
25
|
+
const storageKey = computed(() => `vitepress-plugin-announcement-${localeIndex.value}`)
|
|
26
|
+
const closeFlag = computed(() => `${storageKey.value}-close`)
|
|
25
27
|
|
|
26
28
|
// 移动端最小化
|
|
27
29
|
const { width } = useWindowSize()
|
|
28
30
|
const router = useRouter()
|
|
29
31
|
const route = useRoute()
|
|
30
|
-
|
|
31
|
-
if (!popoverProps?.title) {
|
|
32
|
+
watch(popoverProps, () => {
|
|
33
|
+
if (!popoverProps.value?.title) {
|
|
32
34
|
return
|
|
33
35
|
}
|
|
34
36
|
|
|
@@ -37,53 +39,70 @@ onMounted(() => {
|
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
// 取旧值
|
|
40
|
-
const oldValue = localStorage.getItem(storageKey)
|
|
41
|
-
const newValue = JSON.stringify(popoverProps)
|
|
42
|
-
localStorage.setItem(storageKey, newValue)
|
|
42
|
+
const oldValue = localStorage.getItem(storageKey.value)
|
|
43
|
+
const newValue = JSON.stringify(popoverProps.value)
|
|
44
|
+
localStorage.setItem(storageKey.value, newValue)
|
|
43
45
|
|
|
44
46
|
// 移动端最小化
|
|
45
|
-
if (width.value < 768 && popoverProps?.mobileMinify) {
|
|
47
|
+
if (width.value < 768 && popoverProps.value?.mobileMinify) {
|
|
46
48
|
show.value = false
|
|
47
49
|
return
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
// >= 0 每次都展示,区别是否自动消失
|
|
51
|
-
if (Number(popoverProps?.duration ?? '') >= 0) {
|
|
53
|
+
if (Number(popoverProps.value?.duration ?? '') >= 0) {
|
|
52
54
|
show.value = true
|
|
53
|
-
if (popoverProps?.duration) {
|
|
55
|
+
if (popoverProps.value?.duration) {
|
|
54
56
|
setTimeout(() => {
|
|
55
57
|
show.value = false
|
|
56
|
-
}, popoverProps?.duration)
|
|
58
|
+
}, popoverProps.value?.duration)
|
|
57
59
|
}
|
|
58
60
|
return
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
if (oldValue !== newValue && popoverProps?.duration === -1) {
|
|
63
|
+
if (oldValue !== newValue && popoverProps.value?.duration === -1) {
|
|
62
64
|
// 当做新值处理
|
|
63
65
|
show.value = true
|
|
64
|
-
localStorage.removeItem(closeFlag)
|
|
66
|
+
localStorage.removeItem(closeFlag.value)
|
|
65
67
|
return
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
// 新旧相等,判断是否点击过close,没点击关闭依然展示
|
|
69
|
-
if (oldValue === newValue && popoverProps?.duration === -1 && !localStorage.getItem(closeFlag)) {
|
|
71
|
+
if (oldValue === newValue && popoverProps.value?.duration === -1 && !localStorage.getItem(closeFlag.value)) {
|
|
70
72
|
show.value = true
|
|
71
73
|
}
|
|
72
|
-
})
|
|
74
|
+
}, { immediate: true })
|
|
73
75
|
|
|
74
76
|
const onAfterRouteChanged = useDebounceFn(() => {
|
|
75
|
-
popoverProps?.onRouteChanged?.(route, show)
|
|
77
|
+
popoverProps.value?.onRouteChanged?.(route, show)
|
|
76
78
|
}, 10)
|
|
77
79
|
|
|
78
80
|
watch(route, onAfterRouteChanged, { immediate: true })
|
|
79
81
|
|
|
80
82
|
function handleClose() {
|
|
81
83
|
show.value = false
|
|
82
|
-
if (popoverProps?.duration === -1) {
|
|
83
|
-
localStorage.setItem(closeFlag, `${+new Date()}`)
|
|
84
|
+
if (popoverProps.value?.duration === -1) {
|
|
85
|
+
localStorage.setItem(closeFlag.value, `${+new Date()}`)
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
|
|
89
|
+
function parseMarkdownToHtml(markdown: string): string {
|
|
90
|
+
const rules = [
|
|
91
|
+
{ regex: /###### (.*$)/gim, replacement: '<h6>$1</h6>' },
|
|
92
|
+
{ regex: /##### (.*$)/gim, replacement: '<h5>$1</h5>' },
|
|
93
|
+
{ regex: /#### (.*$)/gim, replacement: '<h4>$1</h4>' },
|
|
94
|
+
{ regex: /### (.*$)/gim, replacement: '<h3>$1</h3>' },
|
|
95
|
+
{ regex: /## (.*$)/gim, replacement: '<h2>$1</h2>' },
|
|
96
|
+
{ regex: /# (.*$)/gim, replacement: '<h1>$1</h1>' },
|
|
97
|
+
{ regex: /\*\*(.*)\*\*/gim, replacement: '<b>$1</b>' },
|
|
98
|
+
{ regex: /\*(.*)\*/gim, replacement: '<i>$1</i>' },
|
|
99
|
+
{ regex: /\[(.*?)\]\((.*?)\)/gim, replacement: '<a href="$2">$1</a>' },
|
|
100
|
+
{ regex: /\n$/gim, replacement: '<br />' },
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
return rules.reduce((acc, rule) => acc.replace(rule.regex, rule.replacement), markdown)
|
|
104
|
+
}
|
|
105
|
+
|
|
87
106
|
function PopoverValue(props: { key: number; item: Announcement.Value },
|
|
88
107
|
{ slots }: any) {
|
|
89
108
|
const { key, item } = props
|
|
@@ -91,18 +110,18 @@ function PopoverValue(props: { key: number; item: Announcement.Value },
|
|
|
91
110
|
return h(
|
|
92
111
|
'h4',
|
|
93
112
|
{
|
|
94
|
-
style: parseStringStyle(item.style || '')
|
|
113
|
+
style: parseStringStyle(item.style || ''),
|
|
114
|
+
innerHTML: parseMarkdownToHtml(item.content),
|
|
95
115
|
},
|
|
96
|
-
item.content
|
|
97
116
|
)
|
|
98
117
|
}
|
|
99
118
|
if (item.type === 'text') {
|
|
100
119
|
return h(
|
|
101
120
|
'p',
|
|
102
121
|
{
|
|
103
|
-
style: parseStringStyle(item.style || '')
|
|
122
|
+
style: parseStringStyle(item.style || ''),
|
|
123
|
+
innerHTML: parseMarkdownToHtml(item.content),
|
|
104
124
|
},
|
|
105
|
-
item.content
|
|
106
125
|
)
|
|
107
126
|
}
|
|
108
127
|
if (item.type === 'image') {
|
|
@@ -140,12 +159,15 @@ function PopoverValue(props: { key: number; item: Announcement.Value },
|
|
|
140
159
|
}
|
|
141
160
|
|
|
142
161
|
const showReopen = computed(() => {
|
|
143
|
-
return !show.value && (popoverProps?.reopen ?? true) && !!popoverProps.title
|
|
162
|
+
return !show.value && (popoverProps.value?.reopen ?? true) && !!popoverProps.value.title
|
|
144
163
|
})
|
|
145
164
|
</script>
|
|
146
165
|
|
|
147
166
|
<template>
|
|
148
167
|
<div v-show="show" class="theme-blog-popover" data-pagefind-ignore="all">
|
|
168
|
+
<component is="style" v-if="popoverProps.style">
|
|
169
|
+
{{ popoverProps.style }}
|
|
170
|
+
</component>
|
|
149
171
|
<div class="header">
|
|
150
172
|
<div class="title-wrapper">
|
|
151
173
|
<AnnouncementIcon size="20px" :icon="popoverProps.icon">
|
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,16 @@ import { Ref } from 'vue';
|
|
|
2
2
|
import { Route } from 'vitepress';
|
|
3
3
|
|
|
4
4
|
interface AnnouncementOptions {
|
|
5
|
+
/**
|
|
6
|
+
* 自定义样式类名
|
|
7
|
+
* @example
|
|
8
|
+
* ```css
|
|
9
|
+
* .theme-blog-popover a {
|
|
10
|
+
* color: var(--vp-c-brand-2);
|
|
11
|
+
* }
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
style?: string;
|
|
5
15
|
/**
|
|
6
16
|
* 公告标题
|
|
7
17
|
*/
|
|
@@ -57,15 +67,25 @@ interface AnnouncementOptions {
|
|
|
57
67
|
* @param to 切换到的目标路由
|
|
58
68
|
*/
|
|
59
69
|
onRouteChanged?: (to: Route, show: Ref<boolean>) => void;
|
|
70
|
+
/**
|
|
71
|
+
* 国际化
|
|
72
|
+
*/
|
|
73
|
+
locales?: Record<string, Omit<AnnouncementOptions, 'locales'>>;
|
|
60
74
|
}
|
|
61
75
|
declare namespace Announcement {
|
|
62
76
|
interface Title {
|
|
63
77
|
type: 'title';
|
|
78
|
+
/**
|
|
79
|
+
* 支持 markdown 和 html
|
|
80
|
+
*/
|
|
64
81
|
content: string;
|
|
65
82
|
style?: string;
|
|
66
83
|
}
|
|
67
84
|
interface Text {
|
|
68
85
|
type: 'text';
|
|
86
|
+
/**
|
|
87
|
+
* 支持 markdown 和 html
|
|
88
|
+
*/
|
|
69
89
|
content: string;
|
|
70
90
|
style?: string;
|
|
71
91
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,16 @@ import { Ref } from 'vue';
|
|
|
2
2
|
import { Route } from 'vitepress';
|
|
3
3
|
|
|
4
4
|
interface AnnouncementOptions {
|
|
5
|
+
/**
|
|
6
|
+
* 自定义样式类名
|
|
7
|
+
* @example
|
|
8
|
+
* ```css
|
|
9
|
+
* .theme-blog-popover a {
|
|
10
|
+
* color: var(--vp-c-brand-2);
|
|
11
|
+
* }
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
style?: string;
|
|
5
15
|
/**
|
|
6
16
|
* 公告标题
|
|
7
17
|
*/
|
|
@@ -57,15 +67,25 @@ interface AnnouncementOptions {
|
|
|
57
67
|
* @param to 切换到的目标路由
|
|
58
68
|
*/
|
|
59
69
|
onRouteChanged?: (to: Route, show: Ref<boolean>) => void;
|
|
70
|
+
/**
|
|
71
|
+
* 国际化
|
|
72
|
+
*/
|
|
73
|
+
locales?: Record<string, Omit<AnnouncementOptions, 'locales'>>;
|
|
60
74
|
}
|
|
61
75
|
declare namespace Announcement {
|
|
62
76
|
interface Title {
|
|
63
77
|
type: 'title';
|
|
78
|
+
/**
|
|
79
|
+
* 支持 markdown 和 html
|
|
80
|
+
*/
|
|
64
81
|
content: string;
|
|
65
82
|
style?: string;
|
|
66
83
|
}
|
|
67
84
|
interface Text {
|
|
68
85
|
type: 'text';
|
|
86
|
+
/**
|
|
87
|
+
* 支持 markdown 和 html
|
|
88
|
+
*/
|
|
69
89
|
content: string;
|
|
70
90
|
style?: string;
|
|
71
91
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitepress-plugin-announcement",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "vitepress plugin, Announcement, 公告窗口",
|
|
5
5
|
"author": "sugar",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"tinyglobby": "^0.2.6",
|
|
44
44
|
"typescript": "^5.5.4",
|
|
45
45
|
"vite": "^5",
|
|
46
|
-
"vitepress": "^1.
|
|
47
|
-
"vue": "^3.
|
|
46
|
+
"vitepress": "^1.4.1",
|
|
47
|
+
"vue": "^3.5.12"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"dev": "pnpm run /^dev:.*/",
|