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.
- package/dist/animate.cjs +252 -0
- package/dist/animate.cjs.map +1 -0
- package/dist/animate.d.cts +117 -0
- package/dist/animate.d.ts +117 -0
- package/dist/animate.js +245 -0
- package/dist/animate.js.map +1 -0
- package/dist/astTransform-ua-eapqs.d.cts +41 -0
- package/dist/astTransform-ua-eapqs.d.ts +41 -0
- package/dist/compiler.cjs +3594 -0
- package/dist/compiler.cjs.map +1 -0
- package/dist/compiler.d.cts +716 -0
- package/dist/compiler.d.ts +716 -0
- package/dist/compiler.js +3535 -0
- package/dist/compiler.js.map +1 -0
- package/dist/css.cjs +71 -0
- package/dist/css.cjs.map +1 -0
- package/dist/css.d.cts +45 -0
- package/dist/css.d.ts +45 -0
- package/dist/css.js +62 -0
- package/dist/css.js.map +1 -0
- package/dist/devtools.cjs +959 -0
- package/dist/devtools.cjs.map +1 -0
- package/dist/devtools.d.cts +22 -0
- package/dist/devtools.d.ts +22 -0
- package/dist/devtools.js +952 -0
- package/dist/devtools.js.map +1 -0
- package/dist/index.cjs +1058 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +584 -0
- package/dist/index.d.ts +449 -980
- package/dist/index.js +1021 -3
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +268 -0
- package/dist/next.cjs.map +1 -0
- package/dist/next.d.cts +45 -0
- package/dist/next.d.ts +45 -0
- package/dist/next.js +261 -0
- package/dist/next.js.map +1 -0
- package/dist/plugins.cjs +396 -0
- package/dist/plugins.cjs.map +1 -0
- package/dist/plugins.d.cts +231 -0
- package/dist/plugins.d.ts +231 -0
- package/dist/plugins.js +381 -0
- package/dist/plugins.js.map +1 -0
- package/dist/preset.cjs +129 -0
- package/dist/preset.cjs.map +1 -0
- package/dist/preset.d.cts +249 -0
- package/dist/preset.d.ts +249 -0
- package/dist/preset.js +124 -0
- package/dist/preset.js.map +1 -0
- package/dist/theme.cjs +154 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.d.cts +181 -0
- package/dist/theme.d.ts +181 -0
- package/dist/theme.js +148 -0
- package/dist/theme.js.map +1 -0
- package/dist/turbopackLoader.cjs +2689 -0
- package/dist/turbopackLoader.cjs.map +1 -0
- package/dist/turbopackLoader.d.cts +22 -0
- package/dist/turbopackLoader.d.ts +22 -0
- package/dist/turbopackLoader.js +2681 -0
- package/dist/turbopackLoader.js.map +1 -0
- package/dist/vite.cjs +105 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.cts +22 -0
- package/dist/vite.d.ts +22 -0
- package/dist/vite.js +96 -0
- package/dist/vite.js.map +1 -0
- package/dist/webpackLoader.cjs +2670 -0
- package/dist/webpackLoader.cjs.map +1 -0
- package/dist/webpackLoader.d.cts +24 -0
- package/dist/webpackLoader.d.ts +24 -0
- package/dist/webpackLoader.js +2662 -0
- package/dist/webpackLoader.js.map +1 -0
- package/package.json +62 -32
- package/CHANGELOG.md +0 -75
- package/LICENSE +0 -21
- package/README.md +0 -608
- package/dist/cli/init.js +0 -208
- package/dist/compiler/index.d.mts +0 -214
- package/dist/compiler/index.d.ts +0 -214
- package/dist/compiler/index.js +0 -546
- package/dist/compiler/index.js.map +0 -1
- package/dist/compiler/index.mjs +0 -504
- package/dist/compiler/index.mjs.map +0 -1
- package/dist/index.d.mts +0 -1115
- package/dist/index.mjs +0 -4
- package/dist/index.mjs.map +0 -1
- package/dist/turbopack-loader.js +0 -232
- package/dist/webpack-loader.js +0 -213
package/dist/css.cjs
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
10
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
11
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
12
|
+
|
|
13
|
+
/* tailwind-styled-v4 v4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
|
|
14
|
+
|
|
15
|
+
async function TwCssInjector({
|
|
16
|
+
cssDir,
|
|
17
|
+
route,
|
|
18
|
+
includeGlobal = true,
|
|
19
|
+
minify = true,
|
|
20
|
+
asLink = false
|
|
21
|
+
}) {
|
|
22
|
+
const resolvedDir = cssDir != null ? cssDir : path__default.default.join(process.cwd(), ".next", "static", "css", "tw");
|
|
23
|
+
const cssChunks = [];
|
|
24
|
+
if (includeGlobal) {
|
|
25
|
+
const globalCss = loadCssFile(path__default.default.join(resolvedDir, "_global.css"));
|
|
26
|
+
if (globalCss) cssChunks.push(globalCss);
|
|
27
|
+
}
|
|
28
|
+
const targetRoute = route != null ? route : "/";
|
|
29
|
+
const routeFile = routeToFilename(targetRoute);
|
|
30
|
+
const routeCss = loadCssFile(path__default.default.join(resolvedDir, routeFile));
|
|
31
|
+
if (routeCss) cssChunks.push(routeCss);
|
|
32
|
+
if (cssChunks.length === 0) return React__default.default.createElement(React__default.default.Fragment, null);
|
|
33
|
+
const combined = cssChunks.join("\n");
|
|
34
|
+
const final = minify ? minifyCss(combined) : combined;
|
|
35
|
+
if (asLink) {
|
|
36
|
+
return React__default.default.createElement("link", {
|
|
37
|
+
rel: "stylesheet",
|
|
38
|
+
href: `/_next/static/css/tw/${routeFile}`,
|
|
39
|
+
crossOrigin: "anonymous"
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return React__default.default.createElement("style", {
|
|
43
|
+
dangerouslySetInnerHTML: { __html: final },
|
|
44
|
+
"data-tw-route": targetRoute
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function useTwClasses(classes) {
|
|
48
|
+
return classes;
|
|
49
|
+
}
|
|
50
|
+
function loadCssFile(filepath) {
|
|
51
|
+
try {
|
|
52
|
+
if (fs__default.default.existsSync(filepath)) {
|
|
53
|
+
return fs__default.default.readFileSync(filepath, "utf-8");
|
|
54
|
+
}
|
|
55
|
+
} catch (e) {
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
function routeToFilename(route) {
|
|
60
|
+
if (route === "/") return "index.css";
|
|
61
|
+
if (route === "__global") return "_global.css";
|
|
62
|
+
return `${route.replace(/^\//, "").replace(/\//g, "_")}.css`;
|
|
63
|
+
}
|
|
64
|
+
function minifyCss(css) {
|
|
65
|
+
return css.replace(/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g, "").replace(/\s+/g, " ").replace(/\s*{\s*/g, "{").replace(/\s*}\s*/g, "}").replace(/\s*;\s*/g, ";").trim();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
exports.TwCssInjector = TwCssInjector;
|
|
69
|
+
exports.useTwClasses = useTwClasses;
|
|
70
|
+
//# sourceMappingURL=css.cjs.map
|
|
71
|
+
//# sourceMappingURL=css.cjs.map
|
package/dist/css.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../runtime-css/src/CssInjector.tsx"],"names":["path","React","fs"],"mappings":";;;;;;;;;;;;;;AAsCA,eAAsB,aAAA,CAAc;AAAA,EAClC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,aAAA,GAAgB,IAAA;AAAA,EAChB,MAAA,GAAS,IAAA;AAAA,EACT,MAAA,GAAS;AACX,CAAA,EAAkD;AAChD,EAAA,MAAM,WAAA,GAAc,MAAA,IAAA,IAAA,GAAA,MAAA,GAAUA,qBAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,KAAI,EAAG,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,IAAI,CAAA;AAErF,EAAA,MAAM,YAAsB,EAAC;AAG7B,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,MAAM,YAAY,WAAA,CAAYA,qBAAA,CAAK,IAAA,CAAK,WAAA,EAAa,aAAa,CAAC,CAAA;AACnE,IAAA,IAAI,SAAA,EAAW,SAAA,CAAU,IAAA,CAAK,SAAS,CAAA;AAAA,EACzC;AAGA,EAAA,MAAM,cAAc,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,GAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,gBAAgB,WAAW,CAAA;AAC7C,EAAA,MAAM,WAAW,WAAA,CAAYA,qBAAA,CAAK,IAAA,CAAK,WAAA,EAAa,SAAS,CAAC,CAAA;AAC9D,EAAA,IAAI,QAAA,EAAU,SAAA,CAAU,IAAA,CAAK,QAAQ,CAAA;AAErC,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG,OAAOC,uBAAM,aAAA,CAAcA,sBAAA,CAAM,UAAU,IAAI,CAAA;AAE3E,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AACpC,EAAA,MAAM,KAAA,GAAQ,MAAA,GAAS,SAAA,CAAU,QAAQ,CAAA,GAAI,QAAA;AAE7C,EAAA,IAAI,MAAA,EAAQ;AAEV,IAAA,OAAOA,sBAAA,CAAM,cAAc,MAAA,EAAQ;AAAA,MACjC,GAAA,EAAK,YAAA;AAAA,MACL,IAAA,EAAM,wBAAwB,SAAS,CAAA,CAAA;AAAA,MACvC,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAGA,EAAA,OAAOA,sBAAA,CAAM,cAAc,OAAA,EAAS;AAAA,IAClC,uBAAA,EAAyB,EAAE,MAAA,EAAQ,KAAA,EAAM;AAAA,IACzC,eAAA,EAAiB;AAAA,GAClB,CAAA;AACH;AAYO,SAAS,aAAa,OAAA,EAAyB;AAGpD,EAAA,OAAO,OAAA;AACT;AAMA,SAAS,YAAY,QAAA,EAAiC;AACpD,EAAA,IAAI;AACF,IAAA,IAAIC,mBAAA,CAAG,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC3B,MAAA,OAAOA,mBAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAAA,IAC1C;AAAA,EACF,CAAA,CAAA,OAAQ,CAAA,EAAA;AAAA,EAER;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,gBAAgB,KAAA,EAAuB;AAC9C,EAAA,IAAI,KAAA,KAAU,KAAK,OAAO,WAAA;AAC1B,EAAA,IAAI,KAAA,KAAU,YAAY,OAAO,aAAA;AACjC,EAAA,OAAO,CAAA,EAAG,MAAM,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAC,CAAA,IAAA,CAAA;AACxD;AAEA,SAAS,UAAU,GAAA,EAAqB;AACtC,EAAA,OAAO,GAAA,CACJ,QAAQ,iCAAA,EAAmC,EAAE,EAC7C,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,OAAA,CAAQ,YAAY,GAAG,CAAA,CACvB,QAAQ,UAAA,EAAY,GAAG,EACvB,OAAA,CAAQ,UAAA,EAAY,GAAG,CAAA,CACvB,IAAA,EAAK;AACV","file":"css.cjs","sourcesContent":["/**\n * tailwind-styled-v4 — CSS Injector (React Server Component)\n *\n * Inject CSS yang sudah di-generate per-route langsung ke <head>.\n * Dipakai di Next.js App Router layout atau page.\n *\n * Di server component — inject inline CSS, zero client JS.\n * Streaming friendly — CSS di-emit bersamaan dengan HTML.\n *\n * Usage:\n * // app/layout.tsx\n * import { TwCssInjector } from \"tailwind-styled-v4/css\"\n * export default function Layout({ children }) {\n * return <html><head><TwCssInjector/></head><body>{children}</body></html>\n * }\n */\n\nimport fs from \"node:fs\"\nimport path from \"node:path\"\nimport React from \"react\"\n\ninterface CssInjectorProps {\n /** Override CSS directory. Default: .next/static/css/tw */\n cssDir?: string\n /** Specific route to inject. Default: auto-detect dari headers */\n route?: string\n /** Inject global CSS juga. Default: true */\n includeGlobal?: boolean\n /** Minify inline CSS. Default: true */\n minify?: boolean\n /** Add <link> tag instead of inline <style> untuk cached CSS */\n asLink?: boolean\n}\n\n/**\n * Server Component — inject route-specific CSS into <head>.\n * No client JS, no hydration overhead.\n */\nexport async function TwCssInjector({\n cssDir,\n route,\n includeGlobal = true,\n minify = true,\n asLink = false,\n}: CssInjectorProps): Promise<React.ReactElement> {\n const resolvedDir = cssDir ?? path.join(process.cwd(), \".next\", \"static\", \"css\", \"tw\")\n\n const cssChunks: string[] = []\n\n // 1. Global CSS (base styles, reset)\n if (includeGlobal) {\n const globalCss = loadCssFile(path.join(resolvedDir, \"_global.css\"))\n if (globalCss) cssChunks.push(globalCss)\n }\n\n // 2. Route-specific CSS\n const targetRoute = route ?? \"/\"\n const routeFile = routeToFilename(targetRoute)\n const routeCss = loadCssFile(path.join(resolvedDir, routeFile))\n if (routeCss) cssChunks.push(routeCss)\n\n if (cssChunks.length === 0) return React.createElement(React.Fragment, null)\n\n const combined = cssChunks.join(\"\\n\")\n const final = minify ? minifyCss(combined) : combined\n\n if (asLink) {\n // Return <link> tag — CSS cached by browser\n return React.createElement(\"link\", {\n rel: \"stylesheet\",\n href: `/_next/static/css/tw/${routeFile}`,\n crossOrigin: \"anonymous\",\n })\n }\n\n // Inline <style> — zero network request, fastest FCP\n return React.createElement(\"style\", {\n dangerouslySetInnerHTML: { __html: final },\n \"data-tw-route\": targetRoute,\n })\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Hook for client components\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Lightweight hook to get current route's CSS classes.\n * Useful for dynamic class injection in client components.\n *\n * Returns empty string on server (SSR) — CSS already injected by TwCssInjector.\n */\nexport function useTwClasses(classes: string): string {\n // In client environment, return classes as-is\n // CSS is already handled by TwCssInjector at server level\n return classes\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction loadCssFile(filepath: string): string | null {\n try {\n if (fs.existsSync(filepath)) {\n return fs.readFileSync(filepath, \"utf-8\")\n }\n } catch {\n // file not found or unreadable\n }\n return null\n}\n\nfunction routeToFilename(route: string): string {\n if (route === \"/\") return \"index.css\"\n if (route === \"__global\") return \"_global.css\"\n return `${route.replace(/^\\//, \"\").replace(/\\//g, \"_\")}.css`\n}\n\nfunction minifyCss(css: string): string {\n return css\n .replace(/\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//g, \"\")\n .replace(/\\s+/g, \" \")\n .replace(/\\s*{\\s*/g, \"{\")\n .replace(/\\s*}\\s*/g, \"}\")\n .replace(/\\s*;\\s*/g, \";\")\n .trim()\n}\n"]}
|
package/dist/css.d.cts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* tailwind-styled-v4 — CSS Injector (React Server Component)
|
|
5
|
+
*
|
|
6
|
+
* Inject CSS yang sudah di-generate per-route langsung ke <head>.
|
|
7
|
+
* Dipakai di Next.js App Router layout atau page.
|
|
8
|
+
*
|
|
9
|
+
* Di server component — inject inline CSS, zero client JS.
|
|
10
|
+
* Streaming friendly — CSS di-emit bersamaan dengan HTML.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* // app/layout.tsx
|
|
14
|
+
* import { TwCssInjector } from "tailwind-styled-v4/css"
|
|
15
|
+
* export default function Layout({ children }) {
|
|
16
|
+
* return <html><head><TwCssInjector/></head><body>{children}</body></html>
|
|
17
|
+
* }
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
interface CssInjectorProps {
|
|
21
|
+
/** Override CSS directory. Default: .next/static/css/tw */
|
|
22
|
+
cssDir?: string;
|
|
23
|
+
/** Specific route to inject. Default: auto-detect dari headers */
|
|
24
|
+
route?: string;
|
|
25
|
+
/** Inject global CSS juga. Default: true */
|
|
26
|
+
includeGlobal?: boolean;
|
|
27
|
+
/** Minify inline CSS. Default: true */
|
|
28
|
+
minify?: boolean;
|
|
29
|
+
/** Add <link> tag instead of inline <style> untuk cached CSS */
|
|
30
|
+
asLink?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Server Component — inject route-specific CSS into <head>.
|
|
34
|
+
* No client JS, no hydration overhead.
|
|
35
|
+
*/
|
|
36
|
+
declare function TwCssInjector({ cssDir, route, includeGlobal, minify, asLink, }: CssInjectorProps): Promise<React.ReactElement>;
|
|
37
|
+
/**
|
|
38
|
+
* Lightweight hook to get current route's CSS classes.
|
|
39
|
+
* Useful for dynamic class injection in client components.
|
|
40
|
+
*
|
|
41
|
+
* Returns empty string on server (SSR) — CSS already injected by TwCssInjector.
|
|
42
|
+
*/
|
|
43
|
+
declare function useTwClasses(classes: string): string;
|
|
44
|
+
|
|
45
|
+
export { TwCssInjector, useTwClasses };
|
package/dist/css.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* tailwind-styled-v4 — CSS Injector (React Server Component)
|
|
5
|
+
*
|
|
6
|
+
* Inject CSS yang sudah di-generate per-route langsung ke <head>.
|
|
7
|
+
* Dipakai di Next.js App Router layout atau page.
|
|
8
|
+
*
|
|
9
|
+
* Di server component — inject inline CSS, zero client JS.
|
|
10
|
+
* Streaming friendly — CSS di-emit bersamaan dengan HTML.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* // app/layout.tsx
|
|
14
|
+
* import { TwCssInjector } from "tailwind-styled-v4/css"
|
|
15
|
+
* export default function Layout({ children }) {
|
|
16
|
+
* return <html><head><TwCssInjector/></head><body>{children}</body></html>
|
|
17
|
+
* }
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
interface CssInjectorProps {
|
|
21
|
+
/** Override CSS directory. Default: .next/static/css/tw */
|
|
22
|
+
cssDir?: string;
|
|
23
|
+
/** Specific route to inject. Default: auto-detect dari headers */
|
|
24
|
+
route?: string;
|
|
25
|
+
/** Inject global CSS juga. Default: true */
|
|
26
|
+
includeGlobal?: boolean;
|
|
27
|
+
/** Minify inline CSS. Default: true */
|
|
28
|
+
minify?: boolean;
|
|
29
|
+
/** Add <link> tag instead of inline <style> untuk cached CSS */
|
|
30
|
+
asLink?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Server Component — inject route-specific CSS into <head>.
|
|
34
|
+
* No client JS, no hydration overhead.
|
|
35
|
+
*/
|
|
36
|
+
declare function TwCssInjector({ cssDir, route, includeGlobal, minify, asLink, }: CssInjectorProps): Promise<React.ReactElement>;
|
|
37
|
+
/**
|
|
38
|
+
* Lightweight hook to get current route's CSS classes.
|
|
39
|
+
* Useful for dynamic class injection in client components.
|
|
40
|
+
*
|
|
41
|
+
* Returns empty string on server (SSR) — CSS already injected by TwCssInjector.
|
|
42
|
+
*/
|
|
43
|
+
declare function useTwClasses(classes: string): string;
|
|
44
|
+
|
|
45
|
+
export { TwCssInjector, useTwClasses };
|
package/dist/css.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
/* tailwind-styled-v4 v4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
|
|
6
|
+
|
|
7
|
+
async function TwCssInjector({
|
|
8
|
+
cssDir,
|
|
9
|
+
route,
|
|
10
|
+
includeGlobal = true,
|
|
11
|
+
minify = true,
|
|
12
|
+
asLink = false
|
|
13
|
+
}) {
|
|
14
|
+
const resolvedDir = cssDir != null ? cssDir : path.join(process.cwd(), ".next", "static", "css", "tw");
|
|
15
|
+
const cssChunks = [];
|
|
16
|
+
if (includeGlobal) {
|
|
17
|
+
const globalCss = loadCssFile(path.join(resolvedDir, "_global.css"));
|
|
18
|
+
if (globalCss) cssChunks.push(globalCss);
|
|
19
|
+
}
|
|
20
|
+
const targetRoute = route != null ? route : "/";
|
|
21
|
+
const routeFile = routeToFilename(targetRoute);
|
|
22
|
+
const routeCss = loadCssFile(path.join(resolvedDir, routeFile));
|
|
23
|
+
if (routeCss) cssChunks.push(routeCss);
|
|
24
|
+
if (cssChunks.length === 0) return React.createElement(React.Fragment, null);
|
|
25
|
+
const combined = cssChunks.join("\n");
|
|
26
|
+
const final = minify ? minifyCss(combined) : combined;
|
|
27
|
+
if (asLink) {
|
|
28
|
+
return React.createElement("link", {
|
|
29
|
+
rel: "stylesheet",
|
|
30
|
+
href: `/_next/static/css/tw/${routeFile}`,
|
|
31
|
+
crossOrigin: "anonymous"
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return React.createElement("style", {
|
|
35
|
+
dangerouslySetInnerHTML: { __html: final },
|
|
36
|
+
"data-tw-route": targetRoute
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function useTwClasses(classes) {
|
|
40
|
+
return classes;
|
|
41
|
+
}
|
|
42
|
+
function loadCssFile(filepath) {
|
|
43
|
+
try {
|
|
44
|
+
if (fs.existsSync(filepath)) {
|
|
45
|
+
return fs.readFileSync(filepath, "utf-8");
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
function routeToFilename(route) {
|
|
52
|
+
if (route === "/") return "index.css";
|
|
53
|
+
if (route === "__global") return "_global.css";
|
|
54
|
+
return `${route.replace(/^\//, "").replace(/\//g, "_")}.css`;
|
|
55
|
+
}
|
|
56
|
+
function minifyCss(css) {
|
|
57
|
+
return css.replace(/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g, "").replace(/\s+/g, " ").replace(/\s*{\s*/g, "{").replace(/\s*}\s*/g, "}").replace(/\s*;\s*/g, ";").trim();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { TwCssInjector, useTwClasses };
|
|
61
|
+
//# sourceMappingURL=css.js.map
|
|
62
|
+
//# sourceMappingURL=css.js.map
|
package/dist/css.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../runtime-css/src/CssInjector.tsx"],"names":[],"mappings":";;;;;;AAsCA,eAAsB,aAAA,CAAc;AAAA,EAClC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,aAAA,GAAgB,IAAA;AAAA,EAChB,MAAA,GAAS,IAAA;AAAA,EACT,MAAA,GAAS;AACX,CAAA,EAAkD;AAChD,EAAA,MAAM,WAAA,GAAc,MAAA,IAAA,IAAA,GAAA,MAAA,GAAU,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,KAAI,EAAG,OAAA,EAAS,QAAA,EAAU,KAAA,EAAO,IAAI,CAAA;AAErF,EAAA,MAAM,YAAsB,EAAC;AAG7B,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,MAAM,YAAY,WAAA,CAAY,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,aAAa,CAAC,CAAA;AACnE,IAAA,IAAI,SAAA,EAAW,SAAA,CAAU,IAAA,CAAK,SAAS,CAAA;AAAA,EACzC;AAGA,EAAA,MAAM,cAAc,KAAA,IAAA,IAAA,GAAA,KAAA,GAAS,GAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,gBAAgB,WAAW,CAAA;AAC7C,EAAA,MAAM,WAAW,WAAA,CAAY,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,SAAS,CAAC,CAAA;AAC9D,EAAA,IAAI,QAAA,EAAU,SAAA,CAAU,IAAA,CAAK,QAAQ,CAAA;AAErC,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG,OAAO,MAAM,aAAA,CAAc,KAAA,CAAM,UAAU,IAAI,CAAA;AAE3E,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AACpC,EAAA,MAAM,KAAA,GAAQ,MAAA,GAAS,SAAA,CAAU,QAAQ,CAAA,GAAI,QAAA;AAE7C,EAAA,IAAI,MAAA,EAAQ;AAEV,IAAA,OAAO,KAAA,CAAM,cAAc,MAAA,EAAQ;AAAA,MACjC,GAAA,EAAK,YAAA;AAAA,MACL,IAAA,EAAM,wBAAwB,SAAS,CAAA,CAAA;AAAA,MACvC,WAAA,EAAa;AAAA,KACd,CAAA;AAAA,EACH;AAGA,EAAA,OAAO,KAAA,CAAM,cAAc,OAAA,EAAS;AAAA,IAClC,uBAAA,EAAyB,EAAE,MAAA,EAAQ,KAAA,EAAM;AAAA,IACzC,eAAA,EAAiB;AAAA,GAClB,CAAA;AACH;AAYO,SAAS,aAAa,OAAA,EAAyB;AAGpD,EAAA,OAAO,OAAA;AACT;AAMA,SAAS,YAAY,QAAA,EAAiC;AACpD,EAAA,IAAI;AACF,IAAA,IAAI,EAAA,CAAG,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC3B,MAAA,OAAO,EAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAAA,IAC1C;AAAA,EACF,CAAA,CAAA,OAAQ,CAAA,EAAA;AAAA,EAER;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,gBAAgB,KAAA,EAAuB;AAC9C,EAAA,IAAI,KAAA,KAAU,KAAK,OAAO,WAAA;AAC1B,EAAA,IAAI,KAAA,KAAU,YAAY,OAAO,aAAA;AACjC,EAAA,OAAO,CAAA,EAAG,MAAM,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAC,CAAA,IAAA,CAAA;AACxD;AAEA,SAAS,UAAU,GAAA,EAAqB;AACtC,EAAA,OAAO,GAAA,CACJ,QAAQ,iCAAA,EAAmC,EAAE,EAC7C,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,OAAA,CAAQ,YAAY,GAAG,CAAA,CACvB,QAAQ,UAAA,EAAY,GAAG,EACvB,OAAA,CAAQ,UAAA,EAAY,GAAG,CAAA,CACvB,IAAA,EAAK;AACV","file":"css.js","sourcesContent":["/**\n * tailwind-styled-v4 — CSS Injector (React Server Component)\n *\n * Inject CSS yang sudah di-generate per-route langsung ke <head>.\n * Dipakai di Next.js App Router layout atau page.\n *\n * Di server component — inject inline CSS, zero client JS.\n * Streaming friendly — CSS di-emit bersamaan dengan HTML.\n *\n * Usage:\n * // app/layout.tsx\n * import { TwCssInjector } from \"tailwind-styled-v4/css\"\n * export default function Layout({ children }) {\n * return <html><head><TwCssInjector/></head><body>{children}</body></html>\n * }\n */\n\nimport fs from \"node:fs\"\nimport path from \"node:path\"\nimport React from \"react\"\n\ninterface CssInjectorProps {\n /** Override CSS directory. Default: .next/static/css/tw */\n cssDir?: string\n /** Specific route to inject. Default: auto-detect dari headers */\n route?: string\n /** Inject global CSS juga. Default: true */\n includeGlobal?: boolean\n /** Minify inline CSS. Default: true */\n minify?: boolean\n /** Add <link> tag instead of inline <style> untuk cached CSS */\n asLink?: boolean\n}\n\n/**\n * Server Component — inject route-specific CSS into <head>.\n * No client JS, no hydration overhead.\n */\nexport async function TwCssInjector({\n cssDir,\n route,\n includeGlobal = true,\n minify = true,\n asLink = false,\n}: CssInjectorProps): Promise<React.ReactElement> {\n const resolvedDir = cssDir ?? path.join(process.cwd(), \".next\", \"static\", \"css\", \"tw\")\n\n const cssChunks: string[] = []\n\n // 1. Global CSS (base styles, reset)\n if (includeGlobal) {\n const globalCss = loadCssFile(path.join(resolvedDir, \"_global.css\"))\n if (globalCss) cssChunks.push(globalCss)\n }\n\n // 2. Route-specific CSS\n const targetRoute = route ?? \"/\"\n const routeFile = routeToFilename(targetRoute)\n const routeCss = loadCssFile(path.join(resolvedDir, routeFile))\n if (routeCss) cssChunks.push(routeCss)\n\n if (cssChunks.length === 0) return React.createElement(React.Fragment, null)\n\n const combined = cssChunks.join(\"\\n\")\n const final = minify ? minifyCss(combined) : combined\n\n if (asLink) {\n // Return <link> tag — CSS cached by browser\n return React.createElement(\"link\", {\n rel: \"stylesheet\",\n href: `/_next/static/css/tw/${routeFile}`,\n crossOrigin: \"anonymous\",\n })\n }\n\n // Inline <style> — zero network request, fastest FCP\n return React.createElement(\"style\", {\n dangerouslySetInnerHTML: { __html: final },\n \"data-tw-route\": targetRoute,\n })\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Hook for client components\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Lightweight hook to get current route's CSS classes.\n * Useful for dynamic class injection in client components.\n *\n * Returns empty string on server (SSR) — CSS already injected by TwCssInjector.\n */\nexport function useTwClasses(classes: string): string {\n // In client environment, return classes as-is\n // CSS is already handled by TwCssInjector at server level\n return classes\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction loadCssFile(filepath: string): string | null {\n try {\n if (fs.existsSync(filepath)) {\n return fs.readFileSync(filepath, \"utf-8\")\n }\n } catch {\n // file not found or unreadable\n }\n return null\n}\n\nfunction routeToFilename(route: string): string {\n if (route === \"/\") return \"index.css\"\n if (route === \"__global\") return \"_global.css\"\n return `${route.replace(/^\\//, \"\").replace(/\\//g, \"_\")}.css`\n}\n\nfunction minifyCss(css: string): string {\n return css\n .replace(/\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//g, \"\")\n .replace(/\\s+/g, \" \")\n .replace(/\\s*{\\s*/g, \"{\")\n .replace(/\\s*}\\s*/g, \"}\")\n .replace(/\\s*;\\s*/g, \";\")\n .trim()\n}\n"]}
|