@dfosco/storyboard-react-primer 3.8.0 → 3.8.2
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.
- package/package.json +2 -2
- package/src/ThemeSync.jsx +73 -0
- package/src/index.js +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dfosco/storyboard-react-primer",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"src"
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@dfosco/storyboard-react": "3.8.
|
|
15
|
+
"@dfosco/storyboard-react": "3.8.2"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
18
|
"@primer/react": ">=37",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThemeSync — invisible React component that bridges the storyboard-core
|
|
3
|
+
* toolbar theme switcher with Primer's ThemeProvider context.
|
|
4
|
+
*
|
|
5
|
+
* Listens for `storyboard:theme:changed` custom events dispatched by the
|
|
6
|
+
* core theme store and calls setColorMode/setDayScheme/setNightScheme on
|
|
7
|
+
* Primer's useTheme() hook accordingly.
|
|
8
|
+
*
|
|
9
|
+
* On mount it reads localStorage to initialize Primer to the correct
|
|
10
|
+
* scheme before the Svelte CoreUIBar has loaded.
|
|
11
|
+
*
|
|
12
|
+
* When prototype sync is disabled (via "Apply theme to" settings), the
|
|
13
|
+
* prototype is forced to light mode regardless of the selected theme.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { useEffect } from 'react'
|
|
17
|
+
import { useTheme } from '@primer/react'
|
|
18
|
+
|
|
19
|
+
const THEME_STORAGE_KEY = 'sb-color-scheme'
|
|
20
|
+
const THEME_SYNC_STORAGE_KEY = 'sb-theme-sync'
|
|
21
|
+
|
|
22
|
+
const DEFAULT_SYNC = {
|
|
23
|
+
prototype: true,
|
|
24
|
+
toolbar: false,
|
|
25
|
+
codeBoxes: true,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function readSyncTargets() {
|
|
29
|
+
try {
|
|
30
|
+
const raw = localStorage.getItem(THEME_SYNC_STORAGE_KEY)
|
|
31
|
+
if (!raw) return DEFAULT_SYNC
|
|
32
|
+
return { ...DEFAULT_SYNC, ...JSON.parse(raw) }
|
|
33
|
+
} catch {
|
|
34
|
+
return DEFAULT_SYNC
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function applyToPrimer(setColorMode, setDayScheme, setNightScheme, themeValue) {
|
|
39
|
+
if (themeValue === 'system' || !themeValue) {
|
|
40
|
+
setColorMode('auto')
|
|
41
|
+
setDayScheme('light')
|
|
42
|
+
setNightScheme('dark')
|
|
43
|
+
} else {
|
|
44
|
+
setColorMode('day')
|
|
45
|
+
setDayScheme(themeValue)
|
|
46
|
+
setNightScheme(themeValue)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default function ThemeSync() {
|
|
51
|
+
const { setColorMode, setDayScheme, setNightScheme } = useTheme()
|
|
52
|
+
|
|
53
|
+
// Restore saved theme on mount
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
const saved = localStorage.getItem(THEME_STORAGE_KEY)
|
|
56
|
+
const syncTargets = readSyncTargets()
|
|
57
|
+
const prototypeTheme = syncTargets.prototype ? saved : 'light'
|
|
58
|
+
applyToPrimer(setColorMode, setDayScheme, setNightScheme, prototypeTheme)
|
|
59
|
+
}, []) // eslint-disable-line react-hooks/exhaustive-deps
|
|
60
|
+
|
|
61
|
+
// Listen for theme changes from the Svelte CoreUIBar
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
function handleThemeChanged(e) {
|
|
64
|
+
const { prototypeTheme } = e.detail || {}
|
|
65
|
+
if (typeof prototypeTheme !== 'string') return
|
|
66
|
+
applyToPrimer(setColorMode, setDayScheme, setNightScheme, prototypeTheme)
|
|
67
|
+
}
|
|
68
|
+
document.addEventListener('storyboard:theme:changed', handleThemeChanged)
|
|
69
|
+
return () => document.removeEventListener('storyboard:theme:changed', handleThemeChanged)
|
|
70
|
+
}, [setColorMode, setDayScheme, setNightScheme])
|
|
71
|
+
|
|
72
|
+
return null
|
|
73
|
+
}
|
package/src/index.js
CHANGED
|
@@ -12,5 +12,8 @@ export { default as Checkbox } from './Checkbox.jsx'
|
|
|
12
12
|
export { default as Textarea } from './Textarea.jsx'
|
|
13
13
|
export { default as StoryboardForm } from './StoryboardForm.jsx'
|
|
14
14
|
|
|
15
|
+
// Theme bridge (Primer ThemeProvider ↔ storyboard-core theme store)
|
|
16
|
+
export { default as ThemeSync } from './ThemeSync.jsx'
|
|
17
|
+
|
|
15
18
|
// Scene data demo
|
|
16
19
|
export { default as SceneDataDemo } from './SceneDataDemo.jsx'
|