Skip to content

Commit 98792c0

Browse files
committed
feat: 明暗模式设置为跟随系统时,支持动态切换
1 parent e07c59f commit 98792c0

File tree

5 files changed

+61
-23
lines changed

5 files changed

+61
-23
lines changed

src/store/modules/settings.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,28 @@ export const useSettingsStore = defineStore(
66
'settings',
77
() => {
88
const settings = ref(settingsDefault)
9-
watch(() => settings.value.app.colorScheme, (colorScheme) => {
9+
10+
const prefersColorScheme = window.matchMedia('(prefers-color-scheme: dark)')
11+
const currentColorScheme = ref<Exclude<Settings.app['colorScheme'], ''>>()
12+
watch(() => settings.value.app.colorScheme, (val) => {
13+
if (val === '') {
14+
prefersColorScheme.addEventListener('change', updateTheme)
15+
}
16+
else {
17+
prefersColorScheme.removeEventListener('change', updateTheme)
18+
}
19+
}, {
20+
immediate: true,
21+
})
22+
watch(() => settings.value.app.colorScheme, updateTheme, {
23+
immediate: true,
24+
})
25+
function updateTheme() {
26+
let colorScheme = settings.value.app.colorScheme
1027
if (colorScheme === '') {
11-
colorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
28+
colorScheme = prefersColorScheme.matches ? 'dark' : 'light'
1229
}
30+
currentColorScheme.value = colorScheme
1331
switch (colorScheme) {
1432
case 'dark':
1533
document.documentElement.classList.add('dark')
@@ -18,9 +36,8 @@ export const useSettingsStore = defineStore(
1836
document.documentElement.classList.remove('dark')
1937
break
2038
}
21-
}, {
22-
immediate: true,
23-
})
39+
}
40+
2441
watch(() => settings.value.menu.menuMode, (val) => {
2542
document.body.setAttribute('data-menu-mode', val)
2643
}, {
@@ -60,6 +77,7 @@ export const useSettingsStore = defineStore(
6077

6178
return {
6279
settings,
80+
currentColorScheme,
6381
os,
6482
title,
6583
previewAllWindows,

src/views/components/AppSetting/index.vue

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ const menuStore = useMenuStore()
1515
1616
const isShow = ref(false)
1717
18-
const isDark = computed({
19-
get() {
20-
return settingsStore.settings.app.colorScheme === 'dark'
21-
},
22-
set(value) {
23-
settingsStore.settings.app.colorScheme = value ? 'dark' : 'light'
24-
},
25-
})
26-
2718
watch(() => settingsStore.settings.menu.menuMode, (value) => {
2819
if (value === 'single') {
2920
menuStore.setActived(0)
@@ -91,7 +82,15 @@ function handleCopy() {
9182
颜色主题风格
9283
</div>
9384
<div class="flex items-center justify-center pb-4">
94-
<HToggle v-model="isDark" on-icon="ri:sun-line" off-icon="ri:moon-line" />
85+
<HTabList
86+
v-model="settingsStore.settings.app.colorScheme"
87+
:options="[
88+
{ icon: 'i-ri:sun-line', label: '明亮', value: 'light' },
89+
{ icon: 'i-ri:moon-line', label: '暗黑', value: 'dark' },
90+
{ icon: 'i-ri:computer-line', label: '系统', value: '' },
91+
]"
92+
class="w-60"
93+
/>
9594
</div>
9695
<div class="divider">
9796
导航栏模式

src/views/components/Topbar/ColorScheme/index.vue

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const settingsStore = useSettingsStore()
99
1010
function toggleColorScheme(event: MouseEvent) {
1111
const { startViewTransition } = useViewTransition(() => {
12-
settingsStore.setColorScheme(settingsStore.settings.app.colorScheme === 'dark' ? 'light' : 'dark')
12+
settingsStore.currentColorScheme && settingsStore.setColorScheme(settingsStore.currentColorScheme === 'dark' ? 'light' : 'dark')
1313
})
1414
startViewTransition()?.ready.then(() => {
1515
const x = event.clientX
@@ -37,7 +37,24 @@ function toggleColorScheme(event: MouseEvent) {
3737
</script>
3838

3939
<template>
40-
<span class="flex-center cursor-pointer px-2 py-1" @click="toggleColorScheme">
41-
<SvgIcon :name="settingsStore.settings.app.colorScheme === 'light' ? 'i-ri:sun-line' : 'i-ri:moon-line'" />
42-
</span>
40+
<HDropdown class="flex-center cursor-pointer px-2 py-1">
41+
<SvgIcon
42+
:name="{
43+
'': 'i-ri:computer-line',
44+
'light': 'i-ri:sun-line',
45+
'dark': 'i-ri:moon-line',
46+
}[settingsStore.settings.app.colorScheme]" @click="toggleColorScheme"
47+
/>
48+
<template #dropdown>
49+
<HTabList
50+
v-model="settingsStore.settings.app.colorScheme"
51+
:options="[
52+
{ icon: 'i-ri:sun-line', label: '', value: 'light' },
53+
{ icon: 'i-ri:moon-line', label: '', value: 'dark' },
54+
{ icon: 'i-ri:computer-line', label: '', value: '' },
55+
]"
56+
class="m-3"
57+
/>
58+
</template>
59+
</HDropdown>
4360
</template>

src/views/ui-kit/HTabList.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Tab, TabGroup, TabList } from '@headlessui/vue'
33
44
const props = defineProps<{
55
options: {
6+
icon?: string
67
label: any
78
value: T
89
}[]
@@ -37,11 +38,12 @@ function handleChange(index: number) {
3738
<TabList class="inline-flex select-none items-center justify-center rounded-md bg-stone-1 p-1 ring-1 ring-stone-2 dark:bg-stone-9 dark:ring-stone-8">
3839
<Tab v-for="(option, index) in options" :key="index" v-slot="{ selected }" as="template">
3940
<button
40-
class="w-full inline-flex items-center justify-center truncate border-size-0 rounded-md bg-inherit px-2 py-1.5 text-sm text-dark ring-stone-2 ring-inset dark:text-white focus:outline-none focus:ring-2 dark:ring-stone-8" :class="{
41+
class="w-full inline-flex items-center justify-center gap-1 break-keep border-size-0 rounded-md bg-inherit px-2 py-1.5 text-sm text-dark ring-stone-2 ring-inset dark:text-white focus:outline-none focus:ring-2 dark:ring-stone-8" :class="{
4142
'cursor-default bg-white dark:bg-dark-9': selected,
42-
'cursor-pointer opacity-50 transition hover:(opacity-100)': !selected,
43+
'cursor-pointer opacity-50 hover:(opacity-100)': !selected,
4344
}"
4445
>
46+
<SvgIcon v-if="option.icon" :name="option.icon" class="flex-shrink-0" />
4547
{{ option.label }}
4648
</button>
4749
</Tab>

src/views/ui-kit/HTooltip.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
withDefaults(
33
defineProps<{
44
text: string
5-
enable: boolean
5+
enable?: boolean
66
}>(),
77
{
88
text: '',
@@ -20,5 +20,7 @@ withDefaults(
2020
</slot>
2121
</template>
2222
</VTooltip>
23-
<slot v-else />
23+
<div v-else>
24+
<slot />
25+
</div>
2426
</template>

0 commit comments

Comments
 (0)