tailwind-styled-v4 5.0.0 → 5.0.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/CHANGELOG.md +398 -0
- package/LICENSE +21 -0
- package/README.md +532 -0
- package/dist/analyzer.d.mts +114 -0
- package/dist/analyzer.d.ts +114 -0
- package/dist/analyzer.js +6808 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/analyzer.mjs +6798 -0
- package/dist/analyzer.mjs.map +1 -0
- package/dist/{animate.d.cts → animate.d.mts} +3 -30
- package/dist/animate.d.ts +3 -30
- package/dist/animate.js +7096 -352
- package/dist/animate.js.map +1 -1
- package/dist/animate.mjs +7482 -0
- package/dist/animate.mjs.map +1 -0
- package/dist/atomic.d.mts +18 -0
- package/dist/atomic.d.ts +18 -0
- package/dist/atomic.js +191 -0
- package/dist/atomic.js.map +1 -0
- package/dist/atomic.mjs +185 -0
- package/dist/atomic.mjs.map +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +45008 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +44980 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/compiler.d.mts +1009 -0
- package/dist/compiler.d.ts +1009 -0
- package/dist/compiler.js +4937 -0
- package/dist/compiler.js.map +1 -0
- package/dist/compiler.mjs +4862 -0
- package/dist/compiler.mjs.map +1 -0
- package/dist/dashboard.d.mts +272 -0
- package/dist/dashboard.d.ts +272 -0
- package/dist/dashboard.js +249 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/dashboard.mjs +239 -0
- package/dist/dashboard.mjs.map +1 -0
- package/dist/devtools.js +171 -158
- package/dist/devtools.js.map +1 -1
- package/dist/{devtools.cjs → devtools.mjs} +166 -167
- package/dist/devtools.mjs.map +1 -0
- package/dist/engine.d.mts +398 -0
- package/dist/engine.d.ts +398 -0
- package/dist/engine.js +19264 -0
- package/dist/engine.js.map +1 -0
- package/dist/engine.mjs +19227 -0
- package/dist/engine.mjs.map +1 -0
- package/dist/{index.d.cts → index.d.mts} +12 -5
- package/dist/index.d.ts +12 -5
- package/dist/index.js +7178 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8408 -0
- package/dist/index.mjs.map +1 -0
- package/dist/liveTokenEngine-DYN3Zale.d.mts +34 -0
- package/dist/liveTokenEngine-DYN3Zale.d.ts +34 -0
- package/dist/{next.d.cts → next.d.mts} +2 -1
- package/dist/next.d.ts +2 -1
- package/dist/next.js +24027 -28
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +24232 -0
- package/dist/next.mjs.map +1 -0
- package/dist/plugin.d.mts +90 -0
- package/dist/plugin.d.ts +90 -0
- package/dist/plugin.js +185 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugin.mjs +174 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/pluginRegistry.d.mts +83 -0
- package/dist/pluginRegistry.d.ts +83 -0
- package/dist/pluginRegistry.js +303 -0
- package/dist/pluginRegistry.js.map +1 -0
- package/dist/pluginRegistry.mjs +298 -0
- package/dist/pluginRegistry.mjs.map +1 -0
- package/dist/preset.js +9 -4
- package/dist/preset.js.map +1 -1
- package/dist/{preset.cjs → preset.mjs} +5 -14
- package/dist/preset.mjs.map +1 -0
- package/dist/rspack.d.mts +33 -0
- package/dist/rspack.d.ts +33 -0
- package/dist/rspack.js +66 -0
- package/dist/rspack.js.map +1 -0
- package/dist/rspack.mjs +55 -0
- package/dist/rspack.mjs.map +1 -0
- package/dist/runtime.d.mts +62 -0
- package/dist/runtime.d.ts +62 -0
- package/dist/runtime.js +455 -0
- package/dist/runtime.js.map +1 -0
- package/dist/runtime.mjs +436 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/runtimeCss.d.mts +65 -0
- package/dist/runtimeCss.d.ts +65 -0
- package/dist/{css.cjs → runtimeCss.js} +71 -4
- package/dist/runtimeCss.js.map +1 -0
- package/dist/{css.js → runtimeCss.mjs} +66 -5
- package/dist/runtimeCss.mjs.map +1 -0
- package/dist/scanner.d.mts +25 -0
- package/dist/scanner.d.ts +25 -0
- package/dist/scanner.js +5774 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scanner.mjs +5760 -0
- package/dist/scanner.mjs.map +1 -0
- package/dist/shared.d.mts +85 -0
- package/dist/shared.d.ts +85 -0
- package/dist/shared.js +255 -0
- package/dist/shared.js.map +1 -0
- package/dist/shared.mjs +233 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/storybookAddon.d.mts +108 -0
- package/dist/storybookAddon.d.ts +108 -0
- package/dist/storybookAddon.js +95 -0
- package/dist/storybookAddon.js.map +1 -0
- package/dist/storybookAddon.mjs +88 -0
- package/dist/storybookAddon.mjs.map +1 -0
- package/dist/svelte.d.mts +114 -0
- package/dist/svelte.d.ts +114 -0
- package/dist/svelte.js +67 -0
- package/dist/svelte.js.map +1 -0
- package/dist/svelte.mjs +59 -0
- package/dist/svelte.mjs.map +1 -0
- package/dist/testing.d.mts +185 -0
- package/dist/testing.d.ts +185 -0
- package/dist/testing.js +173 -0
- package/dist/testing.js.map +1 -0
- package/dist/testing.mjs +158 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/theme.d.mts +188 -0
- package/dist/theme.d.ts +188 -0
- package/dist/theme.js +334 -0
- package/dist/theme.js.map +1 -0
- package/dist/theme.mjs +311 -0
- package/dist/theme.mjs.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types-DXr2PmGP.d.mts +31 -0
- package/dist/types-DXr2PmGP.d.ts +31 -0
- package/dist/vite.js +29611 -17
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +29712 -0
- package/dist/vite.mjs.map +1 -0
- package/dist/vue.d.mts +89 -0
- package/dist/vue.d.ts +89 -0
- package/dist/vue.js +104 -0
- package/dist/vue.js.map +1 -0
- package/dist/vue.mjs +96 -0
- package/dist/vue.mjs.map +1 -0
- package/package.json +170 -64
- package/dist/animate.cjs +0 -771
- package/dist/animate.cjs.map +0 -1
- package/dist/chunk-VZEJV27B.js +0 -11
- package/dist/chunk-VZEJV27B.js.map +0 -1
- package/dist/chunk-Y5D3E72P.cjs +0 -13
- package/dist/chunk-Y5D3E72P.cjs.map +0 -1
- package/dist/css.cjs.map +0 -1
- package/dist/css.d.cts +0 -30
- package/dist/css.d.ts +0 -30
- package/dist/css.js.map +0 -1
- package/dist/devtools.cjs.map +0 -1
- package/dist/index.cjs +0 -1353
- package/dist/index.cjs.map +0 -1
- package/dist/next.cjs +0 -248
- package/dist/next.cjs.map +0 -1
- package/dist/preset.cjs.map +0 -1
- package/dist/turbopackLoader.cjs +0 -37
- package/dist/turbopackLoader.cjs.map +0 -1
- package/dist/turbopackLoader.d.cts +0 -12
- package/dist/turbopackLoader.d.ts +0 -12
- package/dist/turbopackLoader.js +0 -35
- package/dist/turbopackLoader.js.map +0 -1
- package/dist/vite.cjs +0 -138
- package/dist/vite.cjs.map +0 -1
- package/dist/webpackLoader.cjs +0 -51
- package/dist/webpackLoader.cjs.map +0 -1
- package/dist/webpackLoader.d.cts +0 -17
- package/dist/webpackLoader.d.ts +0 -17
- package/dist/webpackLoader.js +0 -49
- package/dist/webpackLoader.js.map +0 -1
- /package/dist/{devtools.d.cts → devtools.d.mts} +0 -0
- /package/dist/{preset.d.cts → preset.d.mts} +0 -0
- /package/dist/{vite.d.cts → vite.d.mts} +0 -0
package/dist/runtime.mjs
ADDED
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/* tailwind-styled-v4 v5.0.1 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
11
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
12
|
+
}) : x)(function(x) {
|
|
13
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
14
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
15
|
+
});
|
|
16
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
17
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
28
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
29
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
30
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
31
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
32
|
+
__defProp(target, "default", { value: mod, enumerable: true }) ,
|
|
33
|
+
mod
|
|
34
|
+
));
|
|
35
|
+
|
|
36
|
+
// dist/theme.js
|
|
37
|
+
var require_theme = __commonJS({
|
|
38
|
+
"dist/theme.js"(exports$1) {
|
|
39
|
+
var React2 = __require("react");
|
|
40
|
+
var module$1 = __require("module");
|
|
41
|
+
var path = __require("path");
|
|
42
|
+
function _interopDefault(e) {
|
|
43
|
+
return e && e.__esModule ? e : { default: e };
|
|
44
|
+
}
|
|
45
|
+
var React__default = /* @__PURE__ */ _interopDefault(React2);
|
|
46
|
+
var path__default = /* @__PURE__ */ _interopDefault(path);
|
|
47
|
+
var __require2 = /* @__PURE__ */ ((x) => typeof __require !== "undefined" ? __require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
48
|
+
get: (a, b) => (typeof __require !== "undefined" ? __require : a)[b]
|
|
49
|
+
}) : x)(function(x) {
|
|
50
|
+
if (typeof __require !== "undefined") return __require.apply(this, arguments);
|
|
51
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
52
|
+
});
|
|
53
|
+
var _currentTokens = {};
|
|
54
|
+
var _subscribers = /* @__PURE__ */ new Set();
|
|
55
|
+
var _styleEl = null;
|
|
56
|
+
function tokenVar2(name) {
|
|
57
|
+
const normalized = name.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
58
|
+
return `--tw-token-${normalized}`;
|
|
59
|
+
}
|
|
60
|
+
function tokenRef2(name) {
|
|
61
|
+
return `var(${tokenVar2(name)})`;
|
|
62
|
+
}
|
|
63
|
+
function buildRootCss(tokens) {
|
|
64
|
+
const vars = Object.entries(tokens).map(([name, value]) => ` ${tokenVar2(name)}: ${value};`).join("\n");
|
|
65
|
+
return `:root {
|
|
66
|
+
${vars}
|
|
67
|
+
}`;
|
|
68
|
+
}
|
|
69
|
+
function syncStyleEl() {
|
|
70
|
+
if (typeof document === "undefined") return;
|
|
71
|
+
if (!_styleEl) {
|
|
72
|
+
_styleEl = document.createElement("style");
|
|
73
|
+
_styleEl.id = "tw-live-tokens";
|
|
74
|
+
_styleEl.setAttribute("data-tw-tokens", "true");
|
|
75
|
+
document.head.appendChild(_styleEl);
|
|
76
|
+
}
|
|
77
|
+
_styleEl.textContent = buildRootCss(_currentTokens);
|
|
78
|
+
}
|
|
79
|
+
function notifySubscribers() {
|
|
80
|
+
const snapshot = { ..._currentTokens };
|
|
81
|
+
for (const subscriber of _subscribers) {
|
|
82
|
+
try {
|
|
83
|
+
subscriber(snapshot);
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function liveToken2(tokens) {
|
|
89
|
+
_currentTokens = { ..._currentTokens, ...tokens };
|
|
90
|
+
syncStyleEl();
|
|
91
|
+
notifySubscribers();
|
|
92
|
+
const vars = {};
|
|
93
|
+
for (const name of Object.keys(tokens)) {
|
|
94
|
+
vars[name] = tokenRef2(name);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
vars,
|
|
98
|
+
get(name) {
|
|
99
|
+
return _currentTokens[name];
|
|
100
|
+
},
|
|
101
|
+
set(name, value) {
|
|
102
|
+
setToken2(name, value);
|
|
103
|
+
},
|
|
104
|
+
setAll(nextTokens) {
|
|
105
|
+
setTokens2(nextTokens);
|
|
106
|
+
},
|
|
107
|
+
snapshot() {
|
|
108
|
+
return { ..._currentTokens };
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function setToken2(name, value) {
|
|
113
|
+
_currentTokens = { ..._currentTokens, [name]: value };
|
|
114
|
+
if (typeof document !== "undefined") {
|
|
115
|
+
document.documentElement.style.setProperty(tokenVar2(name), value);
|
|
116
|
+
}
|
|
117
|
+
notifySubscribers();
|
|
118
|
+
}
|
|
119
|
+
function setTokens2(tokens) {
|
|
120
|
+
_currentTokens = { ..._currentTokens, ...tokens };
|
|
121
|
+
if (typeof document !== "undefined") {
|
|
122
|
+
const root = document.documentElement;
|
|
123
|
+
for (const [name, value] of Object.entries(tokens)) {
|
|
124
|
+
root.style.setProperty(tokenVar2(name), value);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
notifySubscribers();
|
|
128
|
+
}
|
|
129
|
+
function applyTokenSet2(tokens) {
|
|
130
|
+
if (typeof document !== "undefined") {
|
|
131
|
+
const root = document.documentElement;
|
|
132
|
+
for (const name of Object.keys(_currentTokens)) {
|
|
133
|
+
if (!(name in tokens)) {
|
|
134
|
+
root.style.removeProperty(tokenVar2(name));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
_currentTokens = { ...tokens };
|
|
139
|
+
syncStyleEl();
|
|
140
|
+
notifySubscribers();
|
|
141
|
+
}
|
|
142
|
+
function getToken2(name) {
|
|
143
|
+
return _currentTokens[name];
|
|
144
|
+
}
|
|
145
|
+
function getTokens2() {
|
|
146
|
+
return { ..._currentTokens };
|
|
147
|
+
}
|
|
148
|
+
function subscribeTokens2(fn) {
|
|
149
|
+
_subscribers.add(fn);
|
|
150
|
+
return () => {
|
|
151
|
+
_subscribers.delete(fn);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function generateTokenCssString2() {
|
|
155
|
+
return buildRootCss(_currentTokens);
|
|
156
|
+
}
|
|
157
|
+
function createUseTokens2() {
|
|
158
|
+
return function useTokens() {
|
|
159
|
+
const [tokens, setTokensState] = React__default.default.useState({ ..._currentTokens });
|
|
160
|
+
React__default.default.useEffect(() => {
|
|
161
|
+
setTokensState({ ..._currentTokens });
|
|
162
|
+
return subscribeTokens2((nextTokens) => setTokensState({ ...nextTokens }));
|
|
163
|
+
}, []);
|
|
164
|
+
return tokens;
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
var liveTokenEngine2 = {
|
|
168
|
+
getToken: getToken2,
|
|
169
|
+
getTokens: getTokens2,
|
|
170
|
+
setToken: setToken2,
|
|
171
|
+
applyTokenSet: applyTokenSet2,
|
|
172
|
+
subscribeTokens: subscribeTokens2,
|
|
173
|
+
subscribe: subscribeTokens2
|
|
174
|
+
};
|
|
175
|
+
globalThis.__TW_TOKEN_ENGINE__ = liveTokenEngine2;
|
|
176
|
+
if (typeof window !== "undefined") {
|
|
177
|
+
window.__TW_TOKEN_ENGINE__ = liveTokenEngine2;
|
|
178
|
+
}
|
|
179
|
+
var _binding;
|
|
180
|
+
function getNativeThemeBinding() {
|
|
181
|
+
if (_binding !== void 0) return _binding;
|
|
182
|
+
if (process.env.TWS_NO_NATIVE === "1" || process.env.TWS_NO_RUST === "1") {
|
|
183
|
+
return _binding = null;
|
|
184
|
+
}
|
|
185
|
+
const runtimeDir = typeof __dirname === "string" ? __dirname : process.cwd();
|
|
186
|
+
const req = typeof __require2 === "function" ? __require2 : module$1.createRequire(path__default.default.join(runtimeDir, "noop.cjs"));
|
|
187
|
+
const candidates = [
|
|
188
|
+
path__default.default.resolve(process.cwd(), "native", "tailwind_styled_parser.node"),
|
|
189
|
+
path__default.default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node")
|
|
190
|
+
];
|
|
191
|
+
for (const c of candidates) {
|
|
192
|
+
try {
|
|
193
|
+
const mod = req(c);
|
|
194
|
+
if (mod?.compileTheme) return _binding = mod;
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return _binding = null;
|
|
199
|
+
}
|
|
200
|
+
function defineThemeContract(shape) {
|
|
201
|
+
const vars = {};
|
|
202
|
+
for (const group in shape) {
|
|
203
|
+
vars[group] = {};
|
|
204
|
+
for (const token in shape[group]) {
|
|
205
|
+
vars[group][token] = `var(--${group}-${token})`;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return { _contract: shape, _vars: vars };
|
|
209
|
+
}
|
|
210
|
+
function createTheme(contract, name, values, asRoot = false) {
|
|
211
|
+
const native = getNativeThemeBinding();
|
|
212
|
+
if (native?.compileTheme) {
|
|
213
|
+
const result = native.compileTheme(JSON.stringify(values), asRoot ? "light" : name, "");
|
|
214
|
+
if (result) {
|
|
215
|
+
const flatVars2 = {};
|
|
216
|
+
for (const token of result.tokens) {
|
|
217
|
+
flatVars2[token.cssVar] = token.value;
|
|
218
|
+
}
|
|
219
|
+
return { name, contract, values, css: result.css, vars: flatVars2, selector: result.selector };
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const flatVars = {};
|
|
223
|
+
const cssLines = [];
|
|
224
|
+
for (const group in values) {
|
|
225
|
+
for (const token in values[group]) {
|
|
226
|
+
const varName = `--${group}-${token}`;
|
|
227
|
+
const value = values[group][token];
|
|
228
|
+
flatVars[varName] = value;
|
|
229
|
+
cssLines.push(` ${varName}: ${value};`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const selector = asRoot ? ":root" : `[data-theme="${name}"]`;
|
|
233
|
+
const css = `${selector} {
|
|
234
|
+
${cssLines.join("\n")}
|
|
235
|
+
}`;
|
|
236
|
+
return { name, contract, values, css, vars: flatVars, selector };
|
|
237
|
+
}
|
|
238
|
+
var ThemeRegistry = class {
|
|
239
|
+
constructor() {
|
|
240
|
+
this.themes = /* @__PURE__ */ new Map();
|
|
241
|
+
this.defaultTheme = null;
|
|
242
|
+
}
|
|
243
|
+
/** Register a theme */
|
|
244
|
+
register(theme, isDefault = false) {
|
|
245
|
+
this.themes.set(theme.name, theme);
|
|
246
|
+
if (isDefault || !this.defaultTheme) {
|
|
247
|
+
this.defaultTheme = theme.name;
|
|
248
|
+
}
|
|
249
|
+
return this;
|
|
250
|
+
}
|
|
251
|
+
/** Get a theme by name */
|
|
252
|
+
get(name) {
|
|
253
|
+
return this.themes.get(name);
|
|
254
|
+
}
|
|
255
|
+
/** Get all theme names */
|
|
256
|
+
names() {
|
|
257
|
+
return Array.from(this.themes.keys());
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Generate combined CSS for all themes.
|
|
261
|
+
* Inject into <head> or a .css file.
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* // In globals.css or layout.tsx
|
|
265
|
+
* const css = registry.generateCss()
|
|
266
|
+
*/
|
|
267
|
+
generateCss() {
|
|
268
|
+
return Array.from(this.themes.values()).map((t) => t.css).join("\n\n");
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get the CSS for a specific theme only.
|
|
272
|
+
*/
|
|
273
|
+
getThemeCss(name) {
|
|
274
|
+
return this.themes.get(name)?.css ?? null;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Inject all theme CSS into document <head> (browser only).
|
|
278
|
+
* Call once on app init.
|
|
279
|
+
*/
|
|
280
|
+
inject(styleId = "__tw_themes") {
|
|
281
|
+
if (typeof document === "undefined") return;
|
|
282
|
+
let style = document.getElementById(styleId);
|
|
283
|
+
if (!style) {
|
|
284
|
+
style = document.createElement("style");
|
|
285
|
+
style.id = styleId;
|
|
286
|
+
document.head.appendChild(style);
|
|
287
|
+
}
|
|
288
|
+
style.textContent = this.generateCss();
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Switch active theme by setting data-theme on <html>.
|
|
292
|
+
*/
|
|
293
|
+
apply(name, target = document.documentElement) {
|
|
294
|
+
if (typeof document === "undefined") return;
|
|
295
|
+
if (!this.themes.has(name)) {
|
|
296
|
+
console.warn(`[tailwind-styled-v4] Theme "${name}" not registered.`);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
target.dataset.theme = name;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Get current active theme name from data-theme attribute.
|
|
303
|
+
*/
|
|
304
|
+
current(target = document.documentElement) {
|
|
305
|
+
if (typeof document === "undefined") return this.defaultTheme;
|
|
306
|
+
return target.dataset.theme ?? this.defaultTheme;
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
function createMultiTheme(config) {
|
|
310
|
+
const registry = new ThemeRegistry();
|
|
311
|
+
const light = createTheme(config.contract, "light", config.light, true);
|
|
312
|
+
const dark = createTheme(config.contract, "dark", config.dark, false);
|
|
313
|
+
registry.register(light, true);
|
|
314
|
+
registry.register(dark);
|
|
315
|
+
for (const [name, values] of Object.entries(config.extras ?? {})) {
|
|
316
|
+
registry.register(createTheme(config.contract, name, values));
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
registry,
|
|
320
|
+
vars: config.contract._vars,
|
|
321
|
+
light,
|
|
322
|
+
dark
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
function compileDesignTokens(tokens, prefix = "") {
|
|
326
|
+
const native = getNativeThemeBinding();
|
|
327
|
+
if (native?.compileTheme) {
|
|
328
|
+
const result = native.compileTheme(JSON.stringify(tokens), "default", prefix);
|
|
329
|
+
if (result) return result.css;
|
|
330
|
+
}
|
|
331
|
+
const vars = [];
|
|
332
|
+
function flatten(obj, path2) {
|
|
333
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
334
|
+
const varPath = path2 ? `${path2}-${key}` : key;
|
|
335
|
+
if (typeof value === "string") {
|
|
336
|
+
vars.push(` --${varPath}: ${value};`);
|
|
337
|
+
} else {
|
|
338
|
+
flatten(value, varPath);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
flatten(tokens, prefix);
|
|
343
|
+
return `:root {
|
|
344
|
+
${vars.join("\n")}
|
|
345
|
+
}`;
|
|
346
|
+
}
|
|
347
|
+
exports$1.ThemeRegistry = ThemeRegistry;
|
|
348
|
+
exports$1.applyTokenSet = applyTokenSet2;
|
|
349
|
+
exports$1.compileDesignTokens = compileDesignTokens;
|
|
350
|
+
exports$1.createMultiTheme = createMultiTheme;
|
|
351
|
+
exports$1.createTheme = createTheme;
|
|
352
|
+
exports$1.createUseTokens = createUseTokens2;
|
|
353
|
+
exports$1.defineThemeContract = defineThemeContract;
|
|
354
|
+
exports$1.generateTokenCssString = generateTokenCssString2;
|
|
355
|
+
exports$1.getToken = getToken2;
|
|
356
|
+
exports$1.getTokens = getTokens2;
|
|
357
|
+
exports$1.liveToken = liveToken2;
|
|
358
|
+
exports$1.liveTokenEngine = liveTokenEngine2;
|
|
359
|
+
exports$1.setToken = setToken2;
|
|
360
|
+
exports$1.setTokens = setTokens2;
|
|
361
|
+
exports$1.subscribeTokens = subscribeTokens2;
|
|
362
|
+
exports$1.tokenRef = tokenRef2;
|
|
363
|
+
exports$1.tokenVar = tokenVar2;
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// packages/runtime/src/index.ts
|
|
368
|
+
var import_theme = __toESM(require_theme());
|
|
369
|
+
function cx(...inputs) {
|
|
370
|
+
const out = [];
|
|
371
|
+
for (const input of inputs) {
|
|
372
|
+
if (!input) continue;
|
|
373
|
+
if (typeof input === "string") {
|
|
374
|
+
out.push(input);
|
|
375
|
+
} else if (typeof input === "number") {
|
|
376
|
+
out.push(String(input));
|
|
377
|
+
} else if (Array.isArray(input)) {
|
|
378
|
+
const nested = cx(...input);
|
|
379
|
+
if (nested) out.push(nested);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return out.join(" ");
|
|
383
|
+
}
|
|
384
|
+
function createComponent(tag, baseClass, subComponents, conditionals) {
|
|
385
|
+
const Base = React.forwardRef(function TwBase(props, ref) {
|
|
386
|
+
const extra = [];
|
|
387
|
+
if (conditionals) {
|
|
388
|
+
for (const [prop, cls] of Object.entries(conditionals)) {
|
|
389
|
+
if (props[prop]) extra.push(cls);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
const clean = {};
|
|
393
|
+
const stripKeys = /* @__PURE__ */ new Set([
|
|
394
|
+
"className",
|
|
395
|
+
...conditionals ? Object.keys(conditionals) : [],
|
|
396
|
+
...subComponents ? Object.keys(subComponents) : []
|
|
397
|
+
]);
|
|
398
|
+
for (const [k, v] of Object.entries(props)) {
|
|
399
|
+
if (!stripKeys.has(k)) clean[k] = v;
|
|
400
|
+
}
|
|
401
|
+
const className = cx(baseClass, ...extra, props.className ?? "");
|
|
402
|
+
return React.createElement(tag, { ...clean, ref, className: className || void 0 });
|
|
403
|
+
});
|
|
404
|
+
Base.displayName = "tw." + String(tag);
|
|
405
|
+
if (subComponents) {
|
|
406
|
+
for (const [subName, def] of Object.entries(subComponents)) {
|
|
407
|
+
const subTag = def.tag ?? "span";
|
|
408
|
+
const subClass = def.class;
|
|
409
|
+
const SubComp = React.forwardRef(function TwSub(props, ref) {
|
|
410
|
+
const className = cx(subClass, props.className ?? "");
|
|
411
|
+
const clean = { ...props };
|
|
412
|
+
delete clean.className;
|
|
413
|
+
return React.createElement(subTag, { ...clean, ref, className: className || void 0 });
|
|
414
|
+
});
|
|
415
|
+
SubComp.displayName = "tw." + String(tag) + "." + String(subName);
|
|
416
|
+
Base[subName] = SubComp;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return Base;
|
|
420
|
+
}
|
|
421
|
+
var export_applyTokenSet = import_theme.applyTokenSet;
|
|
422
|
+
var export_createUseTokens = import_theme.createUseTokens;
|
|
423
|
+
var export_generateTokenCssString = import_theme.generateTokenCssString;
|
|
424
|
+
var export_getToken = import_theme.getToken;
|
|
425
|
+
var export_getTokens = import_theme.getTokens;
|
|
426
|
+
var export_liveToken = import_theme.liveToken;
|
|
427
|
+
var export_liveTokenEngine = import_theme.liveTokenEngine;
|
|
428
|
+
var export_setToken = import_theme.setToken;
|
|
429
|
+
var export_setTokens = import_theme.setTokens;
|
|
430
|
+
var export_subscribeTokens = import_theme.subscribeTokens;
|
|
431
|
+
var export_tokenRef = import_theme.tokenRef;
|
|
432
|
+
var export_tokenVar = import_theme.tokenVar;
|
|
433
|
+
|
|
434
|
+
export { export_applyTokenSet as applyTokenSet, createComponent, export_createUseTokens as createUseTokens, cx, export_generateTokenCssString as generateTokenCssString, export_getToken as getToken, export_getTokens as getTokens, export_liveToken as liveToken, export_liveTokenEngine as liveTokenEngine, export_setToken as setToken, export_setTokens as setTokens, export_subscribeTokens as subscribeTokens, export_tokenRef as tokenRef, export_tokenVar as tokenVar };
|
|
435
|
+
//# sourceMappingURL=runtime.mjs.map
|
|
436
|
+
//# sourceMappingURL=runtime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../packages/theme/src/liveTokenEngine.ts","../packages/theme/src/native-bridge.ts","../packages/theme/src/index.ts","../packages/runtime/src/index.ts"],"names":["tokenVar","tokenRef","liveToken","setToken","setTokens","applyTokenSet","getToken","getTokens","subscribeTokens","generateTokenCssString","createUseTokens","React","liveTokenEngine","__require","createRequire","path","flatVars"],"mappings":"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","file":"runtime.mjs","sourcesContent":["import React from \"react\"\n\nexport type TokenMap = Record<string, string>\nexport type TokenSubscriber = (tokens: TokenMap) => void\n\nexport interface LiveTokenSet {\n vars: Record<string, string>\n get(name: string): string | undefined\n set(name: string, value: string): void\n setAll(tokens: TokenMap): void\n snapshot(): TokenMap\n}\n\nexport interface LiveTokenEngineBridge {\n getToken(name: string): string | undefined\n getTokens(): TokenMap\n setToken(name: string, value: string): void\n applyTokenSet(tokens: TokenMap): void\n subscribeTokens(fn: TokenSubscriber): () => void\n subscribe?(fn: TokenSubscriber): () => void\n}\n\ndeclare global {\n var __TW_TOKEN_ENGINE__: LiveTokenEngineBridge | undefined\n}\n\nlet _currentTokens: TokenMap = {}\nconst _subscribers = new Set<TokenSubscriber>()\nlet _styleEl: HTMLStyleElement | null = null\n\nexport function tokenVar(name: string): string {\n const normalized = name.replace(/[^a-zA-Z0-9-]/g, \"-\").toLowerCase()\n return `--tw-token-${normalized}`\n}\n\nexport function tokenRef(name: string): string {\n return `var(${tokenVar(name)})`\n}\n\nfunction buildRootCss(tokens: TokenMap): string {\n const vars = Object.entries(tokens)\n .map(([name, value]) => ` ${tokenVar(name)}: ${value};`)\n .join(\"\\n\")\n return `:root {\\n${vars}\\n}`\n}\n\nfunction syncStyleEl(): void {\n if (typeof document === \"undefined\") return\n\n if (!_styleEl) {\n _styleEl = document.createElement(\"style\")\n _styleEl.id = \"tw-live-tokens\"\n _styleEl.setAttribute(\"data-tw-tokens\", \"true\")\n document.head.appendChild(_styleEl)\n }\n\n _styleEl.textContent = buildRootCss(_currentTokens)\n}\n\nfunction notifySubscribers(): void {\n const snapshot = { ..._currentTokens }\n for (const subscriber of _subscribers) {\n try {\n subscriber(snapshot)\n } catch {\n // intentionally ignore subscriber errors\n }\n }\n}\n\nexport function liveToken(tokens: TokenMap): LiveTokenSet {\n _currentTokens = { ..._currentTokens, ...tokens }\n syncStyleEl()\n notifySubscribers()\n\n const vars: Record<string, string> = {}\n for (const name of Object.keys(tokens)) {\n vars[name] = tokenRef(name)\n }\n\n return {\n vars,\n get(name) {\n return _currentTokens[name]\n },\n set(name, value) {\n setToken(name, value)\n },\n setAll(nextTokens) {\n setTokens(nextTokens)\n },\n snapshot() {\n return { ..._currentTokens }\n },\n }\n}\n\nexport function setToken(name: string, value: string): void {\n _currentTokens = { ..._currentTokens, [name]: value }\n\n if (typeof document !== \"undefined\") {\n document.documentElement.style.setProperty(tokenVar(name), value)\n }\n\n notifySubscribers()\n}\n\nexport function setTokens(tokens: TokenMap): void {\n _currentTokens = { ..._currentTokens, ...tokens }\n\n if (typeof document !== \"undefined\") {\n const root = document.documentElement\n for (const [name, value] of Object.entries(tokens)) {\n root.style.setProperty(tokenVar(name), value)\n }\n }\n\n notifySubscribers()\n}\n\nexport function applyTokenSet(tokens: TokenMap): void {\n if (typeof document !== \"undefined\") {\n const root = document.documentElement\n for (const name of Object.keys(_currentTokens)) {\n if (!(name in tokens)) {\n root.style.removeProperty(tokenVar(name))\n }\n }\n }\n\n _currentTokens = { ...tokens }\n syncStyleEl()\n notifySubscribers()\n}\n\nexport function getToken(name: string): string | undefined {\n return _currentTokens[name]\n}\n\nexport function getTokens(): TokenMap {\n return { ..._currentTokens }\n}\n\nexport function subscribeTokens(fn: TokenSubscriber): () => void {\n _subscribers.add(fn)\n return () => {\n _subscribers.delete(fn)\n }\n}\n\nexport function generateTokenCssString(): string {\n return buildRootCss(_currentTokens)\n}\n\nexport function createUseTokens() {\n return function useTokens(): TokenMap {\n const [tokens, setTokensState] = React.useState<TokenMap>({ ..._currentTokens })\n\n React.useEffect(() => {\n setTokensState({ ..._currentTokens })\n return subscribeTokens((nextTokens) => setTokensState({ ...nextTokens }))\n }, [])\n\n return tokens\n }\n}\n\nexport const liveTokenEngine: LiveTokenEngineBridge = {\n getToken,\n getTokens,\n setToken,\n applyTokenSet,\n subscribeTokens,\n subscribe: subscribeTokens,\n}\n\nglobalThis.__TW_TOKEN_ENGINE__ = liveTokenEngine\nif (typeof window !== \"undefined\") {\n ;(window as any).__TW_TOKEN_ENGINE__ = liveTokenEngine\n}\n","/**\n * Theme — Rust native bridge\n */\nimport { createRequire } from \"node:module\"\nimport path from \"node:path\"\n\ninterface NativeThemeBinding {\n compileTheme?: (\n tokensJson: string,\n themeName: string,\n prefix: string\n ) => {\n name: string\n selector: string\n css: string\n tokens: Array<{ key: string; cssVar: string; value: string }>\n } | null\n extractCssVars?: (source: string) => string[] | null\n}\n\nlet _binding: NativeThemeBinding | null | undefined\n\nexport function getNativeThemeBinding(): NativeThemeBinding | null {\n if (_binding !== undefined) return _binding\n if (process.env.TWS_NO_NATIVE === \"1\" || process.env.TWS_NO_RUST === \"1\") {\n return (_binding = null)\n }\n const runtimeDir = typeof __dirname === \"string\" ? __dirname : process.cwd()\n const req =\n typeof require === \"function\" ? require : createRequire(path.join(runtimeDir, \"noop.cjs\"))\n const candidates = [\n path.resolve(process.cwd(), \"native\", \"tailwind_styled_parser.node\"),\n path.resolve(runtimeDir, \"..\", \"..\", \"..\", \"native\", \"tailwind_styled_parser.node\"),\n ]\n for (const c of candidates) {\n try {\n const mod = req(c) as NativeThemeBinding\n if (mod?.compileTheme) return (_binding = mod)\n } catch {\n /* next */\n }\n }\n return (_binding = null)\n}\n","/**\n * tailwind-styled-v5 — Multi-Theme Engine + Live Token Engine\n *\n * Enterprise-grade theming. Support light/dark/brand themes dengan\n * CSS variables. Zero runtime overhead — themes di-resolve via CSS.\n *\n * Live token engine provides runtime token state management with\n * CSS variable sync to document root.\n *\n * Fitur:\n * - Multiple named themes (light, dark, brand, high-contrast)\n * - CSS variable output (Tailwind v4 compatible)\n * - Theme contract (TypeScript-safe — missing tokens = TS error)\n * - Per-component theme override\n * - White-label ready\n * - Live token engine (runtime token state + CSS sync)\n *\n * @example\n * // 1. Define contract\n * const contract = defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\", muted: \"\" },\n * font: { sans: \"\", mono: \"\" },\n * })\n *\n * // 2. Create themes\n * const lightTheme = createTheme(contract, \"light\", {\n * colors: { bg: \"#ffffff\", fg: \"#09090b\", primary: \"#3b82f6\", muted: \"#71717a\" },\n * font: { sans: \"InterVariable, sans-serif\", mono: \"JetBrains Mono, monospace\" },\n * })\n *\n * const darkTheme = createTheme(contract, \"dark\", {\n * colors: { bg: \"#09090b\", fg: \"#fafafa\", primary: \"#60a5fa\", muted: \"#a1a1aa\" },\n * font: { sans: \"InterVariable, sans-serif\", mono: \"JetBrains Mono, monospace\" },\n * })\n *\n * // 3. Use tokens in components\n * const Card = tw.div`bg-[var(--colors-bg)] text-[var(--colors-fg)] p-6`\n *\n * // 4. Apply in layout\n * // <html data-theme=\"dark\"> or inject CSS\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Live Token Engine exports\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type {\n LiveTokenEngineBridge,\n LiveTokenSet,\n TokenMap,\n TokenSubscriber,\n} from \"./liveTokenEngine\"\nexport {\n applyTokenSet,\n createUseTokens,\n generateTokenCssString,\n getToken,\n getTokens,\n liveToken,\n liveTokenEngine,\n setToken,\n setTokens,\n subscribeTokens,\n tokenRef,\n tokenVar,\n} from \"./liveTokenEngine\"\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Theme types\n// ─────────────────────────────────────────────────────────────────────────────\n\nimport { getNativeThemeBinding } from \"./native-bridge\"\n\n// ThemeTokenMap untuk theming (grouped tokens seperti { colors: { bg: \"#fff\" } })\nexport type ThemeTokenMap = Record<string, Record<string, string>>\n\nexport interface ThemeContract<T extends ThemeTokenMap> {\n _contract: T\n _vars: ThemeVars<T>\n}\n\nexport type ThemeVars<T extends ThemeTokenMap> = {\n [Group in keyof T]: {\n [Token in keyof T[Group]]: string // \"var(--group-token)\"\n }\n}\n\nexport interface Theme<T extends ThemeTokenMap> {\n name: string\n contract: ThemeContract<T>\n values: T\n /** CSS string to inject (`:root` or `[data-theme=\"name\"]`) */\n css: string\n /** CSS variables as a flat record */\n vars: Record<string, string>\n /** Apply this theme to an element via data attribute */\n selector: string\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// defineThemeContract\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Define the shape of your theme. All themes must satisfy this contract.\n * Returns typed CSS variable references for use in tw components.\n *\n * @example\n * const contract = defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\" },\n * font: { sans: \"\" },\n * })\n *\n * // Use in components:\n * const Card = tw.div`bg-[${contract._vars.colors.bg}]`\n * // → tw.div`bg-[var(--colors-bg)]`\n */\nexport function defineThemeContract<T extends ThemeTokenMap>(shape: T): ThemeContract<T> {\n const vars = {} as ThemeVars<T>\n\n for (const group in shape) {\n ;(vars as any)[group] = {}\n for (const token in shape[group]) {\n ;(vars as any)[group][token] = `var(--${group}-${token})`\n }\n }\n\n return { _contract: shape, _vars: vars }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// createTheme\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a typed theme that satisfies a contract.\n *\n * @param contract - Theme contract from defineThemeContract()\n * @param name - Theme name (\"light\", \"dark\", \"brand\", etc.)\n * @param values - Token values (TypeScript enforces completeness)\n * @param asRoot - If true, use :root selector. Default: false (uses [data-theme])\n */\nexport function createTheme<T extends ThemeTokenMap>(\n contract: ThemeContract<T>,\n name: string,\n values: T,\n asRoot = false\n): Theme<T> {\n // ── Rust fast-path ─────────────────────────────────────────────────────────\n const native = getNativeThemeBinding()\n if (native?.compileTheme) {\n const result = native.compileTheme(JSON.stringify(values), asRoot ? \"light\" : name, \"\")\n if (result) {\n const flatVars: Record<string, string> = {}\n for (const token of result.tokens) {\n flatVars[token.cssVar] = token.value\n }\n return { name, contract, values, css: result.css, vars: flatVars, selector: result.selector }\n }\n }\n\n // ── JS fallback ────────────────────────────────────────────────────────────\n const flatVars: Record<string, string> = {}\n const cssLines: string[] = []\n\n for (const group in values) {\n for (const token in values[group]) {\n const varName = `--${group}-${token}`\n const value = values[group][token]\n flatVars[varName] = value\n cssLines.push(` ${varName}: ${value};`)\n }\n }\n\n const selector = asRoot ? \":root\" : `[data-theme=\"${name}\"]`\n const css = `${selector} {\\n${cssLines.join(\"\\n\")}\\n}`\n\n return { name, contract, values, css, vars: flatVars, selector }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThemeRegistry — manage multiple themes\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThemeRegistry {\n private themes = new Map<string, Theme<any>>()\n private defaultTheme: string | null = null\n\n /** Register a theme */\n register<T extends ThemeTokenMap>(theme: Theme<T>, isDefault = false): this {\n this.themes.set(theme.name, theme)\n if (isDefault || !this.defaultTheme) {\n this.defaultTheme = theme.name\n }\n return this\n }\n\n /** Get a theme by name */\n get(name: string): Theme<any> | undefined {\n return this.themes.get(name)\n }\n\n /** Get all theme names */\n names(): string[] {\n return Array.from(this.themes.keys())\n }\n\n /**\n * Generate combined CSS for all themes.\n * Inject into <head> or a .css file.\n *\n * @example\n * // In globals.css or layout.tsx\n * const css = registry.generateCss()\n */\n generateCss(): string {\n return Array.from(this.themes.values())\n .map((t) => t.css)\n .join(\"\\n\\n\")\n }\n\n /**\n * Get the CSS for a specific theme only.\n */\n getThemeCss(name: string): string | null {\n return this.themes.get(name)?.css ?? null\n }\n\n /**\n * Inject all theme CSS into document <head> (browser only).\n * Call once on app init.\n */\n inject(styleId = \"__tw_themes\"): void {\n if (typeof document === \"undefined\") return\n\n let style = document.getElementById(styleId) as HTMLStyleElement | null\n if (!style) {\n style = document.createElement(\"style\")\n style.id = styleId\n document.head.appendChild(style)\n }\n style.textContent = this.generateCss()\n }\n\n /**\n * Switch active theme by setting data-theme on <html>.\n */\n apply(name: string, target: HTMLElement = document.documentElement): void {\n if (typeof document === \"undefined\") return\n if (!this.themes.has(name)) {\n console.warn(`[tailwind-styled-v4] Theme \"${name}\" not registered.`)\n return\n }\n target.dataset.theme = name\n }\n\n /**\n * Get current active theme name from data-theme attribute.\n */\n current(target: HTMLElement = document.documentElement): string | null {\n if (typeof document === \"undefined\") return this.defaultTheme\n return target.dataset.theme ?? this.defaultTheme\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Convenience: createMultiTheme — shorthand for common light/dark setup\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MultiThemeConfig<T extends ThemeTokenMap> {\n contract: ThemeContract<T>\n light: T\n dark: T\n /** Additional named themes (brand, high-contrast, etc.) */\n extras?: Record<string, T>\n}\n\n/**\n * Create a ThemeRegistry with light/dark + optional extras in one call.\n *\n * @example\n * const { registry, vars } = createMultiTheme({\n * contract: defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\", border: \"\" }\n * }),\n * light: {\n * colors: { bg: \"#fff\", fg: \"#09090b\", primary: \"#3b82f6\", border: \"#e5e7eb\" }\n * },\n * dark: {\n * colors: { bg: \"#09090b\", fg: \"#fafafa\", primary: \"#60a5fa\", border: \"#27272a\" }\n * },\n * })\n *\n * // Inject CSS:\n * registry.inject()\n *\n * // Use tokens in components:\n * const Card = tw.div`bg-[${vars.colors.bg}] text-[${vars.colors.fg}]`\n */\nexport function createMultiTheme<T extends ThemeTokenMap>(\n config: MultiThemeConfig<T>\n): {\n registry: ThemeRegistry\n vars: ThemeVars<T>\n light: Theme<T>\n dark: Theme<T>\n} {\n const registry = new ThemeRegistry()\n\n const light = createTheme(config.contract, \"light\", config.light, true) // :root\n const dark = createTheme(config.contract, \"dark\", config.dark, false)\n\n registry.register(light, true)\n registry.register(dark)\n\n for (const [name, values] of Object.entries(config.extras ?? {})) {\n registry.register(createTheme(config.contract, name, values as T))\n }\n\n return {\n registry,\n vars: config.contract._vars,\n light,\n dark,\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Design Token Compiler — generate CSS vars from token object\n// (Enterprise feature: sync with Figma variables)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DesignTokens {\n [path: string]: string | DesignTokens\n}\n\n/**\n * Flatten nested design token object into CSS variables.\n * Supports Figma-style nested tokens.\n *\n * @example\n * compileDesignTokens({\n * color: {\n * brand: { primary: \"#3b82f6\", secondary: \"#6366f1\" },\n * neutral: { 50: \"#fafafa\", 900: \"#09090b\" }\n * },\n * spacing: { base: \"4px\", lg: \"16px\" }\n * })\n * →\n * :root {\n * --color-brand-primary: #3b82f6;\n * --color-brand-secondary: #6366f1;\n * --color-neutral-50: #fafafa;\n * --color-neutral-900: #09090b;\n * --spacing-base: 4px;\n * --spacing-lg: 16px;\n * }\n */\nexport function compileDesignTokens(tokens: DesignTokens, prefix = \"\"): string {\n // ── Rust fast-path ─────────────────────────────────────────────────────────\n const native = getNativeThemeBinding()\n if (native?.compileTheme) {\n const result = native.compileTheme(JSON.stringify(tokens), \"default\", prefix)\n if (result) return result.css\n }\n\n // ── JS fallback ────────────────────────────────────────────────────────────\n const vars: string[] = []\n\n function flatten(obj: DesignTokens, path: string) {\n for (const [key, value] of Object.entries(obj)) {\n const varPath = path ? `${path}-${key}` : key\n if (typeof value === \"string\") {\n vars.push(` --${varPath}: ${value};`)\n } else {\n flatten(value as DesignTokens, varPath)\n }\n }\n }\n\n flatten(tokens, prefix)\n return `:root {\\n${vars.join(\"\\n\")}\\n}`\n}\n","/**\n * @tailwind-styled/runtime v5\n *\n * Lightweight runtime helpers for compiled tailwind-styled-v5 components.\n * Live token engine has been moved to @tailwind-styled/theme package.\n */\n\nimport React from \"react\"\n\n// Re-export live token engine from @tailwind-styled/theme\nexport type {\n LiveTokenEngineBridge,\n LiveTokenSet,\n TokenMap,\n TokenSubscriber,\n} from \"@tailwind-styled/theme\"\nexport {\n applyTokenSet,\n createUseTokens,\n generateTokenCssString,\n getToken,\n getTokens,\n liveToken,\n liveTokenEngine,\n setToken,\n setTokens,\n subscribeTokens,\n tokenRef,\n tokenVar,\n} from \"@tailwind-styled/theme\"\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SubComponentDef {\n /** HTML tag to render (default: \"span\") */\n tag?: string\n /** Scoped CSS class generated by Rust, e.g. \"Button_icon_abc123\" */\n class: string\n}\n\nexport type SubComponentMap = Record<string, SubComponentDef>\n\n/**\n * Map of prop name → CSS class appended when the prop is truthy.\n * e.g. { fullWidth: \"w-full\", large: \"text-lg px-6 py-3\" }\n */\nexport type ConditionalProps = Record<string, string>\n\n/**\n * A compound styled component: base ForwardRef + attached .SubName properties.\n * The generic params are intentionally loose so callers don't need to repeat them.\n */\nexport type StyledComponent<S extends SubComponentMap = SubComponentMap> =\n React.ForwardRefExoticComponent<\n React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLElement>\n > & {\n [K in keyof S]: React.ForwardRefExoticComponent<\n React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLElement>\n >\n }\n\n/** Metadata for one compound component produced by Rust. */\nexport interface ComponentMetadata {\n component: string\n tag: string\n baseClass: string\n subComponents: SubComponentMap\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// cx — tiny className utility (no external dependency)\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype ClassInput = string | number | false | null | undefined | ClassInput[]\n\nexport function cx(...inputs: ClassInput[]): string {\n const out: string[] = []\n for (const input of inputs) {\n if (!input) continue // filters 0, false, null, undefined, \"\"\n if (typeof input === \"string\") {\n out.push(input)\n } else if (typeof input === \"number\") {\n out.push(String(input))\n } else if (Array.isArray(input)) {\n const nested = cx(...input)\n if (nested) out.push(nested)\n }\n }\n return out.join(\" \")\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// createComponent\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Build a compound styled React component from Rust-generated metadata.\n *\n * @param tag HTML element tag, e.g. \"button\" | \"div\"\n * @param baseClass Scoped base class from Rust, e.g. \"Button_abc123\"\n * @param subComponents Map of subcomponent definitions (optional)\n * @param conditionals Map of prop name → CSS class (optional)\n *\n * @example\n * // Injected automatically by the compiler — do not call manually\n * const Button = createComponent(\"button\", \"Button_abc123\", {\n * icon: { tag: \"span\", class: \"Button_icon_abc123\" },\n * text: { tag: \"span\", class: \"Button_text_abc123\" },\n * }, { fullWidth: \"w-full\" })\n *\n * // Usage in JSX:\n * <Button fullWidth>\n * <Button.icon>🔍</Button.icon>\n * <Button.text>Search</Button.text>\n * </Button>\n */\nexport function createComponent<S extends SubComponentMap = SubComponentMap>(\n tag: string,\n baseClass: string,\n subComponents?: S,\n conditionals?: ConditionalProps\n): StyledComponent<S> {\n type Props = React.HTMLAttributes<HTMLElement> &\n React.RefAttributes<HTMLElement> &\n Record<string, unknown>\n\n // ── Base component ─────────────────────────────────────────────────────────\n const Base = React.forwardRef<HTMLElement, Props>(function TwBase(props, ref) {\n const extra: string[] = []\n\n // Collect conditional classes\n if (conditionals) {\n for (const [prop, cls] of Object.entries(conditionals)) {\n if (props[prop]) extra.push(cls)\n }\n }\n\n // Build clean props — strip conditional + subcomponent boolean props\n const clean: Record<string, unknown> = {}\n const stripKeys = new Set([\n \"className\",\n ...(conditionals ? Object.keys(conditionals) : []),\n ...(subComponents ? Object.keys(subComponents) : []),\n ])\n for (const [k, v] of Object.entries(props)) {\n if (!stripKeys.has(k)) clean[k] = v\n }\n\n const className = cx(baseClass, ...extra, (props.className as string) ?? \"\")\n\n return React.createElement(tag, { ...clean, ref, className: className || undefined })\n })\n\n ;(Base as { displayName?: string }).displayName = \"tw.\" + String(tag)\n\n // ── Attach subcomponent properties ────────────────────────────────────────\n if (subComponents) {\n for (const [subName, def] of Object.entries(subComponents)) {\n const subTag = def.tag ?? \"span\"\n const subClass = def.class\n\n const SubComp = React.forwardRef<HTMLElement, Props>(function TwSub(props, ref) {\n const className = cx(subClass, (props.className as string) ?? \"\")\n const clean: Record<string, unknown> = { ...props }\n delete clean.className\n return React.createElement(subTag, { ...clean, ref, className: className || undefined })\n })\n\n ;(SubComp as { displayName?: string }).displayName =\n \"tw.\" + String(tag) + \".\" + String(subName)\n\n ;(Base as unknown as Record<string, unknown>)[subName] = SubComp\n }\n }\n\n return Base as unknown as StyledComponent<S>\n}\n"]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface CssInjectorProps {
|
|
4
|
+
/** Override CSS directory. Default: .next/static/css/tw */
|
|
5
|
+
cssDir?: string;
|
|
6
|
+
/** Specific route to inject. Default: auto-detect dari headers */
|
|
7
|
+
route?: string;
|
|
8
|
+
/** Inject global CSS juga. Default: true */
|
|
9
|
+
includeGlobal?: boolean;
|
|
10
|
+
/** Minify inline CSS. Default: true */
|
|
11
|
+
minify?: boolean;
|
|
12
|
+
/** Add <link> tag instead of inline <style> untuk cached CSS */
|
|
13
|
+
asLink?: boolean;
|
|
14
|
+
/** Override manifest path for dev mode */
|
|
15
|
+
manifestPath?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Server Component — inject route-specific CSS into <head>.
|
|
19
|
+
* No client JS, no hydration overhead.
|
|
20
|
+
*/
|
|
21
|
+
declare function TwCssInjector(props?: CssInjectorProps): Promise<React.ReactElement>;
|
|
22
|
+
/**
|
|
23
|
+
* Lightweight hook to get current route's CSS classes.
|
|
24
|
+
* Useful for dynamic class injection in client components.
|
|
25
|
+
*
|
|
26
|
+
* Returns empty string on server (SSR) — CSS already injected by TwCssInjector.
|
|
27
|
+
*/
|
|
28
|
+
declare function useTwClasses(classes: string): string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Queue a CSS rule for batched injection.
|
|
32
|
+
* Multiple rules accumulated during one event loop tick are flushed together
|
|
33
|
+
* in one requestAnimationFrame → one style recalculation.
|
|
34
|
+
*/
|
|
35
|
+
declare function batchedInject(cssRule: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Immediately flush all pending CSS rules to the DOM.
|
|
38
|
+
* Called automatically by RAF each frame. Can also be called manually
|
|
39
|
+
* after synchronous component setup where RAF timing is too late.
|
|
40
|
+
*/
|
|
41
|
+
declare function flushBatchedCss(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Synchronous inject — skips batching.
|
|
44
|
+
* Use for SSR / critical path where RAF is not available.
|
|
45
|
+
*/
|
|
46
|
+
declare function syncInject(cssRule: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a rule has already been injected (deduplication check).
|
|
49
|
+
*/
|
|
50
|
+
declare function isInjected(cssRule: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Clear all injected rules and remove the style element.
|
|
53
|
+
* Useful for testing / SSR resets. Not for production use.
|
|
54
|
+
*/
|
|
55
|
+
declare function resetBatchedCss(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Get stats about the current injection state (for devtools).
|
|
58
|
+
*/
|
|
59
|
+
declare function getBatchedCssStats(): {
|
|
60
|
+
totalInjected: number;
|
|
61
|
+
pendingCount: number;
|
|
62
|
+
hasBatchScheduled: boolean;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export { TwCssInjector, batchedInject, flushBatchedCss, getBatchedCssStats, isInjected, resetBatchedCss, syncInject, useTwClasses };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface CssInjectorProps {
|
|
4
|
+
/** Override CSS directory. Default: .next/static/css/tw */
|
|
5
|
+
cssDir?: string;
|
|
6
|
+
/** Specific route to inject. Default: auto-detect dari headers */
|
|
7
|
+
route?: string;
|
|
8
|
+
/** Inject global CSS juga. Default: true */
|
|
9
|
+
includeGlobal?: boolean;
|
|
10
|
+
/** Minify inline CSS. Default: true */
|
|
11
|
+
minify?: boolean;
|
|
12
|
+
/** Add <link> tag instead of inline <style> untuk cached CSS */
|
|
13
|
+
asLink?: boolean;
|
|
14
|
+
/** Override manifest path for dev mode */
|
|
15
|
+
manifestPath?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Server Component — inject route-specific CSS into <head>.
|
|
19
|
+
* No client JS, no hydration overhead.
|
|
20
|
+
*/
|
|
21
|
+
declare function TwCssInjector(props?: CssInjectorProps): Promise<React.ReactElement>;
|
|
22
|
+
/**
|
|
23
|
+
* Lightweight hook to get current route's CSS classes.
|
|
24
|
+
* Useful for dynamic class injection in client components.
|
|
25
|
+
*
|
|
26
|
+
* Returns empty string on server (SSR) — CSS already injected by TwCssInjector.
|
|
27
|
+
*/
|
|
28
|
+
declare function useTwClasses(classes: string): string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Queue a CSS rule for batched injection.
|
|
32
|
+
* Multiple rules accumulated during one event loop tick are flushed together
|
|
33
|
+
* in one requestAnimationFrame → one style recalculation.
|
|
34
|
+
*/
|
|
35
|
+
declare function batchedInject(cssRule: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Immediately flush all pending CSS rules to the DOM.
|
|
38
|
+
* Called automatically by RAF each frame. Can also be called manually
|
|
39
|
+
* after synchronous component setup where RAF timing is too late.
|
|
40
|
+
*/
|
|
41
|
+
declare function flushBatchedCss(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Synchronous inject — skips batching.
|
|
44
|
+
* Use for SSR / critical path where RAF is not available.
|
|
45
|
+
*/
|
|
46
|
+
declare function syncInject(cssRule: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a rule has already been injected (deduplication check).
|
|
49
|
+
*/
|
|
50
|
+
declare function isInjected(cssRule: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Clear all injected rules and remove the style element.
|
|
53
|
+
* Useful for testing / SSR resets. Not for production use.
|
|
54
|
+
*/
|
|
55
|
+
declare function resetBatchedCss(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Get stats about the current injection state (for devtools).
|
|
58
|
+
*/
|
|
59
|
+
declare function getBatchedCssStats(): {
|
|
60
|
+
totalInjected: number;
|
|
61
|
+
pendingCount: number;
|
|
62
|
+
hasBatchScheduled: boolean;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export { TwCssInjector, batchedInject, flushBatchedCss, getBatchedCssStats, isInjected, resetBatchedCss, syncInject, useTwClasses };
|