theme-toggle.vue 1.8 KB

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