@seyuna/postcss 1.0.0-canary.15 → 1.0.0-canary.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +168 -72
  3. package/dist/at-rules/color-scheme.d.ts +1 -1
  4. package/dist/at-rules/color.d.ts +1 -1
  5. package/dist/at-rules/color.js +1 -1
  6. package/dist/at-rules/container.d.ts +1 -1
  7. package/dist/at-rules/index.d.ts +1 -1
  8. package/dist/at-rules/index.js +4 -13
  9. package/dist/config.d.ts +2 -4
  10. package/dist/errors.d.ts +1 -1
  11. package/dist/functions/color.d.ts +1 -1
  12. package/dist/functions/color.js +27 -74
  13. package/dist/functions/index.d.ts +1 -1
  14. package/dist/functions/index.js +2 -2
  15. package/dist/functions/theme.d.ts +1 -1
  16. package/dist/helpers.d.ts +1 -1
  17. package/dist/helpers.js +1 -1
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.js +2 -2
  20. package/dist/parser.d.ts +1 -1
  21. package/dist/parser.js +1 -1
  22. package/dist/plugin.d.ts +1 -1
  23. package/dist/plugin.js +4 -5
  24. package/package.json +3 -1
  25. package/release.config.mjs +6 -1
  26. package/src/at-rules/color-scheme.ts +1 -1
  27. package/src/at-rules/color.ts +2 -2
  28. package/src/at-rules/container.ts +1 -1
  29. package/src/at-rules/index.ts +5 -14
  30. package/src/config.ts +2 -5
  31. package/src/errors.ts +1 -1
  32. package/src/functions/color.ts +46 -99
  33. package/src/functions/index.ts +3 -3
  34. package/src/functions/theme.ts +1 -1
  35. package/src/helpers.ts +2 -2
  36. package/src/index.ts +2 -2
  37. package/src/parser.ts +2 -2
  38. package/src/plugin.ts +4 -5
  39. package/test-import.mjs +2 -0
  40. package/tests/plugin.test.ts +36 -144
  41. package/tsconfig.json +2 -2
  42. package/dist/at-rules/conditional.d.ts +0 -6
  43. package/dist/at-rules/conditional.js +0 -29
  44. package/dist/at-rules/custom-media.d.ts +0 -15
  45. package/dist/at-rules/custom-media.js +0 -40
  46. package/dist/at-rules/mixin.d.ts +0 -10
  47. package/dist/at-rules/mixin.js +0 -37
  48. package/src/at-rules/conditional.ts +0 -34
  49. package/src/at-rules/custom-media.ts +0 -50
  50. package/src/at-rules/mixin.ts +0 -46
package/dist/parser.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { Node } from 'postcss';
2
- import { PluginContext } from './config';
2
+ import { PluginContext } from './config.js';
3
3
  export type FunctionMap = Record<string, (context: PluginContext, ...args: string[]) => string>;
4
4
  export declare function processFunctions(value: string, fnMap: FunctionMap, node: Node, context: PluginContext): string;
