@sugarat/theme 0.1.42 → 0.1.43

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 CHANGED
@@ -208,8 +208,15 @@ declare namespace Theme {
208
208
  topTitle?: string;
209
209
  list: UserWork[];
210
210
  }
211
+ type ThemeColor = 'vp-default' | 'vp-green' | 'vp-yellow' | 'vp-red' | 'el-blue' | 'el-yellow' | 'el-green' | 'el-red';
211
212
  interface BlogConfig {
212
213
  blog?: false;
214
+ /**
215
+ * 内置一些主题色
216
+ * @default 'vp-default'
217
+ * 也可以自定义颜色,详见 TODO:文档
218
+ */
219
+ themeColor?: ThemeColor;
213
220
  pagesData: PageData[];
214
221
  srcDir?: string;
215
222
  author?: string;
package/node.js CHANGED
@@ -32,7 +32,7 @@ __export(node_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(node_exports);
34
34
 
35
- // ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.0-rc.4_vue@3.3.4/node_modules/vitepress-plugin-tabs/dist/index.js
35
+ // ../../node_modules/.pnpm/vitepress-plugin-tabs@0.2.0_vitepress@1.0.0-rc.11_vue@3.3.4/node_modules/vitepress-plugin-tabs/dist/index.js
36
36
  var tabsMarker = "=tabs";
37
37
  var tabsMarkerLen = tabsMarker.length;
38
38
  var ruleBlockTabs = (state, startLine, endLine, silent) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sugarat/theme",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -51,7 +51,7 @@
51
51
  "sass": "^1.56.1",
52
52
  "tsup": " ^6.5.0",
53
53
  "typescript": "^4.8.2",
54
- "vitepress": "1.0.0-rc.4",
54
+ "vitepress": "1.0.0-rc.11",
55
55
  "vitepress-plugin-tabs": "^0.2.0",
56
56
  "vue": "^3.3.4"
57
57
  },
@@ -24,6 +24,7 @@ const { Layout } = Theme
24
24
  </template>
25
25
 
26
26
  <template #doc-before>
27
+ <slot name="doc-before" />
27
28
  <!-- 阅读时间分析 -->
28
29
  <ClientOnly>
29
30
  <BlogArticleAnalyze />
@@ -34,10 +35,12 @@ const { Layout } = Theme
34
35
 
35
36
  <!-- 自定义搜索,替代Algolia,未来择机移除 -->
36
37
  <template #nav-bar-content-before>
38
+ <slot name="nav-bar-content-before" />
37
39
  <BlogSearch />
38
40
  </template>
39
41
  <!-- 自定义首页 -->
40
42
  <template #home-hero-before v-if="isBlogTheme">
43
+ <slot name="home-hero-before" />
41
44
  <div class="home">
42
45
  <div class="header-banner">
43
46
  <BlogHomeBanner />
@@ -51,12 +54,66 @@ const { Layout } = Theme
51
54
  </div>
52
55
  </template>
53
56
  <template #sidebar-nav-after v-if="isBlogTheme">
57
+ <slot name="sidebar-nav-after" />
54
58
  <BlogSidebar />
55
59
  </template>
56
60
  <!-- 评论 -->
57
61
  <template #doc-after>
62
+ <slot name="doc-after" />
58
63
  <BlogComment />
59
64
  </template>
65
+
66
+ <!-- 透传默认主题的其它插槽 -->
67
+ <!-- navbar -->
68
+ <template #nav-bar-title-before
69
+ ><slot name="nav-bar-title-before"
70
+ /></template>
71
+ <template #nav-bar-title-after
72
+ ><slot name="nav-bar-title-after"
73
+ /></template>
74
+ <template #nav-bar-content-after
75
+ ><slot name="nav-bar-content-after"
76
+ /></template>
77
+ <template #nav-screen-content-before
78
+ ><slot name="nav-screen-content-before"
79
+ /></template>
80
+ <template #nav-screen-content-after
81
+ ><slot name="nav-screen-content-after"
82
+ /></template>
83
+
84
+ <!-- sidebar -->
85
+ <template #sidebar-nav-before><slot name="sidebar-nav-before" /></template>
86
+
87
+ <!-- content -->
88
+ <template #page-top><slot name="page-top" /></template>
89
+ <template #page-bottom><slot name="page-bottom" /></template>
90
+
91
+ <template #not-found><slot name="not-found" /></template>
92
+ <template #home-hero-info><slot name="home-hero-info" /></template>
93
+ <template #home-hero-image><slot name="home-hero-image" /></template>
94
+ <template #home-hero-after><slot name="home-hero-after" /></template>
95
+ <template #home-features-before
96
+ ><slot name="home-features-before"
97
+ /></template>
98
+ <template #home-features-after
99
+ ><slot name="home-features-after"
100
+ /></template>
101
+
102
+ <template #doc-footer-before><slot name="doc-footer-before" /></template>
103
+
104
+ <template #doc-top><slot name="doc-top" /></template>
105
+ <template #doc-bottom><slot name="doc-bottom" /></template>
106
+
107
+ <template #aside-top><slot name="aside-top" /></template>
108
+ <template #aside-bottom><slot name="aside-bottom" /></template>
109
+ <template #aside-outline-before
110
+ ><slot name="aside-outline-before"
111
+ /></template>
112
+ <template #aside-outline-after
113
+ ><slot name="aside-outline-after"
114
+ /></template>
115
+ <template #aside-ads-before><slot name="aside-ads-before" /></template>
116
+ <template #aside-ads-after><slot name="aside-ads-after" /></template>
60
117
  </Layout>
61
118
  </template>
62
119
  <style scoped lang="scss">
@@ -206,7 +206,7 @@ watch(
206
206
  .link {
207
207
  color: var(--vp-c-text-2);
208
208
  &:hover {
209
- color: var(--vp-c-brand);
209
+ color: var(--vp-c-brand-1);
210
210
  cursor: pointer;
211
211
  }
212
212
  }
@@ -43,9 +43,9 @@
43
43
  </div>
44
44
  </template>
45
45
  <script setup lang="ts">
46
- import { useDark, useElementVisibility } from '@vueuse/core'
46
+ import { useElementVisibility } from '@vueuse/core'
47
47
  import { useData, useRoute } from 'vitepress'
48
- import { computed, ref, watch } from 'vue'
48
+ import { computed, nextTick, ref, watch } from 'vue'
49
49
  import { ElAffix, ElButton } from 'element-plus'
50
50
  import { Comment } from '@element-plus/icons-vue'
51
51
  import { useGiscusConfig } from '../composables/config/blog'
@@ -85,9 +85,7 @@ const show = computed(() => {
85
85
  )
86
86
  })
87
87
 
88
- const isDark = useDark({
89
- storageKey: 'vitepress-theme-appearance'
90
- })
88
+ const { isDark } = useData()
91
89
 
92
90
  const route = useRoute()
93
91
  const showComment = ref(true)
@@ -103,12 +101,30 @@ watch(
103
101
  immediate: true
104
102
  }
105
103
  )
