tailwind-styled-v4 1.0.1 → 4.0.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.
Files changed (90) hide show
  1. package/dist/animate.cjs +252 -0
  2. package/dist/animate.cjs.map +1 -0
  3. package/dist/animate.d.cts +117 -0
  4. package/dist/animate.d.ts +117 -0
  5. package/dist/animate.js +245 -0
  6. package/dist/animate.js.map +1 -0
  7. package/dist/astTransform-ua-eapqs.d.cts +41 -0
  8. package/dist/astTransform-ua-eapqs.d.ts +41 -0
  9. package/dist/compiler.cjs +3594 -0
  10. package/dist/compiler.cjs.map +1 -0
  11. package/dist/compiler.d.cts +716 -0
  12. package/dist/compiler.d.ts +716 -0
  13. package/dist/compiler.js +3535 -0
  14. package/dist/compiler.js.map +1 -0
  15. package/dist/css.cjs +71 -0
  16. package/dist/css.cjs.map +1 -0
  17. package/dist/css.d.cts +45 -0
  18. package/dist/css.d.ts +45 -0
  19. package/dist/css.js +62 -0
  20. package/dist/css.js.map +1 -0
  21. package/dist/devtools.cjs +959 -0
  22. package/dist/devtools.cjs.map +1 -0
  23. package/dist/devtools.d.cts +22 -0
  24. package/dist/devtools.d.ts +22 -0
  25. package/dist/devtools.js +952 -0
  26. package/dist/devtools.js.map +1 -0
  27. package/dist/index.cjs +1058 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +584 -0
  30. package/dist/index.d.ts +449 -980
  31. package/dist/index.js +1021 -3
  32. package/dist/index.js.map +1 -1
  33. package/dist/next.cjs +268 -0
  34. package/dist/next.cjs.map +1 -0
  35. package/dist/next.d.cts +45 -0
  36. package/dist/next.d.ts +45 -0
  37. package/dist/next.js +261 -0
  38. package/dist/next.js.map +1 -0
  39. package/dist/plugins.cjs +396 -0
  40. package/dist/plugins.cjs.map +1 -0
  41. package/dist/plugins.d.cts +231 -0
  42. package/dist/plugins.d.ts +231 -0
  43. package/dist/plugins.js +381 -0
  44. package/dist/plugins.js.map +1 -0
  45. package/dist/preset.cjs +129 -0
  46. package/dist/preset.cjs.map +1 -0
  47. package/dist/preset.d.cts +249 -0
  48. package/dist/preset.d.ts +249 -0
  49. package/dist/preset.js +124 -0
  50. package/dist/preset.js.map +1 -0
  51. package/dist/theme.cjs +154 -0
  52. package/dist/theme.cjs.map +1 -0
  53. package/dist/theme.d.cts +181 -0
  54. package/dist/theme.d.ts +181 -0
  55. package/dist/theme.js +148 -0
  56. package/dist/theme.js.map +1 -0
  57. package/dist/turbopackLoader.cjs +2689 -0
  58. package/dist/turbopackLoader.cjs.map +1 -0
  59. package/dist/turbopackLoader.d.cts +22 -0
  60. package/dist/turbopackLoader.d.ts +22 -0
  61. package/dist/turbopackLoader.js +2681 -0
  62. package/dist/turbopackLoader.js.map +1 -0
  63. package/dist/vite.cjs +105 -0
  64. package/dist/vite.cjs.map +1 -0
  65. package/dist/vite.d.cts +22 -0
  66. package/dist/vite.d.ts +22 -0
  67. package/dist/vite.js +96 -0
  68. package/dist/vite.js.map +1 -0
  69. package/dist/webpackLoader.cjs +2670 -0
  70. package/dist/webpackLoader.cjs.map +1 -0
  71. package/dist/webpackLoader.d.cts +24 -0
  72. package/dist/webpackLoader.d.ts +24 -0
  73. package/dist/webpackLoader.js +2662 -0
  74. package/dist/webpackLoader.js.map +1 -0
  75. package/package.json +62 -32
  76. package/CHANGELOG.md +0 -75
  77. package/LICENSE +0 -21
  78. package/README.md +0 -608
  79. package/dist/cli/init.js +0 -208
  80. package/dist/compiler/index.d.mts +0 -214
  81. package/dist/compiler/index.d.ts +0 -214
  82. package/dist/compiler/index.js +0 -546
  83. package/dist/compiler/index.js.map +0 -1
  84. package/dist/compiler/index.mjs +0 -504
  85. package/dist/compiler/index.mjs.map +0 -1
  86. package/dist/index.d.mts +0 -1115
  87. package/dist/index.mjs +0 -4
  88. package/dist/index.mjs.map +0 -1
  89. package/dist/turbopack-loader.js +0 -232
  90. package/dist/webpack-loader.js +0 -213
