tailwind-styled-v4 4.0.0 → 5.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 (77) hide show
  1. package/dist/animate.cjs +754 -235
  2. package/dist/animate.cjs.map +1 -1
  3. package/dist/animate.d.cts +55 -99
  4. package/dist/animate.d.ts +55 -99
  5. package/dist/animate.js +742 -235
  6. package/dist/animate.js.map +1 -1
  7. package/dist/chunk-VZEJV27B.js +11 -0
  8. package/dist/chunk-VZEJV27B.js.map +1 -0
  9. package/dist/chunk-Y5D3E72P.cjs +13 -0
  10. package/dist/chunk-Y5D3E72P.cjs.map +1 -0
  11. package/dist/css.cjs +61 -11
  12. package/dist/css.cjs.map +1 -1
  13. package/dist/css.d.cts +3 -18
  14. package/dist/css.d.ts +3 -18
  15. package/dist/css.js +61 -11
  16. package/dist/css.js.map +1 -1
  17. package/dist/devtools.cjs +200 -88
  18. package/dist/devtools.cjs.map +1 -1
  19. package/dist/devtools.js +200 -88
  20. package/dist/devtools.js.map +1 -1
  21. package/dist/index.cjs +430 -135
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +74 -3
  24. package/dist/index.d.ts +74 -3
  25. package/dist/index.js +415 -132
  26. package/dist/index.js.map +1 -1
  27. package/dist/next.cjs +118 -138
  28. package/dist/next.cjs.map +1 -1
  29. package/dist/next.d.cts +28 -19
  30. package/dist/next.d.ts +28 -19
  31. package/dist/next.js +111 -131
  32. package/dist/next.js.map +1 -1
  33. package/dist/preset.cjs +312 -18
  34. package/dist/preset.cjs.map +1 -1
  35. package/dist/preset.d.cts +29 -2
  36. package/dist/preset.d.ts +29 -2
  37. package/dist/preset.js +311 -19
  38. package/dist/preset.js.map +1 -1
  39. package/dist/turbopackLoader.cjs +24 -2676
  40. package/dist/turbopackLoader.cjs.map +1 -1
  41. package/dist/turbopackLoader.d.cts +3 -13
  42. package/dist/turbopackLoader.d.ts +3 -13
  43. package/dist/turbopackLoader.js +24 -2670
  44. package/dist/turbopackLoader.js.map +1 -1
  45. package/dist/vite.cjs +90 -57
  46. package/dist/vite.cjs.map +1 -1
  47. package/dist/vite.d.cts +35 -6
  48. package/dist/vite.d.ts +35 -6
  49. package/dist/vite.js +90 -58
  50. package/dist/vite.js.map +1 -1
  51. package/dist/webpackLoader.cjs +27 -2646
  52. package/dist/webpackLoader.cjs.map +1 -1
  53. package/dist/webpackLoader.d.cts +3 -10
  54. package/dist/webpackLoader.d.ts +3 -10
  55. package/dist/webpackLoader.js +27 -2640
  56. package/dist/webpackLoader.js.map +1 -1
  57. package/package.json +31 -28
  58. package/dist/astTransform-ua-eapqs.d.cts +0 -41
  59. package/dist/astTransform-ua-eapqs.d.ts +0 -41
  60. package/dist/compiler.cjs +0 -3594
  61. package/dist/compiler.cjs.map +0 -1
  62. package/dist/compiler.d.cts +0 -716
  63. package/dist/compiler.d.ts +0 -716
  64. package/dist/compiler.js +0 -3535
  65. package/dist/compiler.js.map +0 -1
  66. package/dist/plugins.cjs +0 -396
  67. package/dist/plugins.cjs.map +0 -1
  68. package/dist/plugins.d.cts +0 -231
  69. package/dist/plugins.d.ts +0 -231
  70. package/dist/plugins.js +0 -381
  71. package/dist/plugins.js.map +0 -1
  72. package/dist/theme.cjs +0 -154
  73. package/dist/theme.cjs.map +0 -1
  74. package/dist/theme.d.cts +0 -181
  75. package/dist/theme.d.ts +0 -181
  76. package/dist/theme.js +0 -148
  77. package/dist/theme.js.map +0 -1
