next-style 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +31 -0
- package/dist/index.d.cts +259 -0
- package/dist/index.d.ts +259 -5
- package/dist/index.js +31 -4
- package/dist/postcss-plugin/index.cjs +1 -0
- package/dist/postcss-plugin/index.d.cts +19 -0
- package/dist/postcss-plugin/index.d.ts +6 -4
- package/dist/postcss-plugin/index.js +1 -61
- package/package.json +26 -13
- package/dist/compiler/index.d.ts +0 -105
- package/dist/compiler/index.d.ts.map +0 -1
- package/dist/compiler/index.js +0 -245
- package/dist/index.d.ts.map +0 -1
- package/dist/postcss-plugin/index.d.ts.map +0 -1
- package/dist/runtime/index.d.ts +0 -104
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js +0 -65
- package/dist/utils/index.d.ts +0 -60
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -97
|
@@ -1,61 +1 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import os from 'node:os';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import postcss from 'postcss';
|
|
5
|
-
/**
|
|
6
|
-
* PostCSS plugin for next-style.
|
|
7
|
-
*
|
|
8
|
-
* How it works with Turbopack:
|
|
9
|
-
* 1. `css()` / `global()` calls in component files write compiled CSS to a
|
|
10
|
-
* temp file (`os.tmpdir()/next-style.css`) via `styleCollector.flush()`.
|
|
11
|
-
* 2. This plugin reads that temp file and replaces `@import "next-style"`
|
|
12
|
-
* with its contents at PostCSS processing time.
|
|
13
|
-
*
|
|
14
|
-
* Because PostCSS runs in a separate process from the module graph,
|
|
15
|
-
* in-memory collectors cannot be shared. The temp file is the IPC bridge.
|
|
16
|
-
*
|
|
17
|
-
* Usage in postcss.config.js:
|
|
18
|
-
* export default { plugins: { "next-style/plugin": {} } }
|
|
19
|
-
*/
|
|
20
|
-
const IMPORT_RE = /^next-style$/;
|
|
21
|
-
/** Path to the temp file used as IPC bridge between runtime and PostCSS. */
|
|
22
|
-
export const CACHE_FILE = path.join(os.tmpdir(), 'next-style.css');
|
|
23
|
-
function nextStylePlugin(opts = {}) {
|
|
24
|
-
const cacheFile = opts.cacheFile ?? CACHE_FILE;
|
|
25
|
-
const plugin = {
|
|
26
|
-
postcssPlugin: 'next-style',
|
|
27
|
-
Once(root) {
|
|
28
|
-
// Read compiled CSS from the temp file written by the runtime
|
|
29
|
-
let cssContent = '';
|
|
30
|
-
try {
|
|
31
|
-
cssContent = fs.readFileSync(cacheFile, 'utf-8');
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
// Cache file doesn't exist yet (first cold boot before any css() call)
|
|
35
|
-
// — leave the @import in place so PostCSS doesn't error, just remove it
|
|
36
|
-
}
|
|
37
|
-
// Replace @import "next-style" with compiled CSS (or remove if empty)
|
|
38
|
-
let replaced = false;
|
|
39
|
-
root.walkAtRules('import', atRule => {
|
|
40
|
-
const val = atRule.params.replace(/['"]/g, '').trim();
|
|
41
|
-
if (!IMPORT_RE.test(val))
|
|
42
|
-
return;
|
|
43
|
-
if (cssContent.trim()) {
|
|
44
|
-
atRule.replaceWith(postcss.parse(cssContent));
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
atRule.remove();
|
|
48
|
-
}
|
|
49
|
-
replaced = true;
|
|
50
|
-
});
|
|
51
|
-
// No @import directive — prepend at top if there's content
|
|
52
|
-
if (!replaced && cssContent.trim()) {
|
|
53
|
-
root.prepend(postcss.parse(cssContent));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
return plugin;
|
|
58
|
-
}
|
|
59
|
-
nextStylePlugin.postcss = true;
|
|
60
|
-
export default nextStylePlugin;
|
|
61
|
-
export const plugin = nextStylePlugin;
|
|
1
|
+
import l from"fs";import a from"os";import m from"path";import i from"postcss";var u=/^next-style$/,f=m.join(a.tmpdir(),"next-style.css");function s(c={}){let o=c.cacheFile??f;return{postcssPlugin:"next-style",Once(r){let t="";try{t=l.readFileSync(o,"utf-8")}catch{}let n=!1;r.walkAtRules("import",e=>{let p=e.params.replace(/['"]/g,"").trim();u.test(p)&&(t.trim()?e.replaceWith(i.parse(t)):e.remove(),n=!0)}),!n&&t.trim()&&r.prepend(i.parse(t))}}}s.postcss=!0;var O=s,C=s;export{f as CACHE_FILE,O as default,C as plugin};
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-style",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Zero-Runtime CSS-in-JS for Next.js + Turbopack",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/index.
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -15,38 +15,51 @@
|
|
|
15
15
|
"homepage": "https://github.com/TiwPhiraphan/next-style#readme",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.cjs"
|
|
20
21
|
},
|
|
21
22
|
"./plugin": {
|
|
22
|
-
"
|
|
23
|
-
"
|
|
23
|
+
"types": "./dist/postcss-plugin/index.d.ts",
|
|
24
|
+
"import": "./dist/postcss-plugin/index.mjs",
|
|
25
|
+
"require": "./dist/postcss-plugin/index.cjs"
|
|
24
26
|
}
|
|
25
27
|
},
|
|
26
28
|
"publishConfig": {
|
|
27
29
|
"access": "public"
|
|
28
30
|
},
|
|
29
|
-
"files": [
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
30
34
|
"scripts": {
|
|
31
|
-
"export": "
|
|
32
|
-
"build:
|
|
33
|
-
"
|
|
34
|
-
"dev": "tsc --watch",
|
|
35
|
+
"export": "tsup",
|
|
36
|
+
"build:watch": "tsup --watch",
|
|
37
|
+
"dev": "tsup --watch",
|
|
35
38
|
"test": "bun test",
|
|
36
39
|
"lint": "biome lint",
|
|
37
40
|
"format": "biome format --write"
|
|
38
41
|
},
|
|
39
42
|
"devDependencies": {
|
|
40
43
|
"@biomejs/biome": "^2.4.15",
|
|
41
|
-
"@types/bun": "^1.3.14",
|
|
42
44
|
"@types/node": "^25.7.0",
|
|
45
|
+
"@types/bun": "^1.3.14",
|
|
43
46
|
"csstype": "^3.2.3",
|
|
47
|
+
"tsup": "^8.5.1",
|
|
44
48
|
"typescript": "^5"
|
|
45
49
|
},
|
|
46
50
|
"peerDependencies": {
|
|
47
51
|
"postcss": ">=8.4.31"
|
|
48
52
|
},
|
|
49
|
-
"keywords": [
|
|
53
|
+
"keywords": [
|
|
54
|
+
"css-in-js",
|
|
55
|
+
"zero-runtime",
|
|
56
|
+
"next.js",
|
|
57
|
+
"turbopack",
|
|
58
|
+
"postcss",
|
|
59
|
+
"style",
|
|
60
|
+
"next-style",
|
|
61
|
+
"css"
|
|
62
|
+
],
|
|
50
63
|
"author": "TiwPhiraphan",
|
|
51
64
|
"license": "MIT"
|
|
52
65
|
}
|
package/dist/compiler/index.d.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The compiled representation of a single `css({})` call.
|
|
3
|
-
* Produced by `StyleCollector` and consumed by the PostCSS plugin.
|
|
4
|
-
*/
|
|
5
|
-
export interface CompiledStyle {
|
|
6
|
-
/** Scoped class name, e.g. `"ns-1x2y3z"`. */
|
|
7
|
-
className: string;
|
|
8
|
-
/** Base CSS rule block for this class. */
|
|
9
|
-
css: string;
|
|
10
|
-
/** Map of normalized media query string → CSS rule block. */
|
|
11
|
-
mediaQueries: Record<string, string>;
|
|
12
|
-
/** Map of pseudo selector (e.g. `":hover"`) → CSS rule block. */
|
|
13
|
-
pseudoClasses: Record<string, string>;
|
|
14
|
-
/** Concatenated `@keyframes` blocks referenced by this style. */
|
|
15
|
-
keyframes: string;
|
|
16
|
-
/** Map of `@supports` condition → CSS rule block. */
|
|
17
|
-
supports: Record<string, string>;
|
|
18
|
-
/** Map of `@layer` name → CSS rule block. */
|
|
19
|
-
layers: Record<string, string>;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Collects, compiles, and deduplicates styles registered via `css()` and `global()`.
|
|
23
|
-
*
|
|
24
|
-
* A single shared instance is held by the runtime module. The PostCSS plugin
|
|
25
|
-
* calls `getAllStyles()` at build time to drain the collected CSS.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* const collector = new StyleCollector()
|
|
29
|
-
* const className = collector.addStyle({ color: 'red' }) // "ns-abc123"
|
|
30
|
-
* const css = collector.getAllStyles() // ".ns-abc123 { color: red; }"
|
|
31
|
-
*/
|
|
32
|
-
export declare class StyleCollector {
|
|
33
|
-
private styles;
|
|
34
|
-
/**
|
|
35
|
-
* Compiles a style object and registers it in the collector.
|
|
36
|
-
* Returns the same class name for identical style objects (deduplication).
|
|
37
|
-
*
|
|
38
|
-
* @param styleObj - Raw style object from a `css({})` call.
|
|
39
|
-
* @returns Scoped class name string.
|
|
40
|
-
*/
|
|
41
|
-
addStyle(styleObj: any): string;
|
|
42
|
-
/**
|
|
43
|
-
* Registers a global style rule (no scoped class).
|
|
44
|
-
* Subsequent calls with the same selector are ignored (idempotent).
|
|
45
|
-
*
|
|
46
|
-
* @param selector - CSS selector string, e.g. `"body"` or `"h1, h2"`.
|
|
47
|
-
* @param styleObj - Style properties to apply to the selector.
|
|
48
|
-
*/
|
|
49
|
-
addGlobalStyle(selector: string, styleObj: any): void;
|
|
50
|
-
private compileStyle;
|
|
51
|
-
private parseStyles;
|
|
52
|
-
private buildDeclarations;
|
|
53
|
-
/**
|
|
54
|
-
* Serialises all collected styles into a single CSS string.
|
|
55
|
-
*
|
|
56
|
-
* Output order:
|
|
57
|
-
* 1. `@keyframes` blocks
|
|
58
|
-
* 2. Base class rules
|
|
59
|
-
* 3. Pseudo-class/element rules
|
|
60
|
-
* 4. `@layer` blocks
|
|
61
|
-
* 5. `@supports` blocks
|
|
62
|
-
* 6. Media queries (ascending `min-width`, mobile-first)
|
|
63
|
-
*
|
|
64
|
-
* @returns Full CSS string ready to be injected or written to a file.
|
|
65
|
-
*/
|
|
66
|
-
getAllStyles(): string;
|
|
67
|
-
private extractMinWidth;
|
|
68
|
-
/**
|
|
69
|
-
* Writes all collected styles to a temp file so the PostCSS plugin
|
|
70
|
-
* (which runs in a separate process) can read them.
|
|
71
|
-
*
|
|
72
|
-
* Call this after all `css()` / `global()` calls have been evaluated,
|
|
73
|
-
* e.g. at the end of a build-time entry point.
|
|
74
|
-
*
|
|
75
|
-
* @param filePath - Destination file path. Defaults to `os.tmpdir()/next-style.css`.
|
|
76
|
-
*/
|
|
77
|
-
flush(filePath?: string): void;
|
|
78
|
-
/**
|
|
79
|
-
* Returns a snapshot of the internal style map.
|
|
80
|
-
* Intended for inspection and testing — not for direct mutation.
|
|
81
|
-
*/
|
|
82
|
-
getStyleMap(): Map<string, CompiledStyle>;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Creates an isolated `StyleCollector` paired with a transform helper.
|
|
86
|
-
*
|
|
87
|
-
* Primarily used by SWC/Babel transforms and test harnesses that need
|
|
88
|
-
* a fresh collector per file or per test, independent of the shared
|
|
89
|
-
* runtime instance.
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* const { collector, transformCssCall } = createTransformer()
|
|
93
|
-
* const className = transformCssCall({ color: 'red' })
|
|
94
|
-
* const css = collector.getAllStyles()
|
|
95
|
-
*/
|
|
96
|
-
export declare function createTransformer(): {
|
|
97
|
-
collector: StyleCollector;
|
|
98
|
-
/**
|
|
99
|
-
* Equivalent to calling `css()` against this transformer's isolated collector.
|
|
100
|
-
* @param styleObj - Raw style object.
|
|
101
|
-
* @returns Scoped class name string.
|
|
102
|
-
*/
|
|
103
|
-
transformCssCall(styleObj: any): string;
|
|
104
|
-
};
|
|
105
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compiler/index.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAA;IACjB,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAA;IACX,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9B;AAED;;;;;;;;;;GAUG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,MAAM,CAAmC;IAEjD;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM;IAW/B;;;;;;OAMG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;IAgBrD,OAAO,CAAC,YAAY;IA+DpB,OAAO,CAAC,WAAW;IAwCnB,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;;;;;;OAYG;IACH,YAAY,IAAI,MAAM;IAwBtB,OAAO,CAAC,eAAe;IAKvB;;;;;;;;OAQG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAQ9B;;;OAGG;IACH,WAAW;CAGX;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB;;IAI/B;;;;OAIG;+BACwB,GAAG,GAAG,MAAM;EAIxC"}
|
package/dist/compiler/index.js
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { BREAKPOINTS, camelToKebab, generateClassHash, normalizeMediaQuery } from '../utils';
|
|
2
|
-
/**
|
|
3
|
-
* Collects, compiles, and deduplicates styles registered via `css()` and `global()`.
|
|
4
|
-
*
|
|
5
|
-
* A single shared instance is held by the runtime module. The PostCSS plugin
|
|
6
|
-
* calls `getAllStyles()` at build time to drain the collected CSS.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* const collector = new StyleCollector()
|
|
10
|
-
* const className = collector.addStyle({ color: 'red' }) // "ns-abc123"
|
|
11
|
-
* const css = collector.getAllStyles() // ".ns-abc123 { color: red; }"
|
|
12
|
-
*/
|
|
13
|
-
export class StyleCollector {
|
|
14
|
-
constructor() {
|
|
15
|
-
this.styles = new Map();
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Compiles a style object and registers it in the collector.
|
|
19
|
-
* Returns the same class name for identical style objects (deduplication).
|
|
20
|
-
*
|
|
21
|
-
* @param styleObj - Raw style object from a `css({})` call.
|
|
22
|
-
* @returns Scoped class name string.
|
|
23
|
-
*/
|
|
24
|
-
addStyle(styleObj) {
|
|
25
|
-
const hash = generateClassHash(styleObj);
|
|
26
|
-
const className = `ns-${hash}`;
|
|
27
|
-
if (this.styles.has(className)) {
|
|
28
|
-
return className;
|
|
29
|
-
}
|
|
30
|
-
const compiled = this.compileStyle(styleObj);
|
|
31
|
-
this.styles.set(className, compiled);
|
|
32
|
-
return className;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Registers a global style rule (no scoped class).
|
|
36
|
-
* Subsequent calls with the same selector are ignored (idempotent).
|
|
37
|
-
*
|
|
38
|
-
* @param selector - CSS selector string, e.g. `"body"` or `"h1, h2"`.
|
|
39
|
-
* @param styleObj - Style properties to apply to the selector.
|
|
40
|
-
*/
|
|
41
|
-
addGlobalStyle(selector, styleObj) {
|
|
42
|
-
const key = `global:${selector}`;
|
|
43
|
-
if (this.styles.has(key))
|
|
44
|
-
return;
|
|
45
|
-
const props = this.buildDeclarations(styleObj);
|
|
46
|
-
if (!props)
|
|
47
|
-
return;
|
|
48
|
-
this.styles.set(key, {
|
|
49
|
-
className: key,
|
|
50
|
-
css: `${selector} {\n${props}}`,
|
|
51
|
-
mediaQueries: {},
|
|
52
|
-
pseudoClasses: {},
|
|
53
|
-
keyframes: '',
|
|
54
|
-
supports: {},
|
|
55
|
-
layers: {}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
compileStyle(styleObj) {
|
|
59
|
-
const { mediaQueries, pseudoClasses, normalStyles, keyframes, supports, container, layer } = this.parseStyles(styleObj);
|
|
60
|
-
const hash = generateClassHash(styleObj);
|
|
61
|
-
const className = `ns-${hash}`;
|
|
62
|
-
const declarations = this.buildDeclarations(normalStyles);
|
|
63
|
-
const css = `.${className} {\n${declarations}}`;
|
|
64
|
-
const compiledMedia = {};
|
|
65
|
-
Object.entries(mediaQueries).forEach(([query, styles]) => {
|
|
66
|
-
const normalized = normalizeMediaQuery(query);
|
|
67
|
-
const inner = this.buildDeclarations(styles, ' ');
|
|
68
|
-
const existing = compiledMedia[normalized];
|
|
69
|
-
compiledMedia[normalized] = existing
|
|
70
|
-
? `${normalized} {\n .${className} {\n${existing.split('\n').slice(2, -1).join('\n')}\n${inner} }\n}`
|
|
71
|
-
: `${normalized} {\n .${className} {\n${inner} }\n}`;
|
|
72
|
-
});
|
|
73
|
-
Object.entries(container).forEach(([query, styles]) => {
|
|
74
|
-
const inner = this.buildDeclarations(styles, ' ');
|
|
75
|
-
compiledMedia[query] = `${query} {\n .${className} {\n${inner} }\n}`;
|
|
76
|
-
});
|
|
77
|
-
const compiledPseudos = {};
|
|
78
|
-
Object.entries(pseudoClasses).forEach(([pseudo, styles]) => {
|
|
79
|
-
const inner = this.buildDeclarations(styles);
|
|
80
|
-
compiledPseudos[pseudo] = `.${className}${pseudo} {\n${inner}}`;
|
|
81
|
-
});
|
|
82
|
-
let keyframesCss = '';
|
|
83
|
-
Object.entries(keyframes).forEach(([name, frames]) => {
|
|
84
|
-
keyframesCss += `@keyframes ${name} {\n`;
|
|
85
|
-
Object.entries(frames).forEach(([stop, props]) => {
|
|
86
|
-
const inner = this.buildDeclarations(props, ' ');
|
|
87
|
-
keyframesCss += ` ${stop} {\n${inner} }\n`;
|
|
88
|
-
});
|
|
89
|
-
keyframesCss += '}\n';
|
|
90
|
-
});
|
|
91
|
-
const compiledSupports = {};
|
|
92
|
-
Object.entries(supports).forEach(([condition, styles]) => {
|
|
93
|
-
const inner = this.buildDeclarations(styles, ' ');
|
|
94
|
-
compiledSupports[condition] = `@supports ${condition} {\n .${className} {\n${inner} }\n}`;
|
|
95
|
-
});
|
|
96
|
-
const compiledLayers = {};
|
|
97
|
-
Object.entries(layer).forEach(([name, styles]) => {
|
|
98
|
-
const inner = this.buildDeclarations(styles, ' ');
|
|
99
|
-
compiledLayers[name] = `@layer ${name} {\n${inner}}`;
|
|
100
|
-
});
|
|
101
|
-
return {
|
|
102
|
-
className,
|
|
103
|
-
css,
|
|
104
|
-
mediaQueries: compiledMedia,
|
|
105
|
-
pseudoClasses: compiledPseudos,
|
|
106
|
-
keyframes: keyframesCss,
|
|
107
|
-
supports: compiledSupports,
|
|
108
|
-
layers: compiledLayers
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
parseStyles(styleObj) {
|
|
112
|
-
const normalStyles = {};
|
|
113
|
-
const mediaQueries = {};
|
|
114
|
-
const pseudoClasses = {};
|
|
115
|
-
const keyframes = {};
|
|
116
|
-
const supports = {};
|
|
117
|
-
const container = {};
|
|
118
|
-
const layer = {};
|
|
119
|
-
Object.entries(styleObj).forEach(([key, value]) => {
|
|
120
|
-
if (key.startsWith('@keyframes ')) {
|
|
121
|
-
keyframes[key.slice('@keyframes '.length)] = value;
|
|
122
|
-
}
|
|
123
|
-
else if (key === '@keyframes' && typeof value === 'object') {
|
|
124
|
-
Object.assign(keyframes, value);
|
|
125
|
-
}
|
|
126
|
-
else if (key.startsWith('@supports')) {
|
|
127
|
-
supports[key.slice('@supports '.length)] = value;
|
|
128
|
-
}
|
|
129
|
-
else if (key.startsWith('@container')) {
|
|
130
|
-
container[key] = value;
|
|
131
|
-
}
|
|
132
|
-
else if (key.startsWith('@layer')) {
|
|
133
|
-
layer[key.slice('@layer '.length) || 'default'] = value;
|
|
134
|
-
}
|
|
135
|
-
else if (key in BREAKPOINTS || key.startsWith('@media')) {
|
|
136
|
-
mediaQueries[key] = value;
|
|
137
|
-
}
|
|
138
|
-
else if (key.startsWith(':') || key.startsWith('::')) {
|
|
139
|
-
pseudoClasses[key] = value;
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
normalStyles[key] = value;
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
return { normalStyles, mediaQueries, pseudoClasses, keyframes, supports, container, layer };
|
|
146
|
-
}
|
|
147
|
-
buildDeclarations(styles, indent = ' ') {
|
|
148
|
-
let css = '';
|
|
149
|
-
Object.entries(styles).forEach(([key, value]) => {
|
|
150
|
-
if (typeof value === 'string' || typeof value === 'number') {
|
|
151
|
-
css += `${indent}${camelToKebab(key)}: ${value};\n`;
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
return css;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Serialises all collected styles into a single CSS string.
|
|
158
|
-
*
|
|
159
|
-
* Output order:
|
|
160
|
-
* 1. `@keyframes` blocks
|
|
161
|
-
* 2. Base class rules
|
|
162
|
-
* 3. Pseudo-class/element rules
|
|
163
|
-
* 4. `@layer` blocks
|
|
164
|
-
* 5. `@supports` blocks
|
|
165
|
-
* 6. Media queries (ascending `min-width`, mobile-first)
|
|
166
|
-
*
|
|
167
|
-
* @returns Full CSS string ready to be injected or written to a file.
|
|
168
|
-
*/
|
|
169
|
-
getAllStyles() {
|
|
170
|
-
let allCss = '';
|
|
171
|
-
this.styles.forEach(style => {
|
|
172
|
-
if (style.keyframes)
|
|
173
|
-
allCss += `${style.keyframes}\n`;
|
|
174
|
-
if (style.css)
|
|
175
|
-
allCss += `${style.css}\n`;
|
|
176
|
-
Object.values(style.pseudoClasses).forEach(css => {
|
|
177
|
-
allCss += `${css}\n`;
|
|
178
|
-
});
|
|
179
|
-
Object.values(style.layers).forEach(css => {
|
|
180
|
-
allCss += `${css}\n`;
|
|
181
|
-
});
|
|
182
|
-
Object.values(style.supports).forEach(css => {
|
|
183
|
-
allCss += `${css}\n`;
|
|
184
|
-
});
|
|
185
|
-
const mediaEntries = Object.entries(style.mediaQueries).sort(([a], [b]) => this.extractMinWidth(a) - this.extractMinWidth(b));
|
|
186
|
-
mediaEntries.forEach(([, css]) => {
|
|
187
|
-
allCss += `${css}\n`;
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
return allCss;
|
|
191
|
-
}
|
|
192
|
-
extractMinWidth(query) {
|
|
193
|
-
const match = query.match(/min-width:\s*(\d+)px/);
|
|
194
|
-
return match ? parseInt(match[1], 10) : 0;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Writes all collected styles to a temp file so the PostCSS plugin
|
|
198
|
-
* (which runs in a separate process) can read them.
|
|
199
|
-
*
|
|
200
|
-
* Call this after all `css()` / `global()` calls have been evaluated,
|
|
201
|
-
* e.g. at the end of a build-time entry point.
|
|
202
|
-
*
|
|
203
|
-
* @param filePath - Destination file path. Defaults to `os.tmpdir()/next-style.css`.
|
|
204
|
-
*/
|
|
205
|
-
flush(filePath) {
|
|
206
|
-
const fs = require('node:fs');
|
|
207
|
-
const os = require('node:os');
|
|
208
|
-
const path = require('node:path');
|
|
209
|
-
const dest = filePath ?? path.join(os.tmpdir(), 'next-style.css');
|
|
210
|
-
fs.writeFileSync(dest, this.getAllStyles(), 'utf-8');
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Returns a snapshot of the internal style map.
|
|
214
|
-
* Intended for inspection and testing — not for direct mutation.
|
|
215
|
-
*/
|
|
216
|
-
getStyleMap() {
|
|
217
|
-
return new Map(this.styles);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Creates an isolated `StyleCollector` paired with a transform helper.
|
|
222
|
-
*
|
|
223
|
-
* Primarily used by SWC/Babel transforms and test harnesses that need
|
|
224
|
-
* a fresh collector per file or per test, independent of the shared
|
|
225
|
-
* runtime instance.
|
|
226
|
-
*
|
|
227
|
-
* @example
|
|
228
|
-
* const { collector, transformCssCall } = createTransformer()
|
|
229
|
-
* const className = transformCssCall({ color: 'red' })
|
|
230
|
-
* const css = collector.getAllStyles()
|
|
231
|
-
*/
|
|
232
|
-
export function createTransformer() {
|
|
233
|
-
const collector = new StyleCollector();
|
|
234
|
-
return {
|
|
235
|
-
collector,
|
|
236
|
-
/**
|
|
237
|
-
* Equivalent to calling `css()` against this transformer's isolated collector.
|
|
238
|
-
* @param styleObj - Raw style object.
|
|
239
|
-
* @returns Scoped class name string.
|
|
240
|
-
*/
|
|
241
|
-
transformCssCall(styleObj) {
|
|
242
|
-
return collector.addStyle(styleObj);
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC3F,OAAO,EACN,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,SAAS,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/postcss-plugin/index.ts"],"names":[],"mappings":"AAGA,OAAO,OAAO,MAAM,SAAS,CAAA;AAoB7B,4EAA4E;AAC5E,eAAO,MAAM,UAAU,QAA2C,CAAA;AAElE,UAAU,aAAa;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,iBAAS,eAAe,CAAC,IAAI,GAAE,aAAkB,kBAqChD;kBArCQ,eAAe;;;AAyCxB,eAAe,eAAe,CAAA;AAC9B,eAAO,MAAM,MAAM,wBAAkB,CAAA"}
|
package/dist/runtime/index.d.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import type { Properties, Pseudos } from 'csstype';
|
|
2
|
-
import { StyleCollector } from '../compiler';
|
|
3
|
-
/**
|
|
4
|
-
* CSS properties with full type safety and autocomplete via csstype.
|
|
5
|
-
* Accepts both string and number values (e.g. `fontSize: 16` or `fontSize: '16px'`).
|
|
6
|
-
*/
|
|
7
|
-
export type CSSProperties = Properties<string | number>;
|
|
8
|
-
/** @internal Mapped type for pseudo-classes/elements — avoids index signature limitation */
|
|
9
|
-
type PseudoStyles = {
|
|
10
|
-
[P in Pseudos]?: CSSProperties;
|
|
11
|
-
};
|
|
12
|
-
/** @internal At-rule keys (@media, @container, @supports, @layer, @keyframes) */
|
|
13
|
-
type AtRuleStyles = {
|
|
14
|
-
'@sm'?: CSSProperties;
|
|
15
|
-
'@md'?: CSSProperties;
|
|
16
|
-
'@lg'?: CSSProperties;
|
|
17
|
-
'@xl'?: CSSProperties;
|
|
18
|
-
'@2xl'?: CSSProperties;
|
|
19
|
-
[media: `@media ${string}`]: CSSProperties;
|
|
20
|
-
[container: `@container ${string}`]: CSSProperties;
|
|
21
|
-
[supports: `@supports ${string}`]: CSSProperties;
|
|
22
|
-
[layer: `@layer ${string}`]: CSSProperties;
|
|
23
|
-
[keyframes: `@keyframes ${string}`]: Record<string, CSSProperties>;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Style object passed to `css()` and `global()`.
|
|
27
|
-
*
|
|
28
|
-
* Supports:
|
|
29
|
-
* - All CSS properties (typed via csstype)
|
|
30
|
-
* - Responsive breakpoints: `'@sm'`, `'@md'`, `'@lg'`, `'@xl'`, `'@2xl'`
|
|
31
|
-
* - Arbitrary media queries: `'@media (min-width: 900px)'`
|
|
32
|
-
* - Pseudo-classes and pseudo-elements: `':hover'`, `'::before'`, etc.
|
|
33
|
-
* - Container queries: `'@container sidebar (min-width: 300px)'`
|
|
34
|
-
* - Feature queries: `'@supports (display: grid)'`
|
|
35
|
-
* - Keyframe animations: `'@keyframes fadeIn'`
|
|
36
|
-
* - Cascade layers: `'@layer utilities'`
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* const style: CSSObject = {
|
|
40
|
-
* fontSize: '16px',
|
|
41
|
-
* '@md': { fontSize: '20px' },
|
|
42
|
-
* ':hover': { color: 'blue' },
|
|
43
|
-
* '@keyframes spin': { to: { transform: 'rotate(360deg)' } },
|
|
44
|
-
* }
|
|
45
|
-
*/
|
|
46
|
-
export type CSSObject = CSSProperties & PseudoStyles & AtRuleStyles & {
|
|
47
|
-
[key: string]: any;
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Converts a style object into a unique CSS class name.
|
|
51
|
-
*
|
|
52
|
-
* Styles are collected at build time by the PostCSS plugin and emitted as
|
|
53
|
-
* a single static CSS file — there is zero runtime overhead in production.
|
|
54
|
-
* Identical style objects always return the same class name (deduplication).
|
|
55
|
-
*
|
|
56
|
-
* @param styles - A `CSSObject` describing the styles for this element.
|
|
57
|
-
* @returns A stable class name string (e.g. `"ns-1x2y3z"`).
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* const button = css({
|
|
61
|
-
* padding: '8px 16px',
|
|
62
|
-
* borderRadius: '6px',
|
|
63
|
-
* backgroundColor: '#7F77DD',
|
|
64
|
-
* ':hover': { backgroundColor: '#534AB7' },
|
|
65
|
-
* '@md': { padding: '10px 20px' },
|
|
66
|
-
* })
|
|
67
|
-
*
|
|
68
|
-
* export function Button() {
|
|
69
|
-
* return <button className={button}>Click me</button>
|
|
70
|
-
* }
|
|
71
|
-
*/
|
|
72
|
-
export declare function css(styles: CSSObject): string;
|
|
73
|
-
/**
|
|
74
|
-
* Registers global CSS styles applied directly to selectors (no scoped class).
|
|
75
|
-
*
|
|
76
|
-
* Useful for CSS resets, base typography, and third-party element overrides.
|
|
77
|
-
* Like `css()`, styles are extracted at build time — no runtime cost.
|
|
78
|
-
*
|
|
79
|
-
* @param styles - A record mapping CSS selectors to `CSSObject` style definitions.
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* global({
|
|
83
|
-
* '*': { boxSizing: 'border-box', margin: '0' },
|
|
84
|
-
* 'body': { fontFamily: 'Inter, sans-serif', lineHeight: '1.6' },
|
|
85
|
-
* 'h1, h2, h3': { fontWeight: 500 },
|
|
86
|
-
* })
|
|
87
|
-
*/
|
|
88
|
-
export declare function global(styles: Record<string, CSSObject>): void;
|
|
89
|
-
/**
|
|
90
|
-
* The shared `StyleCollector` instance.
|
|
91
|
-
*
|
|
92
|
-
* Consumed by the PostCSS plugin at build time to drain all registered styles
|
|
93
|
-
* into the output CSS file. Not intended for direct use in application code.
|
|
94
|
-
*
|
|
95
|
-
* @internal
|
|
96
|
-
*/
|
|
97
|
-
export { collector as styleCollector };
|
|
98
|
-
declare const collector: StyleCollector;
|
|
99
|
-
/** @deprecated Use `styleCollector` instead. */
|
|
100
|
-
export declare const styleRegistry: {
|
|
101
|
-
get: (key: string) => import("..").CompiledStyle | undefined;
|
|
102
|
-
getAllStyles: () => string;
|
|
103
|
-
};
|
|
104
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,CAAA;AAEvD,4FAA4F;AAC5F,KAAK,YAAY,GAAG;KAAG,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,aAAa;CAAE,CAAA;AAEtD,iFAAiF;AACjF,KAAK,YAAY,GAAG;IACnB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,CAAC,KAAK,EAAE,UAAU,MAAM,EAAE,GAAG,aAAa,CAAA;IAC1C,CAAC,SAAS,EAAE,cAAc,MAAM,EAAE,GAAG,aAAa,CAAA;IAClD,CAAC,QAAQ,EAAE,aAAa,MAAM,EAAE,GAAG,aAAa,CAAA;IAChD,CAAC,KAAK,EAAE,UAAU,MAAM,EAAE,GAAG,aAAa,CAAA;IAC1C,CAAC,SAAS,EAAE,cAAc,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAClE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,GACpC,YAAY,GACZ,YAAY,GAAG;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAClB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAI7C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI,CAK9D;AAED;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,CAAA;AAEtC,QAAA,MAAM,SAAS,gBAAuB,CAAA;AAEtC,gDAAgD;AAChD,eAAO,MAAM,aAAa;eACd,MAAM;;CAEjB,CAAA"}
|
package/dist/runtime/index.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { StyleCollector } from '../compiler';
|
|
2
|
-
/**
|
|
3
|
-
* Converts a style object into a unique CSS class name.
|
|
4
|
-
*
|
|
5
|
-
* Styles are collected at build time by the PostCSS plugin and emitted as
|
|
6
|
-
* a single static CSS file — there is zero runtime overhead in production.
|
|
7
|
-
* Identical style objects always return the same class name (deduplication).
|
|
8
|
-
*
|
|
9
|
-
* @param styles - A `CSSObject` describing the styles for this element.
|
|
10
|
-
* @returns A stable class name string (e.g. `"ns-1x2y3z"`).
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* const button = css({
|
|
14
|
-
* padding: '8px 16px',
|
|
15
|
-
* borderRadius: '6px',
|
|
16
|
-
* backgroundColor: '#7F77DD',
|
|
17
|
-
* ':hover': { backgroundColor: '#534AB7' },
|
|
18
|
-
* '@md': { padding: '10px 20px' },
|
|
19
|
-
* })
|
|
20
|
-
*
|
|
21
|
-
* export function Button() {
|
|
22
|
-
* return <button className={button}>Click me</button>
|
|
23
|
-
* }
|
|
24
|
-
*/
|
|
25
|
-
export function css(styles) {
|
|
26
|
-
const className = collector.addStyle(styles);
|
|
27
|
-
collector.flush();
|
|
28
|
-
return className;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Registers global CSS styles applied directly to selectors (no scoped class).
|
|
32
|
-
*
|
|
33
|
-
* Useful for CSS resets, base typography, and third-party element overrides.
|
|
34
|
-
* Like `css()`, styles are extracted at build time — no runtime cost.
|
|
35
|
-
*
|
|
36
|
-
* @param styles - A record mapping CSS selectors to `CSSObject` style definitions.
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* global({
|
|
40
|
-
* '*': { boxSizing: 'border-box', margin: '0' },
|
|
41
|
-
* 'body': { fontFamily: 'Inter, sans-serif', lineHeight: '1.6' },
|
|
42
|
-
* 'h1, h2, h3': { fontWeight: 500 },
|
|
43
|
-
* })
|
|
44
|
-
*/
|
|
45
|
-
export function global(styles) {
|
|
46
|
-
Object.entries(styles).forEach(([selector, styleObj]) => {
|
|
47
|
-
collector.addGlobalStyle(selector, styleObj);
|
|
48
|
-
});
|
|
49
|
-
collector.flush();
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* The shared `StyleCollector` instance.
|
|
53
|
-
*
|
|
54
|
-
* Consumed by the PostCSS plugin at build time to drain all registered styles
|
|
55
|
-
* into the output CSS file. Not intended for direct use in application code.
|
|
56
|
-
*
|
|
57
|
-
* @internal
|
|
58
|
-
*/
|
|
59
|
-
export { collector as styleCollector };
|
|
60
|
-
const collector = new StyleCollector();
|
|
61
|
-
/** @deprecated Use `styleCollector` instead. */
|
|
62
|
-
export const styleRegistry = {
|
|
63
|
-
get: (key) => collector.getStyleMap().get(key),
|
|
64
|
-
getAllStyles: () => collector.getAllStyles()
|
|
65
|
-
};
|