theme-toggle.vue 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <script lang="ts" setup>
  2. import {
  3. IcRoundMotionPhotosAuto,
  4. IcRoundWbSunny,
  5. MdiMoonAndStars,
  6. } from '@vben-core/iconify';
  7. import {
  8. flatPreferences,
  9. updatePreferences,
  10. usePreferences,
  11. } from '@vben-core/preferences';
  12. import {
  13. ToggleGroup,
  14. ToggleGroupItem,
  15. VbenTooltip,
  16. } from '@vben-core/shadcn-ui';
  17. import { $t } from '@vben/locales';
  18. import ThemeButton from './theme-button.vue';
  19. defineOptions({
  20. name: 'ThemeToggle',
  21. });
  22. withDefaults(defineProps<{ shouldOnHover?: boolean }>(), {
  23. shouldOnHover: false,
  24. });
  25. function handleChange(isDark: boolean) {
  26. updatePreferences({
  27. app: { themeMode: isDark ? 'dark' : 'light' },
  28. });
  29. }
  30. const { isDark } = usePreferences();
  31. const PRESETS = [
  32. {
  33. icon: IcRoundWbSunny,
  34. name: 'light',
  35. title: $t('preference.light'),
  36. },
  37. {
  38. icon: MdiMoonAndStars,
  39. name: 'dark',
  40. title: $t('preference.dark'),
  41. },
  42. {
  43. icon: IcRoundMotionPhotosAuto,
  44. name: 'auto',
  45. title: $t('preference.follow-system'),
  46. },
  47. ];
  48. </script>
  49. <template>
  50. <div>
  51. <VbenTooltip side="bottom" :disabled="!shouldOnHover">
  52. <template #trigger>
  53. <ThemeButton
  54. :model-value="isDark"
  55. type="icon"
  56. @update:model-value="handleChange"
  57. />
  58. </template>
  59. <ToggleGroup
  60. v-model="flatPreferences.appThemeMode"
  61. type="single"
  62. variant="outline"
  63. class="gap-2"
  64. >
  65. <ToggleGroupItem
  66. v-for="item in PRESETS"
  67. :key="item.name"
  68. :value="item.name"
  69. >
  70. <component :is="item.icon" class="size-5" />
  71. </ToggleGroupItem>
  72. </ToggleGroup>
  73. </VbenTooltip>
  74. </div>
  75. </template>