@@ -1,716 +0,0 @@
1
- export { T as TransformOptions, a as TransformResult, t as transformSource } from './astTransform-ua-eapqs.js';
2
-
3
- declare function hasTwUsage(source: string): boolean;
4
- declare function isDynamic(content: string): boolean;
5
- declare function isServerComponent(source: string): boolean;
6
- declare function hasInteractiveFeatures(content: string): boolean;
7
-
8
- /**
9
- * tailwind-styled-v4 — Atomic CSS Mode (Optional)
10
- *
11
- * Mode opsional yang mengubah Tailwind classes menjadi atomic CSS rules.
12
- * Mirip konsep StyleX dari Meta — setiap class menghasilkan satu CSS rule.
13
- *
14
- * Keuntungan:
15
- * - CSS global deduplicated (p-4 hanya satu rule di seluruh app)
16
- * - Bundle CSS lebih kecil untuk app besar
17
- * - Zero duplicate styles
18
- *
19
- * Mode ini TIDAK mengganti Tailwind — tetap pakai Tailwind utilities,
20
- * hanya menambahkan layer extraction untuk SSR streaming.
21
- *
22
- * Usage:
23
- * withTailwindStyled({ atomic: true })(nextConfig)
24
- */
25
- interface AtomicRule {
26
- /** Original Tailwind class */
27
- twClass: string;
28
- /** Generated atomic class name */
29
- atomicName: string;
30
- /** CSS property */
31
- property: string;
32
- /** CSS value */
33
- value: string;
34
- /** Modifier (hover:, md:, etc.) */
35
- modifier?: string;
36
- }
37
- declare function parseAtomicClass(twClass: string): AtomicRule | null;
38
- declare function generateAtomicCss(rules: AtomicRule[]): string;
39
- declare function toAtomicClasses(twClasses: string): {
40
- atomicClasses: string;
41
- rules: AtomicRule[];
42
- unknownClasses: string[];
43
- };
44
- declare function getAtomicRegistry(): Map<string, AtomicRule>;
45
- declare function clearAtomicRegistry(): void;
46
-
47
- declare function extractAllClasses(source: string): string[];
48
-
49
- /**
50
- * tailwind-styled-v4 — classMerger
51
- *
52
- * FIX #05: Ganti custom UTILITY_GROUPS resolver dengan twMerge.
53
- *
54
- * WHY: Custom regex resolver memiliki banyak edge case yang salah
55
- * (ring-, text- grouping, dll). tailwind-merge sudah jadi dependency,
56
- * lebih akurat, dan di-maintain oleh komunitas Tailwind.
57
- *
58
- * RESULT: Output compile-time dan runtime kini identik — tidak ada
59
- * behavior perbedaan antara dev mode dan production build.
60
- */
61
- /**
62
- * Merge Tailwind classes statically at compile time.
63
- * Menggunakan tailwind-merge untuk conflict resolution yang akurat.
64
- *
65
- * FIX #05: Sebelumnya pakai custom UTILITY_GROUPS regex yang tidak
66
- * kompatibel dengan tailwind-merge runtime. Sekarang keduanya identik.
67
- *
68
- * @example
69
- * mergeClassesStatic("p-4 p-2 bg-red-500 bg-blue-500")
70
- * → "p-2 bg-blue-500"
71
- *
72
- * mergeClassesStatic("ring-2 ring-4")
73
- * → "ring-4" ✓ (custom resolver dulu return "ring-2 ring-4" — salah!)
74
- */
75
- declare function mergeClassesStatic(classes: string): string;
76
- /**
77
- * Normalize raw class string — trim, dedupe whitespace, join lines.
78
- */
79
- declare function normalizeClasses(raw: string): string;
80
-
81
- /**
82
- * tailwind-styled-v4 — Component Hoister
83
- *
84
- * Problem: Component yang didefinisikan di dalam fungsi lain
85
- * akan direcreate setiap render — sangat buruk untuk performa.
86
- *
87
- * BEFORE (buruk):
88
- * export default function Page() {
89
- * const Box = tw.div`p-4` ← dibuat ulang tiap render!
90
- * return <Box/>
91
- * }
92
- *
93
- * AFTER (benar):
94
- * const Box = tw.div`p-4` ← module scope, dibuat sekali
95
- * export default function Page() {
96
- * return <Box/>
97
- * }
98
- *
99
- * Hoister mendeteksi pola ini dan memindahkan deklarasi ke module scope.
100
- */
101
- interface HoistResult {
102
- code: string;
103
- hoisted: string[];
104
- warnings: string[];
105
- }
106
- declare function hoistComponents(source: string): HoistResult;
107
-
108
- /**
109
- * tailwind-styled-v4 — Dead Style Eliminator
110
- *
111
- * Build-time analysis yang scan component usage dan hapus variant + class
112
- * yang tidak pernah dipakai. Hasilnya: CSS output yang sangat kecil.
113
- *
114
- * Pipeline:
115
- * scan all .tsx/.ts files
116
- * ↓ extract component usage (JSX props)
117
- * ↓ compare dengan registered variants
118
- * ↓ mark unused variants as dead
119
- * ↓ remove from CSS output
120
- *
121
- * @example
122
- * const Button = tw.button({
123
- * base: "px-4 py-2",
124
- * variants: {
125
- * size: { sm: "text-sm", lg: "text-lg", xl: "text-xl" }, // xl never used!
126
- * intent: { primary: "bg-blue-500", danger: "bg-red-500" }
127
- * }
128
- * })
129
- *
130
- * // In codebase: only <Button size="sm"> and <Button size="lg"> appear
131
- * // Eliminator removes: size.xl → saves CSS
132
- *
133
- * Result:
134
- * Before: 3 size variants in CSS
135
- * After: 2 size variants in CSS (xl eliminated)
136
- */
137
- interface VariantUsage {
138
- /** Component name */
139
- component: string;
140
- /** Which variant props were used with which values */
141
- usedValues: Record<string, Set<string>>;
142
- /** Files where component is used */
143
- usedInFiles: string[];
144
- }
145
- interface EliminationReport {
146
- /** Total unused variant values found */
147
- unusedCount: number;
148
- /** Estimated bytes saved */
149
- bytesSaved: number;
150
- /** Details per component */
151
- components: Record<string, {
152
- usedVariants: Record<string, string[]>;
153
- unusedVariants: Record<string, string[]>;
154
- }>;
155
- }
156
- /**
157
- * Extract all JSX component usages from source.
158
- * Finds: <ComponentName prop="value" /> patterns.
159
- */
160
- declare function extractComponentUsage(source: string): Record<string, Record<string, Set<string>>>;
161
- /**
162
- * Scan entire project for component usage.
163
- *
164
- * @param dirs - Directories to scan (e.g. ["src"])
165
- * @param cwd - Project root
166
- */
167
- declare function scanProjectUsage(dirs: string[], cwd?: string): Record<string, Record<string, Set<string>>>;
168
- interface RegisteredComponent {
169
- name: string;
170
- variants: Record<string, Record<string, string>>;
171
- }
172
- interface EliminationOptions {
173
- dirs?: string[];
174
- cwd?: string;
175
- registered?: RegisteredComponent[];
176
- inputCss: string;
177
- verbose?: boolean;
178
- }
179
- /**
180
- * Run full dead style elimination pipeline.
181
- *
182
- * @example
183
- * const result = await runElimination({
184
- * dirs: ["src"],
185
- * inputCss: fs.readFileSync("dist/styles.css", "utf-8"),
186
- * registered: [...componentConfigs],
187
- * })
188
- * fs.writeFileSync("dist/styles.min.css", result.css)
189
- * console.log(result.report)
190
- */
191
- declare function runElimination(opts: EliminationOptions): {
192
- css: string;
193
- report: EliminationReport;
194
- };
195
-
196
- /**
197
- * tailwind-styled-v4 — Incremental CSS Compiler
198
- *
199
- * Hanya compile ulang file yang berubah, bukan semua file.
200
- * Hasil: hot-reload styling dalam 5–20ms, bukan 3–10s.
201
- *
202
- * Pipeline:
203
- * file watcher detects change
204
- * ↓ hash check → skip jika file belum berubah
205
- * ↓ update dependency graph (hapus rule lama, tambah rule baru)
206
- * ↓ compute CSS diff (only changed rules)
207
- * ↓ write diff ke output — bukan rewrite seluruh file
208
- * ↓ hot reload
209
- *
210
- * Integrasi ke webpack/turbopack loader:
211
- * import { incrementalEngine } from "./incrementalEngine"
212
- * incrementalEngine.processFile(filepath, source, extractedClasses)
213
- *
214
- * Cache disimpan di `.tw-cache/` — persist antar build sessions.
215
- */
216
- /** Satu style node dalam dependency graph */
217
- interface StyleNode {
218
- /** Tailwind class, e.g. "p-4" */
219
- twClass: string;
220
- /** CSS declaration, e.g. "padding: 1rem" */
221
- declaration: string;
222
- /** Modifier (pseudo/media), e.g. ":hover" atau "@media (min-width: 768px)" */
223
- modifier?: string;
224
- /** Generated atomic class name, e.g. "tw-a1b2" */
225
- atomicClass: string;
226
- }
227
- /** Graph: filepath → style nodes yang dihasilkan file itu */
228
- type FileDependencyGraph = Map<string, StyleNode[]>;
229
- /** Diff antara build sebelum dan setelah */
230
- interface CssDiff {
231
- /** Rule yang perlu ditambah ke CSS output */
232
- added: StyleNode[];
233
- /** Atomic class names yang perlu dihapus dari CSS output */
234
- removed: string[];
235
- /** true jika tidak ada perubahan */
236
- noChange: boolean;
237
- }
238
- /** Summary setelah process satu file */
239
- interface ProcessResult {
240
- /** File yang diproses */
241
- filepath: string;
242
- /** true jika file berubah dan registry di-update */
243
- changed: boolean;
244
- /** CSS diff untuk file ini */
245
- diff: CssDiff;
246
- /** Durasi proses dalam ms */
247
- durationMs: number;
248
- }
249
- /** Stats engine */
250
- interface IncrementalStats {
251
- totalFiles: number;
252
- changedFiles: number;
253
- skippedFiles: number;
254
- addedRules: number;
255
- removedRules: number;
256
- buildTimeMs: number;
257
- }
258
- interface IncrementalEngineOptions {
259
- /** Output path untuk CSS file incremental. Default: ".tw-cache/atomic.css" */
260
- outputPath?: string;
261
- /** Apakah persist cache ke disk. Default: true */
262
- persistCache?: boolean;
263
- /** Verbose logging. Default: false */
264
- verbose?: boolean;
265
- }
266
- declare class IncrementalEngine {
267
- private hashCache;
268
- private depGraph;
269
- private globalReg;
270
- private cssWriter;
271
- private opts;
272
- private stats;
273
- private sessionStart;
274
- constructor(opts?: IncrementalEngineOptions);
275
- /**
276
- * Proses satu file. Core method dipanggil oleh webpack/turbopack loader.
277
- *
278
- * @param filepath - Absolute path ke file
279
- * @param source - Source code file (untuk hashing)
280
- * @param extractedNodes - Style nodes yang di-extract compiler dari file ini
281
- * @returns ProcessResult dengan diff dan stats
282
- */
283
- processFile(filepath: string, source: string, extractedNodes: StyleNode[]): ProcessResult;
284
- /**
285
- * Dipanggil di akhir build. Flush CSS ke disk, persist cache.
286
- */
287
- buildEnd(): Promise<void>;
288
- /** Sync version untuk webpack buildEnd hook */
289
- buildEndSync(): void;
290
- /**
291
- * Invalidate satu file (untuk hot reload — file dihapus atau renamed).
292
- */
293
- invalidateFile(filepath: string): void;
294
- /** Get all active style nodes — untuk full CSS generation */
295
- getAllNodes(): StyleNode[];
296
- /** Get stats untuk current build session */
297
- getStats(): Readonly<IncrementalStats>;
298
- /** Get output CSS path */
299
- getOutputPath(): string;
300
- /** Reset stats untuk build session baru */
301
- resetStats(): void;
302
- /** Reset semua cache — untuk clean build */
303
- reset(): void;
304
- private log;
305
- }
306
- /**
307
- * Parse daftar Tailwind classes menjadi StyleNodes untuk incremental engine.
308
- * Supports: responsive variants (md:, lg:), pseudo (hover:, focus:), arbitrary.
309
- *
310
- * @example
311
- * parseClassesToNodes(["p-4", "hover:bg-blue-500", "md:text-lg"])
312
- */
313
- declare function parseClassesToNodes(classes: string[]): StyleNode[];
314
- declare function getIncrementalEngine(opts?: IncrementalEngineOptions): IncrementalEngine;
315
- declare function resetIncrementalEngine(): void;
316
-
317
- /**
318
- * tailwind-styled-v4 — Tailwind Config Loader
319
- *
320
- * Auto-load tailwind config dari project.
321
- * Jika tidak ada → fallback ke defaultPreset (zero-config mode).
322
- *
323
- * Priority:
324
- * 1. tailwind.config.ts (TypeScript)
325
- * 2. tailwind.config.js (JavaScript)
326
- * 3. tailwind.config.mjs (ESM)
327
- * 4. defaultPreset (fallback — zero-config)
328
- */
329
- type TailwindConfig = Record<string, any>;
330
- /**
331
- * Load tailwind config. Cached per process.
332
- * Returns defaultPreset if no config found (zero-config mode).
333
- */
334
- declare function loadTailwindConfig(cwd?: string): TailwindConfig;
335
- /**
336
- * Get content paths dari config (atau default paths)
337
- */
338
- declare function getContentPaths(config: TailwindConfig, cwd?: string): string[];
339
- /**
340
- * Invalidate config cache (useful for watch mode)
341
- */
342
- declare function invalidateConfigCache(): void;
343
- /**
344
- * Check if project has zero-config setup (no user tailwind config)
345
- */
346
- declare function isZeroConfig(cwd?: string): boolean;
347
- /**
348
- * Auto-generate tailwind.config.ts dan globals.css jika tidak ada
349
- * (dipanggil oleh CLI dan withTailwindStyled pada first run)
350
- */
351
- declare function bootstrapZeroConfig(cwd?: string): {
352
- generatedConfig: boolean;
353
- generatedCss: boolean;
354
- };
355
-
356
- /**
357
- * tailwind-styled-v4 — Route CSS Collector
358
- *
359
- * Mengumpulkan Tailwind classes per-route sehingga setiap halaman
360
- * hanya memuat CSS yang benar-benar dipakai.
361
- *
362
- * Tailwind default: ~300kb global CSS
363
- * Route CSS: ~2–10kb per halaman
364
- *
365
- * Cara kerja:
366
- * 1. Setiap file yang di-transform oleh compiler melaporkan classnya
367
- * 2. Collector memetakan file → route
368
- * 3. Di akhir build, CSS di-generate per route
369
- *
370
- * File structure output:
371
- * .next/static/css/
372
- * _global.css ← base + reset (sekali load)
373
- * app/page.css ← hanya class yang dipakai di /
374
- * app/about/page.css ← hanya class untuk /about
375
- * app/dashboard/...
376
- */
377
- interface RouteClassMap {
378
- /** filepath → array of tw classes */
379
- files: Map<string, Set<string>>;
380
- /** route → Set of files yang dipakai */
381
- routes: Map<string, Set<string>>;
382
- /** Global classes (di-load semua route) */
383
- global: Set<string>;
384
- }
385
- /**
386
- * Register classes dari sebuah file setelah compiler transform.
387
- * Dipanggil oleh turbopackLoader/webpackLoader setelah setiap file di-transform.
388
- */
389
- declare function registerFileClasses(filepath: string, classes: string[]): void;
390
- /**
391
- * Register global classes (base styles, layout, dsb.)
392
- * Global classes dimuat di semua route.
393
- */
394
- declare function registerGlobalClasses(classes: string[]): void;
395
- /**
396
- * Get all classes for a specific route (termasuk global)
397
- */
398
- declare function getRouteClasses(route: string): Set<string>;
399
- /**
400
- * Get all routes yang sudah ter-register
401
- */
402
- declare function getAllRoutes(): string[];
403
- /**
404
- * Get complete map (untuk build-time generation)
405
- */
406
- declare function getCollector(): RouteClassMap;
407
- /**
408
- * Reset collector (start of each build)
409
- */
410
- declare function resetCollector(): void;
411
- /**
412
- * Konversi filepath ke Next.js App Router route.
413
- *
414
- * /src/app/page.tsx → /
415
- * /src/app/about/page.tsx → /about
416
- * /src/app/dashboard/page.tsx → /dashboard
417
- * /src/components/Button.tsx → null (shared component, goes to global)
418
- * /src/app/layout.tsx → __layout (global)
419
- */
420
- declare function fileToRoute(filepath: string): string | null;
421
- declare function getCollectorSummary(): string;
422
-
423
- /**
424
- * tailwind-styled-v4 — RSC Analyzer
425
- *
426
- * Inti dari RSC-Aware upgrade.
427
- * Menganalisis setiap file untuk menentukan:
428
- * - Server Component atau Client Component
429
- * - Variant mana yang bisa di-resolve di server
430
- * - Class mana yang membutuhkan client runtime
431
- * - Auto client boundary injection
432
- *
433
- * Hasilnya:
434
- * - Server Component → pure static className, zero JS ke client
435
- * - Client Component → tetap seperti biasa dengan lookup table
436
- */
437
- type ComponentEnv = "server" | "client" | "auto";
438
- interface RscAnalysis {
439
- /** File ini adalah server component */
440
- isServer: boolean;
441
- /** File ini butuh "use client" directive */
442
- needsClientDirective: boolean;
443
- /** Alasan butuh client */
444
- clientReasons: string[];
445
- /** Classes yang membutuhkan client interaction */
446
- interactiveClasses: string[];
447
- /** Apakah semua variants bisa di-resolve statically di server */
448
- canStaticResolveVariants: boolean;
449
- }
450
- declare function analyzeFile(source: string, _filename?: string): RscAnalysis;
451
- interface StaticVariantUsage {
452
- /** Variant prop values yang ditemukan di JSX — bisa di-resolve di server */
453
- resolved: Record<string, string>;
454
- /** Variant props yang dinamis — butuh runtime */
455
- dynamic: string[];
456
- }
457
- /**
458
- * Deteksi penggunaan variant dalam JSX:
459
- * <Button variant="primary"/> → dapat di-resolve statically
460
- * <Button variant={userVariant}/> → dinamis, butuh runtime
461
- */
462
- declare function analyzeVariantUsage(source: string, componentName: string, variantKeys: string[]): StaticVariantUsage;
463
- /**
464
- * Untuk server component dengan variant usage statically known,
465
- * resolve langsung ke className string — nol runtime.
466
- *
467
- * Input:
468
- * base = "px-4 py-2"
469
- * table = { variant: { primary: "px-4 py-2 bg-blue-500" } }
470
- * resolved = { variant: "primary" }
471
- *
472
- * Output:
473
- * "px-4 py-2 bg-blue-500" ← langsung inline di server
474
- */
475
- declare function resolveServerVariant(base: string, table: Record<string, Record<string, string>>, defaults: Record<string, string>, resolved: Record<string, string>): string;
476
- declare function injectClientDirective(code: string): string;
477
- declare function injectServerOnlyComment(code: string): string;
478
-
479
- /**
480
- * tailwind-styled-v4 — safelistGenerator
481
- *
482
- * Scan semua source files dan extract Tailwind classes untuk safelist.
483
- * Output: .tailwind-styled-safelist.json
484
- *
485
- * Developer tidak perlu manual safelist.
486
- */
487
- declare function generateSafelist(scanDirs: string[], outputPath?: string, cwd?: string): string[];
488
- declare function loadSafelist(safelistPath: string): string[];
489
- /**
490
- * Tailwind v4 variant — output CSS dengan @source inline() bukan JSON.
491
- * Tailwind v4 tidak punya 'safelist' di config — pakai @source inline() di CSS.
492
- */
493
- declare function generateSafelistCss(scanDirs: string[], outputPath?: string, cwd?: string): string[];
494
-
495
- /**
496
- * tailwind-styled-v4 — Style Bucket System
497
- *
498
- * Setiap CSS rule masuk ke "bucket" berdasarkan tipe property-nya.
499
- * Bucket di-emit dalam urutan yang selalu sama → CSS order stabil
500
- * meskipun rule di-generate dari banyak file secara incremental.
501
- *
502
- * Tanpa bucket system:
503
- * .tw-color { color: blue } ← dari file A
504
- * .tw-flex { display: flex } ← dari file B
505
- * .tw-color2 { color: red } ← dari file C
506
- * → urutan output bergantung urutan file di-process = TIDAK STABIL
507
- *
508
- * Dengan bucket system:
509
- * /* reset *\/
510
- * /* layout *\/ → display, position, flex, grid, overflow
511
- * /* spacing *\/ → margin, padding, gap, inset
512
- * /* sizing *\/ → width, height, max/min-width/height
513
- * /* typography *\/ → font-size, font-weight, line-height, text-*
514
- * /* visual *\/ → color, background, border, shadow, opacity
515
- * /* interaction *\/ → cursor, pointer-events, user-select, transition
516
- * /* responsive *\/ → @media queries (selalu di akhir)
517
- * → SELALU urutan ini, terlepas dari urutan file
518
- *
519
- * Keuntungan utama:
520
- * 1. CSS output deterministic antar build (reproducible builds)
521
- * 2. Specificity conflict sangat kecil — base selalu lebih awal dari responsive
522
- * 3. Debug lebih mudah — tahu section mana rule berada
523
- *
524
- * Integrasi:
525
- * import { BucketEngine, bucketSort } from "./styleBucketSystem"
526
- *
527
- * const engine = new BucketEngine()
528
- * engine.add(styleNode)
529
- * const css = engine.emit()
530
- */
531
-
532
- /**
533
- * 8 bucket utama + 1 bucket "unknown" untuk fallback.
534
- * Urutan angka = urutan emit di CSS output.
535
- */
536
- type StyleBucket = "reset" | "layout" | "spacing" | "sizing" | "typography" | "visual" | "interaction" | "responsive" | "unknown";
537
- /**
538
- * Classify satu StyleNode ke bucket yang tepat.
539
- *
540
- * Priority:
541
- * 1. Jika ada modifier @media → "responsive" (selalu paling akhir)
542
- * 2. Cek declaration property → lookup PROPERTY_BUCKET_MAP
543
- * 3. Fallback ke "unknown"
544
- */
545
- declare function classifyNode(node: StyleNode): StyleBucket;
546
- interface BucketStats {
547
- totalNodes: number;
548
- perBucket: Record<StyleBucket, number>;
549
- }
550
- /**
551
- * BucketEngine — menyimpan dan emit CSS dalam urutan bucket yang stabil.
552
- *
553
- * @example
554
- * const engine = new BucketEngine()
555
- * for (const node of styleNodes) engine.add(node)
556
- * const css = engine.emit()
557
- */
558
- declare class BucketEngine {
559
- private buckets;
560
- constructor();
561
- /**
562
- * Tambah StyleNode ke bucket yang tepat.
563
- * Idempotent — atomic class yang sama tidak akan duplikat.
564
- */
565
- add(node: StyleNode): void;
566
- /**
567
- * Hapus node dari bucket (untuk incremental update).
568
- */
569
- remove(atomicClass: string): void;
570
- /**
571
- * Apply CssDiff dari incremental engine.
572
- */
573
- applyDiff(diff: {
574
- added: StyleNode[];
575
- removed: string[];
576
- }): void;
577
- /**
578
- * Emit seluruh CSS dalam urutan bucket yang deterministic.
579
- *
580
- * @param comments - Tambahkan komentar section per bucket. Default: true
581
- * @returns CSS string yang siap di-write ke file
582
- */
583
- emit(comments?: boolean): string;
584
- /**
585
- * Emit dengan @layer CSS untuk native browser layering.
586
- * Lebih powerful — browser respects layer order untuk specificity.
587
- *
588
- * @example output:
589
- * @layer tw-layout, tw-spacing, tw-visual, tw-responsive;
590
- * @layer tw-layout { .tw-a1 { display: flex } }
591
- */
592
- emitLayered(): string;
593
- /** Semua nodes dari semua bucket (untuk full registry access) */
594
- allNodes(): StyleNode[];
595
- /** Stats per bucket */
596
- stats(): BucketStats;
597
- /** Clear semua bucket */
598
- clear(): void;
599
- }
600
- /**
601
- * Sort array StyleNodes dalam urutan bucket.
602
- * Berguna untuk one-off sorting tanpa perlu BucketEngine instance.
603
- *
604
- * @example
605
- * const sorted = bucketSort(allNodes)
606
- * const css = sorted.map(nodeToCSS).join("\n")
607
- */
608
- declare function bucketSort(nodes: StyleNode[]): StyleNode[];
609
- interface ConflictWarning {
610
- property: string;
611
- classes: string[];
612
- bucket: StyleBucket;
613
- message: string;
614
- }
615
- /**
616
- * Detect potential CSS conflicts dalam satu set StyleNodes.
617
- * Hanya untuk dev mode — tidak perlu run di production.
618
- *
619
- * Conflict = dua node dengan property yang sama tapi value berbeda
620
- * di bucket yang sama (bukan responsive override).
621
- *
622
- * @example
623
- * const warnings = detectConflicts(nodes)
624
- * if (warnings.length) console.warn(warnings)
625
- */
626
- declare function detectConflicts(nodes: StyleNode[]): ConflictWarning[];
627
- declare function getBucketEngine(): BucketEngine;
628
- declare function resetBucketEngine(): void;
629
-
630
- /**
631
- * tailwind-styled-v4 — Embedded Tailwind Engine
632
- *
633
- * Compiler menjalankan Tailwind internally — tidak perlu tailwind CLI,
634
- * tidak perlu postcss config manual.
635
- *
636
- * Cara kerja:
637
- * 1. Compiler extract semua class dari source (via classExtractor)
638
- * 2. Engine generate CSS hanya untuk class tersebut
639
- * 3. CSS di-output per route (route-level CSS bundling)
640
- *
641
- * Ini membuat CSS output jauh lebih kecil:
642
- * Tailwind normal: ~300kb global
643
- * Route CSS: ~2–10kb per route
644
- *
645
- * Mode operasi:
646
- * "jit" → generate CSS saat file berubah (dev mode)
647
- * "build" → generate semua CSS di akhir build (production)
648
- * "manual" → tidak generate, hanya extract (default untuk kompatibilitas)
649
- */
650
- type TailwindEngineMode = "jit" | "build" | "manual";
651
- interface TailwindEngineOptions {
652
- mode?: TailwindEngineMode;
653
- cwd?: string;
654
- outputDir?: string;
655
- config?: Record<string, any>;
656
- minify?: boolean;
657
- }
658
- interface CssGenerateResult {
659
- route: string;
660
- css: string;
661
- classes: string[];
662
- sizeBytes: number;
663
- }
664
- /**
665
- * Try to use Tailwind's internal API for CSS generation.
666
- * Fallback ke manual CSS generation jika Tailwind API tidak tersedia.
667
- *
668
- * NOTE: Tailwind v4 mengubah API internal — kita support keduanya.
669
- */
670
- declare function generateCssForClasses(classes: string[], config?: Record<string, any>, cwd?: string): Promise<string>;
671
- declare function generateAllRouteCss(opts?: TailwindEngineOptions): Promise<CssGenerateResult[]>;
672
-
673
- /**
674
- * tailwind-styled-v4 — variantCompiler
675
- *
676
- * FIXES:
677
- * #01 — Don't pre-merge base into variant table values (double-merge bug)
678
- * #06 — Use proper AST parser instead of fragile regex
679
- *
680
- * BEFORE (double-merge):
681
- * compileVariants: table["size"]["sm"] = "px-4 py-2 text-sm" ← base included
682
- * astTransform: [base, table["size"][...]] ← base AGAIN → DUPE
683
- *
684
- * AFTER (correct):
685
- * compileVariants: table["size"]["sm"] = "text-sm" ← variant only
686
- * astTransform: [base, table["size"][...], className] ← base once, correct
687
- *
688
- * Input:
689
- * { base: "px-4 py-2", variants: { size: { sm: "text-sm" } } }
690
- *
691
- * Output code:
692
- * const __vt_abc123 = { size: { sm: "text-sm" } }
693
- * // className = [base, table[variant]] → no duplication
694
- */
695
- interface CompiledVariants {
696
- base: string;
697
- table: Record<string, Record<string, string>>;
698
- compounds: Array<{
699
- class: string;
700
- [key: string]: any;
701
- }>;
702
- defaults: Record<string, string>;
703
- }
704
- /**
705
- * Compile variant config into lookup table.
706
- *
707
- * FIX #01: Do NOT pre-merge base into table values.
708
- * Table contains variant-specific classes only.
709
- * Base is always injected separately in the component className array.
710
- */
711
- declare function compileVariants(base: string, variants: Record<string, Record<string, string>>, compounds?: Array<{
712
- class: string;
713
- [key: string]: any;
714
- }>, defaults?: Record<string, string>): CompiledVariants;
715
-
716
- export { type AtomicRule, BucketEngine, type BucketStats, type ComponentEnv, type ConflictWarning, type CssDiff, type CssGenerateResult, type EliminationReport, type FileDependencyGraph, type HoistResult, IncrementalEngine, type IncrementalEngineOptions, type IncrementalStats, type ProcessResult, type RouteClassMap, type RscAnalysis, type StaticVariantUsage, type StyleBucket, type StyleNode, type TailwindEngineOptions, type VariantUsage, analyzeFile, analyzeVariantUsage, bootstrapZeroConfig, bucketSort, classifyNode, clearAtomicRegistry, compileVariants, detectConflicts, extractAllClasses, extractComponentUsage, fileToRoute, generateAllRouteCss, generateAtomicCss, generateCssForClasses, generateSafelist, generateSafelistCss, getAllRoutes, getAtomicRegistry, getBucketEngine, getCollector, getCollectorSummary, getContentPaths, getIncrementalEngine, getRouteClasses, hasInteractiveFeatures, hasTwUsage, hoistComponents, injectClientDirective, injectServerOnlyComment, invalidateConfigCache, isDynamic, isServerComponent, isZeroConfig, loadSafelist, loadTailwindConfig, mergeClassesStatic, normalizeClasses, parseAtomicClass, parseClassesToNodes, registerFileClasses, registerGlobalClasses, resetBucketEngine, resetCollector, resetIncrementalEngine, resolveServerVariant, runElimination, scanProjectUsage, hasTwUsage as shouldProcess, toAtomicClasses };