@@ -0,0 +1,952 @@
1
+ import React, { useState, useRef, useEffect, useCallback } from 'react';
2
+
3
+ /* tailwind-styled-v4 v4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
4
+ var __defProp = Object.defineProperty;
5
+ var __defProps = Object.defineProperties;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
+ function parseDataTw(dataTw) {
24
+ if (!dataTw) return { name: "Unknown", classes: [] };
25
+ const colonIdx = dataTw.indexOf(":");
26
+ if (colonIdx === -1) return { name: dataTw, classes: [] };
27
+ const name = dataTw.slice(0, colonIdx);
28
+ const classes = dataTw.slice(colonIdx + 1).split(/\s+/).filter(Boolean);
29
+ return { name, classes };
30
+ }
31
+ function parseVariantAttr(v) {
32
+ if (!v) return {};
33
+ try {
34
+ return JSON.parse(v);
35
+ } catch (e) {
36
+ return {};
37
+ }
38
+ }
39
+ function findNearestTwElement(el) {
40
+ var _a;
41
+ let cur = el;
42
+ while (cur) {
43
+ if ((_a = cur.dataset) == null ? void 0 : _a.tw) return cur;
44
+ cur = cur.parentElement;
45
+ }
46
+ return null;
47
+ }
48
+ function getAtomicMap(classes) {
49
+ const registry = window.__TW_REGISTRY__;
50
+ if (!registry) return {};
51
+ const map = {};
52
+ for (const cls of classes) {
53
+ if (registry[cls]) map[cls] = registry[cls];
54
+ }
55
+ return map;
56
+ }
57
+ function getActiveStates(el) {
58
+ const states = {};
59
+ for (const attr of el.attributes) {
60
+ if (attr.name.startsWith("data-")) {
61
+ states[attr.name.replace("data-", "")] = attr.value;
62
+ }
63
+ }
64
+ return states;
65
+ }
66
+ function getStateNames(el) {
67
+ const registry = window.__TW_STATE_REGISTRY__;
68
+ if (!registry) return [];
69
+ for (const [id, entry] of registry) {
70
+ if (el.classList.contains(id)) return entry.states;
71
+ }
72
+ return [];
73
+ }
74
+ function getContainerBps(el) {
75
+ const registry = window.__TW_CONTAINER_REGISTRY__;
76
+ if (!registry) return [];
77
+ for (const [id, entry] of registry) {
78
+ if (el.classList.contains(id)) {
79
+ return entry.breakpoints.map((bp) => bp.minWidth);
80
+ }
81
+ }
82
+ return [];
83
+ }
84
+ function InspectorPanel({
85
+ inspected,
86
+ position: _position,
87
+ pinned: _pinned
88
+ }) {
89
+ if (!inspected) {
90
+ return React.createElement(
91
+ "div",
92
+ { style: S.emptyPanel },
93
+ React.createElement("span", { style: { opacity: 0.4 } }, "Hover an element to inspect")
94
+ );
95
+ }
96
+ return React.createElement(
97
+ "div",
98
+ { style: S.scrollArea },
99
+ // Variant props
100
+ Object.keys(inspected.variantProps).length > 0 && React.createElement(
101
+ "div",
102
+ { style: S.section },
103
+ React.createElement("div", { style: S.sectionTitle }, "Variants"),
104
+ Object.entries(inspected.variantProps).map(
105
+ ([k, v]) => React.createElement(
106
+ "div",
107
+ { key: k, style: S.row },
108
+ React.createElement("span", { style: S.varKey }, k),
109
+ React.createElement("span", { style: S.varValue }, `"${v}"`)
110
+ )
111
+ )
112
+ ),
113
+ // Active states
114
+ Object.keys(inspected.activeStates).length > 0 && React.createElement(
115
+ "div",
116
+ { style: S.section },
117
+ React.createElement("div", { style: S.sectionTitle }, "Active Data Attrs"),
118
+ Object.entries(inspected.activeStates).map(
119
+ ([k, v]) => React.createElement(
120
+ "div",
121
+ { key: k, style: S.row },
122
+ React.createElement("code", { style: __spreadProps(__spreadValues({}, S.varKey), { color: "#f59e0b" }) }, `data-${k}`),
123
+ React.createElement("span", { style: __spreadProps(__spreadValues({}, S.varValue), { color: "#34d399" }) }, `"${v}"`)
124
+ )
125
+ )
126
+ ),
127
+ // State names
128
+ inspected.stateNames.length > 0 && React.createElement(
129
+ "div",
130
+ { style: S.section },
131
+ React.createElement("div", { style: S.sectionTitle }, "Reactive States"),
132
+ React.createElement(
133
+ "div",
134
+ { style: S.classGrid },
135
+ inspected.stateNames.map(
136
+ (s) => React.createElement(
137
+ "code",
138
+ {
139
+ key: s,
140
+ style: __spreadProps(__spreadValues({}, S.classChip), {
141
+ background: inspected.activeStates[s] === "true" ? "#065f46" : "#18181b",
142
+ borderColor: inspected.activeStates[s] === "true" ? "#34d399" : "#27272a"
143
+ })
144
+ },
145
+ s
146
+ )
147
+ )
148
+ )
149
+ ),
150
+ // Container breakpoints
151
+ inspected.containerBps.length > 0 && React.createElement(
152
+ "div",
153
+ { style: S.section },
154
+ React.createElement("div", { style: S.sectionTitle }, "Container Breakpoints"),
155
+ React.createElement(
156
+ "div",
157
+ { style: S.classGrid },
158
+ inspected.containerBps.map(
159
+ (bp) => React.createElement(
160
+ "code",
161
+ { key: bp, style: __spreadProps(__spreadValues({}, S.classChip), { color: "#818cf8" }) },
162
+ bp
163
+ )
164
+ )
165
+ )
166
+ ),
167
+ // Tailwind classes
168
+ inspected.twClasses.length > 0 && React.createElement(
169
+ "div",
170
+ { style: S.section },
171
+ React.createElement("div", { style: S.sectionTitle }, "Classes"),
172
+ React.createElement(
173
+ "div",
174
+ { style: S.classGrid },
175
+ inspected.twClasses.map(
176
+ (cls) => React.createElement(
177
+ "code",
178
+ { key: cls, style: S.classChip, title: inspected.atomicMap[cls] },
179
+ cls
180
+ )
181
+ )
182
+ )
183
+ ),
184
+ // Copy
185
+ React.createElement(
186
+ "button",
187
+ {
188
+ style: S.copyBtn,
189
+ onClick: () => {
190
+ var _a;
191
+ (_a = navigator.clipboard) == null ? void 0 : _a.writeText(
192
+ JSON.stringify(
193
+ {
194
+ component: inspected.componentName,
195
+ variants: inspected.variantProps,
196
+ states: inspected.activeStates,
197
+ classes: inspected.twClasses
198
+ },
199
+ null,
200
+ 2
201
+ )
202
+ );
203
+ }
204
+ },
205
+ "Copy to clipboard"
206
+ )
207
+ );
208
+ }
209
+ function StatePanel() {
210
+ const [entries, setEntries] = useState([]);
211
+ useEffect(() => {
212
+ const refresh = () => {
213
+ const reg = window.__TW_STATE_REGISTRY__;
214
+ setEntries(reg ? Array.from(reg.values()) : []);
215
+ };
216
+ refresh();
217
+ const interval = setInterval(refresh, 1e3);
218
+ return () => clearInterval(interval);
219
+ }, []);
220
+ if (entries.length === 0) {
221
+ return React.createElement(
222
+ "div",
223
+ { style: S.emptyPanel },
224
+ React.createElement(
225
+ "span",
226
+ { style: { opacity: 0.4 } },
227
+ "No state-enabled components found."
228
+ ),
229
+ React.createElement("br", null),
230
+ React.createElement(
231
+ "span",
232
+ { style: { opacity: 0.3, fontSize: "11px" } },
233
+ 'Use tw.button({ state: { active: "..." } }) to register.'
234
+ )
235
+ );
236
+ }
237
+ return React.createElement(
238
+ "div",
239
+ { style: S.scrollArea },
240
+ entries.map(
241
+ (entry) => React.createElement(
242
+ "div",
243
+ { key: entry.id, style: S.section },
244
+ React.createElement(
245
+ "div",
246
+ { style: S.sectionTitle },
247
+ React.createElement("span", { style: { color: "#60a5fa" } }, entry.tag.toUpperCase()),
248
+ React.createElement(
249
+ "span",
250
+ { style: { marginLeft: "8px", color: "#52525b", fontSize: "10px" } },
251
+ entry.id
252
+ )
253
+ ),
254
+ React.createElement(
255
+ "div",
256
+ { style: S.classGrid },
257
+ entry.states.map(
258
+ (s) => React.createElement(
259
+ "code",
260
+ { key: s, style: __spreadProps(__spreadValues({}, S.classChip), { color: "#f59e0b" }) },
261
+ `data-${s}`
262
+ )
263
+ )
264
+ ),
265
+ React.createElement(
266
+ "div",
267
+ { style: __spreadProps(__spreadValues({}, S.row), { marginTop: "4px" }) },
268
+ React.createElement(
269
+ "span",
270
+ {
271
+ style: __spreadProps(__spreadValues({}, S.sectionTitle), {
272
+ marginBottom: 0,
273
+ color: entry.cssInjected ? "#34d399" : "#ef4444"
274
+ })
275
+ },
276
+ entry.cssInjected ? "\u25CF CSS injected" : "\u25CB CSS pending"
277
+ )
278
+ )
279
+ )
280
+ )
281
+ );
282
+ }
283
+ function ContainerPanel() {
284
+ const [entries, setEntries] = useState([]);
285
+ useEffect(() => {
286
+ const refresh = () => {
287
+ const reg = window.__TW_CONTAINER_REGISTRY__;
288
+ setEntries(reg ? Array.from(reg.values()) : []);
289
+ };
290
+ refresh();
291
+ const interval = setInterval(refresh, 1e3);
292
+ return () => clearInterval(interval);
293
+ }, []);
294
+ if (entries.length === 0) {
295
+ return React.createElement(
296
+ "div",
297
+ { style: S.emptyPanel },
298
+ React.createElement(
299
+ "span",
300
+ { style: { opacity: 0.4 } },
301
+ "No container query components found."
302
+ ),
303
+ React.createElement("br", null),
304
+ React.createElement(
305
+ "span",
306
+ { style: { opacity: 0.3, fontSize: "11px" } },
307
+ 'Use tw.div({ container: { md: "flex-row" } }) to register.'
308
+ )
309
+ );
310
+ }
311
+ return React.createElement(
312
+ "div",
313
+ { style: S.scrollArea },
314
+ entries.map(
315
+ (entry) => React.createElement(
316
+ "div",
317
+ { key: entry.id, style: S.section },
318
+ React.createElement(
319
+ "div",
320
+ { style: S.sectionTitle },
321
+ React.createElement("span", { style: { color: "#60a5fa" } }, entry.tag.toUpperCase()),
322
+ entry.containerName && React.createElement(
323
+ "span",
324
+ { style: { marginLeft: "6px", color: "#818cf8" } },
325
+ `[${entry.containerName}]`
326
+ ),
327
+ React.createElement(
328
+ "span",
329
+ { style: { marginLeft: "8px", color: "#52525b", fontSize: "10px" } },
330
+ entry.id
331
+ )
332
+ ),
333
+ React.createElement(
334
+ "div",
335
+ null,
336
+ entry.breakpoints.map(
337
+ (bp, i) => React.createElement(
338
+ "div",
339
+ { key: i, style: __spreadProps(__spreadValues({}, S.row), { marginBottom: "2px" }) },
340
+ React.createElement(
341
+ "code",
342
+ { style: { color: "#818cf8", fontSize: "11px" } },
343
+ `\u2265 ${bp.minWidth}`
344
+ ),
345
+ React.createElement(
346
+ "span",
347
+ { style: { color: "#6b7280", fontSize: "11px" } },
348
+ bp.classes
349
+ )
350
+ )
351
+ )
352
+ )
353
+ )
354
+ )
355
+ );
356
+ }
357
+ function TokensPanel() {
358
+ const [tokens, setTokens_] = useState({});
359
+ useEffect(() => {
360
+ const engine = window.__TW_TOKEN_ENGINE__;
361
+ if (!engine) return;
362
+ setTokens_(engine.getTokens());
363
+ const unsub = engine.subscribe((t) => setTokens_(__spreadValues({}, t)));
364
+ return unsub;
365
+ }, []);
366
+ const entries = Object.entries(tokens);
367
+ if (entries.length === 0) {
368
+ return React.createElement(
369
+ "div",
370
+ { style: S.emptyPanel },
371
+ React.createElement("span", { style: { opacity: 0.4 } }, "No live tokens registered."),
372
+ React.createElement("br", null),
373
+ React.createElement(
374
+ "span",
375
+ { style: { opacity: 0.3, fontSize: "11px" } },
376
+ 'Use liveToken({ primary: "#3b82f6" }) to register tokens.'
377
+ )
378
+ );
379
+ }
380
+ return React.createElement(
381
+ "div",
382
+ { style: S.scrollArea },
383
+ React.createElement(
384
+ "div",
385
+ { style: __spreadProps(__spreadValues({}, S.sectionTitle), { padding: "8px 12px 4px", color: "#52525b" }) },
386
+ "Click color to edit \xB7 Changes apply instantly"
387
+ ),
388
+ entries.map(([name, value]) => {
389
+ const isColor = value.startsWith("#") || value.startsWith("rgb") || value.startsWith("hsl");
390
+ return React.createElement(
391
+ "div",
392
+ { key: name, style: __spreadProps(__spreadValues({}, S.row), { padding: "6px 12px", borderBottom: "1px solid #18181b" }) },
393
+ React.createElement(
394
+ "div",
395
+ { style: { display: "flex", alignItems: "center", gap: "8px" } },
396
+ isColor && React.createElement("div", {
397
+ style: {
398
+ width: "16px",
399
+ height: "16px",
400
+ borderRadius: "3px",
401
+ background: value,
402
+ border: "1px solid #27272a",
403
+ flexShrink: 0
404
+ }
405
+ }),
406
+ React.createElement("span", { style: { color: "#a1a1aa", fontSize: "12px" } }, name)
407
+ ),
408
+ isColor ? React.createElement("input", {
409
+ type: "color",
410
+ defaultValue: value.startsWith("#") ? value : "#000000",
411
+ style: {
412
+ width: "52px",
413
+ height: "22px",
414
+ border: "none",
415
+ background: "none",
416
+ cursor: "pointer"
417
+ },
418
+ onChange: (e) => {
419
+ const engine = window.__TW_TOKEN_ENGINE__;
420
+ if (engine) engine.setToken(name, e.target.value);
421
+ }
422
+ }) : React.createElement("input", {
423
+ type: "text",
424
+ defaultValue: value,
425
+ style: {
426
+ background: "#18181b",
427
+ border: "1px solid #27272a",
428
+ borderRadius: "3px",
429
+ color: "#e4e4e7",
430
+ fontSize: "11px",
431
+ padding: "2px 6px",
432
+ width: "100px",
433
+ fontFamily: "monospace"
434
+ },
435
+ onBlur: (e) => {
436
+ const engine = window.__TW_TOKEN_ENGINE__;
437
+ if (engine) engine.setToken(name, e.target.value);
438
+ }
439
+ })
440
+ );
441
+ })
442
+ );
443
+ }
444
+ function AnalyzerPanel() {
445
+ const [scanning, setScanning] = useState(false);
446
+ const [results, setResults] = useState(null);
447
+ const runScan = useCallback(() => {
448
+ setScanning(true);
449
+ setTimeout(() => {
450
+ var _a, _b, _c, _d;
451
+ const twEls = document.querySelectorAll("[data-tw]");
452
+ const classMap = /* @__PURE__ */ new Map();
453
+ for (const el of twEls) {
454
+ const { name, classes } = (() => {
455
+ var _a2;
456
+ const dTw = (_a2 = el.dataset.tw) != null ? _a2 : null;
457
+ if (!dTw) return { name: "?", classes: [] };
458
+ const ci = dTw.indexOf(":");
459
+ return {
460
+ name: ci >= 0 ? dTw.slice(0, ci) : dTw,
461
+ classes: ci >= 0 ? dTw.slice(ci + 1).split(/\s+/).filter(Boolean) : []
462
+ };
463
+ })();
464
+ const key = classes.sort().join(" ");
465
+ if (!classMap.has(key)) classMap.set(key, []);
466
+ classMap.get(key).push(name);
467
+ }
468
+ const duplicates = Array.from(classMap.entries()).filter(([, names]) => names.length > 1).map(([pattern, names]) => ({ pattern, count: names.length, names })).sort((a, b) => b.count - a.count).slice(0, 10);
469
+ const stateReg = window.__TW_STATE_REGISTRY__;
470
+ const containerReg = window.__TW_CONTAINER_REGISTRY__;
471
+ const tokenEngine = window.__TW_TOKEN_ENGINE__;
472
+ setResults({
473
+ duplicates,
474
+ stateCount: (_a = stateReg == null ? void 0 : stateReg.size) != null ? _a : 0,
475
+ containerCount: (_b = containerReg == null ? void 0 : containerReg.size) != null ? _b : 0,
476
+ tokenCount: Object.keys((_d = (_c = tokenEngine == null ? void 0 : tokenEngine.getTokens) == null ? void 0 : _c.call(tokenEngine)) != null ? _d : {}).length
477
+ });
478
+ setScanning(false);
479
+ }, 100);
480
+ }, []);
481
+ return React.createElement(
482
+ "div",
483
+ { style: S.scrollArea },
484
+ React.createElement(
485
+ "div",
486
+ { style: { padding: "10px 12px" } },
487
+ React.createElement(
488
+ "button",
489
+ {
490
+ style: __spreadProps(__spreadValues({}, S.copyBtn), { borderTop: "none", color: "#60a5fa", fontWeight: "600" }),
491
+ onClick: runScan,
492
+ disabled: scanning
493
+ },
494
+ scanning ? "Scanning DOM..." : "\u25B6 Run DOM Scan"
495
+ ),
496
+ results && React.createElement(
497
+ "div",
498
+ null,
499
+ // Summary
500
+ React.createElement(
501
+ "div",
502
+ { style: S.section },
503
+ React.createElement("div", { style: S.sectionTitle }, "Summary"),
504
+ React.createElement(
505
+ "div",
506
+ { style: S.row },
507
+ React.createElement("span", { style: S.varKey }, "State components"),
508
+ React.createElement("span", { style: S.varValue }, String(results.stateCount))
509
+ ),
510
+ React.createElement(
511
+ "div",
512
+ { style: S.row },
513
+ React.createElement("span", { style: S.varKey }, "Container components"),
514
+ React.createElement("span", { style: S.varValue }, String(results.containerCount))
515
+ ),
516
+ React.createElement(
517
+ "div",
518
+ { style: S.row },
519
+ React.createElement("span", { style: S.varKey }, "Live tokens"),
520
+ React.createElement("span", { style: S.varValue }, String(results.tokenCount))
521
+ )
522
+ ),
523
+ // Duplicates
524
+ results.duplicates.length > 0 ? React.createElement(
525
+ "div",
526
+ { style: S.section },
527
+ React.createElement("div", { style: S.sectionTitle }, "Duplicate Class Sets"),
528
+ results.duplicates.map(
529
+ (d, i) => React.createElement(
530
+ "div",
531
+ { key: i, style: { marginBottom: "8px" } },
532
+ React.createElement(
533
+ "div",
534
+ { style: { color: "#f59e0b", fontSize: "11px", marginBottom: "2px" } },
535
+ d.names.join(", ")
536
+ ),
537
+ React.createElement(
538
+ "code",
539
+ {
540
+ style: {
541
+ color: "#52525b",
542
+ fontSize: "10px",
543
+ wordBreak: "break-all"
544
+ }
545
+ },
546
+ d.pattern.split(" ").slice(0, 8).join(" ") + (d.pattern.split(" ").length > 8 ? "..." : "")
547
+ )
548
+ )
549
+ )
550
+ ) : results && React.createElement(
551
+ "div",
552
+ { style: S.section },
553
+ React.createElement(
554
+ "span",
555
+ { style: { color: "#34d399", fontSize: "12px" } },
556
+ "\u2713 No duplicate class sets in current DOM"
557
+ )
558
+ )
559
+ )
560
+ )
561
+ );
562
+ }
563
+ function TwDevTools() {
564
+ if (process.env.NODE_ENV === "production") return null;
565
+ const [state, setState] = useState({
566
+ open: false,
567
+ panel: "inspector",
568
+ pinned: false,
569
+ inspected: null,
570
+ position: { x: 0, y: 0 }
571
+ });
572
+ const overlayRef = useRef(null);
573
+ const isInspecting = state.open && state.panel === "inspector";
574
+ useEffect(() => {
575
+ const onKey = (e) => {
576
+ if (e.ctrlKey && e.shiftKey && e.key === "D") {
577
+ e.preventDefault();
578
+ setState((s) => __spreadProps(__spreadValues({}, s), { open: !s.open, inspected: null }));
579
+ }
580
+ if (e.key === "Escape")
581
+ setState((s) => __spreadProps(__spreadValues({}, s), { open: false, pinned: false, inspected: null }));
582
+ if (e.key === "1") setState((s) => s.open ? __spreadProps(__spreadValues({}, s), { panel: "inspector" }) : s);
583
+ if (e.key === "2") setState((s) => s.open ? __spreadProps(__spreadValues({}, s), { panel: "state" }) : s);
584
+ if (e.key === "3") setState((s) => s.open ? __spreadProps(__spreadValues({}, s), { panel: "container" }) : s);
585
+ if (e.key === "4") setState((s) => s.open ? __spreadProps(__spreadValues({}, s), { panel: "tokens" }) : s);
586
+ if (e.key === "5") setState((s) => s.open ? __spreadProps(__spreadValues({}, s), { panel: "analyzer" }) : s);
587
+ };
588
+ window.addEventListener("keydown", onKey);
589
+ return () => window.removeEventListener("keydown", onKey);
590
+ }, []);
591
+ const onMouseMove = useCallback(
592
+ (e) => {
593
+ var _a;
594
+ if (!isInspecting || state.pinned) return;
595
+ const twEl = findNearestTwElement(e.target);
596
+ if (!twEl) {
597
+ setState((s) => __spreadProps(__spreadValues({}, s), { inspected: null, position: { x: e.clientX, y: e.clientY } }));
598
+ return;
599
+ }
600
+ const { name, classes } = parseDataTw((_a = twEl.dataset.tw) != null ? _a : null);
601
+ setState((s) => {
602
+ var _a2;
603
+ return __spreadProps(__spreadValues({}, s), {
604
+ position: { x: e.clientX, y: e.clientY },
605
+ inspected: {
606
+ componentName: name,
607
+ element: twEl,
608
+ rect: twEl.getBoundingClientRect(),
609
+ twClasses: classes,
610
+ variantProps: parseVariantAttr((_a2 = twEl.dataset.twVariants) != null ? _a2 : null),
611
+ atomicMap: getAtomicMap(classes),
612
+ rawClassName: twEl.className,
613
+ stateNames: getStateNames(twEl),
614
+ activeStates: getActiveStates(twEl),
615
+ containerBps: getContainerBps(twEl)
616
+ }
617
+ });
618
+ });
619
+ },
620
+ [isInspecting, state.pinned]
621
+ );
622
+ const onClick = useCallback(
623
+ (e) => {
624
+ var _a;
625
+ if (!isInspecting) return;
626
+ if ((_a = overlayRef.current) == null ? void 0 : _a.contains(e.target)) return;
627
+ setState((s) => __spreadProps(__spreadValues({}, s), { pinned: !s.pinned && !!s.inspected }));
628
+ },
629
+ [isInspecting]
630
+ );
631
+ useEffect(() => {
632
+ if (!isInspecting) return;
633
+ window.addEventListener("mousemove", onMouseMove);
634
+ window.addEventListener("click", onClick);
635
+ return () => {
636
+ window.removeEventListener("mousemove", onMouseMove);
637
+ window.removeEventListener("click", onClick);
638
+ };
639
+ }, [isInspecting, onMouseMove, onClick]);
640
+ if (!state.open) {
641
+ return React.createElement(
642
+ "button",
643
+ {
644
+ onClick: () => setState((s) => __spreadProps(__spreadValues({}, s), { open: true })),
645
+ style: S.toggleBtn,
646
+ title: "tailwind-styled-v4 DevTools (Ctrl+Shift+D)"
647
+ },
648
+ "\u{1F3A8}"
649
+ );
650
+ }
651
+ const PANELS = [
652
+ { id: "inspector", label: "Inspector", icon: "\u{1F50D}" },
653
+ { id: "state", label: "State", icon: "\u26A1" },
654
+ { id: "container", label: "Container", icon: "\u{1F4E6}" },
655
+ { id: "tokens", label: "Tokens", icon: "\u{1F3A8}" },
656
+ { id: "analyzer", label: "Analyzer", icon: "\u{1F4CA}" }
657
+ ];
658
+ return React.createElement(
659
+ "div",
660
+ { style: S.root },
661
+ // ── Element highlight (inspector only) ──────────────────────────────
662
+ isInspecting && state.inspected && React.createElement("div", {
663
+ style: __spreadProps(__spreadValues({}, S.highlight), {
664
+ top: state.inspected.rect.top + window.scrollY,
665
+ left: state.inspected.rect.left + window.scrollX,
666
+ width: state.inspected.rect.width,
667
+ height: state.inspected.rect.height
668
+ })
669
+ }),
670
+ // ── Component name label ────────────────────────────────────────────
671
+ isInspecting && state.inspected && React.createElement(
672
+ "div",
673
+ {
674
+ style: {
675
+ position: "absolute",
676
+ top: state.inspected.rect.top + window.scrollY - 22,
677
+ left: state.inspected.rect.left + window.scrollX,
678
+ background: "#1e3a5f",
679
+ color: "#93c5fd",
680
+ fontSize: "11px",
681
+ padding: "2px 6px",
682
+ borderRadius: "3px 3px 0 0",
683
+ pointerEvents: "none",
684
+ zIndex: 2147483646,
685
+ fontFamily: "monospace"
686
+ }
687
+ },
688
+ state.inspected.componentName
689
+ ),
690
+ // ── Main DevTools panel ─────────────────────────────────────────────
691
+ React.createElement(
692
+ "div",
693
+ {
694
+ ref: overlayRef,
695
+ style: state.panel === "inspector" && state.inspected ? __spreadProps(__spreadValues({}, S.panel), {
696
+ top: Math.min(state.position.y + 16, window.innerHeight - 460),
697
+ left: Math.min(state.position.x + 16, window.innerWidth - 320)
698
+ }) : __spreadProps(__spreadValues({}, S.panel), {
699
+ top: "auto",
700
+ bottom: "40px",
701
+ right: "12px",
702
+ left: "auto"
703
+ })
704
+ },
705
+ // Header
706
+ React.createElement(
707
+ "div",
708
+ { style: S.header },
709
+ React.createElement(
710
+ "span",
711
+ { style: S.componentName },
712
+ state.inspected && state.panel === "inspector" ? state.inspected.componentName : "tailwind-styled-v4"
713
+ ),
714
+ React.createElement(
715
+ "div",
716
+ { style: S.headerActions },
717
+ state.pinned && React.createElement("span", { style: S.pinBadge }, "\u{1F4CC}"),
718
+ React.createElement(
719
+ "button",
720
+ {
721
+ style: S.closeBtn,
722
+ onClick: () => setState((s) => __spreadProps(__spreadValues({}, s), { open: false, pinned: false, inspected: null }))
723
+ },
724
+ "\u2715"
725
+ )
726
+ )
727
+ ),
728
+ // Tab bar
729
+ React.createElement(
730
+ "div",
731
+ { style: S.tabBar },
732
+ PANELS.map(
733
+ (p) => React.createElement(
734
+ "button",
735
+ {
736
+ key: p.id,
737
+ style: __spreadProps(__spreadValues({}, S.tab), {
738
+ background: state.panel === p.id ? "#18181b" : "none",
739
+ color: state.panel === p.id ? "#e4e4e7" : "#52525b",
740
+ borderBottom: state.panel === p.id ? "2px solid #3b82f6" : "2px solid transparent"
741
+ }),
742
+ onClick: () => setState((s) => __spreadProps(__spreadValues({}, s), { panel: p.id })),
743
+ title: `${p.label} (${PANELS.findIndex((x) => x.id === p.id) + 1})`
744
+ },
745
+ `${p.icon} ${p.label}`
746
+ )
747
+ )
748
+ ),
749
+ // Panel content
750
+ state.panel === "inspector" && React.createElement(InspectorPanel, {
751
+ inspected: state.inspected,
752
+ position: state.position,
753
+ pinned: state.pinned
754
+ }),
755
+ state.panel === "state" && React.createElement(StatePanel, null),
756
+ state.panel === "container" && React.createElement(ContainerPanel, null),
757
+ state.panel === "tokens" && React.createElement(TokensPanel, null),
758
+ state.panel === "analyzer" && React.createElement(AnalyzerPanel, null)
759
+ ),
760
+ // ── Status bar ──────────────────────────────────────────────────────
761
+ React.createElement(
762
+ "div",
763
+ { style: S.statusBar },
764
+ React.createElement("span", null, "\u{1F3A8} tailwind-styled-v4 DevTools"),
765
+ React.createElement(
766
+ "span",
767
+ { style: { opacity: 0.6, fontSize: "10px" } },
768
+ state.pinned ? "Click to unpin" : isInspecting ? "Hover to inspect \xB7 Click to pin \xB7 1-5 switch panel \xB7 Esc close" : "Ctrl+Shift+D close \xB7 1-5 switch panel"
769
+ )
770
+ )
771
+ );
772
+ }
773
+ var S = {
774
+ root: {
775
+ position: "fixed",
776
+ inset: 0,
777
+ zIndex: 2147483647,
778
+ pointerEvents: "none",
779
+ fontFamily: "ui-monospace, 'JetBrains Mono', monospace",
780
+ fontSize: "12px"
781
+ },
782
+ highlight: {
783
+ position: "absolute",
784
+ borderRadius: "3px",
785
+ outline: "2px solid #3b82f6",
786
+ outlineOffset: "1px",
787
+ background: "rgba(59,130,246,0.08)",
788
+ pointerEvents: "none",
789
+ transition: "all 0.1s ease",
790
+ zIndex: 2147483646
791
+ },
792
+ panel: {
793
+ position: "fixed",
794
+ width: 320,
795
+ maxHeight: 480,
796
+ background: "#0f0f0f",
797
+ border: "1px solid #27272a",
798
+ borderRadius: "10px",
799
+ boxShadow: "0 8px 32px rgba(0,0,0,0.8)",
800
+ pointerEvents: "all",
801
+ zIndex: 2147483647,
802
+ userSelect: "text",
803
+ display: "flex",
804
+ flexDirection: "column"
805
+ },
806
+ header: {
807
+ display: "flex",
808
+ alignItems: "center",
809
+ justifyContent: "space-between",
810
+ padding: "8px 12px 6px",
811
+ borderBottom: "1px solid #1f1f1f",
812
+ flexShrink: 0
813
+ },
814
+ tabBar: {
815
+ display: "flex",
816
+ borderBottom: "1px solid #18181b",
817
+ flexShrink: 0,
818
+ overflowX: "auto"
819
+ },
820
+ tab: {
821
+ background: "none",
822
+ border: "none",
823
+ cursor: "pointer",
824
+ fontSize: "10px",
825
+ padding: "5px 8px",
826
+ whiteSpace: "nowrap",
827
+ fontFamily: "inherit",
828
+ transition: "color 0.1s",
829
+ pointerEvents: "all"
830
+ },
831
+ scrollArea: {
832
+ overflowY: "auto",
833
+ flex: 1
834
+ },
835
+ emptyPanel: {
836
+ padding: "24px 12px",
837
+ color: "#71717a",
838
+ fontSize: "12px",
839
+ textAlign: "center",
840
+ lineHeight: 1.6
841
+ },
842
+ componentName: {
843
+ color: "#60a5fa",
844
+ fontWeight: "bold",
845
+ fontSize: "13px"
846
+ },
847
+ headerActions: {
848
+ display: "flex",
849
+ alignItems: "center",
850
+ gap: "6px"
851
+ },
852
+ pinBadge: { color: "#fbbf24", fontSize: "10px" },
853
+ closeBtn: {
854
+ background: "none",
855
+ border: "none",
856
+ color: "#71717a",
857
+ cursor: "pointer",
858
+ fontSize: "14px",
859
+ lineHeight: 1,
860
+ padding: "2px 4px",
861
+ pointerEvents: "all"
862
+ },
863
+ section: {
864
+ padding: "8px 12px",
865
+ borderBottom: "1px solid #18181b"
866
+ },
867
+ sectionTitle: {
868
+ color: "#52525b",
869
+ fontSize: "10px",
870
+ textTransform: "uppercase",
871
+ letterSpacing: "0.08em",
872
+ marginBottom: "6px"
873
+ },
874
+ row: {
875
+ display: "flex",
876
+ justifyContent: "space-between",
877
+ alignItems: "center",
878
+ marginBottom: "3px"
879
+ },
880
+ varKey: { color: "#a1a1aa" },
881
+ varValue: { color: "#34d399", fontWeight: "bold" },
882
+ classGrid: {
883
+ display: "flex",
884
+ flexWrap: "wrap",
885
+ gap: "4px"
886
+ },
887
+ classChip: {
888
+ background: "#18181b",
889
+ border: "1px solid #27272a",
890
+ borderRadius: "4px",
891
+ padding: "2px 6px",
892
+ color: "#e4e4e7",
893
+ cursor: "default",
894
+ fontSize: "11px"
895
+ },
896
+ copyBtn: {
897
+ display: "block",
898
+ width: "100%",
899
+ background: "none",
900
+ border: "none",
901
+ borderTop: "1px solid #18181b",
902
+ color: "#52525b",
903
+ cursor: "pointer",
904
+ padding: "8px 12px",
905
+ textAlign: "left",
906
+ fontSize: "11px",
907
+ pointerEvents: "all",
908
+ fontFamily: "inherit"
909
+ },
910
+ statusBar: {
911
+ position: "fixed",
912
+ bottom: 0,
913
+ left: 0,
914
+ right: 0,
915
+ background: "#1e3a5f",
916
+ color: "#93c5fd",
917
+ fontSize: "11px",
918
+ padding: "4px 12px",
919
+ display: "flex",
920
+ justifyContent: "space-between",
921
+ alignItems: "center",
922
+ pointerEvents: "all",
923
+ zIndex: 2147483647
924
+ },
925
+ toggleBtn: {
926
+ position: "fixed",
927
+ bottom: 12,
928
+ right: 12,
929
+ width: 36,
930
+ height: 36,
931
+ borderRadius: "50%",
932
+ background: "#1e3a5f",
933
+ border: "1px solid #3b82f6",
934
+ color: "white",
935
+ cursor: "pointer",
936
+ fontSize: "16px",
937
+ display: "flex",
938
+ alignItems: "center",
939
+ justifyContent: "center",
940
+ zIndex: 2147483647,
941
+ boxShadow: "0 2px 8px rgba(0,0,0,0.4)",
942
+ pointerEvents: "all"
943
+ }
944
+ };
945
+ function DevToolsProvider() {
946
+ if (process.env.NODE_ENV === "production") return null;
947
+ return React.createElement(TwDevTools);
948
+ }
949
+
950
+ export { DevToolsProvider, TwDevTools };
951
+ //# sourceMappingURL=devtools.js.map
952
+ //# sourceMappingURL=devtools.js.map