Skip to content

Commit 14bd4c6

Browse files
authored
Feature/color mode (#4)
* feat: 新增 darkmode 支持 * build: add package pinia * fix: sync NaiveUI color mode * fix: Hydration render problem * build: update install lock * feat: add default color mode * feat: add Settings * build: update packages
1 parent 3d94c1d commit 14bd4c6

File tree

8 files changed

+581
-353
lines changed

8 files changed

+581
-353
lines changed

app.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
<NuxtPage />
44
</NaiveConfig>
55
</template>
6-
<script setup>
6+
<script setup lang="ts">
77
useServerHead({
88
link: [{
99
rel: 'icon',
1010
type: 'image/png',
1111
href: '/icon.png'
1212
}]
1313
})
14+
1415
</script>

components/settings/ColorMode.vue

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<template>
2+
<div class="h-14 w-14 p-3.5 text-gray-500 hover:text-gray-900 hover:dark:text-gray-300" @click="toggleColorMode">
3+
<Icon class="w-full h-full" name="ph:moon" v-if="modeActually === 'dark'"></Icon>
4+
<Icon class="w-full h-full" name="ph:sun" v-else-if="modeActually === 'light'"></Icon>
5+
</div>
6+
</template>
7+
<script setup lang="ts">
8+
type MODE = 'system' | 'dark' | 'light'
9+
const colorMode = useColorMode()
10+
const { colorModePreference } = useNaiveColorMode()
11+
const mode = ref<MODE>(colorModePreference.value as MODE)
12+
/** Sync NaiveUI color mode settings */
13+
watch(mode, (value) => {
14+
colorMode.preference = value
15+
})
16+
const targetMode = computed(() => {
17+
switch(colorModePreference.value) {
18+
case 'light':
19+
return 'dark'
20+
case 'dark':
21+
return 'light'
22+
case 'system':
23+
return isSystemInDarkMode ? 'light' : 'dark'
24+
}
25+
})
26+
27+
function toggleColorMode() {
28+
mode.value = targetMode.value
29+
colorMode.preference = targetMode.value
30+
colorModePreference.value = targetMode.value
31+
}
32+
33+
const modeActually = computed(() => {
34+
if (mode.value === 'system') {
35+
return isSystemInDarkMode.value ? 'dark' : 'light'
36+
} else {
37+
return mode.value
38+
}
39+
})
40+
41+
const isSystemInDarkMode = computed(() => {
42+
if(typeof window === 'undefined') {
43+
return false
44+
}
45+
if (!window.matchMedia) {
46+
return false
47+
}
48+
return window.matchMedia('(prefers-color-scheme: dark)').matches
49+
})
50+
</script>
51+
<style scoped>
52+
53+
:deep(.n-switch .n-switch__rail) {
54+
@apply w-full h-full rounded-full;
55+
}
56+
</style>

components/settings/FontSize.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="items-center transition-all flex gap-0.5 h-14 overflow-hidden" :class="{ 'w-64': expended, 'w-14': !expended }">
2+
<div class="items-center transition-all flex gap-0.5 h-14 text-gray-500 hover:text-gray-900 hover:dark:text-gray-300 overflow-hidden" :class="{ 'w-64': expended, 'w-14': !expended }">
33
<div class="flex-none w-14 text-center" @click="expended = !expended">
44
<Icon class="w-8 h-8" name="fluent:text-font-16-regular" />
55
</div>

nuxt.config.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@ export default defineNuxtConfig({
1010
'@nuxt/content',
1111
'nuxt-icon',
1212
'@nuxt/image',
13+
'@nuxtjs/color-mode'
1314
],
1415
content: {
1516
documentDriven: true
1617
},
1718
naiveui: {
18-
colorModePreference: "light",
1919
iconSize: 18,
20+
colorModePreference: 'system',
2021
themeConfig: {
2122
shared: {
2223
common: {
23-
primaryColor: '#F25739'
24+
primaryColor: '#F25739',
2425
}
25-
}
26+
},
2627
},
2728
},
2829
image: {
@@ -45,5 +46,10 @@ export default defineNuxtConfig({
4546
autoprefixer: {},
4647
},
4748
},
49+
colorMode: {
50+
preference: 'system',
51+
fallback: 'dark',
52+
classSuffix: ''
53+
},
4854
devtools: { enabled: true }
4955
})

package.json

+10-6
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,23 @@
1010
"publish": "wrangler deploy"
1111
},
1212
"devDependencies": {
13-
"@bg-dev/nuxt-naiveui": "^1.2.1",
14-
"@nuxt/content": "^2.7.0",
13+
"@bg-dev/nuxt-naiveui": "^1.2.2",
14+
"@nuxt/content": "^2.7.1",
1515
"@nuxt/devtools": "latest",
1616
"@nuxt/image": "1.0.0-rc.1",
17-
"@types/node": "^18.16.19",
17+
"@nuxtjs/color-mode": "^3.3.0",
18+
"@types/node": "^18.17.0",
1819
"autoprefixer": "^10.4.14",
1920
"naive-ui": "^2.34.4",
20-
"nuxt": "^3.6.3",
21-
"postcss": "^8.4.26",
21+
"nuxt": "^3.6.5",
22+
"postcss": "^8.4.27",
2223
"tailwindcss": "^3.3.3",
2324
"wrangler": "^3.3.0"
2425
},
2526
"dependencies": {
26-
"nuxt-icon": "^0.4.2"
27+
"@pinia-plugin-persistedstate/nuxt": "^1.1.1",
28+
"@pinia/nuxt": "^0.4.11",
29+
"nuxt-icon": "^0.4.2",
30+
"pinia": "^2.1.4"
2731
}
2832
}

