useAppearance.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import { onMounted, ref } from 'vue';
  2. export function updateTheme(value) {
  3. if (typeof window === 'undefined') {
  4. return;
  5. }
  6. if (value === 'system') {
  7. const mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
  8. const systemTheme = mediaQueryList.matches ? 'dark' : 'light';
  9. document.documentElement.classList.toggle('dark', systemTheme === 'dark');
  10. } else {
  11. document.documentElement.classList.toggle('dark', value === 'dark');
  12. }
  13. }
  14. const setCookie = (name, value, days = 365) => {
  15. if (typeof document === 'undefined') {
  16. return;
  17. }
  18. const maxAge = days * 24 * 60 * 60;
  19. document.cookie = `${name}=${value};path=/;max-age=${maxAge};SameSite=Lax`;
  20. };
  21. const mediaQuery = () => {
  22. if (typeof window === 'undefined') {
  23. return null;
  24. }
  25. return window.matchMedia('(prefers-color-scheme: dark)');
  26. };
  27. const getStoredAppearance = () => {
  28. if (typeof window === 'undefined') {
  29. return null;
  30. }
  31. return localStorage.getItem('appearance') | null;
  32. };
  33. const handleSystemThemeChange = () => {
  34. const currentAppearance = getStoredAppearance();
  35. updateTheme(currentAppearance || 'system');
  36. };
  37. export function initializeTheme() {
  38. if (typeof window === 'undefined') {
  39. return;
  40. }
  41. // Initialize theme from saved preference or default to system...
  42. const savedAppearance = getStoredAppearance();
  43. updateTheme(savedAppearance || 'system');
  44. // Set up system theme change listener...
  45. mediaQuery()?.addEventListener('change', handleSystemThemeChange);
  46. }
  47. const appearance = ref('system');
  48. export function useAppearance() {
  49. onMounted(() => {
  50. const savedAppearance = localStorage.getItem('appearance') | null;
  51. if (savedAppearance) {
  52. appearance.value = savedAppearance;
  53. }
  54. });
  55. function updateAppearance(value) {
  56. appearance.value = value;
  57. // Store in localStorage for client-side persistence...
  58. localStorage.setItem('appearance', value);
  59. // Store in cookie for SSR...
  60. setCookie('appearance', value);
  61. updateTheme(value);
  62. }
  63. return {
  64. appearance,
  65. updateAppearance,
  66. };
  67. }