Skip to content

feat: darkmode (close #1865) #2232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/@vuepress/plugin-darkmode/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__tests__
__mocks__
119 changes: 119 additions & 0 deletions packages/@vuepress/plugin-darkmode/DarkmodeSwitch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<template>
<div
class="darkmode-switch"
@click="toggleDarkmode"
>
<div
class="item day"
:class="{active: !isDarkmode}"
>
<svg
class="icon"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M512 256a42.666667 42.666667 0 0 0 42.666667-42.666667V128a42.666667 42.666667 0 0 0-85.333334 0v85.333333a42.666667 42.666667 0 0 0 42.666667 42.666667zM896 469.333333h-85.333333a42.666667 42.666667 0 0 0 0 85.333334h85.333333a42.666667 42.666667 0 0 0 0-85.333334zM256 512a42.666667 42.666667 0 0 0-42.666667-42.666667H128a42.666667 42.666667 0 0 0 0 85.333334h85.333333a42.666667 42.666667 0 0 0 42.666667-42.666667zM265.386667 213.333333a42.666667 42.666667 0 0 0-59.306667 62.72l61.44 59.306667a42.666667 42.666667 0 0 0 31.146667 11.946667 42.666667 42.666667 0 0 0 30.72-13.226667 42.666667 42.666667 0 0 0 0-60.16zM725.333333 347.306667a42.666667 42.666667 0 0 0 29.44-11.946667l61.44-59.306667A42.666667 42.666667 0 0 0 758.613333 213.333333l-61.44 60.586667a42.666667 42.666667 0 0 0 0 60.16 42.666667 42.666667 0 0 0 28.16 13.226667zM512 768a42.666667 42.666667 0 0 0-42.666667 42.666667v85.333333a42.666667 42.666667 0 0 0 85.333334 0v-85.333333a42.666667 42.666667 0 0 0-42.666667-42.666667zM756.48 688.64a42.666667 42.666667 0 0 0-59.306667 61.44L758.613333 810.666667a42.666667 42.666667 0 0 0 29.44 11.946666 42.666667 42.666667 0 0 0 30.72-12.8 42.666667 42.666667 0 0 0 0-60.586666zM267.52 688.64l-61.44 59.306667a42.666667 42.666667 0 0 0 0 60.586666 42.666667 42.666667 0 0 0 30.72 12.8 42.666667 42.666667 0 0 0 28.586667-10.666666l61.44-59.306667a42.666667 42.666667 0 0 0-59.306667-61.44zM512 341.333333a170.666667 170.666667 0 1 0 170.666667 170.666667 170.666667 170.666667 0 0 0-170.666667-170.666667z"
/>
</svg>
</div>
<div
class="item night"
:class="{ active: isDarkmode }"
>
<svg
class="icon"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M935.538601 630.40178c-11.43005-11.432249-28.673759-14.738607-43.531086-8.353536-46.733115 20.10317-96.362866 30.296859-147.50719 30.296859-99.589478 0-193.221796-38.783705-263.640252-109.20316-108.636744-108.636744-139.609745-270.022125-78.9083-411.148441 6.388069-14.85233 3.078713-32.098837-8.353536-43.532285-11.432249-11.432249-28.675758-14.743604-43.532285-8.354536-52.637312 22.64025-100.017388 54.809439-140.82552 95.616372-85.346135 85.346135-132.346869 198.821199-132.346869 319.519766 0 120.699566 47.001733 234.172631 132.347868 319.518766s198.821199 132.349067 319.517567 132.349067c120.699566 0 234.172431-47.002932 319.520765-132.351066 40.808132-40.810131 72.977122-88.190207 95.615373-140.82552C950.282205 659.081735 946.971849 641.834029 935.538601 630.40178z"
p-id="3638"
/>
</svg>
</div>
</div>
</template>

<script>
export default {
data: () => ({
isDarkmode: { type: Boolean, default: false }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this for? It looks like props style

}),

mounted () {
const darkmode = localStorage.getItem('darkmode')
const classes = document.body.classList

this.isDarkmode = darkmode === 'true'
if (darkmode === 'true') {
classes.add('theme-dark')
} else {
classes.add('theme-light')
}
},

methods: {
toggleDarkmode () {
this.isDarkmode = !this.isDarkmode

const classes = document.body.classList
const changeClass = (domClass, insert, remove) => {
domClass.remove(...remove)
const oldClasses = [...domClass]
domClass.value = ''
domClass.add(...insert, ...oldClasses)
}

if (this.isDarkmode) {
changeClass(classes, ['theme-dark'], ['theme-light'])
} else {
changeClass(classes, ['theme-light'], ['theme-dark'])
}

localStorage.setItem('darkmode', String(this.isDarkmode))
}
}
}
</script>

<style lang="stylus" scoped>
.darkmode-switch
display flex
flex-shrink 0
border-radius 4px
overflow hidden
align-self center
margin-right 0.5rem
height 22px

&:hover
cursor pointer

.item
padding 3px
line-height 1
border 1px solid $accentColor

&.day
border-top-left-radius 4px
border-bottom-left-radius 4px

&.night
border-top-right-radius 4px
border-bottom-right-radius 4px

.icon
width 14px
height 14px
fill $accentColor

&.active
background-color $accentColor

&:hover
cursor default

.icon
fill #fff
</style>
3 changes: 3 additions & 0 deletions packages/@vuepress/plugin-darkmode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @vuepress/plugin-darkmode

> darkmode plugin for vuepress
7 changes: 7 additions & 0 deletions packages/@vuepress/plugin-darkmode/enhanceAppFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import DarkmodeSwitch from './DarkmodeSwitch.vue'
import './styles/index.styl'

export default ({ Vue }) => {
// eslint-disable-next-line vue/match-component-file-name
Vue.component('DarkmodeSwitch', DarkmodeSwitch)
}
5 changes: 5 additions & 0 deletions packages/@vuepress/plugin-darkmode/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const { path } = require('@vuepress/shared-utils')

module.exports = {
enhanceAppFiles: path.resolve(__dirname, 'enhanceAppFile.js')
}
25 changes: 25 additions & 0 deletions packages/@vuepress/plugin-darkmode/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@vuepress/plugin-darkmode",
"version": "1.4.0",
"description": "darkmode plugin for vuepress",
"keywords": [
"documentation",
"generator",
"vue",
"vuepress"
],
"homepage": "https://github.com/vuejs/vuepress/packages/@vuepress/plugin-darkmode#readme",
"bugs": {
"url": "https://github.com/vuejs/vuepress/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/vuepress.git"
},
"license": "MIT",
"author": "Mr.Hope <zhangbowang1998@gmail.com>",
"main": "index.js",
"publishConfig": {
"access": "public"
}
}
13 changes: 13 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/config.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
$nightBgcolor ?= #1e1e1e
$nightFontcolor ?= #9e9e9e
$nightBordercolor ?= #151310
$contentClass = '.theme-default-content'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configurable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configurable?

