@barocss/kit 0.0.2 → 0.0.3

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.d.ts CHANGED
@@ -72,6 +72,87 @@ export declare type AstNode = {
72
72
 
73
73
  export declare function atRule(name: string, params: string, nodes: AstNode[], source?: string): AstNode;
74
74
 
75
+ /**
76
+ * The structured input format for BaroCSS engine.
77
+ * Designed to be easily generated by AI models.
78
+ */
79
+ export declare type BaroJsonInput = {
80
+ /**
81
+ * The core utility to apply.
82
+ * Corresponds to the utility class name in Tailwind (e.g., 'bg-red-500', 'p-4').
83
+ */
84
+ utility: {
85
+ /**
86
+ * The utility prefix.
87
+ * @example 'bg', 'text', 'p', 'm', 'flex', 'hidden'
88
+ */
89
+ name: string;
90
+ /**
91
+ * The value of the utility.
92
+ * Optional for boolean utilities like 'flex', 'hidden'.
93
+ * @example 'red-500', '4', 'lg', '#123456'
94
+ */
95
+ value?: string;
96
+ /**
97
+ * Whether the value is an arbitrary value (JIT).
98
+ * @default false
99
+ * @example true for 'bg-[#123456]'
100
+ */
101
+ arbitrary?: boolean;
102
+ /**
103
+ * Whether the value is negative.
104
+ * @default false
105
+ * @example true for '-m-4'
106
+ */
107
+ negative?: boolean;
108
+ /**
109
+ * Opacity modifier for colors.
110
+ * @example '50' for 'bg-red-500/50'
111
+ */
112
+ opacity?: string;
113
+ /**
114
+ * Whether the value is a custom property.
115
+ * @default false
116
+ * @example true for 'bg-(--my-bg)'
117
+ */
118
+ customProperty?: boolean;
119
+ /**
120
+ * Whether the utility is marked as important (!).
121
+ * @default false
122
+ * @example true for '!bg-red-500'
123
+ */
124
+ important?: boolean;
125
+ };
126
+ /**
127
+ * List of variants/modifiers to apply.
128
+ * Applied from outside to inside (left to right in string format).
129
+ * @example ['hover', 'focus'] for 'hover:focus:bg-red-500'
130
+ */
131
+ variants?: Array<string | BaroVariant>;
132
+ };
133
+
134
+ /**
135
+ * Detailed configuration for a variant.
136
+ */
137
+ export declare type BaroVariant = {
138
+ /**
139
+ * The name of the variant.
140
+ * @example 'hover', 'focus', 'sm', 'data', 'group-hover'
141
+ */
142
+ name: string;
143
+ /**
144
+ * The value for parameterized variants.
145
+ * @example 'open' for 'data-[state=open]'
146
+ */
147
+ value?: string;
148
+ /**
149
+ * Whether the variant is arbitrary.
150
+ * @default false
151
+ * @example true for 'min-[320px]'
152
+ */
153
+ arbitrary?: boolean;
154
+ };
155
+
75
156
  /**
76
157
  * Clear all caches (for context changes or testing)
77
158
  */
@@ -407,6 +488,18 @@ export declare type AstNode = {
407
488
  dedup?: boolean;
408
489
  }): string;
409
490
 
