theme.vue 1.7 KB

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