tailwind-styled-v4 5.0.0 → 5.0.1
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 +1555 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/analyzer.mjs +1544 -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 +149 -99
- package/dist/animate.js.map +1 -1
- package/dist/{animate.cjs → animate.mjs} +130 -119
- 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 +6063 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +6053 -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 +4518 -0
- package/dist/compiler.js.map +1 -0
- package/dist/compiler.mjs +4443 -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 +170 -157
- package/dist/devtools.js.map +1 -1
- package/dist/{devtools.cjs → devtools.mjs} +165 -166
- package/dist/devtools.mjs.map +1 -0
- package/dist/engine.d.mts +84 -0
- package/dist/engine.d.ts +84 -0
- package/dist/engine.js +3014 -0
- package/dist/engine.js.map +1 -0
- package/dist/engine.mjs +3005 -0
- package/dist/engine.mjs.map +1 -0
- package/dist/{index.d.cts → index.d.mts} +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +945 -36
- package/dist/index.js.map +1 -1
- package/dist/{index.cjs → index.mjs} +899 -90
- 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 +6853 -35
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +7050 -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 +55 -0
- package/dist/rspack.js.map +1 -0
- package/dist/rspack.mjs +45 -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 +207 -0
- package/dist/runtime.js.map +1 -0
- package/dist/runtime.mjs +188 -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 +717 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scanner.mjs +703 -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/types-DXr2PmGP.d.mts +31 -0
- package/dist/types-DXr2PmGP.d.ts +31 -0
- package/dist/vite.js +4181 -16
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +4281 -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 +168 -65
- 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.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
|
@@ -0,0 +1,1009 @@
|
|
|
1
|
+
declare function hasTwUsage(source: string): boolean;
|
|
2
|
+
declare function isDynamic(content: string): boolean;
|
|
3
|
+
declare function isServerComponent(source: string): boolean;
|
|
4
|
+
declare function hasInteractiveFeatures(content: string): boolean;
|
|
5
|
+
|
|
6
|
+
interface TransformOptions {
|
|
7
|
+
/** @deprecated Mode is always "zero-runtime" in v5. This option will be removed in v6. */
|
|
8
|
+
mode?: "zero-runtime";
|
|
9
|
+
autoClientBoundary?: boolean;
|
|
10
|
+
addDataAttr?: boolean;
|
|
11
|
+
hoist?: boolean;
|
|
12
|
+
filename?: string;
|
|
13
|
+
/** Keep all imports from tailwind-styled-v4 intact — only transform tw.* usages */
|
|
14
|
+
preserveImports?: boolean;
|
|
15
|
+
/** Enable Dead Style Elimination - removes unused CSS after transformation (default: false) */
|
|
16
|
+
deadStyleElimination?: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface TransformResult {
|
|
19
|
+
code: string;
|
|
20
|
+
classes: string[];
|
|
21
|
+
rsc?: {
|
|
22
|
+
isServer: boolean;
|
|
23
|
+
needsClientDirective: boolean;
|
|
24
|
+
clientReasons: string[];
|
|
25
|
+
};
|
|
26
|
+
changed: boolean;
|
|
27
|
+
}
|
|
28
|
+
declare function transformSource(source: string, opts?: TransformOptions): TransformResult;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* tailwind-styled-v4 — CSS Compiler (Rust-backed LightningCSS-style)
|
|
32
|
+
*
|
|
33
|
+
* v5 CHANGE: Now requires native binding. Previously fell back to JS implementation.
|
|
34
|
+
*
|
|
35
|
+
* Compiles Tailwind class lists to atomic CSS using Rust native engine.
|
|
36
|
+
*/
|
|
37
|
+
interface CssCompileResult$1 {
|
|
38
|
+
/** Generated atomic CSS */
|
|
39
|
+
css: string;
|
|
40
|
+
/** Classes successfully resolved to native CSS */
|
|
41
|
+
resolvedClasses: string[];
|
|
42
|
+
/** Classes with no native mapping (get @apply fallback) */
|
|
43
|
+
unknownClasses: string[];
|
|
44
|
+
/** Byte size of generated CSS */
|
|
45
|
+
sizeBytes: number;
|
|
46
|
+
/** Which engine produced this output */
|
|
47
|
+
engine: "rust" | "fallback";
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Compile a list of Tailwind classes into atomic CSS.
|
|
51
|
+
*
|
|
52
|
+
* v5 CHANGE: Now THROWS if native binding is unavailable.
|
|
53
|
+
* Previously fell back to JS implementation.
|
|
54
|
+
*
|
|
55
|
+
* Uses Rust LightningCSS-style engine when native binary is available.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const { css } = compileCssFromClasses(['flex', 'items-center', 'hover:bg-blue-600'])
|
|
59
|
+
* // → ".flex { display: flex } .items-center { align-items: center } ..."
|
|
60
|
+
*
|
|
61
|
+
* @throws Error if native binding is not available
|
|
62
|
+
*/
|
|
63
|
+
declare function compileCssFromClasses(classes: string[], options?: {
|
|
64
|
+
prefix?: string;
|
|
65
|
+
}): CssCompileResult$1;
|
|
66
|
+
/**
|
|
67
|
+
* Compile CSS for a set of classes and inject as a <style> block (SSR helper).
|
|
68
|
+
*/
|
|
69
|
+
declare function buildStyleTag(classes: string[]): string;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Extract all Tailwind classes from source code.
|
|
73
|
+
*
|
|
74
|
+
* v5 CHANGE: Now THROWS if native binding is unavailable.
|
|
75
|
+
* Previously fell back to JS implementation.
|
|
76
|
+
*
|
|
77
|
+
* @param source - Source code to extract classes from
|
|
78
|
+
* @returns Array of unique class names (sorted)
|
|
79
|
+
* @throws Error if native binding is not available
|
|
80
|
+
*/
|
|
81
|
+
declare function extractAllClasses(source: string): string[];
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* tailwind-styled-v4 — Dead Style Eliminator
|
|
85
|
+
*
|
|
86
|
+
* Build-time analysis yang scan component usage dan hapus variant + class
|
|
87
|
+
* yang tidak pernah dipakai. Hasilnya: CSS output yang sangat kecil.
|
|
88
|
+
*
|
|
89
|
+
* Pipeline:
|
|
90
|
+
* scan all .tsx/.ts files
|
|
91
|
+
* ↓ extract component usage (JSX props)
|
|
92
|
+
* ↓ compare dengan registered variants
|
|
93
|
+
* ↓ mark unused variants as dead
|
|
94
|
+
* ↓ remove from CSS output
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* const Button = tw.button({
|
|
98
|
+
* base: "px-4 py-2",
|
|
99
|
+
* variants: {
|
|
100
|
+
* size: { sm: "text-sm", lg: "text-lg", xl: "text-xl" }, // xl never used!
|
|
101
|
+
* intent: { primary: "bg-blue-500", danger: "bg-red-500" }
|
|
102
|
+
* }
|
|
103
|
+
* })
|
|
104
|
+
*
|
|
105
|
+
* // In codebase: only <Button size="sm"> and <Button size="lg"> appear
|
|
106
|
+
* // Eliminator removes: size.xl → saves CSS
|
|
107
|
+
*
|
|
108
|
+
* Result:
|
|
109
|
+
* Before: 3 size variants in CSS
|
|
110
|
+
* After: 2 size variants in CSS (xl eliminated)
|
|
111
|
+
*/
|
|
112
|
+
interface VariantUsage {
|
|
113
|
+
/** Component name */
|
|
114
|
+
component: string;
|
|
115
|
+
/** Which variant props were used with which values */
|
|
116
|
+
usedValues: Record<string, Set<string>>;
|
|
117
|
+
/** Files where component is used */
|
|
118
|
+
usedInFiles: string[];
|
|
119
|
+
}
|
|
120
|
+
interface EliminationReport {
|
|
121
|
+
/** Total unused variant values found */
|
|
122
|
+
unusedCount: number;
|
|
123
|
+
/** Estimated bytes saved */
|
|
124
|
+
bytesSaved: number;
|
|
125
|
+
/** Details per component */
|
|
126
|
+
components: Record<string, {
|
|
127
|
+
usedVariants: Record<string, string[]>;
|
|
128
|
+
unusedVariants: Record<string, string[]>;
|
|
129
|
+
}>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Extract all JSX component usages from source.
|
|
133
|
+
* Finds: <ComponentName prop="value" /> patterns.
|
|
134
|
+
*/
|
|
135
|
+
declare function extractComponentUsage(source: string): Record<string, Record<string, Set<string>>>;
|
|
136
|
+
/**
|
|
137
|
+
* Scan entire project for component usage.
|
|
138
|
+
*
|
|
139
|
+
* @param dirs - Directories to scan (e.g. ["src"])
|
|
140
|
+
* @param cwd - Project root
|
|
141
|
+
*/
|
|
142
|
+
declare function scanProjectUsage(dirs: string[], cwd?: string): Record<string, Record<string, Set<string>>>;
|
|
143
|
+
interface RegisteredComponent {
|
|
144
|
+
name: string;
|
|
145
|
+
variants: Record<string, Record<string, string>>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Find unused variant values by comparing registered components with actual usage.
|
|
149
|
+
*/
|
|
150
|
+
declare function findDeadVariants(registered: RegisteredComponent[], projectUsage: Record<string, Record<string, Set<string>>>): EliminationReport;
|
|
151
|
+
/**
|
|
152
|
+
* Filter a CSS string to remove selectors for unused classes.
|
|
153
|
+
*
|
|
154
|
+
* @param css - Full CSS string
|
|
155
|
+
* @param deadClasses - Set of class names to remove
|
|
156
|
+
*/
|
|
157
|
+
declare function eliminateDeadCss(css: string, deadClasses: Set<string>): string;
|
|
158
|
+
/**
|
|
159
|
+
* Merge duplicate CSS rules and deduplicate media queries.
|
|
160
|
+
* Reduces final CSS size for atomic outputs.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* optimizeCss(".tw-a1{padding:16px} .tw-b1{padding:16px}")
|
|
164
|
+
* → ".tw-a1,.tw-b1{padding:16px}"
|
|
165
|
+
*/
|
|
166
|
+
declare function optimizeCss(css: string): string;
|
|
167
|
+
interface EliminationOptions {
|
|
168
|
+
dirs?: string[];
|
|
169
|
+
cwd?: string;
|
|
170
|
+
registered?: RegisteredComponent[];
|
|
171
|
+
inputCss: string;
|
|
172
|
+
verbose?: boolean;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Run full dead style elimination pipeline.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* const result = await runElimination({
|
|
179
|
+
* dirs: ["src"],
|
|
180
|
+
* inputCss: fs.readFileSync("dist/styles.css", "utf-8"),
|
|
181
|
+
* registered: [...componentConfigs],
|
|
182
|
+
* })
|
|
183
|
+
* fs.writeFileSync("dist/styles.min.css", result.css)
|
|
184
|
+
* console.log(result.report)
|
|
185
|
+
*/
|
|
186
|
+
declare function runElimination(opts: EliminationOptions): {
|
|
187
|
+
css: string;
|
|
188
|
+
report: EliminationReport;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* tailwind-styled-v4 — Incremental CSS Compiler
|
|
193
|
+
*
|
|
194
|
+
* Hanya compile ulang file yang berubah, bukan semua file.
|
|
195
|
+
* Hasil: hot-reload styling dalam 5–20ms, bukan 3–10s.
|
|
196
|
+
*
|
|
197
|
+
* Pipeline:
|
|
198
|
+
* file watcher detects change
|
|
199
|
+
* ↓ hash check → skip jika file belum berubah
|
|
200
|
+
* ↓ update dependency graph (hapus rule lama, tambah rule baru)
|
|
201
|
+
* ↓ compute CSS diff (only changed rules)
|
|
202
|
+
* ↓ write diff ke output — bukan rewrite seluruh file
|
|
203
|
+
* ↓ hot reload
|
|
204
|
+
*
|
|
205
|
+
* Integrasi ke webpack/turbopack loader:
|
|
206
|
+
* import { incrementalEngine } from "./incrementalEngine"
|
|
207
|
+
* incrementalEngine.processFile(filepath, source, extractedClasses)
|
|
208
|
+
*
|
|
209
|
+
* Cache disimpan di `.tw-cache/` — persist antar build sessions.
|
|
210
|
+
*/
|
|
211
|
+
/** Satu style node dalam dependency graph */
|
|
212
|
+
interface StyleNode {
|
|
213
|
+
/** Tailwind class, e.g. "p-4" */
|
|
214
|
+
twClass: string;
|
|
215
|
+
/** CSS declaration, e.g. "padding: 1rem" */
|
|
216
|
+
declaration: string;
|
|
217
|
+
/** Modifier (pseudo/media), e.g. ":hover" atau "@media (min-width: 768px)" */
|
|
218
|
+
modifier?: string;
|
|
219
|
+
/** Generated atomic class name, e.g. "tw-a1b2" */
|
|
220
|
+
atomicClass: string;
|
|
221
|
+
}
|
|
222
|
+
/** Graph: filepath → style nodes yang dihasilkan file itu */
|
|
223
|
+
type FileDependencyGraph = Map<string, StyleNode[]>;
|
|
224
|
+
/** Diff antara build sebelum dan setelah */
|
|
225
|
+
interface CssDiff {
|
|
226
|
+
/** Rule yang perlu ditambah ke CSS output */
|
|
227
|
+
added: StyleNode[];
|
|
228
|
+
/** Atomic class names yang perlu dihapus dari CSS output */
|
|
229
|
+
removed: string[];
|
|
230
|
+
/** true jika tidak ada perubahan */
|
|
231
|
+
noChange: boolean;
|
|
232
|
+
}
|
|
233
|
+
/** Summary setelah process satu file */
|
|
234
|
+
interface ProcessResult {
|
|
235
|
+
/** File yang diproses */
|
|
236
|
+
filepath: string;
|
|
237
|
+
/** true jika file berubah dan registry di-update */
|
|
238
|
+
changed: boolean;
|
|
239
|
+
/** CSS diff untuk file ini */
|
|
240
|
+
diff: CssDiff;
|
|
241
|
+
/** Durasi proses dalam ms */
|
|
242
|
+
durationMs: number;
|
|
243
|
+
}
|
|
244
|
+
/** Stats engine */
|
|
245
|
+
interface IncrementalStats {
|
|
246
|
+
totalFiles: number;
|
|
247
|
+
changedFiles: number;
|
|
248
|
+
skippedFiles: number;
|
|
249
|
+
addedRules: number;
|
|
250
|
+
removedRules: number;
|
|
251
|
+
buildTimeMs: number;
|
|
252
|
+
}
|
|
253
|
+
interface IncrementalEngineOptions {
|
|
254
|
+
/** Output path untuk CSS file incremental. Default: ".tw-cache/atomic.css" */
|
|
255
|
+
outputPath?: string;
|
|
256
|
+
/** Apakah persist cache ke disk. Default: true */
|
|
257
|
+
persistCache?: boolean;
|
|
258
|
+
/** Verbose logging. Default: false */
|
|
259
|
+
verbose?: boolean;
|
|
260
|
+
}
|
|
261
|
+
declare class IncrementalEngine {
|
|
262
|
+
private hashCache;
|
|
263
|
+
private depGraph;
|
|
264
|
+
private globalReg;
|
|
265
|
+
private cssWriter;
|
|
266
|
+
private opts;
|
|
267
|
+
private stats;
|
|
268
|
+
private sessionStart;
|
|
269
|
+
constructor(opts?: IncrementalEngineOptions);
|
|
270
|
+
/**
|
|
271
|
+
* Proses satu file. Core method dipanggil oleh webpack/turbopack loader.
|
|
272
|
+
*
|
|
273
|
+
* @param filepath - Absolute path ke file
|
|
274
|
+
* @param source - Source code file (untuk hashing)
|
|
275
|
+
* @param extractedNodes - Style nodes yang di-extract compiler dari file ini
|
|
276
|
+
* @returns ProcessResult dengan diff dan stats
|
|
277
|
+
*/
|
|
278
|
+
processFile(filepath: string, source: string, extractedNodes: StyleNode[]): ProcessResult;
|
|
279
|
+
/**
|
|
280
|
+
* Dipanggil di akhir build. Flush CSS ke disk, persist cache.
|
|
281
|
+
*/
|
|
282
|
+
buildEnd(): Promise<void>;
|
|
283
|
+
/** Sync version untuk webpack buildEnd hook */
|
|
284
|
+
buildEndSync(): void;
|
|
285
|
+
/**
|
|
286
|
+
* Invalidate satu file (untuk hot reload — file dihapus atau renamed).
|
|
287
|
+
*/
|
|
288
|
+
invalidateFile(filepath: string): void;
|
|
289
|
+
/** Get all active style nodes — untuk full CSS generation */
|
|
290
|
+
getAllNodes(): StyleNode[];
|
|
291
|
+
/** Get stats untuk current build session */
|
|
292
|
+
getStats(): Readonly<IncrementalStats>;
|
|
293
|
+
/** Get output CSS path */
|
|
294
|
+
getOutputPath(): string;
|
|
295
|
+
/** Reset stats untuk build session baru */
|
|
296
|
+
resetStats(): void;
|
|
297
|
+
/** Reset semua cache — untuk clean build */
|
|
298
|
+
reset(): void;
|
|
299
|
+
private log;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Parse daftar Tailwind classes menjadi StyleNodes untuk incremental engine.
|
|
303
|
+
* Supports: responsive variants (md:, lg:), pseudo (hover:, focus:), arbitrary.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* parseClassesToNodes(["p-4", "hover:bg-blue-500", "md:text-lg"])
|
|
307
|
+
*/
|
|
308
|
+
declare function parseClassesToNodes(classes: string[]): StyleNode[];
|
|
309
|
+
declare function getIncrementalEngine(opts?: IncrementalEngineOptions): IncrementalEngine;
|
|
310
|
+
declare function resetIncrementalEngine(): void;
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* tailwind-styled-v4 — RSC Analyzer
|
|
314
|
+
*
|
|
315
|
+
* Inti dari RSC-Aware upgrade.
|
|
316
|
+
* Menganalisis setiap file untuk menentukan:
|
|
317
|
+
* - Server Component atau Client Component
|
|
318
|
+
* - Variant mana yang bisa di-resolve di server
|
|
319
|
+
* - Class mana yang membutuhkan client runtime
|
|
320
|
+
* - Auto client boundary injection
|
|
321
|
+
*
|
|
322
|
+
* Hasilnya:
|
|
323
|
+
* - Server Component → pure static className, zero JS ke client
|
|
324
|
+
* - Client Component → tetap seperti biasa dengan lookup table
|
|
325
|
+
*/
|
|
326
|
+
type ComponentEnv = "server" | "client" | "auto";
|
|
327
|
+
interface RscAnalysis {
|
|
328
|
+
/** File ini adalah server component */
|
|
329
|
+
isServer: boolean;
|
|
330
|
+
/** File ini butuh "use client" directive */
|
|
331
|
+
needsClientDirective: boolean;
|
|
332
|
+
/** Alasan butuh client */
|
|
333
|
+
clientReasons: string[];
|
|
334
|
+
/** Classes yang membutuhkan client interaction */
|
|
335
|
+
interactiveClasses: string[];
|
|
336
|
+
/** Apakah semua variants bisa di-resolve statically di server */
|
|
337
|
+
canStaticResolveVariants: boolean;
|
|
338
|
+
}
|
|
339
|
+
declare function analyzeFile(source: string, _filename?: string): RscAnalysis;
|
|
340
|
+
interface StaticVariantUsage {
|
|
341
|
+
/** Variant prop values yang ditemukan di JSX — bisa di-resolve di server */
|
|
342
|
+
resolved: Record<string, string>;
|
|
343
|
+
/** Variant props yang dinamis — butuh runtime */
|
|
344
|
+
dynamic: string[];
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Deteksi penggunaan variant dalam JSX:
|
|
348
|
+
* <Button variant="primary"/> → dapat di-resolve statically
|
|
349
|
+
* <Button variant={userVariant}/> → dinamis, butuh runtime
|
|
350
|
+
*/
|
|
351
|
+
declare function analyzeVariantUsage(source: string, componentName: string, variantKeys: string[]): StaticVariantUsage;
|
|
352
|
+
/**
|
|
353
|
+
* Untuk server component dengan variant usage statically known,
|
|
354
|
+
* resolve langsung ke className string — nol runtime.
|
|
355
|
+
*
|
|
356
|
+
* Input:
|
|
357
|
+
* base = "px-4 py-2"
|
|
358
|
+
* table = { variant: { primary: "px-4 py-2 bg-blue-500" } }
|
|
359
|
+
* resolved = { variant: "primary" }
|
|
360
|
+
*
|
|
361
|
+
* Output:
|
|
362
|
+
* "px-4 py-2 bg-blue-500" ← langsung inline di server
|
|
363
|
+
*/
|
|
364
|
+
declare function resolveServerVariant(base: string, table: Record<string, Record<string, string>>, defaults: Record<string, string>, resolved: Record<string, string>): string;
|
|
365
|
+
declare function injectClientDirective(code: string): string;
|
|
366
|
+
declare function injectServerOnlyComment(code: string): string;
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* tailwind-styled-v4 — Style Bucket System
|
|
370
|
+
*
|
|
371
|
+
* Setiap CSS rule masuk ke "bucket" berdasarkan tipe property-nya.
|
|
372
|
+
* Bucket di-emit dalam urutan yang selalu sama → CSS order stabil
|
|
373
|
+
* meskipun rule di-generate dari banyak file secara incremental.
|
|
374
|
+
*
|
|
375
|
+
* Tanpa bucket system:
|
|
376
|
+
* .tw-color { color: blue } ← dari file A
|
|
377
|
+
* .tw-flex { display: flex } ← dari file B
|
|
378
|
+
* .tw-color2 { color: red } ← dari file C
|
|
379
|
+
* → urutan output bergantung urutan file di-process = TIDAK STABIL
|
|
380
|
+
*
|
|
381
|
+
* Dengan bucket system:
|
|
382
|
+
* /* reset *\/
|
|
383
|
+
* /* layout *\/ → display, position, flex, grid, overflow
|
|
384
|
+
* /* spacing *\/ → margin, padding, gap, inset
|
|
385
|
+
* /* sizing *\/ → width, height, max/min-width/height
|
|
386
|
+
* /* typography *\/ → font-size, font-weight, line-height, text-*
|
|
387
|
+
* /* visual *\/ → color, background, border, shadow, opacity
|
|
388
|
+
* /* interaction *\/ → cursor, pointer-events, user-select, transition
|
|
389
|
+
* /* responsive *\/ → @media queries (selalu di akhir)
|
|
390
|
+
* → SELALU urutan ini, terlepas dari urutan file
|
|
391
|
+
*
|
|
392
|
+
* Keuntungan utama:
|
|
393
|
+
* 1. CSS output deterministic antar build (reproducible builds)
|
|
394
|
+
* 2. Specificity conflict sangat kecil — base selalu lebih awal dari responsive
|
|
395
|
+
* 3. Debug lebih mudah — tahu section mana rule berada
|
|
396
|
+
*
|
|
397
|
+
* Integrasi:
|
|
398
|
+
* import { BucketEngine, bucketSort } from "./styleBucketSystem"
|
|
399
|
+
*
|
|
400
|
+
* const engine = new BucketEngine()
|
|
401
|
+
* engine.add(styleNode)
|
|
402
|
+
* const css = engine.emit()
|
|
403
|
+
*/
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* 8 bucket utama + 1 bucket "unknown" untuk fallback.
|
|
407
|
+
* Urutan angka = urutan emit di CSS output.
|
|
408
|
+
*/
|
|
409
|
+
type StyleBucket = "reset" | "layout" | "spacing" | "sizing" | "typography" | "visual" | "interaction" | "responsive" | "unknown";
|
|
410
|
+
/**
|
|
411
|
+
* Classify satu StyleNode ke bucket yang tepat.
|
|
412
|
+
*
|
|
413
|
+
* Priority:
|
|
414
|
+
* 1. Jika ada modifier @media → "responsive" (selalu paling akhir)
|
|
415
|
+
* 2. Cek declaration property → lookup PROPERTY_BUCKET_MAP
|
|
416
|
+
* 3. Fallback ke "unknown"
|
|
417
|
+
*/
|
|
418
|
+
declare function classifyNode(node: StyleNode): StyleBucket;
|
|
419
|
+
interface BucketStats {
|
|
420
|
+
totalNodes: number;
|
|
421
|
+
perBucket: Record<StyleBucket, number>;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* BucketEngine — menyimpan dan emit CSS dalam urutan bucket yang stabil.
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* const engine = new BucketEngine()
|
|
428
|
+
* for (const node of styleNodes) engine.add(node)
|
|
429
|
+
* const css = engine.emit()
|
|
430
|
+
*/
|
|
431
|
+
declare class BucketEngine {
|
|
432
|
+
private buckets;
|
|
433
|
+
constructor();
|
|
434
|
+
/**
|
|
435
|
+
* Tambah StyleNode ke bucket yang tepat.
|
|
436
|
+
* Idempotent — atomic class yang sama tidak akan duplikat.
|
|
437
|
+
*/
|
|
438
|
+
add(node: StyleNode): void;
|
|
439
|
+
/**
|
|
440
|
+
* Hapus node dari bucket (untuk incremental update).
|
|
441
|
+
*/
|
|
442
|
+
remove(atomicClass: string): void;
|
|
443
|
+
/**
|
|
444
|
+
* Apply CssDiff dari incremental engine.
|
|
445
|
+
*/
|
|
446
|
+
applyDiff(diff: {
|
|
447
|
+
added: StyleNode[];
|
|
448
|
+
removed: string[];
|
|
449
|
+
}): void;
|
|
450
|
+
/**
|
|
451
|
+
* Emit seluruh CSS dalam urutan bucket yang deterministic.
|
|
452
|
+
*
|
|
453
|
+
* @param comments - Tambahkan komentar section per bucket. Default: true
|
|
454
|
+
* @returns CSS string yang siap di-write ke file
|
|
455
|
+
*/
|
|
456
|
+
emit(comments?: boolean): string;
|
|
457
|
+
/**
|
|
458
|
+
* Emit dengan @layer CSS untuk native browser layering.
|
|
459
|
+
* Lebih powerful — browser respects layer order untuk specificity.
|
|
460
|
+
*
|
|
461
|
+
* @example output:
|
|
462
|
+
* @layer tw-layout, tw-spacing, tw-visual, tw-responsive;
|
|
463
|
+
* @layer tw-layout { .tw-a1 { display: flex } }
|
|
464
|
+
*/
|
|
465
|
+
emitLayered(): string;
|
|
466
|
+
/** Semua nodes dari semua bucket (untuk full registry access) */
|
|
467
|
+
allNodes(): StyleNode[];
|
|
468
|
+
/** Stats per bucket */
|
|
469
|
+
stats(): BucketStats;
|
|
470
|
+
/** Clear semua bucket */
|
|
471
|
+
clear(): void;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Sort array StyleNodes dalam urutan bucket.
|
|
475
|
+
* Berguna untuk one-off sorting tanpa perlu BucketEngine instance.
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* const sorted = bucketSort(allNodes)
|
|
479
|
+
* const css = sorted.map(nodeToCSS).join("\n")
|
|
480
|
+
*/
|
|
481
|
+
declare function bucketSort(nodes: StyleNode[]): StyleNode[];
|
|
482
|
+
interface ConflictWarning {
|
|
483
|
+
property: string;
|
|
484
|
+
classes: string[];
|
|
485
|
+
bucket: StyleBucket;
|
|
486
|
+
message: string;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Detect potential CSS conflicts dalam satu set StyleNodes.
|
|
490
|
+
* Hanya untuk dev mode — tidak perlu run di production.
|
|
491
|
+
*
|
|
492
|
+
* Conflict = dua node dengan property yang sama tapi value berbeda
|
|
493
|
+
* di bucket yang sama (bukan responsive override).
|
|
494
|
+
*
|
|
495
|
+
* @example
|
|
496
|
+
* const warnings = detectConflicts(nodes)
|
|
497
|
+
* if (warnings.length) console.warn(warnings)
|
|
498
|
+
*/
|
|
499
|
+
declare function detectConflicts(nodes: StyleNode[]): ConflictWarning[];
|
|
500
|
+
declare function getBucketEngine(): BucketEngine;
|
|
501
|
+
declare function resetBucketEngine(): void;
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* @deprecated in v5 — Use @tailwind-styled/atomic package instead
|
|
505
|
+
* This module will be removed in v6
|
|
506
|
+
*
|
|
507
|
+
* tailwind-styled-v4 — Atomic CSS Mode (Optional)
|
|
508
|
+
*
|
|
509
|
+
* Mode opsional yang mengubah Tailwind classes menjadi atomic CSS rules.
|
|
510
|
+
* Mirip konsep StyleX dari Meta — setiap class menghasilkan satu CSS rule.
|
|
511
|
+
*
|
|
512
|
+
* Keuntungan:
|
|
513
|
+
* - CSS global deduplicated (p-4 hanya satu rule di seluruh app)
|
|
514
|
+
* - Bundle CSS lebih kecil untuk app besar
|
|
515
|
+
* - Zero duplicate styles
|
|
516
|
+
*
|
|
517
|
+
* Mode ini TIDAK mengganti Tailwind — tetap pakai Tailwind utilities,
|
|
518
|
+
* hanya menambahkan layer extraction untuk SSR streaming.
|
|
519
|
+
*
|
|
520
|
+
* Usage:
|
|
521
|
+
* withTailwindStyled({ atomic: true })(nextConfig)
|
|
522
|
+
*/
|
|
523
|
+
interface AtomicRule {
|
|
524
|
+
/** Original Tailwind class */
|
|
525
|
+
twClass: string;
|
|
526
|
+
/** Generated atomic class name */
|
|
527
|
+
atomicName: string;
|
|
528
|
+
/** CSS property */
|
|
529
|
+
property: string;
|
|
530
|
+
/** CSS value */
|
|
531
|
+
value: string;
|
|
532
|
+
/** Modifier (hover:, md:, etc.) */
|
|
533
|
+
modifier?: string;
|
|
534
|
+
}
|
|
535
|
+
declare function parseAtomicClass(twClass: string): AtomicRule | null;
|
|
536
|
+
declare function generateAtomicCss(rules: AtomicRule[]): string;
|
|
537
|
+
declare function toAtomicClasses(twClasses: string): {
|
|
538
|
+
atomicClasses: string;
|
|
539
|
+
rules: AtomicRule[];
|
|
540
|
+
unknownClasses: string[];
|
|
541
|
+
};
|
|
542
|
+
declare function getAtomicRegistry(): Map<string, AtomicRule>;
|
|
543
|
+
declare function clearAtomicRegistry(): void;
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* tailwind-styled-v4 — classMerger
|
|
547
|
+
*
|
|
548
|
+
* FIX #05: Ganti custom UTILITY_GROUPS resolver dengan twMerge.
|
|
549
|
+
*
|
|
550
|
+
* WHY: Custom regex resolver memiliki banyak edge case yang salah
|
|
551
|
+
* (ring-, text- grouping, dll). tailwind-merge sudah jadi dependency,
|
|
552
|
+
* lebih akurat, dan di-maintain oleh komunitas Tailwind.
|
|
553
|
+
*
|
|
554
|
+
* RESULT: Output compile-time dan runtime kini identik — tidak ada
|
|
555
|
+
* behavior perbedaan antara dev mode dan production build.
|
|
556
|
+
*/
|
|
557
|
+
/**
|
|
558
|
+
* Merge Tailwind classes statically at compile time.
|
|
559
|
+
* Menggunakan tailwind-merge untuk conflict resolution yang akurat.
|
|
560
|
+
*
|
|
561
|
+
* FIX #05: Sebelumnya pakai custom UTILITY_GROUPS regex yang tidak
|
|
562
|
+
* kompatibel dengan tailwind-merge runtime. Sekarang keduanya identik.
|
|
563
|
+
*
|
|
564
|
+
* @example
|
|
565
|
+
* mergeClassesStatic("p-4 p-2 bg-red-500 bg-blue-500")
|
|
566
|
+
* → "p-2 bg-blue-500"
|
|
567
|
+
*
|
|
568
|
+
* mergeClassesStatic("ring-2 ring-4")
|
|
569
|
+
* → "ring-4" ✓ (custom resolver dulu return "ring-2 ring-4" — salah!)
|
|
570
|
+
*/
|
|
571
|
+
declare function mergeClassesStatic(classes: string): string;
|
|
572
|
+
/**
|
|
573
|
+
* Normalize raw class string — trim, dedupe whitespace, join lines.
|
|
574
|
+
*/
|
|
575
|
+
declare function normalizeClasses(raw: string): string;
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* tailwind-styled-v4 — Component Hoister
|
|
579
|
+
*
|
|
580
|
+
* Problem: Component yang didefinisikan di dalam fungsi lain
|
|
581
|
+
* akan direcreate setiap render — sangat buruk untuk performa.
|
|
582
|
+
*
|
|
583
|
+
* BEFORE (buruk):
|
|
584
|
+
* export default function Page() {
|
|
585
|
+
* const Box = tw.div`p-4` ← dibuat ulang tiap render!
|
|
586
|
+
* return <Box/>
|
|
587
|
+
* }
|
|
588
|
+
*
|
|
589
|
+
* AFTER (benar):
|
|
590
|
+
* const Box = tw.div`p-4` ← module scope, dibuat sekali
|
|
591
|
+
* export default function Page() {
|
|
592
|
+
* return <Box/>
|
|
593
|
+
* }
|
|
594
|
+
*
|
|
595
|
+
* Hoister mendeteksi pola ini dan memindahkan deklarasi ke module scope.
|
|
596
|
+
*/
|
|
597
|
+
interface HoistResult {
|
|
598
|
+
code: string;
|
|
599
|
+
hoisted: string[];
|
|
600
|
+
warnings: string[];
|
|
601
|
+
}
|
|
602
|
+
declare function hoistComponents(source: string): HoistResult;
|
|
603
|
+
|
|
604
|
+
type CompileEngine = "none" | "native" | "js";
|
|
605
|
+
interface CompileInput {
|
|
606
|
+
filepath: string;
|
|
607
|
+
source: string;
|
|
608
|
+
options: TransformOptions;
|
|
609
|
+
}
|
|
610
|
+
declare class CompileContext {
|
|
611
|
+
filepath: string;
|
|
612
|
+
source: string;
|
|
613
|
+
options: TransformOptions;
|
|
614
|
+
result: TransformResult | null;
|
|
615
|
+
done: boolean;
|
|
616
|
+
engine: CompileEngine;
|
|
617
|
+
constructor(input: CompileInput);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* tailwind-styled-v4 — NativeBridge
|
|
622
|
+
*
|
|
623
|
+
* Loads the native Rust engine (.node binding via index.mjs) and exposes
|
|
624
|
+
* its functions to the JS compiler pipeline.
|
|
625
|
+
*
|
|
626
|
+
* The bridge is loaded lazily and cached. If the .node binary is not
|
|
627
|
+
* present (e.g. the user hasn't built the Rust crate yet), every function
|
|
628
|
+
* returns null and the pipeline falls through to the JS implementation.
|
|
629
|
+
*
|
|
630
|
+
* Environment flags:
|
|
631
|
+
* TWS_NO_NATIVE=1 — disable native bridge entirely
|
|
632
|
+
* TWS_NO_RUST=1 — alias for TWS_NO_NATIVE
|
|
633
|
+
*/
|
|
634
|
+
|
|
635
|
+
/** Raw shape returned by Rust transform_source — napi auto-converts snake_case → camelCase */
|
|
636
|
+
interface NativeTransformResult {
|
|
637
|
+
code: string;
|
|
638
|
+
classes: string[];
|
|
639
|
+
changed: boolean;
|
|
640
|
+
/** JSON string: { isServer: boolean, needsClientDirective: boolean } */
|
|
641
|
+
rscJson?: string | null;
|
|
642
|
+
/** JSON string: ComponentMetadata[] */
|
|
643
|
+
metadataJson?: string | null;
|
|
644
|
+
}
|
|
645
|
+
/** Metadata for one compound component, produced by Rust and consumed by @tailwind-styled/runtime */
|
|
646
|
+
interface ComponentMetadata {
|
|
647
|
+
component: string;
|
|
648
|
+
tag: string;
|
|
649
|
+
baseClass: string;
|
|
650
|
+
subComponents: Record<string, {
|
|
651
|
+
tag: string;
|
|
652
|
+
class: string;
|
|
653
|
+
}>;
|
|
654
|
+
}
|
|
655
|
+
/** Full bridge interface — all members optional so feature detection is easy */
|
|
656
|
+
interface NativeBridge {
|
|
657
|
+
/** Parse individual class tokens. Throws if binding is unavailable. */
|
|
658
|
+
parseClassesNative?: (input: string) => Array<{
|
|
659
|
+
raw: string;
|
|
660
|
+
base: string;
|
|
661
|
+
variants: string[];
|
|
662
|
+
modifierType?: string | null;
|
|
663
|
+
modifierValue?: string | null;
|
|
664
|
+
}>;
|
|
665
|
+
/** Fast pre-check — returns null if binding unavailable. */
|
|
666
|
+
hasTwUsageNative?: (source: string) => boolean | null;
|
|
667
|
+
/** Idempotency guard — returns null if binding unavailable. */
|
|
668
|
+
isAlreadyTransformedNative?: (source: string) => boolean | null;
|
|
669
|
+
/** RSC analysis — returns null if binding unavailable. */
|
|
670
|
+
analyzeRscNative?: (source: string, filename?: string) => {
|
|
671
|
+
isServer: boolean;
|
|
672
|
+
needsClientDirective: boolean;
|
|
673
|
+
clientReasons: string[];
|
|
674
|
+
} | null;
|
|
675
|
+
/** Full transform — returns null if binding unavailable (JS pipeline takes over). */
|
|
676
|
+
transformSourceNative?: (source: string, opts: Record<string, unknown>) => NativeTransformResult | null;
|
|
677
|
+
/** AST-based class extraction (Oxc+regex hybrid) */
|
|
678
|
+
astExtractClassesNative?: (source: string, filename?: string) => {
|
|
679
|
+
classes: string[];
|
|
680
|
+
engine: string;
|
|
681
|
+
} | null;
|
|
682
|
+
/** Rust-based class extraction via regex */
|
|
683
|
+
extractClassesFromSourceNative?: (source: string) => string[] | null;
|
|
684
|
+
/** Analyze class frequency - used for DSE */
|
|
685
|
+
analyzeClassesNative?: (filesJson: string, root: string, topN: number) => {
|
|
686
|
+
root: string;
|
|
687
|
+
totalFiles: number;
|
|
688
|
+
uniqueClassCount: number;
|
|
689
|
+
totalClassOccurrences: number;
|
|
690
|
+
topClasses: Array<{
|
|
691
|
+
name: string;
|
|
692
|
+
count: number;
|
|
693
|
+
}>;
|
|
694
|
+
duplicateCandidates: Array<{
|
|
695
|
+
name: string;
|
|
696
|
+
count: number;
|
|
697
|
+
}>;
|
|
698
|
+
safelist: string[];
|
|
699
|
+
} | null;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Get the native bridge - THROWS if unavailable.
|
|
703
|
+
*
|
|
704
|
+
* v5 CHANGE: Previously returned null and fell back to JS pipeline.
|
|
705
|
+
* Now throws an error to ensure native binding is always used.
|
|
706
|
+
*
|
|
707
|
+
* @throws Error if native binding is not available
|
|
708
|
+
*/
|
|
709
|
+
declare function getNativeBridge(): NativeBridge;
|
|
710
|
+
declare function resetNativeBridgeCache(): void;
|
|
711
|
+
declare function adaptNativeResult(raw: NativeTransformResult): TransformResult & {
|
|
712
|
+
metadata?: ComponentMetadata[];
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
interface CoreCompileOptions extends TransformOptions {
|
|
716
|
+
}
|
|
717
|
+
interface CoreCompileResult {
|
|
718
|
+
result: TransformResult;
|
|
719
|
+
engine: CompileEngine;
|
|
720
|
+
cacheHit: boolean;
|
|
721
|
+
/** Compound component metadata produced by Rust — undefined when the JS pipeline ran */
|
|
722
|
+
metadata?: ComponentMetadata[];
|
|
723
|
+
/** CSS output after DSE (when deadStyleElimination option is enabled) */
|
|
724
|
+
css?: string;
|
|
725
|
+
}
|
|
726
|
+
declare function compileWithCore(input: CompileInput): CoreCompileResult;
|
|
727
|
+
declare function resetCompileCache(): void;
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* tailwind-styled-v5 - loaderCore
|
|
731
|
+
*
|
|
732
|
+
* Unified loader path:
|
|
733
|
+
* incremental precheck -> core compiler (native/js pipeline) -> finalize
|
|
734
|
+
*/
|
|
735
|
+
|
|
736
|
+
interface LoaderOptions extends TransformOptions {
|
|
737
|
+
routeCss?: boolean;
|
|
738
|
+
incremental?: boolean;
|
|
739
|
+
verbose?: boolean;
|
|
740
|
+
autoClientBoundary?: boolean;
|
|
741
|
+
}
|
|
742
|
+
interface LoaderContext {
|
|
743
|
+
filepath: string;
|
|
744
|
+
source: string;
|
|
745
|
+
options: LoaderOptions;
|
|
746
|
+
isDev?: boolean;
|
|
747
|
+
}
|
|
748
|
+
interface LoaderOutput {
|
|
749
|
+
code: string;
|
|
750
|
+
changed: boolean;
|
|
751
|
+
classes: string[];
|
|
752
|
+
rsc?: TransformResult["rsc"];
|
|
753
|
+
engine?: "native" | "js" | "none";
|
|
754
|
+
cacheHit?: boolean;
|
|
755
|
+
/** Compound component metadata — only present when Rust engine ran */
|
|
756
|
+
metadata?: ComponentMetadata[];
|
|
757
|
+
}
|
|
758
|
+
declare function shouldSkipFile(filepath: string): boolean;
|
|
759
|
+
declare function runLoaderTransform(ctx: LoaderContext): LoaderOutput;
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* tailwind-styled-v4 — Tailwind Config Loader
|
|
763
|
+
*
|
|
764
|
+
* Auto-load tailwind config dari project.
|
|
765
|
+
* Jika tidak ada → fallback ke defaultPreset (zero-config mode).
|
|
766
|
+
*
|
|
767
|
+
* Priority:
|
|
768
|
+
* 1. tailwind.config.ts (TypeScript)
|
|
769
|
+
* 2. tailwind.config.js (JavaScript)
|
|
770
|
+
* 3. tailwind.config.mjs (ESM)
|
|
771
|
+
* 4. defaultPreset (fallback — zero-config)
|
|
772
|
+
*/
|
|
773
|
+
type TailwindConfig = Record<string, any>;
|
|
774
|
+
/**
|
|
775
|
+
* Load tailwind config. Cached per process.
|
|
776
|
+
* Returns defaultPreset if no config found (zero-config mode).
|
|
777
|
+
*/
|
|
778
|
+
declare function loadTailwindConfig(cwd?: string): TailwindConfig;
|
|
779
|
+
/**
|
|
780
|
+
* Get content paths dari config (atau default paths)
|
|
781
|
+
*/
|
|
782
|
+
declare function getContentPaths(config: TailwindConfig, cwd?: string): string[];
|
|
783
|
+
/**
|
|
784
|
+
* Invalidate config cache (useful for watch mode)
|
|
785
|
+
*/
|
|
786
|
+
declare function invalidateConfigCache(): void;
|
|
787
|
+
/**
|
|
788
|
+
* Check if project has zero-config setup (no user tailwind config)
|
|
789
|
+
*/
|
|
790
|
+
declare function isZeroConfig(cwd?: string): boolean;
|
|
791
|
+
/**
|
|
792
|
+
* Auto-generate tailwind.config.ts dan globals.css jika tidak ada
|
|
793
|
+
* (dipanggil oleh CLI dan withTailwindStyled pada first run)
|
|
794
|
+
*/
|
|
795
|
+
declare function bootstrapZeroConfig(cwd?: string): {
|
|
796
|
+
generatedConfig: boolean;
|
|
797
|
+
generatedCss: boolean;
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
type PipelineStep<T> = (ctx: T) => void;
|
|
801
|
+
declare class Pipeline<T extends {
|
|
802
|
+
done?: boolean;
|
|
803
|
+
}> {
|
|
804
|
+
private steps;
|
|
805
|
+
use(step: PipelineStep<T>): this;
|
|
806
|
+
run(ctx: T): T;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* tailwind-styled-v4 — Route CSS Collector
|
|
811
|
+
*
|
|
812
|
+
* Mengumpulkan Tailwind classes per-route sehingga setiap halaman
|
|
813
|
+
* hanya memuat CSS yang benar-benar dipakai.
|
|
814
|
+
*
|
|
815
|
+
* Tailwind default: ~300kb global CSS
|
|
816
|
+
* Route CSS: ~2–10kb per halaman
|
|
817
|
+
*
|
|
818
|
+
* Cara kerja:
|
|
819
|
+
* 1. Setiap file yang di-transform oleh compiler melaporkan classnya
|
|
820
|
+
* 2. Collector memetakan file → route
|
|
821
|
+
* 3. Di akhir build, CSS di-generate per route
|
|
822
|
+
*
|
|
823
|
+
* File structure output:
|
|
824
|
+
* .next/static/css/
|
|
825
|
+
* _global.css ← base + reset (sekali load)
|
|
826
|
+
* app/page.css ← hanya class yang dipakai di /
|
|
827
|
+
* app/about/page.css ← hanya class untuk /about
|
|
828
|
+
* app/dashboard/...
|
|
829
|
+
*/
|
|
830
|
+
interface RouteClassMap {
|
|
831
|
+
/** filepath → array of tw classes */
|
|
832
|
+
files: Map<string, Set<string>>;
|
|
833
|
+
/** route → Set of files yang dipakai */
|
|
834
|
+
routes: Map<string, Set<string>>;
|
|
835
|
+
/** Global classes (di-load semua route) */
|
|
836
|
+
global: Set<string>;
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* Register classes dari sebuah file setelah compiler transform.
|
|
840
|
+
* Dipanggil oleh turbopackLoader/webpackLoader setelah setiap file di-transform.
|
|
841
|
+
*/
|
|
842
|
+
declare function registerFileClasses(filepath: string, classes: string[]): void;
|
|
843
|
+
/**
|
|
844
|
+
* Register global classes (base styles, layout, dsb.)
|
|
845
|
+
* Global classes dimuat di semua route.
|
|
846
|
+
*/
|
|
847
|
+
declare function registerGlobalClasses(classes: string[]): void;
|
|
848
|
+
/**
|
|
849
|
+
* Get all classes for a specific route (termasuk global)
|
|
850
|
+
*/
|
|
851
|
+
declare function getRouteClasses(route: string): Set<string>;
|
|
852
|
+
/**
|
|
853
|
+
* Get all routes yang sudah ter-register
|
|
854
|
+
*/
|
|
855
|
+
declare function getAllRoutes(): string[];
|
|
856
|
+
/**
|
|
857
|
+
* Get complete map (untuk build-time generation)
|
|
858
|
+
*/
|
|
859
|
+
declare function getCollector(): RouteClassMap;
|
|
860
|
+
/**
|
|
861
|
+
* Reset collector (start of each build)
|
|
862
|
+
*/
|
|
863
|
+
declare function resetCollector(): void;
|
|
864
|
+
/**
|
|
865
|
+
* Konversi filepath ke Next.js App Router route.
|
|
866
|
+
*
|
|
867
|
+
* /src/app/page.tsx → /
|
|
868
|
+
* /src/app/about/page.tsx → /about
|
|
869
|
+
* /src/app/dashboard/page.tsx → /dashboard
|
|
870
|
+
* /src/components/Button.tsx → null (shared component, goes to global)
|
|
871
|
+
* /src/app/layout.tsx → __layout (global)
|
|
872
|
+
*/
|
|
873
|
+
declare function fileToRoute(filepath: string): string | null;
|
|
874
|
+
declare function getCollectorSummary(): string;
|
|
875
|
+
|
|
876
|
+
interface CssCompileResult {
|
|
877
|
+
css: string;
|
|
878
|
+
resolvedClasses: string[];
|
|
879
|
+
unknownClasses: string[];
|
|
880
|
+
sizeBytes: number;
|
|
881
|
+
engine: "rust" | "fallback";
|
|
882
|
+
}
|
|
883
|
+
interface AstExtractResult {
|
|
884
|
+
classes: string[];
|
|
885
|
+
componentNames: string[];
|
|
886
|
+
hasTwUsage: boolean;
|
|
887
|
+
hasUseClient: boolean;
|
|
888
|
+
imports: string[];
|
|
889
|
+
engine: "rust" | "fallback";
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Compile Tailwind class list → atomic CSS via Rust LightningCSS-style compiler.
|
|
893
|
+
*
|
|
894
|
+
* v5 CHANGE: Now THROWS if native binding is unavailable.
|
|
895
|
+
* Previously fell back to JS implementation.
|
|
896
|
+
*
|
|
897
|
+
* @throws Error if native binding is not available
|
|
898
|
+
*/
|
|
899
|
+
declare function compileCssNative(classes: string[], prefix?: string | null): CssCompileResult;
|
|
900
|
+
/**
|
|
901
|
+
* Extract Tailwind classes from source via Rust AST-style extractor.
|
|
902
|
+
*
|
|
903
|
+
* v5 CHANGE: Now THROWS if native binding is unavailable.
|
|
904
|
+
* Previously fell back to JS implementation.
|
|
905
|
+
*
|
|
906
|
+
* @throws Error if native binding is not available
|
|
907
|
+
*/
|
|
908
|
+
declare function astExtractClassesNative(source: string, filename: string): AstExtractResult;
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* tailwind-styled-v4 — safelistGenerator
|
|
912
|
+
*
|
|
913
|
+
* Scan semua source files dan extract Tailwind classes untuk safelist.
|
|
914
|
+
* Output: .tailwind-styled-safelist.json
|
|
915
|
+
*
|
|
916
|
+
* Developer tidak perlu manual safelist.
|
|
917
|
+
*/
|
|
918
|
+
declare function generateSafelist(scanDirs: string[], outputPath?: string, cwd?: string): string[];
|
|
919
|
+
declare function loadSafelist(safelistPath: string): string[];
|
|
920
|
+
/**
|
|
921
|
+
* Tailwind v4 variant — output CSS dengan @source inline() bukan JSON.
|
|
922
|
+
* Tailwind v4 tidak punya 'safelist' di config — pakai @source inline() di CSS.
|
|
923
|
+
*/
|
|
924
|
+
declare function generateSafelistCss(scanDirs: string[], outputPath?: string, cwd?: string): string[];
|
|
925
|
+
|
|
926
|
+
/**
|
|
927
|
+
* tailwind-styled-v4 — Embedded Tailwind Engine
|
|
928
|
+
*
|
|
929
|
+
* Compiler menjalankan Tailwind internally — tidak perlu tailwind CLI,
|
|
930
|
+
* tidak perlu postcss config manual.
|
|
931
|
+
*
|
|
932
|
+
* Cara kerja:
|
|
933
|
+
* 1. Compiler extract semua class dari source (via classExtractor)
|
|
934
|
+
* 2. Engine generate CSS hanya untuk class tersebut
|
|
935
|
+
* 3. CSS di-output per route (route-level CSS bundling)
|
|
936
|
+
*
|
|
937
|
+
* Ini membuat CSS output jauh lebih kecil:
|
|
938
|
+
* Tailwind normal: ~300kb global
|
|
939
|
+
* Route CSS: ~2–10kb per route
|
|
940
|
+
*
|
|
941
|
+
* NOTE: v5 only supports Tailwind v4. v3 support has been removed.
|
|
942
|
+
*/
|
|
943
|
+
type TailwindEngineMode = "jit" | "build" | "manual";
|
|
944
|
+
interface TailwindEngineOptions {
|
|
945
|
+
mode?: TailwindEngineMode;
|
|
946
|
+
cwd?: string;
|
|
947
|
+
outputDir?: string;
|
|
948
|
+
config?: Record<string, any>;
|
|
949
|
+
minify?: boolean;
|
|
950
|
+
}
|
|
951
|
+
interface CssGenerateResult {
|
|
952
|
+
route: string;
|
|
953
|
+
css: string;
|
|
954
|
+
classes: string[];
|
|
955
|
+
sizeBytes: number;
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Try to use Tailwind's internal API for CSS generation.
|
|
959
|
+
* Fallback ke manual CSS generation jika Tailwind API tidak tersedia.
|
|
960
|
+
*
|
|
961
|
+
* NOTE: v5 only supports Tailwind v4. v3 support has been removed.
|
|
962
|
+
*/
|
|
963
|
+
declare function generateCssForClasses(classes: string[], config?: Record<string, any>, cwd?: string): Promise<string>;
|
|
964
|
+
declare function generateAllRouteCss(opts?: TailwindEngineOptions): Promise<CssGenerateResult[]>;
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* tailwind-styled-v4 — variantCompiler
|
|
968
|
+
*
|
|
969
|
+
* FIXES:
|
|
970
|
+
* #01 — Don't pre-merge base into variant table values (double-merge bug)
|
|
971
|
+
* #06 — Use proper AST parser instead of fragile regex
|
|
972
|
+
*
|
|
973
|
+
* BEFORE (double-merge):
|
|
974
|
+
* compileVariants: table["size"]["sm"] = "px-4 py-2 text-sm" ← base included
|
|
975
|
+
* astTransform: [base, table["size"][...]] ← base AGAIN → DUPE
|
|
976
|
+
*
|
|
977
|
+
* AFTER (correct):
|
|
978
|
+
* compileVariants: table["size"]["sm"] = "text-sm" ← variant only
|
|
979
|
+
* astTransform: [base, table["size"][...], className] ← base once, correct
|
|
980
|
+
*
|
|
981
|
+
* Input:
|
|
982
|
+
* { base: "px-4 py-2", variants: { size: { sm: "text-sm" } } }
|
|
983
|
+
*
|
|
984
|
+
* Output code:
|
|
985
|
+
* const __vt_abc123 = { size: { sm: "text-sm" } }
|
|
986
|
+
* // className = [base, table[variant]] → no duplication
|
|
987
|
+
*/
|
|
988
|
+
interface CompiledVariants {
|
|
989
|
+
base: string;
|
|
990
|
+
table: Record<string, Record<string, string>>;
|
|
991
|
+
compounds: Array<{
|
|
992
|
+
class: string;
|
|
993
|
+
[key: string]: any;
|
|
994
|
+
}>;
|
|
995
|
+
defaults: Record<string, string>;
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Compile variant config into lookup table.
|
|
999
|
+
*
|
|
1000
|
+
* FIX #01: Do NOT pre-merge base into table values.
|
|
1001
|
+
* Table contains variant-specific classes only.
|
|
1002
|
+
* Base is always injected separately in the component className array.
|
|
1003
|
+
*/
|
|
1004
|
+
declare function compileVariants(base: string, variants: Record<string, Record<string, string>>, compounds?: Array<{
|
|
1005
|
+
class: string;
|
|
1006
|
+
[key: string]: any;
|
|
1007
|
+
}>, defaults?: Record<string, string>): CompiledVariants;
|
|
1008
|
+
|
|
1009
|
+
export { type AstExtractResult, type AtomicRule, BucketEngine, type BucketStats, CompileContext, type CompileEngine, type CompileInput, type ComponentEnv, type ComponentMetadata, type ConflictWarning, type CoreCompileOptions, type CoreCompileResult, type CssCompileResult$1 as CssCompileResult, type CssDiff, type CssGenerateResult, type EliminationReport, type FileDependencyGraph, type HoistResult, IncrementalEngine, type IncrementalEngineOptions, type IncrementalStats, type LoaderContext, type LoaderOptions, type LoaderOutput, type NativeBridge, type NativeTransformResult, Pipeline, type ProcessResult, type RouteClassMap, type RscAnalysis, type StaticVariantUsage, type StyleBucket, type StyleNode, type TailwindEngineOptions, type TransformOptions, type TransformResult, type VariantUsage, adaptNativeResult, analyzeFile, analyzeVariantUsage, astExtractClassesNative, bootstrapZeroConfig, bucketSort, buildStyleTag, classifyNode, clearAtomicRegistry, compileCssFromClasses, compileCssNative, compileVariants, compileWithCore, detectConflicts, eliminateDeadCss, extractAllClasses, extractComponentUsage, fileToRoute, findDeadVariants, generateAllRouteCss, generateAtomicCss, generateCssForClasses, generateSafelist, generateSafelistCss, getAllRoutes, getAtomicRegistry, getBucketEngine, getCollector, getCollectorSummary, getContentPaths, getIncrementalEngine, getNativeBridge, getRouteClasses, hasInteractiveFeatures, hasTwUsage, hoistComponents, injectClientDirective, injectServerOnlyComment, invalidateConfigCache, isDynamic, isServerComponent, isZeroConfig, loadSafelist, loadTailwindConfig, mergeClassesStatic, normalizeClasses, optimizeCss, parseAtomicClass, parseClassesToNodes, registerFileClasses, registerGlobalClasses, resetBucketEngine, resetCollector, resetCompileCache, resetIncrementalEngine, resetNativeBridgeCache, resolveServerVariant, runElimination, runLoaderTransform, scanProjectUsage, hasTwUsage as shouldProcess, shouldSkipFile, toAtomicClasses, transformSource };
|