491
+ /**
492
+ * Generates CSS from a list of BaroJsonInput objects.
493
+ *
494
+ * @param inputs Array of BaroJsonInput
495
+ * @param ctx Context
496
+ * @param opts Options (minify, etc.)
497
+ * @returns CSS string
498
+ */
499
+ export declare function generateCssFromJson(inputs: BaroJsonInput[], ctx: Context, opts?: {
500
+ minify?: boolean;
501
+ }): string;
502
+
410
503
  /**
411
504
  * Returns an array of optimized results for multiple class names with dedup/filter.
412
505
  * - Each object: { cls, ast, css }
@@ -664,6 +757,16 @@ export declare type AstNode = {
664
757
  getProcessedClasses(): string[];
665
758
  }
666
759
 
760
+ /**
761
+ * Converts a single BaroJsonInput object into an AST tree.
762
+ * Bypasses string parsing and directly invokes utility/modifier handlers.
763
+ *
764
+ * @param input BaroJsonInput object
765
+ * @param ctx Context
766
+ * @returns AstNode[]
767
+ */
768
+ export declare function jsonToAst(input: BaroJsonInput, ctx: Context): AstNode[];
769
+
667
770
  /**
668
771
  * mergeAstTreeList
669
772
  * Takes a list of declPathToAst results (AstNode[][]), merges same at-rule(name, params) etc., and returns the final AST tree.
package/dist/index.js CHANGED
@@ -2442,6 +2442,179 @@ function createContext(configObj) {
2442
2442
  };
2443
2443
  return ctx;
2444
2444
  }
2445
+ function jsonToAst(input, ctx) {
2446
+ let utilReg = getUtility().find((u) => u.name === input.utility.name);
2447
+ if (input.utility.value && !input.utility.arbitrary && !input.utility.customProperty) {
2448
+ const fullName = `${input.utility.name}-${input.utility.value}`;
2449
+ const exactMatch = getUtility().find((u) => u.name === fullName);
2450
+ if (exactMatch) {
2451
+ utilReg = exactMatch;
2452
+ }
2453
+ }
2454
+ if (!utilReg) {
2455
+ console.warn(`[jsonToAst] Unknown utility: "${input.utility.name}"`);
2456
+ return [];
2457
+ }
2458
+ const parsedUtility = {
2459
+ prefix: input.utility.name,
2460
+ value: input.utility.value,
2461
+ arbitrary: input.utility.arbitrary,
2462
+ negative: input.utility.negative,
2463
+ opacity: input.utility.opacity,
2464
+ important: input.utility.important,
2465
+ customProperty: input.utility.customProperty,
2466
+ category: utilReg.category,
2467
+ priority: utilReg.priority
2468
+ };
2469
+ let value = input.utility.value;
2470
+ if (input.utility.negative && value) {
2471
+ value = "-" + value;
2472
+ }
2473
+ let ast = utilReg.handler(value || "", ctx, parsedUtility, utilReg) || [];
2474
+ if (input.variants && input.variants.length > 0) {
2475
+ const wrappers = [];
2476
+ const selector = "&";
2477
+ for (let i = input.variants.length - 1; i >= 0; i--) {
2478
+ const variantInput = input.variants[i];
2479
+ const variantName = typeof variantInput === "string" ? variantInput : variantInput.name;
2480
+ const variantValue = typeof variantInput === "string" ? void 0 : variantInput.value;
2481
+ const variantArbitrary = typeof variantInput === "string" ? false : variantInput.arbitrary;
2482
+ const parsedModifier = {
2483
+ type: variantName,
2484
+ value: variantValue,
2485
+ arbitrary: variantArbitrary
2486
+ };
2487
+ let matchKey = variantName;
2488
+ if (variantArbitrary && variantValue) {
2489
+ if (variantName) {
2490
+ matchKey = `${variantName}-[${variantValue}]`;
2491
+ parsedModifier.type = matchKey;
2492
+ } else {
2493
+ matchKey = `[${variantValue}]`;
2494
+ parsedModifier.type = matchKey;
2495
+ }
2496
+ } else if (variantValue) {
2497
+ matchKey = `${variantName}-[${variantValue}]`;
2498
+ parsedModifier.type = matchKey;
2499
+ }
2500
+ const plugin = getModifier().find((p) => p.match(matchKey, ctx));
2501
+ if (!plugin) {
2502
+ console.warn(`[jsonToAst] Unknown variant: "${matchKey}"`);
2503
+ continue;
2504
+ }
2505
+ if (plugin.wrap) {
2506
+ const items = plugin.wrap(parsedModifier, ctx);
2507
+ wrappers.push({
2508
+ type: "wrap",
2509
+ items
2510
+ });
2511
+ continue;
2512
+ }
2513
+ if (plugin.modifySelector) {
2514
+ const result = plugin.modifySelector({
2515
+ selector,
2516
+ fullClassName: "JSON_GENERATED",
2517
+ // Placeholder
2518
+ mod: parsedModifier,
2519
+ context: ctx,
2520
+ variantChain: [],
2521
+ // We might need to pass the full chain if needed
2522
+ index: i
2523
+ });
2524
+ if (typeof result === "string" && result.includes("&")) {
2525
+ wrappers.push({ type: "rule", selector: result });
2526
+ } else if (typeof result === "object" && !Array.isArray(result) && result.selector) {
2527
+ const r = result;
2528
+ const wrappingType = r.wrappingType || "rule";
2529
+ wrappers.push({
2530
+ type: wrappingType,
2531
+ selector: r.selector,
2532
+ flatten: r.flatten,
2533
+ source: r.source
2534
+ });
2535
+ } else if (Array.isArray(result)) {
2536
+ wrappers.push({
2537
+ type: "wrap",
2538
+ items: result.map((r) => ({
2539
+ type: r.wrappingType || "rule",
2540
+ selector: r.selector,
2541
+ source: r.source,
2542
+ nodes: []
2543
+ // Placeholder, will be filled when wrapping
2544
+ }))
2545
+ });
2546
+ }
2547
+ }
2548
+ }
2549
+ for (let i = 0; i < wrappers.length; i++) {
2550
+ const wrap = wrappers[i];
2551
+ if (wrap.type === "wrap") {
2552
+ ast = wrap.items.map((item) => ({
2553
+ ...item,
2554
+ nodes: Array.isArray(ast) ? ast : [ast]
2555
+ }));
2556
+ } else if (wrap.type === "style-rule") {
2557
+ ast = [
2558
+ {
2559
+ type: "style-rule",
2560
+ selector: wrap.selector,
2561
+ source: wrap.source,
2562
+ nodes: Array.isArray(ast) ? ast : [ast]
2563
+ }
2564
+ ];
2565
+ } else if (wrap.type === "at-rule") {
2566
+ ast = [
2567
+ {
2568
+ type: "at-rule",
2569
+ name: wrap.name || "media",
2570
+ params: wrap.params,
2571
+ source: wrap.source,
2572
+ nodes: Array.isArray(ast) ? ast : [ast]
2573
+ }
2574
+ ];
2575
+ } else if (wrap.type === "rule") {
2576
+ ast = [
2577
+ {
2578
+ type: "rule",
2579
+ selector: wrap.selector,
2580
+ source: wrap.source,
2581
+ nodes: Array.isArray(ast) ? ast : [ast]
2582
+ }
2583
+ ];
2584
+ }
2585
+ }
2586
+ }
2587
+ return ast;
2588
+ }
2589
+ function generateCssFromJson(inputs, ctx, opts) {
2590
+ const allAtRootNodes = [];
2591
+ const cssList = [];
2592
+ inputs.forEach((input) => {
2593
+ const ast = jsonToAst(input, ctx);
2594
+ const cleanAst = optimizeAst(ast);
2595
+ cleanAst.forEach((node) => {
2596
+ if (node.type === "at-root") {
2597
+ allAtRootNodes.push(...node.nodes);
2598
+ }
2599
+ });
2600
+ let reconstructedName = input.utility.name;
2601
+ if (input.utility.value) reconstructedName += `-${input.utility.value}`;
2602
+ if (input.utility.arbitrary) reconstructedName = `${input.utility.name}-[${input.utility.value}]`;
2603
+ if (input.variants) {
2604
+ const variantsStr = input.variants.map((v) => typeof v === "string" ? v : v.name).join(":");
2605
+ reconstructedName = `${variantsStr}:${reconstructedName}`;
2606
+ }
2607
+ const hasStyleRule = cleanAst.some((node) => node.type === "style-rule");
2608
+ const css = astToCss(cleanAst, hasStyleRule ? void 0 : `.${reconstructedName.replace(/[^a-zA-Z0-9-_]/g, "\\$&")}`, {
2609
+ minify: opts?.minify,
2610
+ important: input.utility.important ?? false
2611
+ });
2612
+ if (css) cssList.push(css);
2613
+ });
2614
+ const rootCss = rootToCss(allAtRootNodes);
2615
+ const finalCss = `${rootCss ? `:root,:host {${rootCss}}` : ""}${cssList.join(opts?.minify ? "" : "\n")}`;
2616
+ return finalCss;
2617
+ }
2445
2618
  function parseFraction(input) {
2446
2619
  if (input.includes("/")) {
2447
2620
  const [num, denom] = input.split("/").map(Number);
@@ -7735,11 +7908,13 @@ export {
7735
7908
  functionalModifier,
7736
7909
  functionalUtility,
7737
7910
  generateCss,
7911
+ generateCssFromJson,
7738
7912
  generateCssRules,
7739
7913
  getModifier,
7740
7914
  getPreflightCSS,
7741
7915
  getUtility,
7742
7916
  hasPreset,
7917
+ jsonToAst,
7743
7918
  mergeAstTreeList,
7744
7919
  modifierRegistry,
7745
7920
  optimizeAst,