@seyuna/postcss 1.0.0-canary.37 → 1.0.0-canary.39

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 (54) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +444 -156
  3. package/dist/at-rules/color-scheme.d.ts +3 -2
  4. package/dist/at-rules/color-scheme.js +6 -7
  5. package/dist/at-rules/color.d.ts +5 -4
  6. package/dist/at-rules/color.js +5 -4
  7. package/dist/at-rules/config.d.ts +2 -1
  8. package/dist/at-rules/config.js +44 -13
  9. package/dist/at-rules/container.d.ts +2 -1
  10. package/dist/at-rules/container.js +4 -6
  11. package/dist/at-rules/import.d.ts +3 -2
  12. package/dist/at-rules/import.js +107 -139
  13. package/dist/at-rules/index.d.ts +2 -1
  14. package/dist/at-rules/index.js +3 -4
  15. package/dist/config.js +70 -28
  16. package/dist/errors.d.ts +3 -5
  17. package/dist/errors.js +2 -4
  18. package/dist/functions/color.d.ts +4 -4
  19. package/dist/functions/color.js +4 -4
  20. package/dist/functions/index.js +5 -7
  21. package/dist/helpers.d.ts +4 -6
  22. package/dist/helpers.js +26 -22
  23. package/dist/index.d.ts +8 -1
  24. package/dist/index.js +1 -0
  25. package/dist/parser.js +36 -49
  26. package/dist/plugin.d.ts +3 -1
  27. package/dist/plugin.js +15 -19
  28. package/dist/types.d.ts +6 -1
  29. package/dist/types.js +0 -2
  30. package/package.json +20 -3
  31. package/.github/workflows/release.yml +0 -41
  32. package/.vscode/settings.json +0 -4
  33. package/dist/functions/theme.d.ts +0 -6
  34. package/dist/functions/theme.js +0 -17
  35. package/release.config.mjs +0 -37
  36. package/src/at-rules/color-scheme.ts +0 -54
  37. package/src/at-rules/color.ts +0 -33
  38. package/src/at-rules/config.ts +0 -78
  39. package/src/at-rules/container.ts +0 -58
  40. package/src/at-rules/import.ts +0 -196
  41. package/src/at-rules/index.ts +0 -29
  42. package/src/config.ts +0 -98
  43. package/src/errors.ts +0 -27
  44. package/src/functions/color.ts +0 -123
  45. package/src/functions/index.ts +0 -22
  46. package/src/functions/theme.ts +0 -20
  47. package/src/helpers.ts +0 -75
  48. package/src/index.ts +0 -10
  49. package/src/parser.ts +0 -81
  50. package/src/plugin.ts +0 -58
  51. package/src/styles/seyuna-global.css +0 -94
  52. package/src/types.ts +0 -71
  53. package/tests/plugin.test.ts +0 -244
  54. package/tsconfig.json +0 -14
package/dist/errors.d.ts CHANGED
@@ -1,6 +1,4 @@
1
+ import type { Node } from "postcss";
1
2
  import { PluginContext } from "./types.js";