Yes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I was asking why not use $contentClass ?= to avoid override issues

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I was asking why not use $contentClass ?= to avoid override issues

The default theme is using = instead of ?=

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, it's already a pre-defined value in theme default


bgcolor()
background-color $nightBgcolor

fontcolor()
color $nightFontcolor

bordercolor()
border-color $nightBordercolor
10 changes: 10 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/index.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@require './config'

.theme-dark
bgcolor()
fontcolor()
bordercolor()

@require './layout/index'
@require './markdown'
@require './plugins/pwa'
12 changes: 12 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/layout/base.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.theme-dark
// 表格
tr:nth-child(2n)
background-color #1b1a18

blockquote
border-color #666

{$contentClass}
code
color #999
background-color #333
9 changes: 9 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/layout/home.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.theme-dark
// 主页
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No chs comments

.home
.hero .description
fontcolor()

.feature
h2, p
fontcolor()
4 changes: 4 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/layout/index.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@require './base'
@require './home'
@require './navbar'
@require './sidebar'
45 changes: 45 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/layout/navbar.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.theme-dark
// 导航栏
.navbar
bgcolor()
border-bottom 1px solid $nightBordercolor

.site-name, .links
bgcolor()
fontcolor()

.nav-links a
fontcolor()

@media (min-width: $MQMobile)
&:hover, &.router-link-active
borderColor()

