@aihu/css-engine 0.2.4 → 0.3.0
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/README.md +129 -24
- package/crates/aihu-css-core/src/emit.rs +87 -8
- package/crates/aihu-css-core/src/lib.rs +5 -0
- package/crates/aihu-css-core/src/theme.rs +14 -0
- package/crates/aihu-css-core/src/tokens.rs +579 -8
- package/crates/aihu-css-core/src/variants.rs +101 -0
- package/crates/aihu-css-core/tests/emit.rs +208 -0
- package/crates/aihu-css-core/tests/scoped_snapshot.rs +35 -1
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_animate_spin_hoists_keyframes.snap +25 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_divide_y_nested_rule.snap +23 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_space_y_nested_rule.snap +23 -0
- package/crates/aihu-css-core/tests/snapshots/scoped_snapshot__scoped_transition_and_transform.snap +26 -0
- package/crates/aihu-css-core/tests/tokens.rs +474 -7
- package/dist/index.js +3 -19
- package/dist/index.js.map +1 -1
- package/dist/runtime/cn.js +13 -0
- package/dist/runtime/cn.js.map +1 -1
- package/package.json +2 -2
package/dist/runtime/cn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cn.js","names":[],"sources":["../../src/runtime/cn-conflict-map.generated.ts","../../src/runtime/cn.ts"],"sourcesContent":["// AUTO-GENERATED by scripts/gen-cn-conflict-map.ts — DO NOT EDIT.\n// Source of truth: aihu-css-core `tokens::conflict_groups()` (the utility\n// registry). Regenerate with `bun run gen:cn-map`. Hand-edits will be lost.\n//\n// Maps a utility class PREFIX to the CSS property group it controls. Two\n// classes conflict (last wins) when they resolve to the same group.\n\n/** Prefix → conflict-group key, sorted longest-prefix-first. */\nexport const CONFLICT_GROUPS: Record<string, string> = {\n outline: 'outline-color',\n opacity: 'opacity',\n rounded: 'border-radius',\n border: 'border-color',\n stroke: 'stroke',\n shadow: 'box-shadow',\n 'gap-x': 'column-gap',\n 'gap-y': 'row-gap',\n 'min-w': 'min-width',\n 'max-w': 'max-width',\n 'min-h': 'min-height',\n 'max-h': 'max-height',\n text: 'color',\n fill: 'fill',\n ring: '--tw-ring-color',\n font: 'font-weight',\n gap: 'gap',\n px: 'padding-inline',\n py: 'padding-block',\n pt: 'padding-top',\n pr: 'padding-right',\n pb: 'padding-bottom',\n pl: 'padding-left',\n mx: 'margin-inline',\n my: 'margin-block',\n mt: 'margin-top',\n mr: 'margin-right',\n mb: 'margin-bottom',\n ml: 'margin-left',\n bg: 'background-color',\n p: 'padding',\n m: 'margin',\n w: 'width',\n h: 'height',\n z: 'z-index',\n}\n","/**\n * `@aihu/css-engine/runtime/cn` — the class-merge runtime helper (Plan 3 Task 9).\n *\n * `cn(...inputs)` merges class strings / arrays / conditionals into a single\n * deduplicated class string, resolving Tailwind-style conflicts last-wins per\n * property group (`cn('p-2', 'p-4')` → `'p-4'`).\n *\n * The conflict map (`CONFLICT_GROUPS`) is GENERATED at engine build time from\n * the utility registry (`scripts/gen-cn-conflict-map.ts` → Rust\n * `tokens::conflict_groups()`), NOT hand-maintained — so it never drifts from\n * the utility table. Separate < 1 KB gz sub-export from `runtime/progressive`\n * (Risk #4 size-split).\n *\n * This is the runtime-merge helper for consumer-provided overrides (spec §9.3):\n * recipes use static utility strings at compile time; `cn()` is only for the\n * runtime override case.\n */\nimport { CONFLICT_GROUPS } from './cn-conflict-map.generated.ts'\n\n/** A class value: string, falsy (dropped), or a nested array of the same. */\nexport type ClassValue = string | number | null | undefined | false | ClassValue[]\n\n/** Flatten the (possibly nested / conditional) inputs into a token list. */\nfunction tokens(inputs: ClassValue[], out: string[]): void {\n for (const input of inputs) {\n if (!input) continue\n if (Array.isArray(input)) {\n tokens(input, out)\n } else {\n for (const t of String(input).split(' ')) {\n if (t) out.push(t)\n }\n }\n }\n}\n\n/**\n * The conflict-group key for a class, or the class itself when it belongs to no\n * known group (so unrelated classes always coexist). Strips variant prefixes\n * (`md:`, `hover:`, …) so `hover:p-2` and `hover:p-4` still conflict, while\n * `p-2` and `hover:p-4` do not (different variant scope).\n */\nfunction groupKey(cls: string): string {\n const colon = cls.lastIndexOf(':')\n const variant = colon === -1 ? '' : cls.slice(0, colon + 1)\n const base = colon === -1 ? cls : cls.slice(colon + 1)\n const dash = base.indexOf('-')\n // The prefix is the segment before the first dash (`bg-red-500` → `bg`); for\n // dashless bases (`flex`) there is no group, so the class keys to itself.\n const prefix = dash === -1 ? base : base.slice(0, dash)\n const group = CONFLICT_GROUPS[prefix]\n return group ? `${variant}${group}` : cls\n}\n\n/**\n * Merge class values, resolving last-wins conflicts per property group.\n *\n * @example cn('p-2', 'p-4') // 'p-4'\n * @example cn('a', false && 'b', ['c']) // 'a c'\n * @example cn('bg-red-500', 'bg-blue-500') // 'bg-blue-500'\n */\nexport function cn(...inputs: ClassValue[]): string {\n const flat: string[] = []\n tokens(inputs, flat)\n\n // Last occurrence per group key wins; preserve final order by re-scanning.\n const winner = new Map<string, string>()\n for (const t of flat) winner.set(groupKey(t), t)\n\n const seen = new Set<string>()\n const result: string[] = []\n for (const t of flat) {\n const key = groupKey(t)\n if (winner.get(key) === t && !seen.has(t)) {\n seen.add(t)\n result.push(t)\n }\n }\n return result.join(' ')\n}\n"],"mappings":";;AAQA,MAAa,kBAA0C;CACrD,SAAS;CACT,SAAS;CACT,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"cn.js","names":[],"sources":["../../src/runtime/cn-conflict-map.generated.ts","../../src/runtime/cn.ts"],"sourcesContent":["// AUTO-GENERATED by scripts/gen-cn-conflict-map.ts — DO NOT EDIT.\n// Source of truth: aihu-css-core `tokens::conflict_groups()` (the utility\n// registry). Regenerate with `bun run gen:cn-map`. Hand-edits will be lost.\n//\n// Maps a utility class PREFIX to the CSS property group it controls. Two\n// classes conflict (last wins) when they resolve to the same group.\n\n/** Prefix → conflict-group key, sorted longest-prefix-first. */\nexport const CONFLICT_GROUPS: Record<string, string> = {\n 'translate-x': 'translate',\n 'translate-y': 'translate',\n 'grid-cols': 'grid-template-columns',\n 'grid-rows': 'grid-template-rows',\n 'col-span': 'grid-column',\n 'row-span': 'grid-row',\n duration: 'transition-duration',\n 'space-x': 'space-x',\n 'space-y': 'space-y',\n outline: 'outline-color',\n opacity: 'opacity',\n rounded: 'border-radius',\n 'scale-x': 'scale',\n 'scale-y': 'scale',\n border: 'border-color',\n stroke: 'stroke',\n shadow: 'box-shadow',\n rotate: 'rotate',\n 'gap-x': 'column-gap',\n 'gap-y': 'row-gap',\n 'min-w': 'min-width',\n 'max-w': 'max-width',\n 'min-h': 'min-height',\n 'max-h': 'max-height',\n scale: 'scale',\n text: 'color',\n fill: 'fill',\n ring: '--tw-ring-color',\n font: 'font-weight',\n gap: 'gap',\n px: 'padding-inline',\n py: 'padding-block',\n pt: 'padding-top',\n pr: 'padding-right',\n pb: 'padding-bottom',\n pl: 'padding-left',\n mx: 'margin-inline',\n my: 'margin-block',\n mt: 'margin-top',\n mr: 'margin-right',\n mb: 'margin-bottom',\n ml: 'margin-left',\n bg: 'background-color',\n p: 'padding',\n m: 'margin',\n w: 'width',\n h: 'height',\n z: 'z-index',\n}\n","/**\n * `@aihu/css-engine/runtime/cn` — the class-merge runtime helper (Plan 3 Task 9).\n *\n * `cn(...inputs)` merges class strings / arrays / conditionals into a single\n * deduplicated class string, resolving Tailwind-style conflicts last-wins per\n * property group (`cn('p-2', 'p-4')` → `'p-4'`).\n *\n * The conflict map (`CONFLICT_GROUPS`) is GENERATED at engine build time from\n * the utility registry (`scripts/gen-cn-conflict-map.ts` → Rust\n * `tokens::conflict_groups()`), NOT hand-maintained — so it never drifts from\n * the utility table. Separate < 1 KB gz sub-export from `runtime/progressive`\n * (Risk #4 size-split).\n *\n * This is the runtime-merge helper for consumer-provided overrides (spec §9.3):\n * recipes use static utility strings at compile time; `cn()` is only for the\n * runtime override case.\n */\nimport { CONFLICT_GROUPS } from './cn-conflict-map.generated.ts'\n\n/** A class value: string, falsy (dropped), or a nested array of the same. */\nexport type ClassValue = string | number | null | undefined | false | ClassValue[]\n\n/** Flatten the (possibly nested / conditional) inputs into a token list. */\nfunction tokens(inputs: ClassValue[], out: string[]): void {\n for (const input of inputs) {\n if (!input) continue\n if (Array.isArray(input)) {\n tokens(input, out)\n } else {\n for (const t of String(input).split(' ')) {\n if (t) out.push(t)\n }\n }\n }\n}\n\n/**\n * The conflict-group key for a class, or the class itself when it belongs to no\n * known group (so unrelated classes always coexist). Strips variant prefixes\n * (`md:`, `hover:`, …) so `hover:p-2` and `hover:p-4` still conflict, while\n * `p-2` and `hover:p-4` do not (different variant scope).\n */\nfunction groupKey(cls: string): string {\n const colon = cls.lastIndexOf(':')\n const variant = colon === -1 ? '' : cls.slice(0, colon + 1)\n const base = colon === -1 ? cls : cls.slice(colon + 1)\n const dash = base.indexOf('-')\n // The prefix is the segment before the first dash (`bg-red-500` → `bg`); for\n // dashless bases (`flex`) there is no group, so the class keys to itself.\n const prefix = dash === -1 ? base : base.slice(0, dash)\n const group = CONFLICT_GROUPS[prefix]\n return group ? `${variant}${group}` : cls\n}\n\n/**\n * Merge class values, resolving last-wins conflicts per property group.\n *\n * @example cn('p-2', 'p-4') // 'p-4'\n * @example cn('a', false && 'b', ['c']) // 'a c'\n * @example cn('bg-red-500', 'bg-blue-500') // 'bg-blue-500'\n */\nexport function cn(...inputs: ClassValue[]): string {\n const flat: string[] = []\n tokens(inputs, flat)\n\n // Last occurrence per group key wins; preserve final order by re-scanning.\n const winner = new Map<string, string>()\n for (const t of flat) winner.set(groupKey(t), t)\n\n const seen = new Set<string>()\n const result: string[] = []\n for (const t of flat) {\n const key = groupKey(t)\n if (winner.get(key) === t && !seen.has(t)) {\n seen.add(t)\n result.push(t)\n }\n }\n return result.join(' ')\n}\n"],"mappings":";;AAQA,MAAa,kBAA0C;CACrD,eAAe;CACf,eAAe;CACf,aAAa;CACb,aAAa;CACb,YAAY;CACZ,YAAY;CACZ,UAAU;CACV,WAAW;CACX,WAAW;CACX,SAAS;CACT,SAAS;CACT,SAAS;CACT,WAAW;CACX,WAAW;CACX,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;CACT,OAAO;CACP,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;;;;;;;;;;;;;;;;;;;;;AClCD,SAAS,OAAO,QAAsB,KAAqB;CACzD,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,CAAC,OAAO;EACZ,IAAI,MAAM,QAAQ,MAAM,EACtB,OAAO,OAAO,IAAI;OAElB,KAAK,MAAM,KAAK,OAAO,MAAM,CAAC,MAAM,IAAI,EACtC,IAAI,GAAG,IAAI,KAAK,EAAE;;;;;;;;;AAY1B,SAAS,SAAS,KAAqB;CACrC,MAAM,QAAQ,IAAI,YAAY,IAAI;CAClC,MAAM,UAAU,UAAU,KAAK,KAAK,IAAI,MAAM,GAAG,QAAQ,EAAE;CAC3D,MAAM,OAAO,UAAU,KAAK,MAAM,IAAI,MAAM,QAAQ,EAAE;CACtD,MAAM,OAAO,KAAK,QAAQ,IAAI;CAI9B,MAAM,QAAQ,gBADC,SAAS,KAAK,OAAO,KAAK,MAAM,GAAG,KAAK;CAEvD,OAAO,QAAQ,GAAG,UAAU,UAAU;;;;;;;;;AAUxC,SAAgB,GAAG,GAAG,QAA8B;CAClD,MAAM,OAAiB,EAAE;CACzB,OAAO,QAAQ,KAAK;CAGpB,MAAM,yBAAS,IAAI,KAAqB;CACxC,KAAK,MAAM,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,EAAE,EAAE;CAEhD,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,SAAmB,EAAE;CAC3B,KAAK,MAAM,KAAK,MAAM;EACpB,MAAM,MAAM,SAAS,EAAE;EACvB,IAAI,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;GACzC,KAAK,IAAI,EAAE;GACX,OAAO,KAAK,EAAE;;;CAGlB,OAAO,OAAO,KAAK,IAAI"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aihu/css-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
],
|
|
38
38
|
"sideEffects": false,
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@aihu/compiler": "0.5.
|
|
40
|
+
"@aihu/compiler": "^0.5.4"
|
|
41
41
|
},
|
|
42
42
|
"optionalDependencies": {
|
|
43
43
|
"@aihu/css-engine-darwin-arm64": "0.1.2",
|