theme.vue 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <script setup lang="ts">
  2. import type { ThemeModeType } from '@vben/types';
  3. import type { Component } from 'vue';
  4. import { MoonStar, Sun, SunMoon } from '@vben/icons';
  5. import { $t } from '@vben/locales';
  6. import SwitchItem from '../switch-item.vue';
  7. defineOptions({
  8. name: 'PreferenceTheme',
  9. });
  10. const modelValue = defineModel<string>({ default: 'auto' });
  11. const themeSemiDarkMenu = defineModel<boolean>('themeSemiDarkMenu', {
  12. default: true,
  13. });
  14. const THEME_PRESET: Array<{ icon: Component; name: ThemeModeType }> = [
  15. {
  16. icon: Sun,
  17. name: 'light',
  18. },
  19. {
  20. icon: MoonStar,
  21. name: 'dark',
  22. },
  23. {
  24. icon: SunMoon,
  25. name: 'auto',
  26. },
  27. ];
  28. function activeClass(theme: string): string[] {
  29. return theme === modelValue.value ? ['outline-box-active'] : [];
  30. }
  31. function nameView(name: string) {
  32. switch (name) {
  33. case 'light': {
  34. return $t('preferences.theme.light');
  35. }
  36. case 'dark': {
  37. return $t('preferences.theme.dark');
  38. }
  39. case 'auto': {
  40. return $t('preferences.followSystem');
  41. }
  42. }
  43. }
  44. </script>
  45. <template>
  46. <div class="flex w-full flex-wrap justify-between">
  47. <template v-for="theme in THEME_PRESET" :key="theme.name">
  48. <div
  49. class="flex cursor-pointer flex-col"
  50. @click="modelValue = theme.name"
  51. >
  52. <div
  53. :class="activeClass(theme.name)"
  54. class="outline-box flex-center py-4"
  55. >
  56. <component :is="theme.icon" class="mx-9 size-5" />
  57. </div>
  58. <div class="text-muted-foreground mt-2 text-center text-xs">
  59. {{ nameView(theme.name) }}
  60. </div>
  61. </div>
  62. </template>
  63. <SwitchItem
  64. v-model="themeSemiDarkMenu"
  65. :disabled="modelValue === 'dark'"
  66. class="mt-6"
  67. >
  68. {{ $t('preferences.theme.darkMenu') }}
  69. </SwitchItem>
  70. </div>
  71. </template>