@media (min-width: $MQMobile)
.dropdown-wrapper .nav-dropdown
bgcolor()
border 1px solid $nightBordercolor !important

// 下拉列表
.dropdown-wrapper .dropdown-title .title
fontcolor()

// 搜索框
.search-box
input
fontcolor()
background-color $nightBgcolor !important

@media (min-width: $MQNarrow)
bordercolor()
background-color lighten($nightBgcolor, 10%) !important

&:focus
background-color lighten($nightBgcolor, 10%) !important
border-color $accentColor

.suggestions
background-color #000

.suggestion.focused
background-color #0c0b0a
15 changes: 15 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/layout/sidebar.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.theme-dark
// 侧边栏
.sidebar
bgcolor()
bordercolor()

.nav-links a
fontcolor()

.sidebar-heading
color $night-fontcolor

// 侧边栏链接
a.sidebar-link
fontcolor()
23 changes: 23 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/markdown.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.theme-dark
// 提示框
.custom-block
&.tip, &.warning, &.danger, &.details
background-color lighten($nightBgcolor, 15%)

a
color $accentColor

&.warning
color darken(#ffe564, 50%)

.custom-block-title
color darken(#ffe564, 40%)

&.danger
color darken(red, 30%)

.custom-block-title
color darken(red, 20%)

&.details
fontcolor()
8 changes: 8 additions & 0 deletions packages/@vuepress/plugin-darkmode/styles/plugins/pwa.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.theme-dark
// pwa
.sw-update-popup
background-color $night-bgcolor !important
color $night-fontcolor !important
box-shadow none
border 1px solid
bordercolor()
5 changes: 5 additions & 0 deletions packages/@vuepress/theme-default/components/Navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
'max-width': linksWrapMaxWidth + 'px'
} : {}"
>
<DarkmodeSwitch v-if="isdarkmodeEnabled" />
<AlgoliaSearchBox
v-if="isAlgoliaSearch"
:options="algolia"
Expand Down Expand Up @@ -65,6 +66,10 @@ export default {

isAlgoliaSearch () {
return this.algolia && this.algolia.apiKey && this.algolia.indexName
},

isdarkmodeEnabled () {
return this.$themeConfig.darkmode
}
},

Expand Down
2 changes: 2 additions & 0 deletions packages/@vuepress/theme-default/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = (options, ctx) => {
.some(base => themeConfig.locales[base].algolia)
)

const enableDarkmode = themeConfig.darkmode === true
const enableSmoothScroll = themeConfig.smoothScroll === true

return {
Expand Down Expand Up @@ -53,6 +54,7 @@ module.exports = (options, ctx) => {
before: info => `<details class="custom-block details">${info ? `<summary>${info}</summary>` : ''}\n`,
after: () => '</details>\n'
}],
['@vuepress/darkmode', enableDarkmode],
['smooth-scroll', enableSmoothScroll]
]
}
Expand Down
1 change: 1 addition & 0 deletions packages/@vuepress/theme-default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"main": "index.js",
"dependencies": {
"@vuepress/plugin-active-header-links": "^1.4.0",
"@vuepress/plugin-darkmode": "^1.4.0",
"@vuepress/plugin-nprogress": "^1.4.0",
"@vuepress/plugin-search": "^1.4.0",
"docsearch.js": "^2.5.2",
Expand Down
5 changes: 5 additions & 0 deletions packages/@vuepress/theme-vue/styles/index.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.theme-dark
.bsa-cpc
background-color #070707
a._default_
color #999
1 change: 1 addition & 0 deletions packages/docs/docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports = ctx => ({
apiKey: '3a539aab83105f01761a137c61004d85',
indexName: 'vuepress'
}) : null,
darkmode: true,
smoothScroll: true,
locales: {
'/': {
Expand Down
4 changes: 4 additions & 0 deletions packages/docs/docs/.vuepress/styles/index.styl
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ pre.vue-container
color #808080
font-weight light


.theme-dark
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only theme-vue has bit-sponsor class

.bit-sponsor
background-color #0c0907
Loading