@dfosco/storyboard-core 1.21.0 → 1.22.0
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 +1 -1
- package/src/bodyClasses.js +8 -4
- package/src/featureFlags.js +26 -5
- package/src/index.js +1 -1
package/package.json
CHANGED
package/src/bodyClasses.js
CHANGED
|
@@ -11,9 +11,11 @@ import { getAllParams } from './session.js'
|
|
|
11
11
|
import { isHideMode, getAllShadows } from './hideMode.js'
|
|
12
12
|
import { subscribeToHash } from './hashSubscribe.js'
|
|
13
13
|
import { subscribeToStorage } from './localStorage.js'
|
|
14
|
+
import { syncFlagBodyClasses } from './featureFlags.js'
|
|
14
15
|
|
|
15
16
|
const PREFIX = 'sb-'
|
|
16
17
|
const SCENE_PREFIX = 'sb-scene--'
|
|
18
|
+
const FF_PREFIX = 'sb-ff-'
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Sanitize a string for use in a CSS class name.
|
|
@@ -41,13 +43,13 @@ function overrideClass(key, value) {
|
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
/**
|
|
44
|
-
* Get all current sb- classes on body (excluding scene classes).
|
|
46
|
+
* Get all current sb- classes on body (excluding scene and feature-flag classes).
|
|
45
47
|
* @returns {Set<string>}
|
|
46
48
|
*/
|
|
47
49
|
function getCurrentOverrideClasses() {
|
|
48
50
|
const classes = new Set()
|
|
49
51
|
for (const cls of document.body.classList) {
|
|
50
|
-
if (cls.startsWith(PREFIX) && !cls.startsWith(SCENE_PREFIX)) {
|
|
52
|
+
if (cls.startsWith(PREFIX) && !cls.startsWith(SCENE_PREFIX) && !cls.startsWith(FF_PREFIX)) {
|
|
51
53
|
classes.add(cls)
|
|
52
54
|
}
|
|
53
55
|
}
|
|
@@ -108,8 +110,10 @@ export function setSceneClass(name) {
|
|
|
108
110
|
*/
|
|
109
111
|
export function installBodyClassSync() {
|
|
110
112
|
syncOverrideClasses()
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
+
syncFlagBodyClasses()
|
|
114
|
+
const sync = () => { syncOverrideClasses(); syncFlagBodyClasses() }
|
|
115
|
+
const unsubHash = subscribeToHash(sync)
|
|
116
|
+
const unsubStorage = subscribeToStorage(sync)
|
|
113
117
|
return () => {
|
|
114
118
|
unsubHash()
|
|
115
119
|
unsubStorage()
|
package/src/featureFlags.js
CHANGED
|
@@ -15,23 +15,42 @@ import { getParam, setParam, removeParam, getAllParams } from './session.js'
|
|
|
15
15
|
import { getLocal, setLocal, removeLocal, getAllLocal } from './localStorage.js'
|
|
16
16
|
|
|
17
17
|
const FLAG_PREFIX = 'flag.'
|
|
18
|
+
const BODY_CLASS_PREFIX = 'sb-ff-'
|
|
18
19
|
|
|
19
20
|
/** Module-level storage for config defaults */
|
|
20
21
|
let _defaults = {}
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Sync body classes for active feature flags.
|
|
25
|
+
* Adds `sb-ff-{name}` for every flag that resolves to true,
|
|
26
|
+
* removes it for every flag that resolves to false.
|
|
27
|
+
*/
|
|
28
|
+
export function syncFlagBodyClasses() {
|
|
29
|
+
if (typeof document === 'undefined') return
|
|
30
|
+
for (const key of Object.keys(_defaults)) {
|
|
31
|
+
const cls = BODY_CLASS_PREFIX + key
|
|
32
|
+
if (getFlag(key)) {
|
|
33
|
+
document.body.classList.add(cls)
|
|
34
|
+
} else {
|
|
35
|
+
document.body.classList.remove(cls)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
22
40
|
/**
|
|
23
41
|
* Initialize the feature flag system with config defaults.
|
|
24
|
-
*
|
|
42
|
+
* Syncs localStorage with config defaults on every call.
|
|
25
43
|
* @param {Record<string, boolean>} defaults - Flag key → default value
|
|
26
44
|
*/
|
|
27
45
|
export function initFeatureFlags(defaults = {}) {
|
|
28
46
|
_defaults = { ...defaults }
|
|
29
|
-
//
|
|
47
|
+
// Sync localStorage with config defaults — always overwrite so config
|
|
48
|
+
// changes take effect. User overrides live in the URL hash, which is
|
|
49
|
+
// checked first by getFlag(), so this is safe.
|
|
30
50
|
for (const [key, value] of Object.entries(_defaults)) {
|
|
31
|
-
|
|
32
|
-
setLocal(FLAG_PREFIX + key, String(value))
|
|
33
|
-
}
|
|
51
|
+
setLocal(FLAG_PREFIX + key, String(value))
|
|
34
52
|
}
|
|
53
|
+
syncFlagBodyClasses()
|
|
35
54
|
}
|
|
36
55
|
|
|
37
56
|
/**
|
|
@@ -59,6 +78,7 @@ export function getFlag(key) {
|
|
|
59
78
|
*/
|
|
60
79
|
export function setFlag(key, value) {
|
|
61
80
|
setParam(FLAG_PREFIX + key, String(value))
|
|
81
|
+
syncFlagBodyClasses()
|
|
62
82
|
}
|
|
63
83
|
|
|
64
84
|
/**
|
|
@@ -101,6 +121,7 @@ export function resetFlags() {
|
|
|
101
121
|
removeLocal(localKey)
|
|
102
122
|
}
|
|
103
123
|
}
|
|
124
|
+
syncFlagBodyClasses()
|
|
104
125
|
}
|
|
105
126
|
|
|
106
127
|
/**
|
package/src/index.js
CHANGED
|
@@ -38,7 +38,7 @@ export { mountSceneDebug } from './sceneDebug.js'
|
|
|
38
38
|
export { hash, resolveSceneRoute, getSceneMeta } from './viewfinder.js'
|
|
39
39
|
|
|
40
40
|
// Feature flags
|
|
41
|
-
export { initFeatureFlags, getFlag, setFlag, toggleFlag, getAllFlags, resetFlags, getFlagKeys } from './featureFlags.js'
|
|
41
|
+
export { initFeatureFlags, getFlag, setFlag, toggleFlag, getAllFlags, resetFlags, getFlagKeys, syncFlagBodyClasses } from './featureFlags.js'
|
|
42
42
|
|
|
43
43
|
// Plugin configuration
|
|
44
44
|
export { initPlugins, isPluginEnabled, getPluginsConfig } from './plugins.js'
|