2
- export declare function reportError(message: string, node: any, context: PluginContext, options?: {
3
- word?: string;
4
- index?: number;
5
- }): void;
6
- export declare function reportWarning(message: string, node: any, context?: PluginContext): void;
3
+ export declare function reportError(message: string, node: Node, context: PluginContext): void;
4
+ export declare function reportWarning(message: string, node: Node, context?: PluginContext): void;
package/dist/errors.js CHANGED
@@ -1,7 +1,5 @@
1
- export function reportError(message, node, context, options = {}) {
2
- const { options: pluginOptions } = context;
3
- const formattedMessage = `[Seyuna PostCSS] ${message}`;
4
- reportWarning(formattedMessage, node, context);
1
+ export function reportError(message, node, context) {
2
+ reportWarning(message, node, context);
5
3
  }
6
4
  export function reportWarning(message, node, context) {
7
5
  if (context?.result) {
@@ -1,7 +1,7 @@
1
1
  import { PluginContext } from "../types.js";
2
- export declare function SeyunaStandardColor(context: PluginContext, name: string, alpha?: string, lightness?: string, chroma?: string): string;
3
- export declare function SeyunaFixedColor(context: PluginContext, name: string, alpha?: string, lightness?: string, chroma?: string): string;
2
+ export declare function SeyunaTone(context: PluginContext, name: string, alpha?: string, lightness?: string, chroma?: string): string;
3
+ export declare function SeyunaSwatch(context: PluginContext, name: string, alpha?: string, lightness?: string, chroma?: string): string;
4
4
  export declare function SeyunaAlpha(context: PluginContext, color: string, value: string): string;
5
- export declare function SeyunaLighten(context: PluginContext, color: string, amount: string): string;
6
- export declare function SeyunaDarken(context: PluginContext, color: string, amount: string): string;
5
+ export declare function SeyunaTint(context: PluginContext, color: string, amount: string): string;
6
+ export declare function SeyunaShade(context: PluginContext, color: string, amount: string): string;
7
7
  export declare function SeyunaContrast(context: PluginContext, color: string): string;
@@ -47,14 +47,14 @@ function getColorVariables(context, color, type) {
47
47
  h: `var(--${color}-hue)`,
48
48
  };
49
49
  }
50
- export function SeyunaStandardColor(context, name, alpha, lightness, chroma) {
50
+ export function SeyunaTone(context, name, alpha, lightness, chroma) {
51
51
  const vars = getColorVariables(context, name, "sc");
52
52
  const a = alpha && alpha !== "null" ? alpha : "1";
53
53
  const l = lightness && lightness !== "null" ? lightness : vars.l;
54
54
  const c = chroma && chroma !== "null" ? chroma : vars.c;
55
55
  return `oklch(${l} ${c} ${vars.h} / ${a})`;
56
56
  }
57
- export function SeyunaFixedColor(context, name, alpha, lightness, chroma) {
57
+ export function SeyunaSwatch(context, name, alpha, lightness, chroma) {
58
58
  const vars = getColorVariables(context, name, "fc");
59
59
  const a = alpha && alpha !== "null" ? alpha : "1";
60
60
  const l = lightness && lightness !== "null" ? lightness : vars.l;
@@ -65,11 +65,11 @@ export function SeyunaAlpha(context, color, value) {
65
65
  const { l, c, h } = getColorVariables(context, color);
66
66
  return `oklch(${l} ${c} ${h} / ${value})`;
67
67
  }
68
- export function SeyunaLighten(context, color, amount) {
68
+ export function SeyunaTint(context, color, amount) {
69
69
  const { l, c, h } = getColorVariables(context, color);
70
70
  return `oklch(calc(${l} + ${amount}) ${c} ${h} / 1)`;
71
71
  }
72
- export function SeyunaDarken(context, color, amount) {
72
+ export function SeyunaShade(context, color, amount) {
73
73
  const { l, c, h } = getColorVariables(context, color);
74
74
  return `oklch(calc(${l} - ${amount}) ${c} ${h} / 1)`;
75
75
  }
@@ -1,11 +1,9 @@
1
- import { SeyunaStandardColor, SeyunaFixedColor, SeyunaAlpha, SeyunaLighten, SeyunaDarken, SeyunaContrast, } from "./color.js";
2
- import { SeyunaTheme } from "./theme.js";
1
+ import { SeyunaTone, SeyunaSwatch, SeyunaAlpha, SeyunaTint, SeyunaShade, SeyunaContrast, } from "./color.js";
3
2
  export const functions = {
4
- SeyunaStandardColor,
5
- SeyunaFixedColor,
3
+ SeyunaTone,
4
+ SeyunaSwatch,
6
5
  SeyunaAlpha,
7
- SeyunaLighten,
8
- SeyunaDarken,
6
+ SeyunaTint,
7
+ SeyunaShade,
9
8
  SeyunaContrast,
10
- SeyunaTheme,
11
9
  };
package/dist/helpers.d.ts CHANGED
@@ -1,13 +1,11 @@
1
- import Rule from "postcss/lib/rule";
2
- import { PluginContext } from './types.js';
1
+ import { type AtRule, type ChildNode } from "postcss";
2
+ import { PluginContext } from "./types.js";
3
3
  /**
4
4
  * Helper: clone nodes and replace {name} placeholders safely
5
5
  * Returns only valid Rules or Declarations (never raw AtRules)
6
6
  */
7
- export declare function cloneNodes(nodes: any[], // ChildNode[]
8
- name: string, context: PluginContext): any[];
7
+ export declare function cloneNodes(nodes: ChildNode[], name: string, context: PluginContext): ChildNode[];
9
8
  /**
10
9
  * Generate CSS rules from a list of names
11
10
  */
12
- export declare function generateRules(names: string[], atRule: any, // AtRule
13
- context: PluginContext): Rule[];
11
+ export declare function generateRules(names: string[], atRule: AtRule, context: PluginContext): ChildNode[];
package/dist/helpers.js CHANGED
@@ -1,18 +1,22 @@
1
- import Rule from "postcss/lib/rule";
2
- // import type { ChildNode, Declaration, AtRule } from "postcss";
1
+ import postcss from "postcss";
3
2
  import { processFunctions } from "./parser.js";
3
+ function getSelectorTemplate(params) {
4
+ const trimmed = params.trim();
5
+ if (!trimmed)
6
+ return undefined;
7
+ return trimmed.replace(/^['"]|['"]$/g, "");
8
+ }
4
9
  /**
5
10
  * Helper: clone nodes and replace {name} placeholders safely
6
11
  * Returns only valid Rules or Declarations (never raw AtRules)
7
12
  */
8
- export function cloneNodes(nodes, // ChildNode[]
9
- name, context) {
13
+ export function cloneNodes(nodes, name, context) {
10
14
  const { functions: fnMap } = context;
11
15
  return nodes.flatMap((node) => {
12
16
  const cloned = node.clone();
13
17
  if (cloned.type === "decl") {
14
- const decl = cloned; // Declaration
15
- let value = decl.value.replace(/\{name\}/g, name);
18
+ const decl = cloned;
19
+ const value = decl.value.replace(/\{name\}/g, name);
16
20
  // Process functions using the robust parser
17
21
  decl.value = processFunctions(value, fnMap, decl, context);
18
22
  return decl;
@@ -35,23 +39,23 @@ name, context) {
35
39
  /**
36
40
  * Generate CSS rules from a list of names
37
41
  */
38
- export function generateRules(names, atRule, // AtRule
39
- context) {
42
+ export function generateRules(names, atRule, context) {
40
43
  const nodes = atRule.nodes ?? [];
41
- const generatedRules = [];
44
+ const generatedNodes = [];
45
+ const selectorTemplate = getSelectorTemplate(atRule.params);
42
46
  for (const name of names) {
43
- const rule = new Rule({
44
- selector: `&.${name}`,
45
- source: atRule.source,
46
- });
47
- cloneNodes(nodes, name, context).forEach((n) => {
48
- if (n.type === "rule" && n.selector && n.nodes?.length)
49
- rule.append(n);
50
- if (n.type === "decl")
51
- rule.append(n);
52
- });
53
- if (rule.nodes.length)
54
- generatedRules.push(rule);
47
+ const clonedNodes = cloneNodes(nodes, name, context);
48
+ const topLevelRules = clonedNodes.filter((node) => node.type === "rule");
49
+ const topLevelDecls = clonedNodes.filter((node) => node.type === "decl");
50
+ generatedNodes.push(...topLevelRules);
51
+ if (topLevelDecls.length > 0) {
52
+ const rule = postcss.rule({
53
+ selector: (selectorTemplate ?? `&.${name}`).replace(/\{name\}/g, name),
54
+ source: atRule.source,
55
+ });
56
+ rule.append(...topLevelDecls);
57
+ generatedNodes.push(rule);
58
+ }
55
59
  }
56
- return generatedRules;
60
+ return generatedNodes;
57
61
  }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,9 @@
1
- declare const plugin: any;
1
+ import { dynamicFunctionsPlugin } from './plugin.js';
2
+ import { functions } from './functions/index.js';
3
+ declare const plugin: import("postcss").PluginCreator<import("./types.js").PluginOptions> & {
4
+ postcss: boolean;
5
+ functions: Record<string, import("./functions/index.js").FnHandler>;
6
+ };
2
7
  export default plugin;
8
+ export { dynamicFunctionsPlugin, functions };
9
+ export type { Color, Palette, Theme, Mode, UI, SeyunaConfig, FunctionMap, PluginOptions, PluginContext, } from "./types.js";
package/dist/index.js CHANGED
@@ -6,3 +6,4 @@ const plugin = Object.assign(dynamicFunctionsPlugin, {
6
6
  functions
7
7
  });
8
8
  export default plugin;
9
+ export { dynamicFunctionsPlugin, functions };
package/dist/parser.js CHANGED
@@ -2,58 +2,45 @@ import valueParser from 'postcss-value-parser';
2
2
  import { reportError } from './errors.js';
3
3
  export function processFunctions(value, fnMap, node, context) {
4
4
  const parsed = valueParser(value);
5
- // Helper to process nodes recursively (inner-first)
6
- function processNode(parsedValue) {
7
- parsedValue.walk((nodeIter) => {
8
- // If nested nodes exist (e.g., in a function), process them first
9
- if (nodeIter.type === 'function' && nodeIter.nodes.length > 0) {
10
- // Here we recursively process child nodes before handling the current function
11
- // However, value-parser's walk is already a visitor. To do inner-first,
12
- // we can either walk in reverse or specifically handle children.
13
- // A simpler way: since walk visits all, we can check if it's a function
14
- // and if it's one we handle, we process its arguments.
5
+ function splitArgs(nodes) {
6
+ const args = [];
7
+ let currentArg = "";
8
+ for (const argNode of nodes) {
9
+ if (argNode.type === "div" && argNode.value === ",") {
10
+ args.push(currentArg.trim());
11
+ currentArg = "";
12
+ continue;
15
13
  }
16
- });
17
- // Actually, a manual walk is safer for inner-first replacement
18
- function traverse(nodes) {
19
- for (const nodeIter of nodes) {
20
- if (nodeIter.type === 'function') {
21
- // Process inner functions first
22
- traverse(nodeIter.nodes);
23
- // Now handle this function if it's in our map
24
- if (fnMap[nodeIter.value]) {
25
- const handler = fnMap[nodeIter.value];
26
- const args = [];
27
- let currentArg = '';
28
- nodeIter.nodes.forEach((argNode) => {
29
- if (argNode.type === 'div' && argNode.value === ',') {
30
- args.push(currentArg.trim());
31
- currentArg = '';
32
- }
33
- else {
34
- currentArg += valueParser.stringify(argNode);
35
- }
36
- });
37
- if (currentArg) {
38
- args.push(currentArg.trim());
39
- }
40
- const cleanedArgs = args.map(arg => arg.replace(/^['"]|['"]$/g, ''));
41
- try {
42
- const result = handler(context, ...cleanedArgs);
43
- // Replace function with its result
44
- nodeIter.type = 'word';
45
- nodeIter.value = result;
46
- nodeIter.nodes = []; // Clear children
47
- }
48
- catch (error) {
49
- reportError(`Failed to process function "${nodeIter.value}": ${error instanceof Error ? error.message : String(error)}`, node, context);
50
- }
51
- }
52
- }
14
+ currentArg += valueParser.stringify(argNode);
15
+ }
16
+ if (currentArg.trim() || nodes.length > 0) {
17
+ args.push(currentArg.trim());
18
+ }
19
+ return args.map((arg) => arg.replace(/^['"]|['"]$/g, ""));
20
+ }
21
+ function traverse(nodes) {
22
+ for (const nodeIter of nodes) {
23
+ if (nodeIter.type !== "function") {
24
+ continue;
25
+ }
26
+ traverse(nodeIter.nodes);
27
+ const handler = fnMap[nodeIter.value];
28
+ if (!handler) {
29
+ continue;
30
+ }
31
+ const functionName = nodeIter.value;
32
+ try {
33
+ const result = handler(context, ...splitArgs(nodeIter.nodes));
34
+ const replacementNode = nodeIter;
35
+ replacementNode.type = "word";
36
+ replacementNode.value = result;
37
+ replacementNode.nodes = [];
38
+ }
39
+ catch (error) {
40
+ reportError(`Failed to process function "${functionName}": ${error instanceof Error ? error.message : String(error)}`, node, context);
53
41
  }
54
42
  }
55
- traverse(parsedValue.nodes);
56
43
  }
57
- processNode(parsed);
44
+ traverse(parsed.nodes);
58
45
  return parsed.toString();
59
46
  }
package/dist/plugin.d.ts CHANGED
@@ -1 +1,3 @@
1
- export declare const dynamicFunctionsPlugin: any;
1
+ import type { PluginCreator } from "postcss";
2
+ import { PluginOptions } from "./types.js";
3
+ export declare const dynamicFunctionsPlugin: PluginCreator<PluginOptions>;
package/dist/plugin.js CHANGED
@@ -1,4 +1,3 @@
1
- // import type { PluginCreator } from "postcss";
2
1
  import { functions } from "./functions/index.js";
3
2
  import { atRuleHandlers } from "./at-rules/index.js";
4
3
  import { loadConfigAsync } from "./config.js";
@@ -7,40 +6,37 @@ export const dynamicFunctionsPlugin = (opts = {}) => {
7
6
  let context;
8
7
  let fnMap;
9
8
  return {
10
- postcssPlugin: "postcss-dynamic-functions",
9
+ postcssPlugin: "@seyuna/postcss",
11
10
  async Once() {
12
- try {
13
- const { config, options } = await loadConfigAsync(opts);
14
- fnMap = { ...functions, ...opts.functions };
15
- context = {
16
- config,
17
- options,
18
- functions: fnMap,
19
- result: undefined
20
- };
21
- }
22
- catch (e) {
23
- throw e;
24
- }
11
+ const { config, options } = await loadConfigAsync(opts);
12
+ fnMap = { ...functions, ...(opts.functions ?? {}) };
13
+ context = {
14
+ config,
15
+ options,
16
+ functions: fnMap,
17
+ result: undefined,
18
+ state: {
19
+ hasInjectedSeyuna: false,
20
+ },
21
+ };
25
22
  },
26
23
  Declaration(decl, { result }) {
27
24
  if (!context || !fnMap)
28
25
  return;
29
- // Update context with the current result object
30
26
  context.result = result;
31
27
  const newValue = processFunctions(decl.value, fnMap, decl, context);
32
28
  if (newValue !== decl.value) {
33
29
  decl.value = newValue;
34
30
  }
35
31
  },
36
- // Override AtRule handler to ensure ordered execution
37
- AtRule(atRule) {
32
+ AtRule(atRule, { result }) {
38
33
  if (!context)
39
34
  return;
40
- // Iterate over handlers in order (array) instead of object spread
35
+ context.result = result;
41
36
  for (const { name, handler } of atRuleHandlers) {
42
37
  if (atRule.name === name) {
43
38
  handler(atRule, context);
39
+ break;
44
40
  }
45
41
  }
46
42
  },
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { Result } from "postcss";
1
2
  /**
2
3
  * Represents a color in the Oklch color space.
3
4
  */
@@ -24,6 +25,7 @@ export interface Theme {
24
25
  colors: Record<string, Color>;
25
26
  light: Palette;
26
27
  dark: Palette;
28
+ breakpoints?: Record<string, string>;
27
29
  }
28
30
  /**
29
31
  * Supported color appearance modes.
@@ -53,5 +55,8 @@ export interface PluginContext {
53
55
  modeAttribute: string;
54
56
  };
55
57
  functions: FunctionMap;
56
- result?: any;
58
+ result?: Result;
59
+ state: {
60
+ hasInjectedSeyuna: boolean;
61
+ };
57
62
  }
package/dist/types.js CHANGED
@@ -1,3 +1 @@
1
- // Local type definitions to avoid @seyuna/cli runtime import
2
- // The @seyuna/cli package imports Deno polyfills that conflict with Vite/Astro
3
1
  export {};
package/package.json CHANGED
@@ -1,10 +1,22 @@
1
1
  {
2
2
  "name": "@seyuna/postcss",
3
- "version": "1.0.0-canary.37",
4
- "description": "Seyuna UI's postcss plugin",
3
+ "version": "1.0.0-canary.39",
4
+ "description": "PostCSS design system compiler for Seyuna's theme-aware OKLCH tokens and at-rules",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "CHANGELOG.md"
19
+ ],
8
20
  "scripts": {
9
21
  "build": "tsc && mkdir -p dist/styles && cp src/styles/* dist/styles/",
10
22
  "dev": "tsc -w",
@@ -14,7 +26,12 @@
14
26
  "keywords": [
15
27
  "postcss",
16
28
  "plugin",
17
- "seyuna"
29
+ "seyuna",
30
+ "design-system",
31
+ "oklch",
32
+ "theming",
33
+ "container-queries",
34
+ "design-tokens"
18
35
  ],
19
36
  "license": "MIT",
20
37
  "repository": {
@@ -1,41 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- - canary
8
-
9
- permissions:
10
- contents: write
11
- issues: write
12
- pull-requests: write
13
- id-token: write
14
-
15
- jobs:
16
- release:
17
- name: Semantic Release
18
- runs-on: ubuntu-latest
19
- steps:
20
- - uses: actions/checkout@v4
21
- with:
22
- fetch-depth: 0
23
-
24
- - name: Setup Node.js with npm auth
25
- uses: actions/setup-node@v4
26
- with:
27
- node-version: 22
28
- registry-url: https://registry.npmjs.org/
29
- scope: "@seyuna"
30
- always-auth: true
31
- env:
32
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
33
-
34
- - name: Install dependencies
35
- run: npm ci
36
-
37
- - name: Run Semantic Release
38
- env:
39
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
41
- run: npx semantic-release
@@ -1,4 +0,0 @@
1
- {
2
- "editor.formatOnSave": true,
3
- "editor.defaultFormatter": "esbenp.prettier-vscode"
4
- }
@@ -1,6 +0,0 @@
1
- import { PluginContext } from "../types.js";
2
- /**
3
- * Accesses values from the Seyuna configuration using dot notation
4
- * Example: theme(ui.theme.breakpoints.tablet)
5
- */
6
- export declare function SeyunaTheme(context: PluginContext, path: string): string;
@@ -1,17 +0,0 @@
1
- /**
2
- * Accesses values from the Seyuna configuration using dot notation
3
- * Example: theme(ui.theme.breakpoints.tablet)
4
- */
5
- export function SeyunaTheme(context, path) {
6
- const parts = path.split('.');
7
- let current = context.config;
8
- for (const part of parts) {
9
- if (current && typeof current === 'object' && part in current) {
10
- current = current[part];
11
- }
12
- else {
13
- return path; // Return original path if not found
14
- }
15
- }
16
- return String(current);
17
- }
@@ -1,37 +0,0 @@
1
- /**
2
- * @type {import('semantic-release').GlobalConfig}
3
- */
4
- export default {
5
- branches: [{ name: "canary", prerelease: "canary" }, "main"],
6
- plugins: [
7
- [
8
- "@semantic-release/commit-analyzer",
9
- {
10
- preset: "conventionalcommits",
11
- },
12
- ],
13
- "@semantic-release/release-notes-generator",
14
- ["@semantic-release/changelog", { changelogFile: "CHANGELOG.md" }],
15
- [
16
- "@semantic-release/exec", // Runs build before publishing
17
- {
18
- prepareCmd: "npm run build",
19
- },
20
- ],
21
- [
22
- "@semantic-release/npm", // Publishes to npm
23
- {
24
- npmPublish: true,
25
- },
26
- ],
27
- [
28
- "@semantic-release/git", // Commits updated files
29
- {
30
- assets: ["package.json", "package-lock.json", "CHANGELOG.md"],
31
- message:
32
- "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
33
- },
34
- ],
35
- "@semantic-release/github", // Creates GitHub release
36
- ],
37
- };
@@ -1,54 +0,0 @@
1
- import Rule from "postcss/lib/rule";
2
- import AtRule from "postcss/lib/at-rule";
3
- // import type { ChildNode } from "postcss";
4
- import { PluginContext } from "../types.js";
5
-
6
- /**
7
- * Custom PostCSS plugin handler factory for `@light` and `@dark` at-rules.
8
- */
9
- function createColorSchemeHandler(scheme: 'light' | 'dark') {
10
- return (atRule: any, context: PluginContext) => {
11
- const { options } = context;
12
- const modeAttribute = options.modeAttribute;
13
- const clonedNodes: any[] = [];
14
-
15
- // Clone all child nodes inside the block
16
- atRule.each((node: any) => {
17
- clonedNodes.push(node.clone());
18
- });
19
-
20
- /**
21
- * Rule 1: [data-mode="scheme"] & { ... } (Explicit mode)
22
- */
23
- const explicitRule = new Rule({
24
- selector: `[${modeAttribute}="${scheme}"] &`,
25
- source: atRule.source,
26
- });
27
- clonedNodes.forEach((node) => explicitRule.append(node.clone()));
28
-
29
- /**
30
- * Rule 2: @media (prefers-color-scheme: scheme) { [data-mode="system"] & { ... } } (System preference)
31
- */
32
- const mediaAtRule = new AtRule({
33
- name: "media",
34
- params: `(prefers-color-scheme: ${scheme})`,
35
- source: atRule.source,
36
- });
37
-
38
- const systemRule = new Rule({
39
- selector: `[${modeAttribute}="system"] &`,
40
- source: atRule.source,
41
- });
42
- clonedNodes.forEach((node) => systemRule.append(node.clone()));
43
-
44
- mediaAtRule.append(systemRule);
45
-
46
- /**
47
- * Replace the original at-rule with the generated rules.
48
- */
49
- atRule.replaceWith(mediaAtRule, explicitRule);
50
- };
51
- }
52
-
53
- export const light = createColorSchemeHandler('light');
54
- export const dark = createColorSchemeHandler('dark');
@@ -1,33 +0,0 @@
1
- // import type { AtRule } from "postcss";
2
- import { PluginContext } from "../types.js";
3
- import { generateRules } from "../helpers.js";
4
-
5
- /**
6
- * Handler for @each-standard-color
7
- */
8
- export function eachStandardColor(atRule: any, context: PluginContext) {
9
- const { config } = context;
10
- const hueNames = config.ui ? Object.keys(config.ui.theme.hues) : [];
11
-
12
- const rules = generateRules(hueNames, atRule, context);
13
- if (rules.length) atRule.replaceWith(...rules);
14
- else atRule.remove();
15
- }
16
-
17
- /**
18
- * Handler for @each-fixed-color
19
- */
20
- export function eachFixedColor(atRule: any, context: PluginContext) {
21
- const { config } = context;
22
-
23
- const mergedNames = [
24
- ...new Set([
25
- ...(config.ui ? Object.keys(config.ui.theme.light.colors) : []),
26
- ...(config.ui ? Object.keys(config.ui.theme.dark.colors) : []),
27
- ]),
28
- ];
29
-
30
- const rules = generateRules(mergedNames, atRule, context);
31
- if (rules.length) atRule.replaceWith(...rules);
32
- else atRule.remove();
33
- }