@ttoss/fsl-theme 1.1.12 → 1.1.14
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/dist/Types-BiBa17RL.d.cts +1427 -0
- package/dist/Types-BiBa17RL.d.mts +1427 -0
- package/dist/baseBundle-DxvXyhGa.mjs +17 -0
- package/dist/baseBundle-iEFf5nqT.cjs +22 -0
- package/dist/{esm/chunk-SE5Z52RE.js → createTheme-BLNYztZU.mjs} +76 -172
- package/dist/createTheme-Cv6RP9D6.cjs +1825 -0
- package/dist/css.cjs +48 -0
- package/dist/{css.d.ts → css.d.cts} +67 -63
- package/dist/css.d.mts +168 -0
- package/dist/css.mjs +42 -0
- package/dist/dataviz/index.cjs +45 -0
- package/dist/dataviz/{index.d.ts → index.d.cts} +9 -5
- package/dist/dataviz/index.d.mts +66 -0
- package/dist/dataviz/index.mjs +39 -0
- package/dist/dtcg.cjs +115 -0
- package/dist/{dtcg.d.ts → dtcg.d.cts} +9 -7
- package/dist/dtcg.d.mts +51 -0
- package/dist/dtcg.mjs +112 -0
- package/dist/helpers-4p4-QVt_.cjs +258 -0
- package/dist/helpers-CaswNJMy.mjs +211 -0
- package/dist/{index.d.ts → index-CsIjfw86.d.cts} +42 -34
- package/dist/index-nJrjI0BA.d.mts +94 -0
- package/dist/index.cjs +16 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.mjs +7 -0
- package/dist/{react.d.ts → react-CGa6FlNL.d.cts} +130 -106
- package/dist/react-DnKxR2gK.d.mts +370 -0
- package/dist/react-EUwpdvY7.cjs +481 -0
- package/dist/react.cjs +12 -0
- package/dist/react.d.cts +4 -0
- package/dist/react.d.mts +4 -0
- package/dist/react.mjs +412 -0
- package/dist/runtime-entry.cjs +9 -0
- package/dist/runtime-entry.d.cts +3 -0
- package/dist/runtime-entry.d.mts +3 -0
- package/dist/runtime-entry.mjs +3 -0
- package/dist/{runtime-entry.d.ts → ssrScript-BVysxDws.d.cts} +26 -23
- package/dist/ssrScript-BVysxDws.d.mts +98 -0
- package/dist/ssrScript-CRfrN8Pm.cjs +202 -0
- package/dist/ssrScript-D3kGPQpi.mjs +179 -0
- package/dist/themes/bruttal.cjs +75 -0
- package/dist/themes/bruttal.d.cts +3 -0
- package/dist/themes/bruttal.d.mts +3 -0
- package/dist/themes/bruttal.mjs +72 -0
- package/dist/themes/corporate.cjs +34 -0
- package/dist/themes/corporate.d.cts +3 -0
- package/dist/themes/corporate.d.mts +3 -0
- package/dist/{esm/chunk-TPMN75JM.js → themes/corporate.mjs} +7 -5
- package/dist/themes/oca.cjs +34 -0
- package/dist/themes/oca.d.cts +3 -0
- package/dist/themes/oca.d.mts +3 -0
- package/dist/{esm/chunk-DU4QDQUC.js → themes/oca.mjs} +7 -5
- package/dist/themes/ventures.cjs +34 -0
- package/dist/themes/ventures.d.cts +3 -0
- package/dist/themes/ventures.d.mts +3 -0
- package/dist/{esm/chunk-BXKVVQEP.js → themes/ventures.mjs} +7 -5
- package/dist/toCssVars-CYZCe-on.mjs +286 -0
- package/dist/toCssVars-DudHKvt2.cjs +297 -0
- package/dist/{esm/chunk-4Q4P3JBB.js → tokenRegistry-DjgSN3oU.mjs} +23 -20
- package/dist/tokenRegistry-OhaJ9sPJ.cjs +199 -0
- package/dist/vars.cjs +127 -0
- package/dist/{vars.d.ts → vars.d.cts} +8 -7
- package/dist/vars.d.mts +128 -0
- package/dist/vars.mjs +123 -0
- package/dist/withDataviz-B4pVsOwV.cjs +192 -0
- package/dist/{esm/chunk-FBVUI2PK.js → withDataviz-DY5s7R51.mjs} +40 -12
- package/package.json +6 -6
- package/dist/Types-6tR0_2Ss.d.ts +0 -1452
- package/dist/esm/chunk-5PWPAQMC.js +0 -9
- package/dist/esm/chunk-HRNXVRS3.js +0 -54
- package/dist/esm/chunk-IJGA42O6.js +0 -141
- package/dist/esm/chunk-PQPQNZ73.js +0 -262
- package/dist/esm/chunk-UMRQ4OTX.js +0 -11
- package/dist/esm/chunk-VL6EGE6Z.js +0 -222
- package/dist/esm/chunk-WVQSTQD5.js +0 -192
- package/dist/esm/css.js +0 -6
- package/dist/esm/dataviz/index.js +0 -19
- package/dist/esm/dtcg.js +0 -65
- package/dist/esm/index.js +0 -10
- package/dist/esm/react.js +0 -8
- package/dist/esm/runtime-entry.js +0 -4
- package/dist/esm/themes/bruttal.js +0 -6
- package/dist/esm/themes/corporate.js +0 -6
- package/dist/esm/themes/oca.js +0 -6
- package/dist/esm/themes/ventures.js +0 -6
- package/dist/esm/vars.js +0 -28
- package/dist/themes/bruttal.d.ts +0 -5
- package/dist/themes/corporate.d.ts +0 -5
- package/dist/themes/oca.d.ts +0 -5
- package/dist/themes/ventures.d.ts +0 -5
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: (k => from[k]).bind(null, key),
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
24
|
+
value: mod,
|
|
25
|
+
enumerable: true
|
|
26
|
+
}) : target, mod));
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
const require_helpers = require('./helpers-4p4-QVt_.cjs');
|
|
30
|
+
const require_css = require('./css.cjs');
|
|
31
|
+
const require_ssrScript = require('./ssrScript-CRfrN8Pm.cjs');
|
|
32
|
+
let react = require("react");
|
|
33
|
+
react = __toESM(react);
|
|
34
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
35
|
+
|
|
36
|
+
//#region src/react.tsx
|
|
37
|
+
const COARSE_QUERY = "(any-pointer: coarse)";
|
|
38
|
+
/**
|
|
39
|
+
* Subscribe to coarse-pointer media query changes.
|
|
40
|
+
* Returns `true` when the device has at least one coarse pointer (touch).
|
|
41
|
+
* Returns `false` on SSR or when `matchMedia` is unavailable (React Native).
|
|
42
|
+
*/
|
|
43
|
+
const useCoarsePointer = () => {
|
|
44
|
+
const [isCoarse, setIsCoarse] = react.useState(() => {
|
|
45
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(COARSE_QUERY).matches : false;
|
|
46
|
+
});
|
|
47
|
+
react.useEffect(() => {
|
|
48
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
49
|
+
const mql = window.matchMedia(COARSE_QUERY);
|
|
50
|
+
const handler = e => {
|
|
51
|
+
return setIsCoarse(e.matches);
|
|
52
|
+
};
|
|
53
|
+
mql.addEventListener("change", handler);
|
|
54
|
+
return () => {
|
|
55
|
+
return mql.removeEventListener("change", handler);
|
|
56
|
+
};
|
|
57
|
+
}, []);
|
|
58
|
+
return isCoarse;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Apply coarse-pointer hit target overrides to a resolved token map.
|
|
62
|
+
*
|
|
63
|
+
* When `isCoarse` is true, replaces `semantic.sizing.hit.{step}` values with
|
|
64
|
+
* the raw coarse values from `core.sizing.hit.coarse.{step}`. This mirrors
|
|
65
|
+
* the `@media (any-pointer: coarse)` block that `toCssVars` emits for CSS
|
|
66
|
+
* consumers — ensuring non-CSS consumers (React Native, canvas) get
|
|
67
|
+
* touch-appropriate hit targets.
|
|
68
|
+
*/
|
|
69
|
+
const applyCoarseHitOverrides = (tokens, theme, isCoarse) => {
|
|
70
|
+
if (!isCoarse) return tokens;
|
|
71
|
+
const overrides = {
|
|
72
|
+
...tokens
|
|
73
|
+
};
|
|
74
|
+
for (const [key, value] of Object.entries(theme.core.sizing.hit.coarse)) if (typeof value === "string") overrides[`semantic.sizing.hit.${key}`] = value;
|
|
75
|
+
return overrides;
|
|
76
|
+
};
|
|
77
|
+
const SemanticTokensCtx = react.createContext(null);
|
|
78
|
+
/**
|
|
79
|
+
* Resolves semantic tokens for the given bundle + mode combination.
|
|
80
|
+
*/
|
|
81
|
+
const resolveSemanticTokens = (bundle, resolvedMode) => {
|
|
82
|
+
if (resolvedMode === bundle.baseMode || !bundle.alternate?.semantic) return bundle.base.semantic;
|
|
83
|
+
return require_helpers.deepMerge(bundle.base.semantic, bundle.alternate.semantic);
|
|
84
|
+
};
|
|
85
|
+
const ResolvedTokensCtx = react.createContext(null);
|
|
86
|
+
const ModeCtx = react.createContext(null);
|
|
87
|
+
/**
|
|
88
|
+
* React provider that manages theme switching via `createThemeRuntime`.
|
|
89
|
+
*
|
|
90
|
+
* Applies `data-tt-theme` and `data-tt-mode` on `<html>` (or `root`),
|
|
91
|
+
* persists to localStorage, and listens to system color scheme changes.
|
|
92
|
+
* When `theme` is provided, automatically injects CSS Custom Properties into
|
|
93
|
+
* the document `<head>` via React 19 style hoisting.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```tsx
|
|
97
|
+
* import { ThemeProvider } from '@ttoss/fsl-theme/react';
|
|
98
|
+
* import { createTheme } from '@ttoss/fsl-theme';
|
|
99
|
+
*
|
|
100
|
+
* const myTheme = createTheme();
|
|
101
|
+
*
|
|
102
|
+
* export const App = () => (
|
|
103
|
+
* <ThemeProvider theme={myTheme}>
|
|
104
|
+
* <YourApp />
|
|
105
|
+
* </ThemeProvider>
|
|
106
|
+
* );
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
const ThemeProvider = ({
|
|
110
|
+
defaultMode,
|
|
111
|
+
storageKey,
|
|
112
|
+
theme,
|
|
113
|
+
themeId,
|
|
114
|
+
onModeChange,
|
|
115
|
+
root,
|
|
116
|
+
children
|
|
117
|
+
}) => {
|
|
118
|
+
const runtimeRef = react.useRef(null);
|
|
119
|
+
const initDefaultMode = react.useRef(defaultMode);
|
|
120
|
+
const initStorageKey = react.useRef(storageKey);
|
|
121
|
+
const [state, setState] = react.useState(() => {
|
|
122
|
+
return {
|
|
123
|
+
mode: defaultMode ?? "system",
|
|
124
|
+
resolvedMode: (defaultMode ?? "system") === "system" ? "light" : defaultMode
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
react.useEffect(() => {
|
|
128
|
+
const runtime = require_ssrScript.createThemeRuntime({
|
|
129
|
+
defaultTheme: themeId,
|
|
130
|
+
defaultMode: initDefaultMode.current,
|
|
131
|
+
storageKey: initStorageKey.current,
|
|
132
|
+
root
|
|
133
|
+
});
|
|
134
|
+
runtimeRef.current = runtime;
|
|
135
|
+
setState(runtime.getState());
|
|
136
|
+
const unsubscribe = runtime.subscribe(setState);
|
|
137
|
+
return () => {
|
|
138
|
+
unsubscribe();
|
|
139
|
+
runtime.destroy();
|
|
140
|
+
runtimeRef.current = null;
|
|
141
|
+
};
|
|
142
|
+
}, [root, themeId]);
|
|
143
|
+
const setMode = react.useCallback(mode => {
|
|
144
|
+
runtimeRef.current?.setMode(mode);
|
|
145
|
+
}, []);
|
|
146
|
+
const semanticTokens = react.useMemo(() => {
|
|
147
|
+
return theme ? resolveSemanticTokens(theme, state.resolvedMode) : null;
|
|
148
|
+
}, [theme, state.resolvedMode]);
|
|
149
|
+
const isCoarse = useCoarsePointer();
|
|
150
|
+
const resolvedTokens = react.useMemo(() => {
|
|
151
|
+
if (!theme || !semanticTokens) return null;
|
|
152
|
+
const all = require_helpers.toFlatTokens({
|
|
153
|
+
core: theme.base.core,
|
|
154
|
+
semantic: semanticTokens
|
|
155
|
+
});
|
|
156
|
+
const result = {};
|
|
157
|
+
for (const [key, value] of Object.entries(all)) if (key.startsWith("semantic.")) result[key] = value;
|
|
158
|
+
return applyCoarseHitOverrides(result, theme.base, isCoarse);
|
|
159
|
+
}, [theme, semanticTokens, isCoarse]);
|
|
160
|
+
const cssContent = react.useMemo(() => {
|
|
161
|
+
return theme ? require_css.getThemeStylesContent(theme, themeId) : null;
|
|
162
|
+
}, [theme, themeId]);
|
|
163
|
+
const onModeChangeRef = react.useRef(onModeChange);
|
|
164
|
+
react.useEffect(() => {
|
|
165
|
+
onModeChangeRef.current = onModeChange;
|
|
166
|
+
});
|
|
167
|
+
const prevModeRef = react.useRef(null);
|
|
168
|
+
react.useEffect(() => {
|
|
169
|
+
const prev = prevModeRef.current;
|
|
170
|
+
prevModeRef.current = {
|
|
171
|
+
mode: state.mode,
|
|
172
|
+
resolvedMode: state.resolvedMode
|
|
173
|
+
};
|
|
174
|
+
if (prev === null) return;
|
|
175
|
+
if (prev.mode === state.mode && prev.resolvedMode === state.resolvedMode) return;
|
|
176
|
+
onModeChangeRef.current?.(state.mode, state.resolvedMode);
|
|
177
|
+
}, [state.mode, state.resolvedMode]);
|
|
178
|
+
const modeCtxValue = react.useMemo(() => {
|
|
179
|
+
return {
|
|
180
|
+
mode: state.mode,
|
|
181
|
+
resolvedMode: state.resolvedMode,
|
|
182
|
+
setMode
|
|
183
|
+
};
|
|
184
|
+
}, [state.mode, state.resolvedMode, setMode]);
|
|
185
|
+
const coreNode = /* @__PURE__ */(0, react_jsx_runtime.jsx)(ModeCtx.Provider, {
|
|
186
|
+
value: modeCtxValue,
|
|
187
|
+
children
|
|
188
|
+
});
|
|
189
|
+
if (theme) return /* @__PURE__ */(0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
|
|
190
|
+
children: [/* @__PURE__ */(0, react_jsx_runtime.jsx)("style", {
|
|
191
|
+
precedence: "default",
|
|
192
|
+
children: cssContent
|
|
193
|
+
}), /* @__PURE__ */(0, react_jsx_runtime.jsx)(ResolvedTokensCtx.Provider, {
|
|
194
|
+
value: resolvedTokens,
|
|
195
|
+
children: /* @__PURE__ */(0, react_jsx_runtime.jsx)(SemanticTokensCtx.Provider, {
|
|
196
|
+
value: semanticTokens,
|
|
197
|
+
children: coreNode
|
|
198
|
+
})
|
|
199
|
+
})]
|
|
200
|
+
});
|
|
201
|
+
return coreNode;
|
|
202
|
+
};
|
|
203
|
+
const useColorMode = () => {
|
|
204
|
+
const context = react.useContext(ModeCtx);
|
|
205
|
+
if (!context) throw new Error("useColorMode must be used within a <ThemeProvider>");
|
|
206
|
+
return context;
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* Access the current theme's **semantic tokens only** — the structural tree
|
|
210
|
+
* with **unresolved** `TokenRef` values (e.g. `'{core.colors.brand.500}'`).
|
|
211
|
+
*
|
|
212
|
+
* ### Primary use cases
|
|
213
|
+
* - Introspection and devtools
|
|
214
|
+
* - Token path comparison (e.g. checking which tokens differ between themes)
|
|
215
|
+
* - Passing to `createTheme` calls
|
|
216
|
+
*
|
|
217
|
+
* ### ✗ Do not use for styling
|
|
218
|
+
* `TokenRef` values are reference strings, not CSS values. Using them in
|
|
219
|
+
* inline styles produces silently broken rendering:
|
|
220
|
+
*
|
|
221
|
+
* ```tsx
|
|
222
|
+
* // ✗ WRONG — tokens.colors.brand.main is '{core.colors.brand.main}', not '#FF0000'
|
|
223
|
+
* <div style={{ color: tokens.colors.brand.main }} />
|
|
224
|
+
*
|
|
225
|
+
* // ✓ CSS consumers — use vars:
|
|
226
|
+
* <div style={{ color: 'var(--tt-color-brand-main)' }} />
|
|
227
|
+
*
|
|
228
|
+
* // ✓ Non-CSS consumers (React Native, canvas) — use useResolvedTokens():
|
|
229
|
+
* const resolved = useResolvedTokens();
|
|
230
|
+
* <View style={{ backgroundColor: resolved['semantic.colors.action.primary.background.default'] }} />
|
|
231
|
+
* ```
|
|
232
|
+
*
|
|
233
|
+
* Requires `<ThemeProvider theme={...}>`.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```tsx
|
|
237
|
+
* import { useTokens } from '@ttoss/fsl-theme/react';
|
|
238
|
+
*
|
|
239
|
+
* const Button = () => {
|
|
240
|
+
* const tokens = useTokens(); // introspection only
|
|
241
|
+
* // tokens.colors.action.primary.background.default → '{core.colors.brand.500}'
|
|
242
|
+
* return <button style={{ background: 'var(--tt-action-primary-background-default)' }} />;
|
|
243
|
+
* };
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
const useTokens = () => {
|
|
247
|
+
const tokens = react.useContext(SemanticTokensCtx);
|
|
248
|
+
if (!react.useContext(ModeCtx)) throw new Error("useTokens must be used within a <ThemeProvider>");
|
|
249
|
+
if (tokens === null) throw new Error("useTokens requires a <ThemeProvider theme={...}>. Pass your theme bundle: <ThemeProvider theme={myTheme} />");
|
|
250
|
+
return tokens;
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* Access fully resolved token values as a flat `Record<string, string | number>`.
|
|
254
|
+
*
|
|
255
|
+
* All `{ref}` indirections are resolved to their final raw values — hex colors,
|
|
256
|
+
* px sizes, unitless numbers, etc. Keys use `semantic.*` dot-path notation.
|
|
257
|
+
*
|
|
258
|
+
* ### When to use
|
|
259
|
+
* Use in non-CSS environments where CSS custom properties (`var()`) are not
|
|
260
|
+
* available: React Native, canvas renderers, PDF generation, test assertions.
|
|
261
|
+
*
|
|
262
|
+
* ### ✗ Do not use for CSS rendering
|
|
263
|
+
* CSS consumers should use `vars.*` instead for zero-JS rendering:
|
|
264
|
+
*
|
|
265
|
+
* ```tsx
|
|
266
|
+
* // ✓ CSS (browser)
|
|
267
|
+
* <div style={{ color: 'var(--tt-color-informational-primary-default)' }} />
|
|
268
|
+
*
|
|
269
|
+
* // ✓ Non-CSS (React Native, canvas)
|
|
270
|
+
* const resolved = useResolvedTokens();
|
|
271
|
+
* <View style={{ backgroundColor: resolved['semantic.colors.action.primary.background.default'] }} />
|
|
272
|
+
* ```
|
|
273
|
+
*
|
|
274
|
+
* Requires `<ThemeProvider theme={...}>`.
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```tsx
|
|
278
|
+
* import { useResolvedTokens } from '@ttoss/fsl-theme/react';
|
|
279
|
+
*
|
|
280
|
+
* const ReactNativeButton = () => {
|
|
281
|
+
* const resolved = useResolvedTokens();
|
|
282
|
+
* return (
|
|
283
|
+
* <View style={{ backgroundColor: resolved['semantic.colors.action.primary.background.default'] }}>
|
|
284
|
+
* <Text>Click</Text>
|
|
285
|
+
* </View>
|
|
286
|
+
* );
|
|
287
|
+
* };
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
const useResolvedTokens = () => {
|
|
291
|
+
const resolved = react.useContext(ResolvedTokensCtx);
|
|
292
|
+
if (!react.useContext(ModeCtx)) throw new Error("useResolvedTokens must be used within a <ThemeProvider>");
|
|
293
|
+
if (resolved === null) throw new Error("useResolvedTokens requires a <ThemeProvider theme={...}>. Pass your theme bundle: <ThemeProvider theme={myTheme} />");
|
|
294
|
+
return resolved;
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Renders an inline `<script>` that prevents theme flash on SSR/SSG.
|
|
298
|
+
*
|
|
299
|
+
* Place in the `<head>` before stylesheets.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```tsx
|
|
303
|
+
* // Next.js app/layout.tsx
|
|
304
|
+
* import { ThemeScript } from '@ttoss/fsl-theme/react';
|
|
305
|
+
*
|
|
306
|
+
* export default function RootLayout({ children }) {
|
|
307
|
+
* return (
|
|
308
|
+
* <html lang="en">
|
|
309
|
+
* <head>
|
|
310
|
+
* <ThemeScript defaultTheme="bruttal" />
|
|
311
|
+
* </head>
|
|
312
|
+
* <body>{children}</body>
|
|
313
|
+
* </html>
|
|
314
|
+
* );
|
|
315
|
+
* }
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
const ThemeScript = ({
|
|
319
|
+
defaultTheme,
|
|
320
|
+
defaultMode,
|
|
321
|
+
storageKey,
|
|
322
|
+
nonce
|
|
323
|
+
} = {}) => {
|
|
324
|
+
return /* @__PURE__ */(0, react_jsx_runtime.jsx)("script", {
|
|
325
|
+
nonce,
|
|
326
|
+
dangerouslySetInnerHTML: {
|
|
327
|
+
__html: require_ssrScript.getThemeScriptContent({
|
|
328
|
+
defaultTheme,
|
|
329
|
+
defaultMode,
|
|
330
|
+
storageKey
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
};
|
|
335
|
+
/**
|
|
336
|
+
* Renders an inline `<style>` tag with all CSS Custom Properties for a theme
|
|
337
|
+
* bundle — including coarse-pointer, reduced-motion, and container query
|
|
338
|
+
* progressive enhancement blocks.
|
|
339
|
+
*
|
|
340
|
+
* Use as an escape hatch for SSR frameworks that need explicit `<head>` style
|
|
341
|
+
* injection. In most React apps, `<ThemeProvider theme={...}>` already injects
|
|
342
|
+
* styles automatically via React 19 style hoisting — no `<ThemeStyles>` needed.
|
|
343
|
+
*
|
|
344
|
+
* `dangerouslySetInnerHTML` is safe: content comes exclusively from
|
|
345
|
+
* `toCssVars()` (a pure internal function) — no user input is interpolated.
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* ```tsx
|
|
349
|
+
* // SSR escape hatch — no themeId needed for canonical 1-theme model
|
|
350
|
+
* import { ThemeScript, ThemeStyles } from '@ttoss/fsl-theme/react';
|
|
351
|
+
* import { createTheme } from '@ttoss/fsl-theme';
|
|
352
|
+
*
|
|
353
|
+
* const myTheme = createTheme();
|
|
354
|
+
*
|
|
355
|
+
* export default function RootLayout({ children }) {
|
|
356
|
+
* return (
|
|
357
|
+
* <html lang="en">
|
|
358
|
+
* <head>
|
|
359
|
+
* <ThemeScript />
|
|
360
|
+
* <ThemeStyles theme={myTheme} />
|
|
361
|
+
* </head>
|
|
362
|
+
* <body>
|
|
363
|
+
* <ThemeProvider theme={myTheme}>{children}</ThemeProvider>
|
|
364
|
+
* </body>
|
|
365
|
+
* </html>
|
|
366
|
+
* );
|
|
367
|
+
* }
|
|
368
|
+
* ```
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* ```tsx
|
|
372
|
+
* // Multi-theme: explicit themeId for CSS scoping
|
|
373
|
+
* <ThemeStyles theme={brandA} themeId="brand-a" />
|
|
374
|
+
* <ThemeStyles theme={brandB} themeId="brand-b" />
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
const ThemeStyles = ({
|
|
378
|
+
theme,
|
|
379
|
+
themeId,
|
|
380
|
+
nonce
|
|
381
|
+
}) => {
|
|
382
|
+
return /* @__PURE__ */(0, react_jsx_runtime.jsx)("style", {
|
|
383
|
+
nonce,
|
|
384
|
+
dangerouslySetInnerHTML: {
|
|
385
|
+
__html: require_css.getThemeStylesContent(theme, themeId)
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* Convenience component that renders both `<ThemeScript>` and `<ThemeStyles>`
|
|
391
|
+
* in a single line — the complete SSR `<head>` setup for flash-free theming.
|
|
392
|
+
*
|
|
393
|
+
* Use in SSR frameworks (Next.js, Remix) where you need explicit `<head>`
|
|
394
|
+
* injection. In CSR apps, `<ThemeProvider theme={...}>` handles everything.
|
|
395
|
+
*
|
|
396
|
+
* @example
|
|
397
|
+
* ```tsx
|
|
398
|
+
* // Next.js app/layout.tsx
|
|
399
|
+
* import { ThemeHead, ThemeProvider } from '@ttoss/fsl-theme/react';
|
|
400
|
+
* import { createTheme } from '@ttoss/fsl-theme';
|
|
401
|
+
*
|
|
402
|
+
* const myTheme = createTheme();
|
|
403
|
+
*
|
|
404
|
+
* export default function RootLayout({ children }) {
|
|
405
|
+
* return (
|
|
406
|
+
* <html lang="en">
|
|
407
|
+
* <head>
|
|
408
|
+
* <ThemeHead theme={myTheme} />
|
|
409
|
+
* </head>
|
|
410
|
+
* <body>
|
|
411
|
+
* <ThemeProvider theme={myTheme}>{children}</ThemeProvider>
|
|
412
|
+
* </body>
|
|
413
|
+
* </html>
|
|
414
|
+
* );
|
|
415
|
+
* }
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
418
|
+
const ThemeHead = ({
|
|
419
|
+
theme,
|
|
420
|
+
themeId,
|
|
421
|
+
nonce,
|
|
422
|
+
defaultMode,
|
|
423
|
+
storageKey
|
|
424
|
+
}) => {
|
|
425
|
+
return /* @__PURE__ */(0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
|
|
426
|
+
children: [/* @__PURE__ */(0, react_jsx_runtime.jsx)(ThemeScript, {
|
|
427
|
+
defaultTheme: themeId,
|
|
428
|
+
defaultMode,
|
|
429
|
+
storageKey,
|
|
430
|
+
nonce
|
|
431
|
+
}), /* @__PURE__ */(0, react_jsx_runtime.jsx)(ThemeStyles, {
|
|
432
|
+
theme,
|
|
433
|
+
themeId,
|
|
434
|
+
nonce
|
|
435
|
+
})]
|
|
436
|
+
});
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
//#endregion
|
|
440
|
+
Object.defineProperty(exports, 'ThemeHead', {
|
|
441
|
+
enumerable: true,
|
|
442
|
+
get: function () {
|
|
443
|
+
return ThemeHead;
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
Object.defineProperty(exports, 'ThemeProvider', {
|
|
447
|
+
enumerable: true,
|
|
448
|
+
get: function () {
|
|
449
|
+
return ThemeProvider;
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
Object.defineProperty(exports, 'ThemeScript', {
|
|
453
|
+
enumerable: true,
|
|
454
|
+
get: function () {
|
|
455
|
+
return ThemeScript;
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
Object.defineProperty(exports, 'ThemeStyles', {
|
|
459
|
+
enumerable: true,
|
|
460
|
+
get: function () {
|
|
461
|
+
return ThemeStyles;
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
Object.defineProperty(exports, 'useColorMode', {
|
|
465
|
+
enumerable: true,
|
|
466
|
+
get: function () {
|
|
467
|
+
return useColorMode;
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
Object.defineProperty(exports, 'useResolvedTokens', {
|
|
471
|
+
enumerable: true,
|
|
472
|
+
get: function () {
|
|
473
|
+
return useResolvedTokens;
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
Object.defineProperty(exports, 'useTokens', {
|
|
477
|
+
enumerable: true,
|
|
478
|
+
get: function () {
|
|
479
|
+
return useTokens;
|
|
480
|
+
}
|
|
481
|
+
});
|
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, {
|
|
3
|
+
value: 'Module'
|
|
4
|
+
});
|
|
5
|
+
const require_react = require('./react-EUwpdvY7.cjs');
|
|
6
|
+
exports.ThemeHead = require_react.ThemeHead;
|
|
7
|
+
exports.ThemeProvider = require_react.ThemeProvider;
|
|
8
|
+
exports.ThemeScript = require_react.ThemeScript;
|
|
9
|
+
exports.ThemeStyles = require_react.ThemeStyles;
|
|
10
|
+
exports.useColorMode = require_react.useColorMode;
|
|
11
|
+
exports.useResolvedTokens = require_react.useResolvedTokens;
|
|
12
|
+
exports.useTokens = require_react.useTokens;
|
package/dist/react.d.cts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
|
|
2
|
+
import { a as ResolvedMode, o as ThemeMode } from "./ssrScript-BVysxDws.cjs";
|
|
3
|
+
import { a as ThemeScript, c as ThemeStylesProps, d as useResolvedTokens, f as useTokens, i as ThemeProviderProps, l as UseColorModeResult, n as ThemeHeadProps, o as ThemeScriptProps, r as ThemeProvider, s as ThemeStyles, t as ThemeHead, u as useColorMode } from "./react-CGa6FlNL.cjs";
|
|
4
|
+
export { type ResolvedMode, ThemeHead, ThemeHeadProps, type ThemeMode, ThemeProvider, ThemeProviderProps, ThemeScript, ThemeScriptProps, ThemeStyles, ThemeStylesProps, UseColorModeResult, useColorMode, useResolvedTokens, useTokens };
|
package/dist/react.d.mts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
|
|
2
|
+
import { a as ResolvedMode, o as ThemeMode } from "./ssrScript-BVysxDws.mjs";
|
|
3
|
+
import { a as ThemeScript, c as ThemeStylesProps, d as useResolvedTokens, f as useTokens, i as ThemeProviderProps, l as UseColorModeResult, n as ThemeHeadProps, o as ThemeScriptProps, r as ThemeProvider, s as ThemeStyles, t as ThemeHead, u as useColorMode } from "./react-DnKxR2gK.mjs";
|
|
4
|
+
export { type ResolvedMode, ThemeHead, ThemeHeadProps, type ThemeMode, ThemeProvider, ThemeProviderProps, ThemeScript, ThemeScriptProps, ThemeStyles, ThemeStylesProps, UseColorModeResult, useColorMode, useResolvedTokens, useTokens };
|