@try-works/dsh-recursive-mode 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Board/Inspector theme state (run 16 / Paper). Default LIGHT, dark via a
3
+ * header toggle that flips data-theme on the root .rec-board / .rec-inspector.
4
+ * Persisted to localStorage under 'dsh-recursive-theme' (first visit = light).
5
+ */
6
+ import { createElement, useCallback, useEffect, useState } from 'react'
7
+
8
+ export const BOARD_THEME_STORAGE_KEY = 'dsh-recursive-theme'
9
+
10
+ export type BoardTheme = 'light' | 'dark'
11
+
12
+ export interface BoardThemeState {
13
+ theme: BoardTheme
14
+ toggle: () => void
15
+ }
16
+
17
+ function readInitialTheme(): BoardTheme {
18
+ if (typeof localStorage === 'undefined') return 'light'
19
+ try {
20
+ return localStorage.getItem(BOARD_THEME_STORAGE_KEY) === 'dark' ? 'dark' : 'light'
21
+ } catch {
22
+ return 'light'
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Hoisted at the TOP of Board and Inspector (never after an early return — run
28
+ * 0.1.10 invariant). Defaults light, reads a persisted dark on init, and writes
29
+ * the chosen theme back to localStorage.
30
+ */
31
+ export function useBoardTheme(): BoardThemeState {
32
+ const [theme, setTheme] = useState<BoardTheme>(readInitialTheme)
33
+ const toggle = useCallback(() => setTheme((t) => (t === 'light' ? 'dark' : 'light')), [])
34
+ useEffect(() => {
35
+ try {
36
+ localStorage.setItem(BOARD_THEME_STORAGE_KEY, theme)
37
+ } catch {
38
+ /* storage unavailable — theme still works for the session */
39
+ }
40
+ }, [theme])
41
+ return { theme, toggle }
42
+ }
43
+
44
+ /** The shared header toggle button (moon in light, sun in dark). */
45
+ export function ThemeToggle({ theme, toggle }: BoardThemeState) {
46
+ return createElement('button', {
47
+ type: 'button',
48
+ className: 'rec-theme-toggle',
49
+ onClick: toggle,
50
+ title: theme === 'light' ? 'Switch to dark theme' : 'Switch to light theme',
51
+ 'aria-label': 'Toggle theme',
52
+ }, theme === 'light' ? '☾' : '☀')
53
+ }