package/dist/parser.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import valueParser from 'postcss-value-parser';
2
- import { reportError } from './errors';
2
+ import { reportError } from './errors.js';
3
3
  export function processFunctions(value, fnMap, node, context) {
4
4
  const parsed = valueParser(value);
5
5
  // Helper to process nodes recursively (inner-first)
package/dist/plugin.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { PluginCreator } from "postcss";
2
- import { PluginOptions as ConfigOptions } from "./config";
2
+ import { PluginOptions as ConfigOptions } from "./config.js";
3
3
  export declare const dynamicFunctionsPlugin: PluginCreator<ConfigOptions>;
package/dist/plugin.js CHANGED
@@ -1,7 +1,7 @@
1
- import { functions } from "./functions";
2
- import { atRuleHandlers } from "./at-rules";
3
- import { loadConfig } from "./config";
4
- import { processFunctions } from "./parser";
1
+ import { functions } from "./functions/index.js";
2
+ import { atRuleHandlers } from "./at-rules/index.js";
3
+ import { loadConfig } from "./config.js";
4
+ import { processFunctions } from "./parser.js";
5
5
  export const dynamicFunctionsPlugin = (opts = {}) => {
6
6
  const { config, options } = loadConfig(opts);
7
7
  const fnMap = { ...functions, ...opts.functions };
@@ -9,7 +9,6 @@ export const dynamicFunctionsPlugin = (opts = {}) => {
9
9
  config,
10
10
  options,
11
11
  functions: fnMap,
12
- mixins: {},
13
12
  };
14
13
  return {
15
14
  postcssPlugin: "postcss-dynamic-functions",
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@seyuna/postcss",
3
- "version": "1.0.0-canary.15",
3
+ "version": "1.0.0-canary.17",
4
4
  "description": "Seyuna UI's postcss plugin",
5
+ "type": "module",
5
6
  "main": "dist/index.js",
6
7
  "types": "dist/index.d.ts",
7
8
  "scripts": {
@@ -36,6 +37,7 @@
36
37
  "@semantic-release/npm": "^13.1.3",
37
38
  "@semantic-release/release-notes-generator": "^14.0.3",
38
39
  "@types/node": "^20.0.0",
40
+ "conventional-changelog-conventionalcommits": "^9.1.0",
39
41
  "postcss": "^8.5.6",
40
42
  "postcss-selector-parser": "^7.1.0",
41
43
  "semantic-release": "^25.0.2",
@@ -4,7 +4,12 @@
4
4
  export default {
5
5
  branches: [{ name: "canary", prerelease: "canary" }, "main"],
6
6
  plugins: [
7
- "@semantic-release/commit-analyzer",
7
+ [
8
+ "@semantic-release/commit-analyzer",
9
+ {
10
+ preset: "conventionalcommits",
11
+ },
12
+ ],
8
13
  "@semantic-release/release-notes-generator",
9
14
  ["@semantic-release/changelog", { changelogFile: "CHANGELOG.md" }],
10
15
  [
@@ -1,5 +1,5 @@
1
1
  import { Rule, AtRule, ChildNode } from "postcss";
2
- import { PluginContext } from "../config";
2
+ import { PluginContext } from "../config.js";
3
3
 
4
4
  /**
5
5
  * Custom PostCSS plugin handler factory for `@light` and `@dark` at-rules.
@@ -1,6 +1,6 @@
1
1
  import { AtRule } from "postcss";
2
- import { PluginContext } from "../config";
3
- import { generateRules } from "../helpers";
2
+ import { PluginContext } from "../config.js";
3
+ import { generateRules } from "../helpers.js";
4
4
 
5
5
  /**
6
6
  * Handler for @each-standard-color
@@ -1,5 +1,5 @@
1
1
  import { AtRule, ChildNode } from "postcss";
2
- import { PluginContext } from "../config";
2
+ import { PluginContext } from "../config.js";
3
3
 
4
4
  /**
5
5
  * Custom PostCSS plugin handler for responsive at-rules.
@@ -1,11 +1,8 @@
1
1
  import { AtRule } from "postcss";
2
- import { eachStandardColor, eachFixedColor } from "./color";
3
- import container from "./container";
4
- import { light, dark } from "./color-scheme";
5
- import { defineMixin, applyMixin } from "./mixin";
6
- import { conditional } from "./conditional";
7
- import { resolveCustomMedia, defineCustomMedia } from "./custom-media";
8
- import { PluginContext } from "../config";
2
+ import { eachStandardColor, eachFixedColor } from "./color.js";
3
+ import container from "./container.js";
4
+ import { light, dark } from "./color-scheme.js";
5
+ import { PluginContext } from "../config.js";
9
6
 
10
7
  // Each handler has a name (matches the at-rule) and the function
11
8
  export interface AtRuleHandler {
@@ -15,12 +12,7 @@ export interface AtRuleHandler {
15
12
 
16
13
  // Ordered array ensures execution order
17
14
  export const atRuleHandlers: AtRuleHandler[] = [
18
- { name: "define-mixin", handler: defineMixin },
19
- { name: "custom-media", handler: defineCustomMedia },
20
- { name: "apply", handler: applyMixin },
21
- { name: "if", handler: conditional },
22
- { name: "media", handler: resolveCustomMedia },
23
- { name: "each-standard-color", handler: eachStandardColor }, // first
15
+ { name: "each-standard-color", handler: eachStandardColor },
24
16
  { name: "each-fixed-color", handler: eachFixedColor },
25
17
  { name: "light", handler: light },
26
18
  { name: "dark", handler: dark },
@@ -30,5 +22,4 @@ export const atRuleHandlers: AtRuleHandler[] = [
30
22
  { name: "lg", handler: container },
31
23
  { name: "xl", handler: container },
32
24
  { name: "2xl", handler: container },
33
- // add more handlers here as needed
34
25
  ];
package/src/config.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { SeyunaConfig } from './types';
4
- import { FunctionMap } from './parser';
3
+ import { SeyunaConfig } from './types.js';
4
+ import { FunctionMap } from './parser.js';
5
5
 
6
6
  export interface PluginOptions {
7
7
  configPath?: string;
@@ -11,13 +11,10 @@ export interface PluginOptions {
11
11
  functions?: FunctionMap;
12
12
  }
13
13
 
14
- import { ChildNode } from 'postcss';
15
-
16
14
  export interface PluginContext {
17
15
  config: SeyunaConfig;
18
16
  options: Required<PluginOptions>;
19
17
  functions: FunctionMap;
20
- mixins: Record<string, ChildNode[]>;
21
18
  }
22
19
 
23
20
  const DEFAULT_OPTIONS: Required<PluginOptions> = {
package/src/errors.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Node } from 'postcss';
2
- import { PluginContext } from './config';
2
+ import { PluginContext } from "./config.js";
3
3
 
4
4
  export function reportError(
5
5
  message: string,
@@ -1,61 +1,26 @@
1
- import { PluginContext } from "../config";
2
-
3
- /**
4
- * Utility to parse an oklch string and return its parts
5
- */
6
- function parseOklch(color: string) {
7
- const match = color.match(/oklch\(([^ ]+) ([^ ]+) ([^ /]+)(?: \/ ([^)]+))?\)/);
8
- if (!match) return null;
9
- return {
10
- l: match[1],
11
- c: match[2],
12
- h: match[3],
13
- a: match[4] || "1",
14
- };
15
- }
16
-
17
- export function sc(
18
- context: PluginContext,
19
- name: string,
20
- alpha?: string,
21
- lightness?: string,
22
- chroma?: string
23
- ) {
24
- let a: string = alpha && alpha !== "null" ? alpha : "1";
25
- let l: string = lightness && lightness !== "null" ? lightness : "var(--lightness)";
26
- let c: string = chroma && chroma !== "null" ? chroma : "var(--chroma)";
27
- let h: string = `var(--${name}-hue)`;
28
-
29
- return `oklch(${l} ${c} ${h} / ${a})`;
30
- }
31
-
32
- export function fc(
33
- context: PluginContext,
34
- name: string,
35
- alpha?: string,
36
- lightness?: string,
37
- chroma?: string
38
- ) {
39
- let a: string = alpha && alpha !== "null" ? alpha : "1";
40
- let l: string = lightness && lightness !== "null" ? lightness : `var(--${name}-lightness)`;
41
- let c: string = chroma && chroma !== "null" ? chroma : `var(--${name}-chroma)`;
42
- let h: string = `var(--${name}-hue)`;
43
-
44
- return `oklch(${l} ${c} ${h} / ${a})`;
45
- }
1
+ import { PluginContext } from "../config.js";
46
2
 
47
3
  /**
48
4
  * Resolves a color name to its CSS variables based on its type (standard or fixed)
49
5
  */
50
- function getColorVariables(context: PluginContext, color: string) {
6
+ function getColorVariables(context: PluginContext, color: string, type?: 'sc' | 'fc') {
51
7
  const { config } = context;
52
8
  const hues = config?.ui?.theme?.hues || {};
53
9
  const colors = config?.ui?.theme?.colors || {};
54
10
  const lightColors = config?.ui?.theme?.light?.colors || {};
55
11
  const darkColors = config?.ui?.theme?.dark?.colors || {};
56
12
 
57
- // Check if it's a standard color (sc)
58
- if (color in hues) {
13
+ const isStandard = color in hues;
14
+ const isFixed = color in colors || color in lightColors || color in darkColors;
15
+
16
+ if (type === 'sc' && !isStandard) {
17
+ throw new Error(`Standard color '${color}' not found in seyuna.json hues`);
18
+ }
19
+ if (type === 'fc' && !isFixed) {
20
+ throw new Error(`Fixed color '${color}' not found in seyuna.json colors`);
21
+ }
22
+
23
+ if (isStandard) {
59
24
  return {
60
25
  l: "var(--lightness)",
61
26
  c: "var(--chroma)",
@@ -63,8 +28,7 @@ function getColorVariables(context: PluginContext, color: string) {
63
28
  };
64
29
  }
65
30
 
66
- // Check if it's a fixed color (fc)
67
- if (color in colors || color in lightColors || color in darkColors) {
31
+ if (isFixed) {
68
32
  return {
69
33
  l: `var(--${color}-lightness)`,
70
34
  c: `var(--${color}-chroma)`,
@@ -72,72 +36,55 @@ function getColorVariables(context: PluginContext, color: string) {
72
36
  };
73
37
  }
74
38
 
75
- // Fallback to assume it's a fixed color if unknown but used as a name
76
- return {
77
- l: `var(--${color}-lightness)`,
78
- c: `var(--${color}-chroma)`,
79
- h: `var(--${color}-hue)`,
80
- };
39
+ throw new Error(`Color '${color}' not found in seyuna.json`);
81
40
  }
82
41
 
83
- export function alpha(context: PluginContext, color: string, value: string) {
84
- const parsed = parseOklch(color);
85
- if (parsed) {
86
- return `oklch(${parsed.l} ${parsed.c} ${parsed.h} / ${value})`;
87
- }
42
+ export function sc(
43
+ context: PluginContext,
44
+ name: string,
45
+ alpha?: string,
46
+ lightness?: string,
47
+ chroma?: string
48
+ ) {
49
+ const vars = getColorVariables(context, name, 'sc');
50
+ const a = alpha && alpha !== "null" ? alpha : "1";
51
+ const l = lightness && lightness !== "null" ? lightness : vars.l;
52
+ const c = chroma && chroma !== "null" ? chroma : vars.c;
88
53
 
54
+ return `oklch(${l} ${c} ${vars.h} / ${a})`;
55
+ }
56
+
57
+ export function fc(
58
+ context: PluginContext,
59
+ name: string,
60
+ alpha?: string,
61
+ lightness?: string,
62
+ chroma?: string
63
+ ) {
64
+ const vars = getColorVariables(context, name, 'fc');
65
+ const a = alpha && alpha !== "null" ? alpha : "1";
66
+ const l = lightness && lightness !== "null" ? lightness : vars.l;
67
+ const c = chroma && chroma !== "null" ? chroma : vars.c;
68
+
69
+ return `oklch(${l} ${c} ${vars.h} / ${a})`;
70
+ }
71
+
72
+ export function alpha(context: PluginContext, color: string, value: string) {
89
73
  const { l, c, h } = getColorVariables(context, color);
90
74
  return `oklch(${l} ${c} ${h} / ${value})`;
91
75
  }
92
76
 
93
77
  export function lighten(context: PluginContext, color: string, amount: string) {
94
- const parsed = parseOklch(color);
95
-
96
- if (parsed) {
97
- if (parsed.l.startsWith('var(')) {
98
- return `oklch(calc(${parsed.l} + ${amount}) ${parsed.c} ${parsed.h} / ${parsed.a})`;
99
- }
100
-
101
- const lValue = parseFloat(parsed.l);
102
- const amtValue = parseFloat(amount);
103
- return `oklch(${Math.min(1, lValue + amtValue)} ${parsed.c} ${parsed.h} / ${parsed.a})`;
104
- }
105
-
106
78
  const { l, c, h } = getColorVariables(context, color);
107
79
  return `oklch(calc(${l} + ${amount}) ${c} ${h} / 1)`;
108
80
  }
109
81
 
110
82
  export function darken(context: PluginContext, color: string, amount: string) {
111
- const parsed = parseOklch(color);
112
-
113
- if (parsed) {
114
- if (parsed.l.startsWith('var(')) {
115
- return `oklch(calc(${parsed.l} - ${amount}) ${parsed.c} ${parsed.h} / ${parsed.a})`;
116
- }
117
-
118
- const lValue = parseFloat(parsed.l);
119
- const amtValue = parseFloat(amount);
120
- return `oklch(${Math.max(0, lValue - amtValue)} ${parsed.c} ${parsed.h} / ${parsed.a})`;
121
- }
122
-
123
83
  const { l, c, h } = getColorVariables(context, color);
124
84
  return `oklch(calc(${l} - ${amount}) ${c} ${h} / 1)`;
125
85
  }
126
86
 
127
87
  export function contrast(context: PluginContext, color: string) {
128
- const parsed = parseOklch(color);
129
- let l: string;
130
-
131
- if (parsed) {
132
- l = parsed.l;
133
- } else {
134
- const vars = getColorVariables(context, color);
135
- l = vars.l;
136
- }
137
-
138
- // Dynamic CSS contrast logic:
139
- // (L - 0.6) * -1000 will be:
140
- // - very negative if L > 0.6 (clamped to 0 / black)
141
- // - very positive if L < 0.6 (clamped to 1 / white)
88
+ const { l } = getColorVariables(context, color);
142
89
  return `oklch(calc((${l} - 0.6) * -1000) 0 0)`;
143
90
  }
@@ -1,6 +1,6 @@
1
- import { sc, fc, alpha, lighten, darken, contrast } from "./color";
2
- import { theme } from "./theme";
3
- import { PluginContext } from "../config";
1
+ import { sc, fc, alpha, lighten, darken, contrast } from "./color.js";
2
+ import { theme } from "./theme.js";
3
+ import { PluginContext } from "../config.js";
4
4
 
5
5
  export type FnHandler = (context: PluginContext, ...args: string[]) => string;
6
6
 
@@ -1,4 +1,4 @@
1
- import { PluginContext } from "../config";
1
+ import { PluginContext } from "../config.js";
2
2
 
3
3
  /**
4
4
  * Accesses values from the Seyuna configuration using dot notation
package/src/helpers.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Rule, ChildNode, Declaration, AtRule } from "postcss";
2
- import { processFunctions } from "./parser";
3
- import { PluginContext } from "./config";
2
+ import { processFunctions } from "./parser.js";
3
+ import { PluginContext } from "./config.js";
4
4
 
5
5
  /**
6
6
  * Helper: clone nodes and replace {name} placeholders safely
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { dynamicFunctionsPlugin } from './plugin';
2
- import { functions } from './functions';
1
+ import { dynamicFunctionsPlugin } from './plugin.js';
2
+ import { functions } from './functions/index.js';
3
3
 
4
4
  // CommonJS-friendly export
5
5
  const plugin = Object.assign(dynamicFunctionsPlugin, {
package/src/parser.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import valueParser from 'postcss-value-parser';
2
2
  import { Node } from 'postcss';
3
- import { PluginContext } from './config';
4
- import { reportError } from './errors';
3
+ import { PluginContext } from './config.js';
4
+ import { reportError } from './errors.js';
5
5
 
6
6
  export type FunctionMap = Record<string, (context: PluginContext, ...args: string[]) => string>;
7
7
 
package/src/plugin.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { PluginCreator } from "postcss";
2
- import { functions } from "./functions";
3
- import { atRuleHandlers } from "./at-rules";
4
- import { loadConfig, PluginOptions as ConfigOptions, PluginContext } from "./config";
5
- import { processFunctions, FunctionMap } from "./parser";
2
+ import { functions } from "./functions/index.js";
3
+ import { atRuleHandlers } from "./at-rules/index.js";
4
+ import { loadConfig, PluginOptions as ConfigOptions, PluginContext } from "./config.js";
5
+ import { processFunctions, FunctionMap } from "./parser.js";
6
6
 
7
7
  export const dynamicFunctionsPlugin: PluginCreator<ConfigOptions> = (
8
8
  opts = {}
@@ -13,7 +13,6 @@ export const dynamicFunctionsPlugin: PluginCreator<ConfigOptions> = (
13
13
  config,
14
14
  options,
15
15
  functions: fnMap,
16
- mixins: {},
17
16
  };
18
17
 
19
18
  return {
@@ -0,0 +1,2 @@
1
+ import plugin from './dist/index.js';
2
+ console.log('Plugin loaded:', plugin);