Files
SuBlog/components/layout/ThemeToggle.vue
T
2026-06-30 00:06:02 +08:00

49 lines
1.3 KiB
Vue

<script setup lang="ts">
import { Icon } from '@iconify/vue'
const colorMode = useColorMode()
type Mode = 'system' | 'dark' | 'light'
const iconMap: Record<Mode, string> = {
system: 'mdi:monitor',
dark: 'mdi:weather-night',
light: 'mdi:weather-sunny',
}
const labelMap: Record<Mode, string> = {
system: '跟随系统',
dark: '深色模式',
light: '浅色模式',
}
const cycleOrder = computed<Mode[]>(() => {
const isDark = colorMode.value === 'dark'
return isDark ? ['system', 'light', 'dark'] : ['system', 'dark', 'light']
})
const currentMode = computed(() => colorMode.preference as Mode)
const currentIcon = computed(() => iconMap[currentMode.value] || iconMap.system)
const currentLabel = computed(() => labelMap[currentMode.value] || labelMap.system)
function cycle() {
const order = cycleOrder.value
const idx = order.indexOf(currentMode.value)
colorMode.preference = order[(idx + 1) % order.length]
}
</script>
<template>
<button
@click="cycle"
class="inline-flex items-center justify-center rounded-md w-8 h-8 transition-colors"
style="color: var(--color-text-secondary)"
:class="[
'hover:bg-[var(--color-bg-hover)] hover:text-[var(--color-text)]',
]"
:aria-label="currentLabel"
:title="currentLabel"
>
<Icon :icon="currentIcon" class="w-5 h-5" />
</button>
</template>