pages/[...slug].vue

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
<template>
22
<div class="app">
33
<div class="max-w-7xl m-auto flex">
4-
<main class="flex gap-4 w-full max-w-3xl text-zinc-900 whitespace-pre-line ">
5-
<ContentDoc class="p-10 leading-relaxed bg-neutral-50" :class="`text-${fontSize} paragraph-${fontSize}`" />
4+
<main class="flex gap-4 w-full max-w-3xl text-zinc-900 dark:text-zinc-300 whitespace-pre-line ">
5+
<ContentDoc class="p-10 leading-relaxed bg-neutral-50 dark:bg-neutral-800 " :class="`text-${fontSize} paragraph-${fontSize}`" />
66
<div class="relative mb-3">
7-
<div class="fixed bottom-3 bg-white rounded-full shadow">
8-
<SettingsFontSize :default-value="fontSize" @change="(value) => fontSize = value" />
7+
<div class="fixed bottom-3 flex flex-col gap-3">
8+
<SettingsColorMode class="bg-stone-100 hover:bg-stone-50 dark:bg-stone-800 dark:hover:bg-stone-700 rounded-full shadow h-14 w-14" />
9+
<SettingsFontSize
10+
class="bg-stone-100 hover:bg-stone-50 dark:bg-stone-800 dark:hover:bg-stone-700 rounded-full shadow"
11+
:default-value="fontSize"
12+
@change="(value) => fontSize = value"
13+
/>
914
</div>
1015
</div>
1116
</main>
1217
</div>
1318
</div>
1419
</template>
1520
<script setup lang="ts">
16-
1721
const { page } = useContent()
1822
useContentHead(page)
1923
const fontSize = ref('lg')
2024
</script>
2125
<style scoped>
2226
.app {
23-
@apply bg-stone-200;
27+
@apply bg-stone-200 dark:bg-stone-900;
2428
}
2529
:deep(.paragraph-base p){
2630
@apply py-1;
@@ -40,4 +44,5 @@ const fontSize = ref('lg')
4044
:deep(.paragraph-4xl p){
4145
@apply py-5;
4246
}
47+
4348
</style>

pages/index.vue

+10-10
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
<NuxtLink to="/" class="flex my-16">
55
<NuxtImg src="/icon.png" class="w-14 h-14 " />
66
<div class="ml-4">
7-
<h1 class="text-3xl font-black text-slate-900 songti">佛典电子化计划</h1>
7+
<h1 class="text-3xl font-black text-slate-900 dark:text-slate-200 songti">佛典电子化计划</h1>
88
<p class="description">用现代 Web 技术重排佛典</p>
99
</div>
1010
</NuxtLink>
1111
<ul class="flex">
1212
<li>
13-
<NuxtLink class="flex transition bg-stone-50 hover:bg-white hover:shadow p-3 rounded" to="/xifangquezhi">
13+
<NuxtLink class="flex transition bg-stone-50 dark:bg-neutral-800 hover:bg-white dark:hover:bg-stone-800 hover:shadow p-3 rounded" to="/xifangquezhi">
1414
<NuxtImg :width="128" class="w-16" src="/cover/xifangquezhi.jpg" />
1515
<div class="p-3">
16-
<span class="font-semibold text-base mb-2 block">西方确指</span>
16+
<span class="dark:text-white font-semibold text-base mb-2 block">西方确指</span>
1717
<p class="block text-gray-400 whitespace-pre-line text-[12px]">觉明妙行菩萨说
1818
菩萨戒弟子常摄集</p>
1919
<p class="text-gray-400 whitespace-pre-line text-[12px]">庐山东林寺印经处</p>
@@ -22,19 +22,19 @@
2222
</li>
2323
</ul>
2424
</div>
25-
<footer class="mt-10 w-full border-t">
25+
<footer class="mt-10 w-full border-t dark:border-zinc-800">
2626
<section class="max-w-7xl m-auto text-[13px] py-5 text-gray-500">
27-
<p class="text-sm kaiti text-zinc-600">
27+
<div class="text-sm kaiti text-zinc-600 dark:text-zinc-200">
2828
<h3>回向偈</h3>
29-
愿以此功德,
29+
<p>愿以此功德,
3030
庄严佛净土。
3131
上报四重恩,
3232
下济三途苦。
3333
若有见闻者,
3434
悉发菩提心。
3535
尽此一报身,
36-
同生极乐国。
37-
</p>
36+
同生极乐国。</p>
37+
</div>
3838
<ul class="mt-3">
3939
<li class="kaiti"></li>
4040
<li>* 本项目与各地的护法寺均不存在任何关系</li>
@@ -52,9 +52,9 @@ useSeoMeta({
5252
<style scoped>
5353
5454
.app {
55-
@apply h-screen bg-[--background-color] bg-stone-100 relative;
55+
@apply h-screen bg-[--background-color] bg-stone-100 dark:bg-stone-900 relative;
5656
}
5757
.description {
58-
@apply text-gray-500 text-sm py-0 px-1;
58+
@apply text-gray-500 dark:text-gray-400 text-sm py-0 px-1;
5959
}
6060
</style>

0 commit comments

Comments
 (0)