theme.vue 1.9 KB

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