@ttoss/fsl-theme 1.1.22 → 2.1.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/README.md +54 -41
- package/dist/{Types-BiBa17RL.d.cts → Types-a_sfpbha.d.cts} +84 -24
- package/dist/{Types-BiBa17RL.d.mts → Types-a_sfpbha.d.mts} +84 -24
- package/dist/{baseBundle-DiYlHNG5.mjs → baseBundle-CXdxj_re.mjs} +3 -2
- package/dist/{baseBundle-BWbICg4p.cjs → baseBundle-a9LDsqYy.cjs} +3 -2
- package/dist/{createTheme-BHGc1IFI.cjs → createTheme-B7H0xSVp.cjs} +128 -19
- package/dist/{createTheme-C1r5nJco.mjs → createTheme-Bm9LVQ4w.mjs} +123 -20
- package/dist/css.cjs +5 -4
- package/dist/css.d.cts +21 -2
- package/dist/css.d.mts +21 -2
- package/dist/css.mjs +5 -4
- package/dist/dataviz/index.cjs +2 -2
- package/dist/dataviz/index.d.cts +1 -1
- package/dist/dataviz/index.d.mts +1 -1
- package/dist/dataviz/index.mjs +1 -1
- package/dist/dtcg.cjs +26 -9
- package/dist/dtcg.d.cts +17 -4
- package/dist/dtcg.d.mts +17 -4
- package/dist/dtcg.mjs +26 -9
- package/dist/{helpers-CIqeJ8yd.cjs → helpers-BU40JvFA.cjs} +27 -5
- package/dist/{helpers-Dz7NfNK6.mjs → helpers-BXaKe2s3.mjs} +27 -5
- package/dist/{index-BuszkWMy.d.mts → index-BmZQVd3G.d.cts} +9 -12
- package/dist/{index-Djro6G4e.d.cts → index-XZsRrMTF.d.mts} +9 -12
- package/dist/index.cjs +2 -8
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -5
- package/dist/{react-D2J482kx.d.mts → react-BwsjWKmo.d.mts} +59 -16
- package/dist/{react-BKLEzIN8.cjs → react-DQErMGJz.cjs} +107 -19
- package/dist/{react-BXqSYnmk.d.cts → react-Drr-QSuX.d.cts} +59 -16
- package/dist/react.cjs +3 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.mts +1 -1
- package/dist/react.mjs +109 -19
- package/dist/runtime-entry.cjs +1 -1
- package/dist/runtime-entry.mjs +1 -1
- package/dist/{ssrScript-D3mYscp1.cjs → ssrScript-D73WcrCM.cjs} +52 -4
- package/dist/{ssrScript-DfmopH-w.mjs → ssrScript-zDK1dqXr.mjs} +52 -4
- package/dist/themes/bruttal.cjs +19 -4
- package/dist/themes/bruttal.d.cts +1 -1
- package/dist/themes/bruttal.d.mts +1 -1
- package/dist/themes/bruttal.mjs +19 -4
- package/dist/{toCssVars-CeckLjW1.mjs → toCssVars-CWTlp9St.mjs} +65 -5
- package/dist/{toCssVars-DDowz4wU.cjs → toCssVars-D0BR23cP.cjs} +65 -5
- package/dist/{tokenRegistry-DolhB5Vf.mjs → tokenRegistry-DviyqDeE.mjs} +19 -28
- package/dist/{tokenRegistry-B9zMRjpL.cjs → tokenRegistry-f_Bx_BAN.cjs} +19 -28
- package/dist/vars.cjs +8 -8
- package/dist/vars.d.cts +6 -6
- package/dist/vars.d.mts +6 -6
- package/dist/vars.mjs +8 -8
- package/dist/{withDataviz-BzZwFV2e.cjs → withDataviz-DrUtw8cc.cjs} +2 -2
- package/dist/{withDataviz-CrgXLR5A.mjs → withDataviz-Ln3sEwb7.mjs} +2 -2
- package/llms.txt +11 -9
- package/package.json +1 -1
- package/dist/themes/corporate.cjs +0 -34
- package/dist/themes/corporate.d.cts +0 -3
- package/dist/themes/corporate.d.mts +0 -3
- package/dist/themes/corporate.mjs +0 -31
- package/dist/themes/oca.cjs +0 -34
- package/dist/themes/oca.d.cts +0 -3
- package/dist/themes/oca.d.mts +0 -3
- package/dist/themes/oca.mjs +0 -31
- package/dist/themes/ventures.cjs +0 -34
- package/dist/themes/ventures.d.cts +0 -3
- package/dist/themes/ventures.d.mts +0 -3
- package/dist/themes/ventures.mjs +0 -31
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
-
const require_helpers = require('./helpers-
|
|
2
|
+
const require_helpers = require('./helpers-BU40JvFA.cjs');
|
|
3
3
|
|
|
4
4
|
//#region src/themeBootstrap.ts
|
|
5
5
|
/**
|
|
@@ -18,7 +18,7 @@ var resolveTheme = cfg => {
|
|
|
18
18
|
const mode = stored != null && stored.mode != null && cfg.validModes.indexOf(stored.mode) !== -1 ? stored.mode : cfg.defaultMode;
|
|
19
19
|
return {
|
|
20
20
|
mode,
|
|
21
|
-
resolvedMode: mode === "system" ? typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : mode
|
|
21
|
+
resolvedMode: mode === "system" ? typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : mode
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -34,6 +34,20 @@ var writeStorage = (key, data) => {
|
|
|
34
34
|
localStorage.setItem(key, JSON.stringify(data));
|
|
35
35
|
} catch {}
|
|
36
36
|
};
|
|
37
|
+
var createMediaQuery = () => {
|
|
38
|
+
if (typeof window.matchMedia === "function") return window.matchMedia("(prefers-color-scheme: dark)");
|
|
39
|
+
return {
|
|
40
|
+
matches: false,
|
|
41
|
+
addEventListener: () => {},
|
|
42
|
+
removeEventListener: () => {}
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* DEV-only registry of live runtimes per root element. Two runtimes writing
|
|
47
|
+
* `data-tt-*` to the same root overwrite each other (last writer wins), so
|
|
48
|
+
* the second attach warns. Entries are decremented on `destroy()`.
|
|
49
|
+
*/
|
|
50
|
+
var activeRuntimesPerRoot = /* @__PURE__ */new WeakMap();
|
|
37
51
|
/**
|
|
38
52
|
* Creates a framework-agnostic runtime that manages theme switching.
|
|
39
53
|
*
|
|
@@ -60,6 +74,11 @@ var createThemeRuntime = (config = {}) => {
|
|
|
60
74
|
} = config;
|
|
61
75
|
const listeners = /* @__PURE__ */new Set();
|
|
62
76
|
let destroyed = false;
|
|
77
|
+
if (process.env.NODE_ENV !== "production") {
|
|
78
|
+
const count = (activeRuntimesPerRoot.get(root) ?? 0) + 1;
|
|
79
|
+
activeRuntimesPerRoot.set(root, count);
|
|
80
|
+
if (count > 1) console.warn("[fsl-theme] Multiple theme runtimes are attached to the same root element. They overwrite each other's data-tt-* attributes (last writer wins) and their mode states do not sync. Render a single <ThemeProvider> per root, or pass a distinct `root` to each.");
|
|
81
|
+
}
|
|
63
82
|
const init = resolveTheme({
|
|
64
83
|
storageKey,
|
|
65
84
|
defaultMode,
|
|
@@ -94,7 +113,7 @@ var createThemeRuntime = (config = {}) => {
|
|
|
94
113
|
const state = getState();
|
|
95
114
|
for (const listener of listeners) listener(state);
|
|
96
115
|
};
|
|
97
|
-
const mediaQuery =
|
|
116
|
+
const mediaQuery = createMediaQuery();
|
|
98
117
|
const onSystemChange = () => {
|
|
99
118
|
if (destroyed) return;
|
|
100
119
|
resolvedMode = mediaQuery.matches ? "dark" : "light";
|
|
@@ -107,6 +126,30 @@ var createThemeRuntime = (config = {}) => {
|
|
|
107
126
|
if (active) mediaQuery.addEventListener("change", onSystemChange);
|
|
108
127
|
};
|
|
109
128
|
syncMediaListener(mode === "system");
|
|
129
|
+
/** Parse + validate a persisted `{ mode }` payload; null when unusable. */
|
|
130
|
+
const parseStoredMode = raw => {
|
|
131
|
+
let stored = null;
|
|
132
|
+
try {
|
|
133
|
+
stored = JSON.parse(raw);
|
|
134
|
+
} catch {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const nextMode = stored?.mode;
|
|
138
|
+
return nextMode && VALID_MODES.includes(nextMode) ? nextMode : null;
|
|
139
|
+
};
|
|
140
|
+
const onStorage = event => {
|
|
141
|
+
if (destroyed || event.key !== storageKey || event.newValue === null) return;
|
|
142
|
+
if (event.storageArea != null && event.storageArea !== localStorage) return;
|
|
143
|
+
const nextMode = parseStoredMode(event.newValue);
|
|
144
|
+
if (!nextMode) return;
|
|
145
|
+
mode = nextMode;
|
|
146
|
+
resolvedMode = mode === "system" ? mediaQuery.matches ? "dark" : "light" : mode;
|
|
147
|
+
syncMediaListener(mode === "system");
|
|
148
|
+
applyState({
|
|
149
|
+
persist: false
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
window.addEventListener("storage", onStorage);
|
|
110
153
|
const setMode = newMode => {
|
|
111
154
|
if (destroyed || !VALID_MODES.includes(newMode)) return;
|
|
112
155
|
mode = newMode;
|
|
@@ -126,7 +169,12 @@ var createThemeRuntime = (config = {}) => {
|
|
|
126
169
|
const destroy = () => {
|
|
127
170
|
destroyed = true;
|
|
128
171
|
syncMediaListener(false);
|
|
172
|
+
window.removeEventListener("storage", onStorage);
|
|
129
173
|
listeners.clear();
|
|
174
|
+
if (process.env.NODE_ENV !== "production") {
|
|
175
|
+
const count = activeRuntimesPerRoot.get(root) ?? 0;
|
|
176
|
+
activeRuntimesPerRoot.set(root, Math.max(0, count - 1));
|
|
177
|
+
}
|
|
130
178
|
};
|
|
131
179
|
return {
|
|
132
180
|
getState,
|
|
@@ -173,7 +221,7 @@ var getThemeScriptContent = (config = {}) => {
|
|
|
173
221
|
defaultTheme,
|
|
174
222
|
defaultMode,
|
|
175
223
|
validModes: [...VALID_MODES]
|
|
176
|
-
})};var d=document.documentElement;var s=null;try{var r=localStorage.getItem(cfg.storageKey);if(r)s=JSON.parse(r);}catch(e){}var m=(s!=null&&s.mode!=null&&cfg.validModes.indexOf(s.mode)!==-1)?s.mode:cfg.defaultMode;var rm=m==="system"?(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"):m;if(cfg.defaultTheme){d.setAttribute("data-tt-theme",cfg.defaultTheme);}else{d.removeAttribute("data-tt-theme");}d.setAttribute("data-tt-mode",rm);d.style.colorScheme=rm;})()`;
|
|
224
|
+
}).replace(/</g, "\\u003C")};var d=document.documentElement;var s=null;try{var r=localStorage.getItem(cfg.storageKey);if(r)s=JSON.parse(r);}catch(e){}var m=(s!=null&&s.mode!=null&&cfg.validModes.indexOf(s.mode)!==-1)?s.mode:cfg.defaultMode;var rm=m==="system"?(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"):m;if(cfg.defaultTheme){d.setAttribute("data-tt-theme",cfg.defaultTheme);}else{d.removeAttribute("data-tt-theme");}d.setAttribute("data-tt-mode",rm);d.style.colorScheme=rm;})()`;
|
|
177
225
|
};
|
|
178
226
|
|
|
179
227
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
-
import { n as SAFE_ID_RE } from "./helpers-
|
|
2
|
+
import { n as SAFE_ID_RE } from "./helpers-BXaKe2s3.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/themeBootstrap.ts
|
|
5
5
|
/**
|
|
@@ -18,7 +18,7 @@ var resolveTheme = cfg => {
|
|
|
18
18
|
const mode = stored != null && stored.mode != null && cfg.validModes.indexOf(stored.mode) !== -1 ? stored.mode : cfg.defaultMode;
|
|
19
19
|
return {
|
|
20
20
|
mode,
|
|
21
|
-
resolvedMode: mode === "system" ? typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : mode
|
|
21
|
+
resolvedMode: mode === "system" ? typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : mode
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -34,6 +34,20 @@ var writeStorage = (key, data) => {
|
|
|
34
34
|
localStorage.setItem(key, JSON.stringify(data));
|
|
35
35
|
} catch {}
|
|
36
36
|
};
|
|
37
|
+
var createMediaQuery = () => {
|
|
38
|
+
if (typeof window.matchMedia === "function") return window.matchMedia("(prefers-color-scheme: dark)");
|
|
39
|
+
return {
|
|
40
|
+
matches: false,
|
|
41
|
+
addEventListener: () => {},
|
|
42
|
+
removeEventListener: () => {}
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* DEV-only registry of live runtimes per root element. Two runtimes writing
|
|
47
|
+
* `data-tt-*` to the same root overwrite each other (last writer wins), so
|
|
48
|
+
* the second attach warns. Entries are decremented on `destroy()`.
|
|
49
|
+
*/
|
|
50
|
+
var activeRuntimesPerRoot = /* @__PURE__ */new WeakMap();
|
|
37
51
|
/**
|
|
38
52
|
* Creates a framework-agnostic runtime that manages theme switching.
|
|
39
53
|
*
|
|
@@ -60,6 +74,11 @@ var createThemeRuntime = (config = {}) => {
|
|
|
60
74
|
} = config;
|
|
61
75
|
const listeners = /* @__PURE__ */new Set();
|
|
62
76
|
let destroyed = false;
|
|
77
|
+
if (process.env.NODE_ENV !== "production") {
|
|
78
|
+
const count = (activeRuntimesPerRoot.get(root) ?? 0) + 1;
|
|
79
|
+
activeRuntimesPerRoot.set(root, count);
|
|
80
|
+
if (count > 1) console.warn("[fsl-theme] Multiple theme runtimes are attached to the same root element. They overwrite each other's data-tt-* attributes (last writer wins) and their mode states do not sync. Render a single <ThemeProvider> per root, or pass a distinct `root` to each.");
|
|
81
|
+
}
|
|
63
82
|
const init = resolveTheme({
|
|
64
83
|
storageKey,
|
|
65
84
|
defaultMode,
|
|
@@ -94,7 +113,7 @@ var createThemeRuntime = (config = {}) => {
|
|
|
94
113
|
const state = getState();
|
|
95
114
|
for (const listener of listeners) listener(state);
|
|
96
115
|
};
|
|
97
|
-
const mediaQuery =
|
|
116
|
+
const mediaQuery = createMediaQuery();
|
|
98
117
|
const onSystemChange = () => {
|
|
99
118
|
if (destroyed) return;
|
|
100
119
|
resolvedMode = mediaQuery.matches ? "dark" : "light";
|
|
@@ -107,6 +126,30 @@ var createThemeRuntime = (config = {}) => {
|
|
|
107
126
|
if (active) mediaQuery.addEventListener("change", onSystemChange);
|
|
108
127
|
};
|
|
109
128
|
syncMediaListener(mode === "system");
|
|
129
|
+
/** Parse + validate a persisted `{ mode }` payload; null when unusable. */
|
|
130
|
+
const parseStoredMode = raw => {
|
|
131
|
+
let stored = null;
|
|
132
|
+
try {
|
|
133
|
+
stored = JSON.parse(raw);
|
|
134
|
+
} catch {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const nextMode = stored?.mode;
|
|
138
|
+
return nextMode && VALID_MODES.includes(nextMode) ? nextMode : null;
|
|
139
|
+
};
|
|
140
|
+
const onStorage = event => {
|
|
141
|
+
if (destroyed || event.key !== storageKey || event.newValue === null) return;
|
|
142
|
+
if (event.storageArea != null && event.storageArea !== localStorage) return;
|
|
143
|
+
const nextMode = parseStoredMode(event.newValue);
|
|
144
|
+
if (!nextMode) return;
|
|
145
|
+
mode = nextMode;
|
|
146
|
+
resolvedMode = mode === "system" ? mediaQuery.matches ? "dark" : "light" : mode;
|
|
147
|
+
syncMediaListener(mode === "system");
|
|
148
|
+
applyState({
|
|
149
|
+
persist: false
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
window.addEventListener("storage", onStorage);
|
|
110
153
|
const setMode = newMode => {
|
|
111
154
|
if (destroyed || !VALID_MODES.includes(newMode)) return;
|
|
112
155
|
mode = newMode;
|
|
@@ -126,7 +169,12 @@ var createThemeRuntime = (config = {}) => {
|
|
|
126
169
|
const destroy = () => {
|
|
127
170
|
destroyed = true;
|
|
128
171
|
syncMediaListener(false);
|
|
172
|
+
window.removeEventListener("storage", onStorage);
|
|
129
173
|
listeners.clear();
|
|
174
|
+
if (process.env.NODE_ENV !== "production") {
|
|
175
|
+
const count = activeRuntimesPerRoot.get(root) ?? 0;
|
|
176
|
+
activeRuntimesPerRoot.set(root, Math.max(0, count - 1));
|
|
177
|
+
}
|
|
130
178
|
};
|
|
131
179
|
return {
|
|
132
180
|
getState,
|
|
@@ -173,7 +221,7 @@ var getThemeScriptContent = (config = {}) => {
|
|
|
173
221
|
defaultTheme,
|
|
174
222
|
defaultMode,
|
|
175
223
|
validModes: [...VALID_MODES]
|
|
176
|
-
})};var d=document.documentElement;var s=null;try{var r=localStorage.getItem(cfg.storageKey);if(r)s=JSON.parse(r);}catch(e){}var m=(s!=null&&s.mode!=null&&cfg.validModes.indexOf(s.mode)!==-1)?s.mode:cfg.defaultMode;var rm=m==="system"?(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"):m;if(cfg.defaultTheme){d.setAttribute("data-tt-theme",cfg.defaultTheme);}else{d.removeAttribute("data-tt-theme");}d.setAttribute("data-tt-mode",rm);d.style.colorScheme=rm;})()`;
|
|
224
|
+
}).replace(/</g, "\\u003C")};var d=document.documentElement;var s=null;try{var r=localStorage.getItem(cfg.storageKey);if(r)s=JSON.parse(r);}catch(e){}var m=(s!=null&&s.mode!=null&&cfg.validModes.indexOf(s.mode)!==-1)?s.mode:cfg.defaultMode;var rm=m==="system"?(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"):m;if(cfg.defaultTheme){d.setAttribute("data-tt-theme",cfg.defaultTheme);}else{d.removeAttribute("data-tt-theme");}d.setAttribute("data-tt-mode",rm);d.style.colorScheme=rm;})()`;
|
|
177
225
|
};
|
|
178
226
|
|
|
179
227
|
//#endregion
|
package/dist/themes/bruttal.cjs
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, {
|
|
3
3
|
value: 'Module'
|
|
4
4
|
});
|
|
5
|
-
const require_createTheme = require('../createTheme-
|
|
6
|
-
const require_helpers = require('../helpers-
|
|
7
|
-
const require_withDataviz = require('../withDataviz-
|
|
5
|
+
const require_createTheme = require('../createTheme-B7H0xSVp.cjs');
|
|
6
|
+
const require_helpers = require('../helpers-BU40JvFA.cjs');
|
|
7
|
+
const require_withDataviz = require('../withDataviz-DrUtw8cc.cjs');
|
|
8
8
|
|
|
9
9
|
//#region src/themes/bruttal.ts
|
|
10
10
|
/**
|
|
@@ -67,7 +67,22 @@ var bundle = require_createTheme.createTheme({
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
})
|
|
70
|
+
}),
|
|
71
|
+
brief: {
|
|
72
|
+
name: "bruttal",
|
|
73
|
+
purpose: "warm-brown brutalist brand identity",
|
|
74
|
+
primaryPosture: "expressive",
|
|
75
|
+
secondaryPosture: "technical",
|
|
76
|
+
densityProfile: "balanced",
|
|
77
|
+
readingMode: "mixed",
|
|
78
|
+
pointerProfile: "hybrid",
|
|
79
|
+
interactionRisk: "medium",
|
|
80
|
+
surfaceModel: "flat",
|
|
81
|
+
brandEnergy: "expressive",
|
|
82
|
+
accessibilityTarget: "AA+",
|
|
83
|
+
colorModeStrategy: "dark-supported",
|
|
84
|
+
platformBias: "web"
|
|
85
|
+
}
|
|
71
86
|
});
|
|
72
87
|
var bruttal = require_withDataviz.withDataviz(bundle);
|
|
73
88
|
|
package/dist/themes/bruttal.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
-
import {
|
|
3
|
-
import { r as deepMerge } from "../helpers-
|
|
4
|
-
import { t as withDataviz } from "../withDataviz-
|
|
2
|
+
import { a as darkAlternate, n as createTheme } from "../createTheme-Bm9LVQ4w.mjs";
|
|
3
|
+
import { r as deepMerge } from "../helpers-BXaKe2s3.mjs";
|
|
4
|
+
import { t as withDataviz } from "../withDataviz-Ln3sEwb7.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/themes/bruttal.ts
|
|
7
7
|
/**
|
|
@@ -64,7 +64,22 @@ var bundle = createTheme({
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
})
|
|
67
|
+
}),
|
|
68
|
+
brief: {
|
|
69
|
+
name: "bruttal",
|
|
70
|
+
purpose: "warm-brown brutalist brand identity",
|
|
71
|
+
primaryPosture: "expressive",
|
|
72
|
+
secondaryPosture: "technical",
|
|
73
|
+
densityProfile: "balanced",
|
|
74
|
+
readingMode: "mixed",
|
|
75
|
+
pointerProfile: "hybrid",
|
|
76
|
+
interactionRisk: "medium",
|
|
77
|
+
surfaceModel: "flat",
|
|
78
|
+
brandEnergy: "expressive",
|
|
79
|
+
accessibilityTarget: "AA+",
|
|
80
|
+
colorModeStrategy: "dark-supported",
|
|
81
|
+
platformBias: "web"
|
|
82
|
+
}
|
|
68
83
|
});
|
|
69
84
|
var bruttal = withDataviz(bundle);
|
|
70
85
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
-
import { a as flattenTheme, i as flattenObject, n as SAFE_ID_RE, r as deepMerge, t as COMPOUND_REF_RE } from "./helpers-
|
|
3
|
-
import { t as CSS_PATH_PREFIXES } from "./tokenRegistry-
|
|
2
|
+
import { a as flattenTheme, i as flattenObject, n as SAFE_ID_RE, r as deepMerge, t as COMPOUND_REF_RE } from "./helpers-BXaKe2s3.mjs";
|
|
3
|
+
import { t as CSS_PATH_PREFIXES } from "./tokenRegistry-DviyqDeE.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/roots/toCssVars.ts
|
|
6
6
|
/**
|
|
@@ -11,7 +11,7 @@ import { t as CSS_PATH_PREFIXES } from "./tokenRegistry-DolhB5Vf.mjs";
|
|
|
11
11
|
*/
|
|
12
12
|
var toCssVarName = tokenPath => {
|
|
13
13
|
for (const [prefix, cssPrefix] of CSS_PATH_PREFIXES) if (tokenPath.startsWith(prefix)) return `${cssPrefix}${tokenPath.slice(prefix.length).replace(/\./g, "-")}`;
|
|
14
|
-
return `--tt-${tokenPath.replace(/\./g, "-")}`;
|
|
14
|
+
return `--tt-${(tokenPath.startsWith("semantic.") ? tokenPath.slice(9) : tokenPath).replace(/\./g, "-")}`;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
17
|
* Replace all embedded `{token.path}` refs inside a raw string with `var(--tt-...)` references.
|
|
@@ -26,6 +26,27 @@ var inlineRefsToVars = value => {
|
|
|
26
26
|
});
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
|
+
* Assert that no two token paths collapse to the same CSS custom property name.
|
|
30
|
+
*
|
|
31
|
+
* `toCssVarName` is first-match-wins with no duplicate detection, so two
|
|
32
|
+
* distinct token paths sharing a `cssPrefix` (e.g. a future
|
|
33
|
+
* `semantic.dataviz.color.state.*` vs `semantic.dataviz.geo.state.*`) could
|
|
34
|
+
* silently overwrite each other in the flat record. This guards the whole
|
|
35
|
+
* registry, not just dataviz.
|
|
36
|
+
*
|
|
37
|
+
* **DEV-only** — callers gate this behind `process.env.NODE_ENV !== 'production'`
|
|
38
|
+
* so bundlers tree-shake the entire call in production builds.
|
|
39
|
+
*/
|
|
40
|
+
var assertDistinctCssVars = flat => {
|
|
41
|
+
const byVarName = /* @__PURE__ */new Map();
|
|
42
|
+
for (const path of Object.keys(flat)) {
|
|
43
|
+
const varName = toCssVarName(path);
|
|
44
|
+
const existing = byVarName.get(varName);
|
|
45
|
+
if (existing !== void 0 && existing !== path) throw new Error(`[fsl-theme] CSS variable name collision: '${varName}' is produced by both '${existing}' and '${path}'. Give one of them a distinct token path or CSS prefix (see roots/tokenRegistry.ts).`);
|
|
46
|
+
byVarName.set(varName, path);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
29
50
|
* Build a flat CSS custom properties record from a ThemeTokens.
|
|
30
51
|
*
|
|
31
52
|
* Core tokens get raw values. Semantic tokens get `var()` references
|
|
@@ -42,6 +63,10 @@ var buildCssVars = theme => {
|
|
|
42
63
|
const varName = toCssVarName(path);
|
|
43
64
|
if (typeof value === "string" && value.includes("{")) vars[varName] = inlineRefsToVars(value);else vars[varName] = value;
|
|
44
65
|
}
|
|
66
|
+
if (process.env.NODE_ENV !== "production") assertDistinctCssVars({
|
|
67
|
+
...coreFlat,
|
|
68
|
+
...semanticFlat
|
|
69
|
+
});
|
|
45
70
|
return vars;
|
|
46
71
|
};
|
|
47
72
|
var sanitizeId = value => {
|
|
@@ -187,6 +212,34 @@ var isThemeBundle = input => {
|
|
|
187
212
|
return "baseMode" in input && "base" in input;
|
|
188
213
|
};
|
|
189
214
|
/**
|
|
215
|
+
* Build the no-JS / pre-hydration system-mode fallback block.
|
|
216
|
+
*
|
|
217
|
+
* Canonical 1-theme model only (no `themeId`): before the runtime (or the SSR
|
|
218
|
+
* bootstrap script) stamps `data-tt-mode`, and for users with JavaScript
|
|
219
|
+
* disabled, the alternate mode would otherwise never apply. This block scopes
|
|
220
|
+
* the alternate diff vars to `@media (prefers-color-scheme: <mode>)` behind
|
|
221
|
+
* `:root:not([data-tt-mode])`, so it applies exactly while no explicit mode
|
|
222
|
+
* attribute exists and gets out of the way the moment the runtime writes one
|
|
223
|
+
* (persisted user choice always wins over the OS preference).
|
|
224
|
+
*/
|
|
225
|
+
var buildSystemModeFallbackBlock = ({
|
|
226
|
+
mode,
|
|
227
|
+
vars
|
|
228
|
+
}) => {
|
|
229
|
+
const entries = Object.entries(vars);
|
|
230
|
+
const selector = ":root:not([data-tt-mode])";
|
|
231
|
+
const lines = entries.map(([name, value]) => {
|
|
232
|
+
return ` ${name}: ${hasCqUnits(value) ? toViewportFallback(String(value)) : value};`;
|
|
233
|
+
});
|
|
234
|
+
const cqEntries = entries.filter(([, value]) => {
|
|
235
|
+
return hasCqUnits(value);
|
|
236
|
+
});
|
|
237
|
+
const cqBlock = cqEntries.length > 0 ? `\n\n @supports (width: 1cqi) {\n ${selector} {\n${cqEntries.map(([name, value]) => {
|
|
238
|
+
return ` ${name}: ${value};`;
|
|
239
|
+
}).join("\n")}\n }\n }` : "";
|
|
240
|
+
return `@media (prefers-color-scheme: ${mode}) {\n ${selector} {\n color-scheme: ${mode};\n${lines.join("\n")}\n }${cqBlock}\n}`;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
190
243
|
* Compute a diff record: only entries in `full` whose values differ from `base`.
|
|
191
244
|
*/
|
|
192
245
|
var diffCssVars = ({
|
|
@@ -213,7 +266,8 @@ var diffCssVars = ({
|
|
|
213
266
|
*/
|
|
214
267
|
var bundleToCssVars = (bundle, options) => {
|
|
215
268
|
const {
|
|
216
|
-
themeId
|
|
269
|
+
themeId,
|
|
270
|
+
systemModeFallback = true
|
|
217
271
|
} = options;
|
|
218
272
|
const {
|
|
219
273
|
baseMode,
|
|
@@ -272,7 +326,13 @@ var bundleToCssVars = (bundle, options) => {
|
|
|
272
326
|
alternate: alternateResult,
|
|
273
327
|
toCssString: () => {
|
|
274
328
|
const parts = [baseResult.toCssString()];
|
|
275
|
-
if (Object.keys(diffVars).length > 0)
|
|
329
|
+
if (Object.keys(diffVars).length > 0) {
|
|
330
|
+
parts.push(alternateResult.toCssString());
|
|
331
|
+
if (!themeId && systemModeFallback) parts.push(buildSystemModeFallbackBlock({
|
|
332
|
+
mode: alternateMode,
|
|
333
|
+
vars: diffVars
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
276
336
|
return parts.join("\n\n");
|
|
277
337
|
}
|
|
278
338
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
-
const require_helpers = require('./helpers-
|
|
3
|
-
const require_tokenRegistry = require('./tokenRegistry-
|
|
2
|
+
const require_helpers = require('./helpers-BU40JvFA.cjs');
|
|
3
|
+
const require_tokenRegistry = require('./tokenRegistry-f_Bx_BAN.cjs');
|
|
4
4
|
|
|
5
5
|
//#region src/roots/toCssVars.ts
|
|
6
6
|
/**
|
|
@@ -11,7 +11,7 @@ const require_tokenRegistry = require('./tokenRegistry-B9zMRjpL.cjs');
|
|
|
11
11
|
*/
|
|
12
12
|
var toCssVarName = tokenPath => {
|
|
13
13
|
for (const [prefix, cssPrefix] of require_tokenRegistry.CSS_PATH_PREFIXES) if (tokenPath.startsWith(prefix)) return `${cssPrefix}${tokenPath.slice(prefix.length).replace(/\./g, "-")}`;
|
|
14
|
-
return `--tt-${tokenPath.replace(/\./g, "-")}`;
|
|
14
|
+
return `--tt-${(tokenPath.startsWith("semantic.") ? tokenPath.slice(9) : tokenPath).replace(/\./g, "-")}`;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
17
|
* Replace all embedded `{token.path}` refs inside a raw string with `var(--tt-...)` references.
|
|
@@ -26,6 +26,27 @@ var inlineRefsToVars = value => {
|
|
|
26
26
|
});
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
|
+
* Assert that no two token paths collapse to the same CSS custom property name.
|
|
30
|
+
*
|
|
31
|
+
* `toCssVarName` is first-match-wins with no duplicate detection, so two
|
|
32
|
+
* distinct token paths sharing a `cssPrefix` (e.g. a future
|
|
33
|
+
* `semantic.dataviz.color.state.*` vs `semantic.dataviz.geo.state.*`) could
|
|
34
|
+
* silently overwrite each other in the flat record. This guards the whole
|
|
35
|
+
* registry, not just dataviz.
|
|
36
|
+
*
|
|
37
|
+
* **DEV-only** — callers gate this behind `process.env.NODE_ENV !== 'production'`
|
|
38
|
+
* so bundlers tree-shake the entire call in production builds.
|
|
39
|
+
*/
|
|
40
|
+
var assertDistinctCssVars = flat => {
|
|
41
|
+
const byVarName = /* @__PURE__ */new Map();
|
|
42
|
+
for (const path of Object.keys(flat)) {
|
|
43
|
+
const varName = toCssVarName(path);
|
|
44
|
+
const existing = byVarName.get(varName);
|
|
45
|
+
if (existing !== void 0 && existing !== path) throw new Error(`[fsl-theme] CSS variable name collision: '${varName}' is produced by both '${existing}' and '${path}'. Give one of them a distinct token path or CSS prefix (see roots/tokenRegistry.ts).`);
|
|
46
|
+
byVarName.set(varName, path);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
29
50
|
* Build a flat CSS custom properties record from a ThemeTokens.
|
|
30
51
|
*
|
|
31
52
|
* Core tokens get raw values. Semantic tokens get `var()` references
|
|
@@ -42,6 +63,10 @@ var buildCssVars = theme => {
|
|
|
42
63
|
const varName = toCssVarName(path);
|
|
43
64
|
if (typeof value === "string" && value.includes("{")) vars[varName] = inlineRefsToVars(value);else vars[varName] = value;
|
|
44
65
|
}
|
|
66
|
+
if (process.env.NODE_ENV !== "production") assertDistinctCssVars({
|
|
67
|
+
...coreFlat,
|
|
68
|
+
...semanticFlat
|
|
69
|
+
});
|
|
45
70
|
return vars;
|
|
46
71
|
};
|
|
47
72
|
var sanitizeId = value => {
|
|
@@ -187,6 +212,34 @@ var isThemeBundle = input => {
|
|
|
187
212
|
return "baseMode" in input && "base" in input;
|
|
188
213
|
};
|
|
189
214
|
/**
|
|
215
|
+
* Build the no-JS / pre-hydration system-mode fallback block.
|
|
216
|
+
*
|
|
217
|
+
* Canonical 1-theme model only (no `themeId`): before the runtime (or the SSR
|
|
218
|
+
* bootstrap script) stamps `data-tt-mode`, and for users with JavaScript
|
|
219
|
+
* disabled, the alternate mode would otherwise never apply. This block scopes
|
|
220
|
+
* the alternate diff vars to `@media (prefers-color-scheme: <mode>)` behind
|
|
221
|
+
* `:root:not([data-tt-mode])`, so it applies exactly while no explicit mode
|
|
222
|
+
* attribute exists and gets out of the way the moment the runtime writes one
|
|
223
|
+
* (persisted user choice always wins over the OS preference).
|
|
224
|
+
*/
|
|
225
|
+
var buildSystemModeFallbackBlock = ({
|
|
226
|
+
mode,
|
|
227
|
+
vars
|
|
228
|
+
}) => {
|
|
229
|
+
const entries = Object.entries(vars);
|
|
230
|
+
const selector = ":root:not([data-tt-mode])";
|
|
231
|
+
const lines = entries.map(([name, value]) => {
|
|
232
|
+
return ` ${name}: ${hasCqUnits(value) ? toViewportFallback(String(value)) : value};`;
|
|
233
|
+
});
|
|
234
|
+
const cqEntries = entries.filter(([, value]) => {
|
|
235
|
+
return hasCqUnits(value);
|
|
236
|
+
});
|
|
237
|
+
const cqBlock = cqEntries.length > 0 ? `\n\n @supports (width: 1cqi) {\n ${selector} {\n${cqEntries.map(([name, value]) => {
|
|
238
|
+
return ` ${name}: ${value};`;
|
|
239
|
+
}).join("\n")}\n }\n }` : "";
|
|
240
|
+
return `@media (prefers-color-scheme: ${mode}) {\n ${selector} {\n color-scheme: ${mode};\n${lines.join("\n")}\n }${cqBlock}\n}`;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
190
243
|
* Compute a diff record: only entries in `full` whose values differ from `base`.
|
|
191
244
|
*/
|
|
192
245
|
var diffCssVars = ({
|
|
@@ -213,7 +266,8 @@ var diffCssVars = ({
|
|
|
213
266
|
*/
|
|
214
267
|
var bundleToCssVars = (bundle, options) => {
|
|
215
268
|
const {
|
|
216
|
-
themeId
|
|
269
|
+
themeId,
|
|
270
|
+
systemModeFallback = true
|
|
217
271
|
} = options;
|
|
218
272
|
const {
|
|
219
273
|
baseMode,
|
|
@@ -272,7 +326,13 @@ var bundleToCssVars = (bundle, options) => {
|
|
|
272
326
|
alternate: alternateResult,
|
|
273
327
|
toCssString: () => {
|
|
274
328
|
const parts = [baseResult.toCssString()];
|
|
275
|
-
if (Object.keys(diffVars).length > 0)
|
|
329
|
+
if (Object.keys(diffVars).length > 0) {
|
|
330
|
+
parts.push(alternateResult.toCssString());
|
|
331
|
+
if (!themeId && systemModeFallback) parts.push(buildSystemModeFallbackBlock({
|
|
332
|
+
mode: alternateMode,
|
|
333
|
+
vars: diffVars
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
276
336
|
return parts.join("\n\n");
|
|
277
337
|
}
|
|
278
338
|
};
|
|
@@ -20,28 +20,25 @@ var TOKEN_PATH_REGISTRY = [{
|
|
|
20
20
|
dtcgType: "number"
|
|
21
21
|
}, {
|
|
22
22
|
path: "core.dataviz.",
|
|
23
|
-
cssPrefix: "--tt-core-dataviz-"
|
|
24
|
-
dtcgType: "string"
|
|
23
|
+
cssPrefix: "--tt-core-dataviz-"
|
|
25
24
|
}, {
|
|
26
25
|
path: "semantic.dataviz.color.",
|
|
27
|
-
cssPrefix: "--tt-dataviz-",
|
|
26
|
+
cssPrefix: "--tt-dataviz-color-",
|
|
28
27
|
dtcgType: "color"
|
|
29
28
|
}, {
|
|
30
29
|
path: "semantic.dataviz.encoding.opacity.",
|
|
31
|
-
cssPrefix: "--tt-dataviz-",
|
|
30
|
+
cssPrefix: "--tt-dataviz-encoding-opacity-",
|
|
32
31
|
dtcgType: "number"
|
|
33
32
|
}, {
|
|
34
33
|
path: "semantic.dataviz.geo.",
|
|
35
|
-
cssPrefix: "--tt-dataviz-",
|
|
34
|
+
cssPrefix: "--tt-dataviz-geo-",
|
|
36
35
|
dtcgType: "color"
|
|
37
36
|
}, {
|
|
38
37
|
path: "semantic.dataviz.encoding.",
|
|
39
|
-
cssPrefix: "--tt-dataviz-"
|
|
40
|
-
dtcgType: "string"
|
|
38
|
+
cssPrefix: "--tt-dataviz-encoding-"
|
|
41
39
|
}, {
|
|
42
40
|
path: "semantic.dataviz.",
|
|
43
|
-
cssPrefix: "--tt-dataviz-"
|
|
44
|
-
dtcgType: "string"
|
|
41
|
+
cssPrefix: "--tt-dataviz-"
|
|
45
42
|
}, {
|
|
46
43
|
path: "core.colors.",
|
|
47
44
|
cssPrefix: "--tt-core-colors-",
|
|
@@ -72,12 +69,10 @@ var TOKEN_PATH_REGISTRY = [{
|
|
|
72
69
|
dtcgType: "dimension"
|
|
73
70
|
}, {
|
|
74
71
|
path: "core.font.optical.",
|
|
75
|
-
cssPrefix: "--tt-core-font-optical-"
|
|
76
|
-
dtcgType: "string"
|
|
72
|
+
cssPrefix: "--tt-core-font-optical-"
|
|
77
73
|
}, {
|
|
78
74
|
path: "core.font.numeric.",
|
|
79
|
-
cssPrefix: "--tt-core-font-numeric-"
|
|
80
|
-
dtcgType: "string"
|
|
75
|
+
cssPrefix: "--tt-core-font-numeric-"
|
|
81
76
|
}, {
|
|
82
77
|
path: "core.font.scale.",
|
|
83
78
|
cssPrefix: "--tt-core-font-scale-",
|
|
@@ -88,8 +83,7 @@ var TOKEN_PATH_REGISTRY = [{
|
|
|
88
83
|
dtcgType: "dimension"
|
|
89
84
|
}, {
|
|
90
85
|
path: "core.sizing.behavior.",
|
|
91
|
-
cssPrefix: "--tt-core-sizing-behavior-"
|
|
92
|
-
dtcgType: "string"
|
|
86
|
+
cssPrefix: "--tt-core-sizing-behavior-"
|
|
93
87
|
}, {
|
|
94
88
|
path: "core.sizing.",
|
|
95
89
|
cssPrefix: "--tt-core-sizing-",
|
|
@@ -104,8 +98,7 @@ var TOKEN_PATH_REGISTRY = [{
|
|
|
104
98
|
dtcgType: "dimension"
|
|
105
99
|
}, {
|
|
106
100
|
path: "core.border.style.",
|
|
107
|
-
cssPrefix: "--tt-core-border-style-"
|
|
108
|
-
dtcgType: "string"
|
|
101
|
+
cssPrefix: "--tt-core-border-style-"
|
|
109
102
|
}, {
|
|
110
103
|
path: "core.opacity.",
|
|
111
104
|
cssPrefix: "--tt-core-opacity-",
|
|
@@ -116,8 +109,7 @@ var TOKEN_PATH_REGISTRY = [{
|
|
|
116
109
|
dtcgType: "duration"
|
|
117
110
|
}, {
|
|
118
111
|
path: "core.motion.easing.",
|
|
119
|
-
cssPrefix: "--tt-core-motion-easing-"
|
|
120
|
-
dtcgType: "string"
|
|
112
|
+
cssPrefix: "--tt-core-motion-easing-"
|
|
121
113
|
}, {
|
|
122
114
|
path: "core.zIndex.level.",
|
|
123
115
|
cssPrefix: "--tt-core-z-index-",
|
|
@@ -136,8 +128,7 @@ var TOKEN_PATH_REGISTRY = [{
|
|
|
136
128
|
dtcgType: "shadow"
|
|
137
129
|
}, {
|
|
138
130
|
path: "semantic.text.",
|
|
139
|
-
cssPrefix: "--tt-text-"
|
|
140
|
-
dtcgType: "string"
|
|
131
|
+
cssPrefix: "--tt-text-"
|
|
141
132
|
}, {
|
|
142
133
|
path: "semantic.spacing.",
|
|
143
134
|
cssPrefix: "--tt-spacing-",
|
|
@@ -152,24 +143,21 @@ var TOKEN_PATH_REGISTRY = [{
|
|
|
152
143
|
dtcgType: "dimension"
|
|
153
144
|
}, {
|
|
154
145
|
path: "semantic.focus.",
|
|
155
|
-
cssPrefix: "--tt-focus-"
|
|
156
|
-
dtcgType: "string"
|
|
146
|
+
cssPrefix: "--tt-focus-"
|
|
157
147
|
}, {
|
|
158
148
|
path: "semantic.overlay.",
|
|
159
149
|
cssPrefix: "--tt-overlay-",
|
|
160
150
|
dtcgType: "color"
|
|
161
151
|
}, {
|
|
162
152
|
path: "semantic.border.",
|
|
163
|
-
cssPrefix: "--tt-border-"
|
|
164
|
-
dtcgType: "string"
|
|
153
|
+
cssPrefix: "--tt-border-"
|
|
165
154
|
}, {
|
|
166
155
|
path: "semantic.opacity.",
|
|
167
156
|
cssPrefix: "--tt-opacity-",
|
|
168
157
|
dtcgType: "number"
|
|
169
158
|
}, {
|
|
170
159
|
path: "semantic.motion.",
|
|
171
|
-
cssPrefix: "--tt-motion-"
|
|
172
|
-
dtcgType: "string"
|
|
160
|
+
cssPrefix: "--tt-motion-"
|
|
173
161
|
}, {
|
|
174
162
|
path: "semantic.zIndex.layer.",
|
|
175
163
|
cssPrefix: "--tt-z-index-",
|
|
@@ -179,7 +167,10 @@ var TOKEN_PATH_REGISTRY = [{
|
|
|
179
167
|
var CSS_PATH_PREFIXES = TOKEN_PATH_REGISTRY.map(e => {
|
|
180
168
|
return [e.path, e.cssPrefix];
|
|
181
169
|
});
|
|
182
|
-
/**
|
|
170
|
+
/**
|
|
171
|
+
* Derived lookup table: `[path, dtcgType]` pairs. `dtcgType` is `undefined` for
|
|
172
|
+
* opaque tokens — `toDTCG` omits `$type` when the matched entry has none.
|
|
173
|
+
*/
|
|
183
174
|
var DTCG_TYPE_PREFIXES = TOKEN_PATH_REGISTRY.map(e => {
|
|
184
175
|
return [e.path, e.dtcgType];
|
|
185
176
|
});
|