104
+
105
+ // TODO:可以优化,不需要重载
106
+ watch(isDark, () => {
107
+ showComment.value = false
108
+ nextTick(() => {
109
+ showComment.value = true
110
+ })
111
+ })
106
112
  </script>
107
113
  <style scoped lang="scss">
108
114
  .comment {
109
115
  width: 100%;
110
116
  text-align: center;
111
117
  padding: 40px 0;
118
+ :deep(.el-button.el-button--primary:hover) {
119
+ background-color: var(--vp-c-brand-2);
120
+ border-color: var(--vp-c-brand-2);
121
+ color: #fff;
122
+ }
123
+ :deep(.el-button.el-button--primary) {
124
+ background-color: var(--vp-c-brand-soft);
125
+ border-color: var(--vp-c-brand-2);
126
+ color: var(--vp-c-brand-2);
127
+ }
112
128
  }
113
129
 
114
130
  .hidden {
@@ -138,7 +138,7 @@ const showChangeBtn = computed(() => {
138
138
  }
139
139
 
140
140
  &:nth-child(3) .num {
141
- background-color: #409eff;
141
+ background-color: var(--vp-c-brand-2);
142
142
  color: #fff;
143
143
  font-size: 12px;
144
144
  border-radius: 6px;
@@ -16,17 +16,19 @@
16
16
  </ul>
17
17
  <!-- 解决element-ui bug -->
18
18
  <ClientOnly>
19
- <el-pagination
20
- v-if="wikiList.length >= pageSize"
21
- small
22
- background
23
- :default-current-page="1"
24
- :current-page="currentPage"
25
- @update:current-page="handleUpdatePageNum"
26
- :page-size="pageSize"
27
- :total="filterData.length"
28
- layout="prev, pager, next, jumper"
29
- />
19
+ <div class="el-pagination-wrapper">
20
+ <el-pagination
21
+ v-if="wikiList.length >= pageSize"
22
+ small
23
+ background
24
+ :default-current-page="1"
25
+ :current-page="currentPage"
26
+ @update:current-page="handleUpdatePageNum"
27
+ :page-size="pageSize"
28
+ :total="filterData.length"
29
+ layout="prev, pager, next, jumper"
30
+ />
31
+ </div>
30
32
  </ClientOnly>
31
33
  </template>
32
34
  <script setup lang="ts">
@@ -116,3 +118,20 @@ watch(
116
118
  }
117
119
  )
118
120
  </script>
121
+ <style lang="scss" scoped>
122
+ .el-pagination-wrapper {
123
+ :deep(.el-pagination li.is-active.number) {
124
+ background-color: var(--vp-c-brand-2);
125
+ }
126
+ :deep(.el-pagination button:hover) {
127
+ color: var(--vp-c-brand-2);
128
+ }
129
+
130
+ :deep(.el-pager li:not(.is-active):hover) {
131
+ color: var(--vp-c-brand-2);
132
+ }
133
+ :deep(.el-input__wrapper.is-focus) {
134
+ box-shadow: 0 0 0 1px var(--vp-c-brand-2) inset;
135
+ }
136
+ }
137
+ </style>
@@ -132,16 +132,21 @@ const PopoverValue = (
132
132
 
133
133
  <style lang="scss" scoped>
134
134
  .theme-blog-popover {
135
+ color: rgba(60, 60, 67);
135
136
  width: 258px;
136
137
  position: fixed;
137
138
  top: 80px;
138
139
  right: 20px;
139
140
  z-index: 19;
140
141
  box-sizing: border-box;
141
- border: 1px solid var(--el-color-primary-light-3);
142
+ border: 1px solid var(--vp-c-brand-3);
142
143
  border-radius: 6px;
143
144
  background-color: rgba(var(--bg-gradient-home));
144
145
  box-shadow: var(--box-shadow);
146
+ :deep(.el-button.el-button--primary) {
147
+ background-color: var(--vp-c-brand-2);
148
+ border-color: var(--vp-c-brand-2);
149
+ }
145
150
  }
146
151
  @media screen and (min-width: 760px) and (max-width: 1140px) {
147
152
  .theme-blog-popover {
@@ -149,7 +154,7 @@ const PopoverValue = (
149
154
  }
150
155
  }
151
156
  .header {
152
- background-color: var(--el-color-primary-light-3);
157
+ background-color: var(--vp-c-brand-3);
153
158
  color: #fff;
154
159
  padding: 6px 4px;
155
160
  display: flex;
@@ -207,7 +212,7 @@ const PopoverValue = (
207
212
  top: 80px;
208
213
  right: 10px;
209
214
  position: fixed;
210
- background-color: var(--el-color-primary-light-3);
215
+ background-color: var(--vp-c-brand-3);
211
216
  padding: 8px;
212
217
  color: #fff;
213
218
  font-size: 12px;
@@ -191,7 +191,7 @@ const showChangeBtn = computed(() => {
191
191
  word-break: break-all;
192
192
  white-space: break-spaces;
193
193
  &.current {
194
- color: var(--vp-c-brand);
194
+ color: var(--vp-c-brand-1);
195
195
  }
196
196
  }
197
197
 
@@ -362,7 +362,7 @@ const handleSelect = (target: any) => {
362
362
  }
363
363
 
364
364
  &:hover {
365
- border: 1px solid var(--vp-c-brand);
365
+ border: 1px solid var(--vp-c-brand-1);
366
366
  border-radius: 6px;
367
367
  }
368
368
 
@@ -406,7 +406,7 @@ div[command-item] {
406
406
  }
407
407
  div[command-item] mark {
408
408
  background: none;
409
- color: var(--vp-c-brand);
409
+ color: var(--vp-c-brand-1);
410
410
  }
411
411
 
412
412
  div[command-item][aria-selected='true'] mark,
@@ -376,7 +376,7 @@ const handleChooseTag = (tag: string) => {
376
376
  }
377
377
  a {
378
378
  font-weight: 500;
379
- color: var(--vp-c-brand);
379
+ color: var(--vp-c-brand-1);
380
380
  }
381
381
  }
382
382
  .works-container {
@@ -13,6 +13,7 @@ import {
13
13
  reactive,
14
14
  ref
15
15
  } from 'vue'
16
+ import { useColorMode } from '@vueuse/core'
16
17
 
17
18
  import type { Theme } from './index'
18
19
 
@@ -21,22 +22,13 @@ const configSymbol: InjectionKey<Ref<Theme.Config>> = Symbol('theme-config')
21
22
  const activeTagSymbol: InjectionKey<Ref<Theme.activeTag>> = Symbol('active-tag')
22
23
 
23
24
  const currentPageNum: InjectionKey<Ref<number>> = Symbol('home-page-num')
24
- const homeConfigSymbol: InjectionKey<Theme.HomeConfig> = Symbol('home-config')
25
25
 
26
26
  const userWorks: InjectionKey<Ref<Theme.UserWorks>> = Symbol('user-works')
27
27
 
28
28
  export function withConfigProvider(App: Component) {
29
29
  return defineComponent({
30
30
  name: 'ConfigProvider',
31
- props: {
32
- handleChangeSlogan: {
33
- type: Function,
34
- required: false
35
- }
36
- },
37
- setup(props, { slots }) {
38
- provide(homeConfigSymbol, props as Theme.HomeConfig)
39
-
31
+ setup(_, { slots }) {
40
32
  const { theme } = useData()
41
33
  const config = computed(() => resolveConfig(theme.value))
42
34
  provide(configSymbol, config)
@@ -59,6 +51,22 @@ export function withConfigProvider(App: Component) {
59
51
 
60
52
  const pageNum = ref(1)
61
53
  provide(currentPageNum, pageNum)
54
+
55
+ const mode = useColorMode({
56
+ attribute: 'theme',
57
+ modes: {
58
+ // 内置的颜色主题
59
+ 'vp-default': 'vp-default',
60
+ 'vp-green': 'vp-green',
61
+ 'vp-yellow': 'vp-yellow',
62
+ 'vp-red': 'vp-red',
63
+ 'el-blue': 'el-blue',
64
+ 'el-yellow': 'el-yellow',
65
+ 'el-green': 'el-green',
66
+ 'el-red': 'el-red'
67
+ }
68
+ })
69
+ mode.value = config.value.blog?.themeColor ?? 'vp-default'
62
70
  return () => h(App, null, slots)
63
71
  }
64
72
  })
@@ -77,9 +85,6 @@ export function useBlogConfig() {
77
85
  export function useBlogThemeMode() {
78
86
  return inject(configSymbol)!.value?.blog?.blog ?? true
79
87
  }
80
- export function useHomeConfig() {
81
- return inject(homeConfigSymbol)!
82
- }
83
88
 
84
89
  export function useGiscusConfig() {
85
90
  const blogConfig = useConfig()
@@ -228,8 +228,23 @@ export namespace Theme {
228
228
  topTitle?: string
229
229
  list: UserWork[]
230
230
  }
231
+ export type ThemeColor =
232
+ | 'vp-default'
233
+ | 'vp-green'
234
+ | 'vp-yellow'
235
+ | 'vp-red'
236
+ | 'el-blue'
237
+ | 'el-yellow'
238
+ | 'el-green'
239
+ | 'el-red'
231
240
  export interface BlogConfig {
232
241
  blog?: false
242
+ /**
243
+ * 内置一些主题色
244
+ * @default 'vp-default'
245
+ * 也可以自定义颜色,详见 TODO:文档
246
+ */
247
+ themeColor?: ThemeColor
233
248
  pagesData: PageData[]
234
249
  srcDir?: string
235
250
  author?: string
package/src/index.ts CHANGED
@@ -14,6 +14,9 @@ import { withConfigProvider } from './composables/config/blog'
14
14
  import TimelinePage from './components/TimelinePage.vue'
15
15
  import UserWorksPage from './components/UserWorks.vue'
16
16
 
17
+ // 内置一些特殊的主题色
18
+ import './styles/theme/inline-theme.var.css'
19
+
17
20
  export const BlogTheme: Theme = {
18
21
  ...DefaultTheme,
19
22
  Layout: withConfigProvider(BlogApp),
@@ -8,7 +8,8 @@ html {
8
8
  --nav-bgc: rgba(255, 255, 255, 0.9);
9
9
  --badge-font-color: #4e5969;
10
10
  --description-font-color: #86909c;
11
- --blog-theme-color: #409eff;
11
+ --blog-theme-color: var(--vp-c-brand-1);
12
+ // --blog-theme-color: #409eff;
12
13
  }
13
14
 
14
15
  html[class='dark'] {
@@ -105,8 +106,8 @@ html[class='dark'] {
105
106
  }
106
107
 
107
108
  ::-webkit-scrollbar {
108
- width: 5px;
109
- height: 5px;
109
+ width: 4px;
110
+ height: 4px;
110
111
  }
111
112
 
112
113
  ::-webkit-scrollbar-track-piece {
@@ -114,13 +115,13 @@ html[class='dark'] {
114
115
  }
115
116
 
116
117
  ::-webkit-scrollbar-thumb:vertical {
117
- height: 5px;
118
+ height: 4px;
118
119
  border-radius: 4px;
119
- background-color: var(--el-color-primary);
120
+ background-color: var(--vp-c-brand-1);
120
121
  }
121
122
 
122
123
  ::-webkit-scrollbar-thumb:horizontal {
123
- width: 5px;
124
+ width: 4px;
124
125
  border-radius: 4px;
125
- background-color: var(--el-color-primary);
126
+ background-color: var(--vp-c-brand-1);
126
127
  }
@@ -24,7 +24,7 @@ ul {
24
24
 
25
25
  --lowContrast: #ffffff;
26
26
  --highContrast: #000000;
27
- --vcp-c-brand: #44bd87;
27
+ --vcp-c-brand: var(--vp-c-brand-2);
28
28
  --vcp-c-accent: #35495e;
29
29
 
30
30
  --gray1: hsl(0, 0%, 98%);
@@ -0,0 +1,56 @@
1
+ /* 所有变量:https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css */
2
+
3
+ /* VitePress 绿色 */
4
+ html[theme="vp-green"] {
5
+ --vp-c-brand-1: var(--vp-c-green-1);
6
+ --vp-c-brand-2: var(--vp-c-green-2);
7
+ --vp-c-brand-3: var(--vp-c-green-3);
8
+ --vp-c-brand-soft: var(--vp-c-green-soft);
9
+ }
10
+ /* VitePress 黄色 */
11
+ html[theme="vp-yellow"]{
12
+ --vp-c-brand-1: var(--vp-c-yellow-1);
13
+ --vp-c-brand-2: var(--vp-c-yellow-2);
14
+ --vp-c-brand-3: var(--vp-c-yellow-3);
15
+ --vp-c-brand-soft: var(--vp-c-yellow-soft);
16
+ }
17
+
18
+ /* VitePress 红色 */
19
+ html[theme="vp-red"]{
20
+ --vp-c-brand-1: var(--vp-c-red-1);
21
+ --vp-c-brand-2: var(--vp-c-red-2);
22
+ --vp-c-brand-3: var(--vp-c-red-3);
23
+ --vp-c-brand-soft: var(--vp-c-red-soft);
24
+ }
25
+
26
+ /* element plus 蓝色 */
27
+ html[theme="el-blue"]{
28
+ --vp-c-brand-1: var(--el-color-primary);
29
+ --vp-c-brand-2: var(--el-color-primary-light-3);
30
+ --vp-c-brand-3: var(--el-color-primary-light-5);
31
+ --vp-c-brand-soft: var(--el-color-primary-light-9);
32
+ }
33
+
34
+ /* element plus 绿色 */
35
+ html[theme="el-green"]{
36
+ --vp-c-brand-1: var(--el-color-success);
37
+ --vp-c-brand-2: var(--el-color-success-light-3);
38
+ --vp-c-brand-3: var(--el-color-success-light-5);
39
+ --vp-c-brand-soft: var(--el-color-success-light-9);
40
+ }
41
+
42
+ /* element plus 黄色 */
43
+ html[theme="el-yellow"]{
44
+ --vp-c-brand-1: var(--el-color-warning);
45
+ --vp-c-brand-2: var(--el-color-warning-light-3);
46
+ --vp-c-brand-3: var(--el-color-warning-light-5);
47
+ --vp-c-brand-soft: var(--el-color-warning-light-9);
48
+ }
49
+
50
+ /* element plus 红色 */
51
+ html[theme="el-red"]{
52
+ --vp-c-brand-1: var(--el-color-danger);
53
+ --vp-c-brand-2: var(--el-color-danger-light-3);
54
+ --vp-c-brand-3: var(--el-color-danger-light-5);
55
+ --vp-c-brand-soft: var(--el-color-danger-light-9);
56
+ }