Skip to content

Commit 680e429

Browse files
committed
feat(theme-default): support dark mode (close #29)
BREAKING CHANGE: most sass variables are migrated to css variables
1 parent 6c778a8 commit 680e429

File tree

23 files changed

+428
-221
lines changed

23 files changed

+428
-221
lines changed

docs/.vuepress/styles/palette.scss

-3
This file was deleted.

docs/reference/default-theme/styles.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,32 @@ Users can custom style variables via [palette file](#palette-file), and add extr
88

99
## Palette File
1010

11-
You can create a `.vuepress/styles/palette.scss` file to override predefined variables of default theme:
11+
The path of palette file is `.vuepress/styles/palette.scss`.
1212

13+
You can make use of it to override predefined SASS variables of default theme.
14+
15+
::: details Click to expand SASS variables
1316
@[code{3-} scss](@vuepress/theme-default/src/client/styles/_variables.scss)
17+
:::
1418

1519
## Style File
1620

17-
You can override default styles or add extra styles in `.vuepress/styles/index.scss` file. For example:
21+
The path of style file is `.vuepress/styles/index.scss`.
22+
23+
You can add extra styles here, or override default styles:
1824

1925
```scss
2026
:root {
2127
scroll-behavior: smooth;
2228
}
2329
```
30+
31+
You can also make use of it to override predefined CSS variables of default theme.
32+
33+
::: details Click to expand CSS variables
34+
@[code scss](@vuepress/theme-default/src/client/styles/vars.scss)
35+
:::
36+
37+
::: details Click to expand dark mode CSS variables
38+
@[code scss](@vuepress/theme-default/src/client/styles/vars-dark.scss)
39+
:::

docs/zh/reference/default-theme/styles.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,32 @@
88

99
## Palette 文件
1010

11-
你可以创建一个 `.vuepress/styles/palette.scss` 文件来覆盖默认主题的预定义变量:
11+
Palette 文件的路径是 `.vuepress/styles/palette.scss`
1212

13+
你可以利用它来覆盖默认主题的预定义 SASS 变量。
14+
15+
::: details 点击查看 SASS 变量
1316
@[code{3-} scss](@vuepress/theme-default/src/client/styles/_variables.scss)
17+
:::
1418

1519
## Style 文件
1620

17-
你可以在 `.vuepress/styles/index.scss` 文件中覆盖默认样式或者添加额外样式。例如:
21+
Style 文件的路径是 `.vuepress/styles/index.scss`
22+
23+
你可以在这里添加额外的样式,或者覆盖默认样式:
1824

1925
```scss
2026
:root {
2127
scroll-behavior: smooth;
2228
}
2329
```
30+
31+
你也可以利用它来覆盖默认主题的预定义 CSS 变量。
32+
33+
::: details 点击查看 CSS 变量
34+
@[code scss](@vuepress/theme-default/src/client/styles/vars.scss)
35+
:::
36+
37+
::: details 点击查看暗黑模式 CSS 变量
38+
@[code scss](@vuepress/theme-default/src/client/styles/vars-dark.scss)
39+
:::

packages/@vuepress/theme-default/src/client/components/Navbar.vue

+7
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@
2323

2424
<div class="navbar-links-wrapper" :style="linksWrapperStyle">
2525
<slot name="before" />
26+
2627
<NavbarLinks class="can-hide" />
28+
2729
<slot name="after" />
30+
31+
<ToggleDarkButton />
32+
2833
<NavbarSearch />
2934
</div>
3035
</header>
@@ -35,13 +40,15 @@ import { computed, defineComponent, onMounted, ref } from 'vue'
3540
import { useRouteLocale, useSiteLocaleData, withBase } from '@vuepress/client'
3641
import { useThemeLocaleData } from '../composables'
3742
import NavbarLinks from './NavbarLinks.vue'
43+
import ToggleDarkButton from './ToggleDarkButton.vue'
3844
import ToggleSidebarButton from './ToggleSidebarButton.vue'
3945
4046
export default defineComponent({
4147
name: 'Navbar',
4248
4349
components: {
4450
NavbarLinks,
51+
ToggleDarkButton,
4552
ToggleSidebarButton,
4653
},
4754
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<template>
2+
<button class="toggle-dark-button" @click="toggleDark">
3+
<svg v-show="!isDark" class="icon" focusable="false" viewBox="0 0 32 32">
4+
<path
5+
d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6z"
6+
fill="currentColor"
7+
/>
8+
<path
9+
d="M5.394 6.813l1.414-1.415l3.506 3.506L8.9 10.318z"
10+
fill="currentColor"
11+
/>
12+
<path d="M2 15.005h5v2H2z" fill="currentColor" />
13+
<path
14+
d="M5.394 25.197L8.9 21.691l1.414 1.415l-3.506 3.505z"
15+
fill="currentColor"
16+
/>
17+
<path d="M15 25.005h2v5h-2z" fill="currentColor" />
18+
<path
19+
d="M21.687 23.106l1.414-1.415l3.506 3.506l-1.414 1.414z"
20+
fill="currentColor"
21+
/>
22+
<path d="M25 15.005h5v2h-5z" fill="currentColor" />
23+
<path
24+
d="M21.687 8.904l3.506-3.506l1.414 1.415l-3.506 3.505z"
25+
fill="currentColor"
26+
/>
27+
<path d="M15 2.005h2v5h-2z" fill="currentColor" />
28+
</svg>
29+
30+
<svg v-show="isDark" class="icon" focusable="false" viewBox="0 0 32 32">
31+
<path
32+
d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z"
33+
fill="currentColor"
34+
/>
35+
</svg>
36+
</button>
37+
</template>
38+
39+
<script setup lang="ts">
40+
import { onMounted, ref, watch } from 'vue'
41+
42+
const isDark = ref(false)
43+
const toggleDark = (): void => {
44+
isDark.value = !isDark.value
45+
}
46+
47+
const setDarkClass = (): void => {
48+
const htmlEl = window?.document.querySelector('html')
49+
htmlEl?.classList.toggle('dark', isDark.value)
50+
}
51+
52+
onMounted(() => {
53+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
54+
isDark.value = mediaQuery.matches
55+
mediaQuery.addEventListener('change', (event) => {
56+
isDark.value = event.matches
57+
})
58+
watch(isDark, setDarkClass, { immediate: true })
59+
})
60+
</script>
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,11 @@
11
@import '@vuepress/plugin-palette/palette';
22

3-
// base colors
4-
$accentColor: #3eaf7c !default;
5-
$textColor: #2c3e50 !default;
6-
$borderColor: #eaecef !default;
7-
$arrowBgColor: #ccc !default;
8-
$tipColor: #42b983 !default;
9-
$warningColor: #e7c000 !default;
10-
$dangerColor: #cc0000 !default;
11-
12-
// badge component colors
13-
$badgeTipColor: $tipColor !default;
14-
$badgeWarningColor: $warningColor !default;
15-
$badgeDangerColor: $dangerColor !default;
16-
17-
// layout
18-
$navbarHeight: 3.6rem !default;
19-
$sidebarWidth: 20rem !default;
20-
$mobileSidebarWidth: $sidebarWidth * 0.82 !default;
21-
$contentWidth: 740px !default;
22-
$homePageWidth: 960px !default;
23-
243
// responsive breakpoints
254
$MQNarrow: 959px !default;
265
$MQMobile: 719px !default;
276
$MQMobileNarrow: 419px !default;
287

29-
// code blocks
30-
$codeBgColor: #282c34 !default;
31-
$highlightLineBgColor: rgba(0, 0, 0, 66%) !default;
32-
$lineNumbersColor: rgba(255, 255, 255, 0.3) !default;
33-
$lineNumbersWrapperWidth: 3.5rem !default;
8+
// code languages
349
$codeLang: 'c' 'cpp' 'cs' 'css' 'dart' 'docker' 'fs' 'go' 'html' 'java' 'js'
3510
'json' 'kt' 'less' 'makefile' 'md' 'php' 'py' 'rb' 'rs' 'sass' 'scss' 'sh'
3611
'styl' 'ts' 'toml' 'vue' 'yml' !default;

packages/@vuepress/theme-default/src/client/styles/_wrapper.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@import '_variables';
22

33
%wrapper {
4-
max-width: $contentWidth;
4+
max-width: var(--content-width);
55
margin: 0 auto;
66
padding: 2rem 2.5rem;
77

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@import '_variables';
2-
31
.arrow {
42
display: inline-block;
53
width: 0;
@@ -9,31 +7,31 @@
97
border: {
108
left: 4px solid transparent;
119
right: 4px solid transparent;
12-
bottom: 6px solid $arrowBgColor;
10+
bottom: 6px solid var(--c-bg-arrow);
1311
}
1412
}
1513

1614
&.down {
1715
border: {
1816
left: 4px solid transparent;
1917
right: 4px solid transparent;
20-
top: 6px solid $arrowBgColor;
18+
top: 6px solid var(--c-bg-arrow);
2119
}
2220
}
2321

2422
&.right {
2523
border: {
2624
top: 4px solid transparent;
2725
bottom: 4px solid transparent;
28-
left: 6px solid $arrowBgColor;
26+
left: 6px solid var(--c-bg-arrow);
2927
}
3028
}
3129

3230
&.left {
3331
border: {
3432
top: 4px solid transparent;
3533
bottom: 4px solid transparent;
36-
right: 6px solid $arrowBgColor;
34+
right: 6px solid var(--c-bg-arrow);
3735
}
3836
}
3937
}

packages/@vuepress/theme-default/src/client/styles/badge.scss

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
1-
@import '_variables';
2-
31
.badge {
42
display: inline-block;
53
font-size: 14px;
64
height: 18px;
75
line-height: 18px;
86
border-radius: 3px;
97
padding: 0 6px;
10-
color: white;
11-
background-color: #42b983;
8+
color: var(--c-bg);
129
vertical-align: top;
1310

14-
.table-of-contents & {
15-
vertical-align: middle;
16-
}
17-
1811
&.tip {
19-
background-color: $badgeTipColor;
12+
background-color: var(--c-badge-tip);
2013
}
2114

2215
&.warning {
23-
background-color: $badgeWarningColor;
16+
background-color: var(--c-badge-warning);
2417
}
2518

2619
&.danger {
27-
background-color: $badgeDangerColor;
20+
background-color: var(--c-badge-danger);
21+
}
22+
23+
.table-of-contents & {
24+
vertical-align: middle;
2825
}
2926

3027
& + & {

packages/@vuepress/theme-default/src/client/styles/code-group.scss

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
@import '_variables';
22

3+
/**
4+
* code-group
5+
*/
36
.code-group__nav {
47
margin-top: 0.85rem;
58
// 2 * margin + border-radius of <pre> tag
@@ -9,7 +12,7 @@
912
padding-top: 10px;
1013
border-top-left-radius: 6px;
1114
border-top-right-radius: 6px;
12-
background-color: $codeBgColor;
15+
background-color: var(--code-bg-color);
1316
}
1417

1518
.code-group__ul {
@@ -35,7 +38,7 @@
3538
}
3639

3740
.code-group__nav-tab-active {
38-
border-bottom: $accentColor 1px solid;
41+
border-bottom: var(--c-brand) 1px solid;
3942
}
4043

4144
@media (max-width: $MQMobileNarrow) {

0 commit comments

Comments
 (0)