@seyuna/postcss 1.0.0-canary.6 → 1.0.0-canary.7
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 +7 -0
- package/dist/at-rules/color.d.ts +18 -0
- package/dist/at-rules/color.js +68 -0
- package/dist/at-rules/index.d.ts +5 -2
- package/dist/at-rules/index.js +9 -5
- package/dist/plugin.js +8 -2
- package/dist/types.d.ts +19 -0
- package/dist/types.js +2 -0
- package/package.json +1 -1
- package/src/at-rules/color.ts +76 -0
- package/src/at-rules/index.ts +14 -6
- package/src/plugin.ts +8 -2
- package/src/types.ts +19 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.0.0-canary.7](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.6...v1.0.0-canary.7) (2025-09-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Added at-rule ([8a08289](https://github.com/seyuna-corp/seyuna-postcss/commit/8a08289023f4aa6f65d56e10697e64d02444f118))
|
|
7
|
+
|
|
1
8
|
# [1.0.0-canary.6](https://github.com/seyuna-corp/seyuna-postcss/compare/v1.0.0-canary.5...v1.0.0-canary.6) (2025-09-09)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AtRule } from "postcss";
|
|
2
|
+
/**
|
|
3
|
+
* Custom PostCSS plugin handler for `@each-seyuna-color` at-rules.
|
|
4
|
+
*
|
|
5
|
+
* Example usage:
|
|
6
|
+
*
|
|
7
|
+
* @each-seyuna-color {
|
|
8
|
+
* color: white;
|
|
9
|
+
* }
|
|
10
|
+
*
|
|
11
|
+
* Will generate:
|
|
12
|
+
*
|
|
13
|
+
* .alpha { color: white; }
|
|
14
|
+
* .beta { color: white; }
|
|
15
|
+
* .gamma { color: white; }
|
|
16
|
+
* ...
|
|
17
|
+
*/
|
|
18
|
+
export declare function eachSeyunaColor(atRule: AtRule): void;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.eachSeyunaColor = eachSeyunaColor;
|
|
7
|
+
const postcss_1 = require("postcss");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
/**
|
|
11
|
+
* Custom PostCSS plugin handler for `@each-seyuna-color` at-rules.
|
|
12
|
+
*
|
|
13
|
+
* Example usage:
|
|
14
|
+
*
|
|
15
|
+
* @each-seyuna-color {
|
|
16
|
+
* color: white;
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* Will generate:
|
|
20
|
+
*
|
|
21
|
+
* .alpha { color: white; }
|
|
22
|
+
* .beta { color: white; }
|
|
23
|
+
* .gamma { color: white; }
|
|
24
|
+
* ...
|
|
25
|
+
*/
|
|
26
|
+
function eachSeyunaColor(atRule) {
|
|
27
|
+
// Read seyuna.json from project root
|
|
28
|
+
const jsonPath = path_1.default.resolve(process.cwd(), "seyuna.json");
|
|
29
|
+
const fileContents = fs_1.default.readFileSync(jsonPath, "utf-8");
|
|
30
|
+
const data = JSON.parse(fileContents);
|
|
31
|
+
const hues = data.ui.theme.hues;
|
|
32
|
+
const light_colors = data.ui.theme.light;
|
|
33
|
+
const dark_colors = data.ui.theme.dark;
|
|
34
|
+
const hueNamesSet = new Set(Object.keys(hues));
|
|
35
|
+
const lightColorNamesSet = new Set(Object.keys(light_colors));
|
|
36
|
+
const darkColorNamesSet = new Set(Object.keys(dark_colors));
|
|
37
|
+
const mergedColorNamesSet = new Set([
|
|
38
|
+
...lightColorNamesSet,
|
|
39
|
+
...darkColorNamesSet,
|
|
40
|
+
]);
|
|
41
|
+
// Guard against atRule.nodes being undefined
|
|
42
|
+
const nodes = atRule.nodes ?? [];
|
|
43
|
+
const generatedRules = [];
|
|
44
|
+
// Helper to clone nodes and replace {name} placeholder
|
|
45
|
+
const cloneNodesWithName = (name) => nodes.map((node) => {
|
|
46
|
+
const cloned = node.clone();
|
|
47
|
+
// Only process declarations
|
|
48
|
+
if (cloned.type === "decl") {
|
|
49
|
+
const decl = cloned;
|
|
50
|
+
decl.value = decl.value.replace(/\{name\}/g, name);
|
|
51
|
+
}
|
|
52
|
+
return cloned;
|
|
53
|
+
});
|
|
54
|
+
// Generate rules for each hue
|
|
55
|
+
for (const hueName of hueNamesSet) {
|
|
56
|
+
const rule = new postcss_1.Rule({ selector: `.${hueName}` });
|
|
57
|
+
cloneNodesWithName(hueName).forEach((n) => rule.append(n));
|
|
58
|
+
generatedRules.push(rule);
|
|
59
|
+
}
|
|
60
|
+
// Generate rules for mergedColorNamesSet
|
|
61
|
+
for (const colorName of mergedColorNamesSet) {
|
|
62
|
+
const rule = new postcss_1.Rule({ selector: `.${colorName}` });
|
|
63
|
+
cloneNodesWithName(colorName).forEach((n) => rule.append(n));
|
|
64
|
+
generatedRules.push(rule);
|
|
65
|
+
}
|
|
66
|
+
// Replace the original @each-seyuna-color at-rule with all the generated rules
|
|
67
|
+
atRule.replaceWith(...generatedRules);
|
|
68
|
+
}
|
package/dist/at-rules/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { AtRule } from "postcss";
|
|
2
|
-
export
|
|
3
|
-
|
|
2
|
+
export interface AtRuleHandler {
|
|
3
|
+
name: string;
|
|
4
|
+
handler: (atRule: AtRule) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare const atRuleHandlers: AtRuleHandler[];
|
package/dist/at-rules/index.js
CHANGED
|
@@ -4,12 +4,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.atRuleHandlers = void 0;
|
|
7
|
+
// atRuleHandlers.ts
|
|
7
8
|
const dark_1 = __importDefault(require("./dark"));
|
|
8
9
|
const light_1 = __importDefault(require("./light"));
|
|
9
10
|
const container_1 = __importDefault(require("./container"));
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const color_1 = require("./color");
|
|
12
|
+
// Ordered array ensures execution order
|
|
13
|
+
exports.atRuleHandlers = [
|
|
14
|
+
{ name: "each-seyuna-color", handler: color_1.eachSeyunaColor }, // first
|
|
15
|
+
{ name: "light", handler: light_1.default },
|
|
16
|
+
{ name: "dark", handler: dark_1.default },
|
|
17
|
+
{ name: "container", handler: container_1.default },
|
|
14
18
|
// add more handlers here as needed
|
|
15
|
-
|
|
19
|
+
];
|
package/dist/plugin.js
CHANGED
|
@@ -20,8 +20,14 @@ const dynamicFunctionsPlugin = (opts = {}) => {
|
|
|
20
20
|
}
|
|
21
21
|
decl.value = value;
|
|
22
22
|
},
|
|
23
|
-
AtRule
|
|
24
|
-
|
|
23
|
+
// Override AtRule handler to ensure ordered execution
|
|
24
|
+
AtRule(atRule) {
|
|
25
|
+
// Iterate over handlers in order (array) instead of object spread
|
|
26
|
+
for (const { name, handler } of at_rules_1.atRuleHandlers) {
|
|
27
|
+
if (atRule.name === name) {
|
|
28
|
+
handler(atRule);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
25
31
|
},
|
|
26
32
|
};
|
|
27
33
|
};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface SeyunaConfig {
|
|
2
|
+
ui: {
|
|
3
|
+
theme: {
|
|
4
|
+
hues: Record<string, number>;
|
|
5
|
+
light: {
|
|
6
|
+
colors: Record<string, Color>;
|
|
7
|
+
};
|
|
8
|
+
dark: {
|
|
9
|
+
colors: Record<string, Color>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
type Color = {
|
|
15
|
+
lightness: number;
|
|
16
|
+
chroma: number;
|
|
17
|
+
hue: number;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
package/dist/types.js
ADDED
package/package.json
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { AtRule, Rule, ChildNode, Declaration } from "postcss";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { SeyunaConfig } from "../types";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Custom PostCSS plugin handler for `@each-seyuna-color` at-rules.
|
|
8
|
+
*
|
|
9
|
+
* Example usage:
|
|
10
|
+
*
|
|
11
|
+
* @each-seyuna-color {
|
|
12
|
+
* color: white;
|
|
13
|
+
* }
|
|
14
|
+
*
|
|
15
|
+
* Will generate:
|
|
16
|
+
*
|
|
17
|
+
* .alpha { color: white; }
|
|
18
|
+
* .beta { color: white; }
|
|
19
|
+
* .gamma { color: white; }
|
|
20
|
+
* ...
|
|
21
|
+
*/
|
|
22
|
+
export function eachSeyunaColor(atRule: AtRule) {
|
|
23
|
+
// Read seyuna.json from project root
|
|
24
|
+
const jsonPath = path.resolve(process.cwd(), "seyuna.json");
|
|
25
|
+
const fileContents = fs.readFileSync(jsonPath, "utf-8");
|
|
26
|
+
const data: SeyunaConfig = JSON.parse(fileContents);
|
|
27
|
+
|
|
28
|
+
const hues = data.ui.theme.hues;
|
|
29
|
+
const light_colors = data.ui.theme.light;
|
|
30
|
+
const dark_colors = data.ui.theme.dark;
|
|
31
|
+
|
|
32
|
+
const hueNamesSet = new Set(Object.keys(hues));
|
|
33
|
+
const lightColorNamesSet = new Set(Object.keys(light_colors));
|
|
34
|
+
const darkColorNamesSet = new Set(Object.keys(dark_colors));
|
|
35
|
+
|
|
36
|
+
const mergedColorNamesSet = new Set([
|
|
37
|
+
...lightColorNamesSet,
|
|
38
|
+
...darkColorNamesSet,
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
// Guard against atRule.nodes being undefined
|
|
42
|
+
const nodes = atRule.nodes ?? [];
|
|
43
|
+
|
|
44
|
+
const generatedRules: Rule[] = [];
|
|
45
|
+
|
|
46
|
+
// Helper to clone nodes and replace {name} placeholder
|
|
47
|
+
const cloneNodesWithName = (name: string) =>
|
|
48
|
+
nodes.map((node) => {
|
|
49
|
+
const cloned = node.clone();
|
|
50
|
+
|
|
51
|
+
// Only process declarations
|
|
52
|
+
if (cloned.type === "decl") {
|
|
53
|
+
const decl = cloned as Declaration;
|
|
54
|
+
decl.value = decl.value.replace(/\{name\}/g, name);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return cloned;
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Generate rules for each hue
|
|
61
|
+
for (const hueName of hueNamesSet) {
|
|
62
|
+
const rule = new Rule({ selector: `.${hueName}` });
|
|
63
|
+
cloneNodesWithName(hueName).forEach((n) => rule.append(n));
|
|
64
|
+
generatedRules.push(rule);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Generate rules for mergedColorNamesSet
|
|
68
|
+
for (const colorName of mergedColorNamesSet) {
|
|
69
|
+
const rule = new Rule({ selector: `.${colorName}` });
|
|
70
|
+
cloneNodesWithName(colorName).forEach((n) => rule.append(n));
|
|
71
|
+
generatedRules.push(rule);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Replace the original @each-seyuna-color at-rule with all the generated rules
|
|
75
|
+
atRule.replaceWith(...generatedRules);
|
|
76
|
+
}
|
package/src/at-rules/index.ts
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
// atRuleHandlers.ts
|
|
1
2
|
import dark from "./dark";
|
|
2
3
|
import light from "./light";
|
|
3
4
|
import container from "./container";
|
|
5
|
+
import { eachSeyunaColor } from "./color";
|
|
4
6
|
import type { AtRule } from "postcss";
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
// Each handler has a name (matches the at-rule) and the function
|
|
9
|
+
export interface AtRuleHandler {
|
|
10
|
+
name: string;
|
|
11
|
+
handler: (atRule: AtRule) => void;
|
|
12
|
+
}
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
// Ordered array ensures execution order
|
|
15
|
+
export const atRuleHandlers: AtRuleHandler[] = [
|
|
16
|
+
{ name: "each-seyuna-color", handler: eachSeyunaColor }, // first
|
|
17
|
+
{ name: "light", handler: light },
|
|
18
|
+
{ name: "dark", handler: dark },
|
|
19
|
+
{ name: "container", handler: container },
|
|
12
20
|
// add more handlers here as needed
|
|
13
|
-
|
|
21
|
+
];
|
package/src/plugin.ts
CHANGED
|
@@ -31,8 +31,14 @@ export const dynamicFunctionsPlugin: PluginCreator<PluginOptions> = (
|
|
|
31
31
|
decl.value = value;
|
|
32
32
|
},
|
|
33
33
|
|
|
34
|
-
AtRule
|
|
35
|
-
|
|
34
|
+
// Override AtRule handler to ensure ordered execution
|
|
35
|
+
AtRule(atRule) {
|
|
36
|
+
// Iterate over handlers in order (array) instead of object spread
|
|
37
|
+
for (const { name, handler } of atRuleHandlers) {
|
|
38
|
+
if (atRule.name === name) {
|
|
39
|
+
handler(atRule);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
36
42
|
},
|
|
37
43
|
};
|
|
38
44
|
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface SeyunaConfig {
|
|
2
|
+
ui: {
|
|
3
|
+
theme: {
|
|
4
|
+
hues: Record<string, number>;
|
|
5
|
+
light: {
|
|
6
|
+
colors: Record<string, Color>;
|
|
7
|
+
};
|
|
8
|
+
dark: {
|
|
9
|
+
colors: Record<string, Color>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type Color = {
|
|
16
|
+
lightness: number;
|
|
17
|
+
chroma: number;
|
|
18
|
+
hue: number;
|
|
19
|
+
};
|