|
1 | 1 | 'use client' |
2 | | -import { useId, useState } from 'react' |
3 | 2 |
|
4 | | -import type { DevupTheme } from '../types/theme' |
5 | | -import { useSafeEffect } from './use-safe-effect' |
| 3 | +import { useSyncExternalStore } from 'react' |
| 4 | +import { themeStore } from 'src/stores/themeStore' |
6 | 5 |
|
7 | | -let observer: null | MutationObserver = null |
8 | | -const setThemeMap: Record<string, React.Dispatch<keyof DevupTheme>> = {} |
9 | | -let globalTheme: keyof DevupTheme | null = null |
10 | | - |
11 | | -export function useTheme(): keyof DevupTheme | null { |
12 | | - const id = useId() |
13 | | - const [theme, setTheme] = useState<keyof DevupTheme | null>(globalTheme) |
14 | | - useSafeEffect(() => { |
15 | | - if (globalTheme !== null) return |
16 | | - const currentTheme = document.documentElement.getAttribute('data-theme') |
17 | | - if (currentTheme !== null && currentTheme !== theme) |
18 | | - setTheme(currentTheme as keyof DevupTheme) |
19 | | - }, [theme]) |
20 | | - useSafeEffect(() => { |
21 | | - const targetNode = document.documentElement |
22 | | - setThemeMap[id] = setTheme |
23 | | - if (!observer) { |
24 | | - observer = new MutationObserver(() => { |
25 | | - const theme = document.documentElement.getAttribute('data-theme') |
26 | | - globalTheme = theme as keyof DevupTheme |
27 | | - for (const key in setThemeMap) |
28 | | - setThemeMap[key](theme as keyof DevupTheme) |
29 | | - }) |
30 | | - observer.observe(targetNode, { |
31 | | - attributes: true, |
32 | | - attributeFilter: ['data-theme'], |
33 | | - childList: false, |
34 | | - subtree: false, |
35 | | - characterData: false, |
36 | | - attributeOldValue: false, |
37 | | - characterDataOldValue: false, |
38 | | - }) |
39 | | - } |
40 | | - |
41 | | - return () => { |
42 | | - delete setThemeMap[id] |
43 | | - if (observer && Object.keys(setThemeMap).length === 0) |
44 | | - observer.disconnect() |
45 | | - } |
46 | | - }, [id]) |
| 6 | +export function useTheme() { |
| 7 | + const theme = useSyncExternalStore( |
| 8 | + themeStore.subscribe, |
| 9 | + themeStore.get, |
| 10 | + themeStore.get, |
| 11 | + ) |
47 | 12 | return theme |
48 | 13 | } |
0 commit comments