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 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, onMounted, ref, watch } from 'vue'
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 popoverProps: AnnouncementOptions = announcementOptions
12
+ const { localeIndex } = useData()
13
13
 
14
- const show = ref((popoverProps?.duration ?? 0) >= 0)
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 = 'vitepress-plugin-announcement'
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
- onMounted(() => {
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.2",
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.3.4",
47
- "vue": "^3.4.26"
46
+ "vitepress": "^1.4.1",
47
+ "vue": "^3.5.12"
48
48
  },
49
49
  "scripts": {
50
50
  "dev": "pnpm run /^dev:.*/",