@salty-css/core 0.1.0-alpha.27 → 0.1.0-alpha.28
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 +82 -0
- package/{class-name-generator-BIYysuhW.cjs → class-name-generator-DZcz_NT4.cjs} +1 -1
- package/{class-name-generator-B2LriwKm.js → class-name-generator-zQ8zLbPI.js} +1 -1
- package/compiler/salty-compiler.cjs +27 -4
- package/compiler/salty-compiler.js +28 -5
- package/css/dynamic-styles.cjs +1 -1
- package/css/dynamic-styles.js +1 -1
- package/css/keyframes.cjs +1 -1
- package/css/keyframes.js +1 -1
- package/generators/index.cjs +1 -1
- package/generators/index.js +2 -2
- package/instances/classname-instance.cjs +1 -1
- package/instances/classname-instance.js +1 -1
- package/package.json +1 -1
- package/{parse-styles-jPtMfgXH.cjs → parse-styles-BFoV7HiL.cjs} +187 -6
- package/{parse-styles--vHKY6Mw.js → parse-styles-CtA-RKqt.js} +187 -6
- package/parsers/index.cjs +80 -3
- package/parsers/index.js +81 -4
- package/parsers/parse-templates.d.ts +10 -0
- package/parsers/resolve-template-variants.d.ts +21 -0
- package/runtime/index.cjs +1 -1
- package/runtime/index.js +1 -1
- package/types/config-types.d.ts +32 -1
package/README.md
CHANGED
|
@@ -321,6 +321,88 @@ Example usage:
|
|
|
321
321
|
styled('div', { base: { textStyle: 'headline.large', card: '20px' } });
|
|
322
322
|
```
|
|
323
323
|
|
|
324
|
+
### Template variants
|
|
325
|
+
|
|
326
|
+
Static templates can opt into named variants by switching a node from a plain styles object to a "rich" shape with `base` and `variants` keys — the same authoring API as `styled`. Variants declared at a parent node are inherited by every descendant leaf, so one declaration of `weight` on `heading` flows down to `heading.large`, `heading.small`, etc.
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
// /styles/templates.css.ts
|
|
330
|
+
import { defineTemplates } from '@salty-css/core/factories';
|
|
331
|
+
|
|
332
|
+
export default defineTemplates({
|
|
333
|
+
textStyle: {
|
|
334
|
+
heading: {
|
|
335
|
+
// Rich node: variants declared here are available to every child leaf.
|
|
336
|
+
base: {
|
|
337
|
+
fontFamily: '{fontFamily.heading}',
|
|
338
|
+
lineHeight: '1.1em',
|
|
339
|
+
},
|
|
340
|
+
variants: {
|
|
341
|
+
weight: {
|
|
342
|
+
light: { fontWeight: 300 },
|
|
343
|
+
regular: { fontWeight: 500 },
|
|
344
|
+
heavy: { fontWeight: 800 },
|
|
345
|
+
},
|
|
346
|
+
italic: {
|
|
347
|
+
true: { fontStyle: 'italic' },
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
defaultVariants: {
|
|
351
|
+
weight: 'regular',
|
|
352
|
+
},
|
|
353
|
+
compoundVariants: [
|
|
354
|
+
// Applied when ALL listed axes match.
|
|
355
|
+
{ weight: 'heavy', italic: true, css: { letterSpacing: '-0.01em' } },
|
|
356
|
+
],
|
|
357
|
+
// Leaves can be plain styles…
|
|
358
|
+
small: { fontSize: '{fontSize.heading.small}' },
|
|
359
|
+
regular: { fontSize: '{fontSize.heading.regular}' },
|
|
360
|
+
// …or rich, with their own additional variants / overrides.
|
|
361
|
+
large: {
|
|
362
|
+
base: { fontSize: '{fontSize.heading.large}' },
|
|
363
|
+
variants: {
|
|
364
|
+
weight: {
|
|
365
|
+
// Override the inherited bundle just for `large`.
|
|
366
|
+
heavy: { fontWeight: 900, letterSpacing: '-0.02em' },
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Apply variants at the call site in either of two equivalent forms — string query or object:
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
styled('h1', {
|
|
379
|
+
base: {
|
|
380
|
+
// String form: `path@axis=value&axis=value&boolFlag`
|
|
381
|
+
textStyle: 'heading.large@weight=heavy&italic',
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
styled('h2', {
|
|
386
|
+
base: {
|
|
387
|
+
// Object form: `name` is the dot-path, the rest are axis values.
|
|
388
|
+
textStyle: { name: 'heading.large', weight: 'heavy', italic: true },
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// No variants — existing simple usage still works.
|
|
393
|
+
styled('p', { base: { textStyle: 'heading.regular' } });
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Behaviour worth knowing:
|
|
397
|
+
|
|
398
|
+
- **Inheritance is parent → leaf only.** A leaf sees variants from its ancestors; siblings and children are invisible.
|
|
399
|
+
- **Closest wins.** If the same axis/value bundle is declared at multiple levels, the deepest one replaces (not merges) the ancestor's bundle for that single call.
|
|
400
|
+
- **`defaultVariants` apply when the call site omits an axis.** Walked bottom-up, same closest-wins rule.
|
|
401
|
+
- **`compoundVariants` (AND) and `anyOfVariants` (OR) are accumulated top-down** across the path — every matching rule contributes.
|
|
402
|
+
- **Boolean axes accept a shorthand.** `@italic` is equivalent to `@italic=true`; in object form pass `italic: true`.
|
|
403
|
+
- **Reserved keys** inside a rich node: `base`, `variants`, `defaultVariants`, `compoundVariants`, `anyOfVariants`. Don't use `name` as an axis (reserved for the object call-site form).
|
|
404
|
+
- **Function templates** (e.g. `card: (v) => ({ … })`) don't support variants — keep them as plain functions.
|
|
405
|
+
|
|
324
406
|
## Custom fonts
|
|
325
407
|
|
|
326
408
|
Register custom fonts that will be emitted as `@font-face` declarations and exposed as a CSS variable. Mirrors the developer experience of Next.js / Astro font loaders, but generated at build time alongside the rest of your Salty CSS output.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
-
const parseStyles = require("./parse-styles-
|
|
5
|
+
const parseStyles = require("./parse-styles-BFoV7HiL.cjs");
|
|
6
6
|
const dashCase = require("./dash-case-DIwKaYgE.cjs");
|
|
7
7
|
const toHash = require("./to-hash-C05Y906F.cjs");
|
|
8
8
|
class StylesGenerator {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { p as parseAndJoinStyles } from "./parse-styles
|
|
4
|
+
import { p as parseAndJoinStyles } from "./parse-styles-CtA-RKqt.js";
|
|
5
5
|
import { d as dashCase } from "./dash-case-DblXvymC.js";
|
|
6
6
|
import { t as toHash } from "./to-hash-DAN2LcHK.js";
|
|
7
7
|
class StylesGenerator {
|
|
@@ -14,7 +14,7 @@ const dashCase = require("../dash-case-DIwKaYgE.cjs");
|
|
|
14
14
|
const toHash = require("../to-hash-C05Y906F.cjs");
|
|
15
15
|
const defineTemplates = require("../define-templates-Deq1aCbN.cjs");
|
|
16
16
|
const module$1 = require("module");
|
|
17
|
-
const parseStyles = require("../parse-styles-
|
|
17
|
+
const parseStyles = require("../parse-styles-BFoV7HiL.cjs");
|
|
18
18
|
const css_merge = require("../css/merge.cjs");
|
|
19
19
|
const parsers_index = require("../parsers/index.cjs");
|
|
20
20
|
const moduleType = require("../util/module-type");
|
|
@@ -553,6 +553,7 @@ ${css}
|
|
|
553
553
|
const templates = css_merge.mergeObjects(config.templates, generationResults.templates);
|
|
554
554
|
const templateStylesString = await parsers_index.parseTemplates(templates);
|
|
555
555
|
const templateTokens = parsers_index.getTemplateTypes(templates);
|
|
556
|
+
const templateVariantMaps = parsers_index.getTemplateVariantMaps(templates);
|
|
556
557
|
fs.writeFileSync(templateStylesPath, `@layer templates { ${templateStylesString} }`);
|
|
557
558
|
configCacheContent.templates = templates;
|
|
558
559
|
const importsPath = path.join(destDir, "css/_imports.css");
|
|
@@ -592,16 +593,38 @@ ${css}
|
|
|
592
593
|
}
|
|
593
594
|
const tsTokensPath = path.join(destDir, "types/css-tokens.d.ts");
|
|
594
595
|
const tsVariableTokens = [...variableTokens].join("|");
|
|
596
|
+
const pascal = (str) => str.split(/[.\-_]/).filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
597
|
+
const templateVariantMapEntries = Object.entries(templateVariantMaps);
|
|
598
|
+
const hasVariantMaps = templateVariantMapEntries.some(([, pathMap]) => Object.keys(pathMap).length > 0);
|
|
599
|
+
const tsTemplateVariantMap = hasVariantMaps ? `type TemplateVariantTokens = {
|
|
600
|
+
${templateVariantMapEntries.filter(([, pathMap]) => Object.keys(pathMap).length > 0).map(([templateKey, pathMap]) => {
|
|
601
|
+
const pathEntries = Object.entries(pathMap).map(
|
|
602
|
+
([dotPath, axes]) => `'${dotPath}': { ${Object.entries(axes).map(([axis, valueType]) => `${axis}?: ${valueType}`).join("; ")} }`
|
|
603
|
+
).join(";\n ");
|
|
604
|
+
return `${templateKey}: {
|
|
605
|
+
${pathEntries}
|
|
606
|
+
}`;
|
|
607
|
+
}).join(";\n ")}
|
|
608
|
+
}` : `type TemplateVariantTokens = Record<string, Record<string, Record<string, never>>>;`;
|
|
609
|
+
const tsTemplateVariantAliases = templateVariantMapEntries.flatMap(
|
|
610
|
+
([templateKey, pathMap]) => Object.keys(pathMap).map(
|
|
611
|
+
(dotPath) => `type ${pascal(templateKey)}${pascal(dotPath)}Variants = TemplateVariantTokens['${templateKey}']['${dotPath}'];`
|
|
612
|
+
)
|
|
613
|
+
).join("\n ");
|
|
595
614
|
const tsTokensTypes = `
|
|
596
615
|
// Variable types
|
|
597
|
-
type VariableTokens = ${tsVariableTokens || `''`};
|
|
616
|
+
type VariableTokens = ${tsVariableTokens || `''`};
|
|
598
617
|
type PropertyValueToken = \`{\${VariableTokens}}\`;
|
|
599
|
-
|
|
618
|
+
|
|
600
619
|
// Template types
|
|
601
620
|
type TemplateTokens = {
|
|
602
621
|
${Object.entries(templateTokens).map(([key, value]) => `${key}?: ${value}`).join("\n")}
|
|
603
622
|
}
|
|
604
|
-
|
|
623
|
+
|
|
624
|
+
// Template variant types (per docs/template-variants-spec.md §7)
|
|
625
|
+
${tsTemplateVariantMap}
|
|
626
|
+
${tsTemplateVariantAliases}
|
|
627
|
+
|
|
605
628
|
// Media query types
|
|
606
629
|
type MediaQueryKeys = ${mediaQueryKeys || `''`};
|
|
607
630
|
`;
|
|
@@ -12,9 +12,9 @@ import { d as dashCase } from "../dash-case-DblXvymC.js";
|
|
|
12
12
|
import { t as toHash } from "../to-hash-DAN2LcHK.js";
|
|
13
13
|
import { d as defineTemplates } from "../define-templates-CVhhgPnd.js";
|
|
14
14
|
import { createRequire } from "module";
|
|
15
|
-
import { p as parseAndJoinStyles, b as parseVariableTokens } from "../parse-styles
|
|
15
|
+
import { p as parseAndJoinStyles, b as parseVariableTokens } from "../parse-styles-CtA-RKqt.js";
|
|
16
16
|
import { mergeObjects, mergeFactories } from "../css/merge.js";
|
|
17
|
-
import { parseTemplates, getTemplateTypes } from "../parsers/index.js";
|
|
17
|
+
import { parseTemplates, getTemplateTypes, getTemplateVariantMaps } from "../parsers/index.js";
|
|
18
18
|
import { detectCurrentModuleType } from "../util/module-type";
|
|
19
19
|
import console from "console";
|
|
20
20
|
const logger = createLogger({
|
|
@@ -534,6 +534,7 @@ ${css}
|
|
|
534
534
|
const templates = mergeObjects(config.templates, generationResults.templates);
|
|
535
535
|
const templateStylesString = await parseTemplates(templates);
|
|
536
536
|
const templateTokens = getTemplateTypes(templates);
|
|
537
|
+
const templateVariantMaps = getTemplateVariantMaps(templates);
|
|
537
538
|
writeFileSync(templateStylesPath, `@layer templates { ${templateStylesString} }`);
|
|
538
539
|
configCacheContent.templates = templates;
|
|
539
540
|
const importsPath = join(destDir, "css/_imports.css");
|
|
@@ -573,16 +574,38 @@ ${css}
|
|
|
573
574
|
}
|
|
574
575
|
const tsTokensPath = join(destDir, "types/css-tokens.d.ts");
|
|
575
576
|
const tsVariableTokens = [...variableTokens].join("|");
|
|
577
|
+
const pascal = (str) => str.split(/[.\-_]/).filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
578
|
+
const templateVariantMapEntries = Object.entries(templateVariantMaps);
|
|
579
|
+
const hasVariantMaps = templateVariantMapEntries.some(([, pathMap]) => Object.keys(pathMap).length > 0);
|
|
580
|
+
const tsTemplateVariantMap = hasVariantMaps ? `type TemplateVariantTokens = {
|
|
581
|
+
${templateVariantMapEntries.filter(([, pathMap]) => Object.keys(pathMap).length > 0).map(([templateKey, pathMap]) => {
|
|
582
|
+
const pathEntries = Object.entries(pathMap).map(
|
|
583
|
+
([dotPath, axes]) => `'${dotPath}': { ${Object.entries(axes).map(([axis, valueType]) => `${axis}?: ${valueType}`).join("; ")} }`
|
|
584
|
+
).join(";\n ");
|
|
585
|
+
return `${templateKey}: {
|
|
586
|
+
${pathEntries}
|
|
587
|
+
}`;
|
|
588
|
+
}).join(";\n ")}
|
|
589
|
+
}` : `type TemplateVariantTokens = Record<string, Record<string, Record<string, never>>>;`;
|
|
590
|
+
const tsTemplateVariantAliases = templateVariantMapEntries.flatMap(
|
|
591
|
+
([templateKey, pathMap]) => Object.keys(pathMap).map(
|
|
592
|
+
(dotPath) => `type ${pascal(templateKey)}${pascal(dotPath)}Variants = TemplateVariantTokens['${templateKey}']['${dotPath}'];`
|
|
593
|
+
)
|
|
594
|
+
).join("\n ");
|
|
576
595
|
const tsTokensTypes = `
|
|
577
596
|
// Variable types
|
|
578
|
-
type VariableTokens = ${tsVariableTokens || `''`};
|
|
597
|
+
type VariableTokens = ${tsVariableTokens || `''`};
|
|
579
598
|
type PropertyValueToken = \`{\${VariableTokens}}\`;
|
|
580
|
-
|
|
599
|
+
|
|
581
600
|
// Template types
|
|
582
601
|
type TemplateTokens = {
|
|
583
602
|
${Object.entries(templateTokens).map(([key, value]) => `${key}?: ${value}`).join("\n")}
|
|
584
603
|
}
|
|
585
|
-
|
|
604
|
+
|
|
605
|
+
// Template variant types (per docs/template-variants-spec.md §7)
|
|
606
|
+
${tsTemplateVariantMap}
|
|
607
|
+
${tsTemplateVariantAliases}
|
|
608
|
+
|
|
586
609
|
// Media query types
|
|
587
610
|
type MediaQueryKeys = ${mediaQueryKeys || `''`};
|
|
588
611
|
`;
|
package/css/dynamic-styles.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const parseStyles = require("../parse-styles-
|
|
3
|
+
const parseStyles = require("../parse-styles-BFoV7HiL.cjs");
|
|
4
4
|
const toHash = require("../to-hash-C05Y906F.cjs");
|
|
5
5
|
const cache_resolveDynamicConfigCache = require("../cache/resolve-dynamic-config-cache.cjs");
|
|
6
6
|
const getDynamicStylesClassName = (styles) => {
|
package/css/dynamic-styles.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as parseStyles } from "../parse-styles
|
|
1
|
+
import { a as parseStyles } from "../parse-styles-CtA-RKqt.js";
|
|
2
2
|
import { t as toHash } from "../to-hash-DAN2LcHK.js";
|
|
3
3
|
import { resolveDynamicConfigCache } from "../cache/resolve-dynamic-config-cache.js";
|
|
4
4
|
const getDynamicStylesClassName = (styles) => {
|
package/css/keyframes.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const parseStyles = require("../parse-styles-
|
|
3
|
+
const parseStyles = require("../parse-styles-BFoV7HiL.cjs");
|
|
4
4
|
const toHash = require("../to-hash-C05Y906F.cjs");
|
|
5
5
|
const keyframes = ({ animationName: _name, params: _params, appendInitialStyles, ...keyframes2 }) => {
|
|
6
6
|
const modifyKeyframes = async (params = {}) => {
|
package/css/keyframes.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { p as parseAndJoinStyles } from "../parse-styles
|
|
1
|
+
import { p as parseAndJoinStyles } from "../parse-styles-CtA-RKqt.js";
|
|
2
2
|
import { t as toHash } from "../to-hash-DAN2LcHK.js";
|
|
3
3
|
const keyframes = ({ animationName: _name, params: _params, appendInitialStyles, ...keyframes2 }) => {
|
|
4
4
|
const modifyKeyframes = async (params = {}) => {
|
package/generators/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const classNameGenerator = require("../class-name-generator-
|
|
3
|
+
const classNameGenerator = require("../class-name-generator-DZcz_NT4.cjs");
|
|
4
4
|
const dashCase = require("../dash-case-DIwKaYgE.cjs");
|
|
5
5
|
class StyledGenerator extends classNameGenerator.StylesGenerator {
|
|
6
6
|
constructor(tagName, _params) {
|
package/generators/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as StylesGenerator } from "../class-name-generator-
|
|
2
|
-
import { C } from "../class-name-generator-
|
|
1
|
+
import { S as StylesGenerator } from "../class-name-generator-zQ8zLbPI.js";
|
|
2
|
+
import { C } from "../class-name-generator-zQ8zLbPI.js";
|
|
3
3
|
import { d as dashCase } from "../dash-case-DblXvymC.js";
|
|
4
4
|
class StyledGenerator extends StylesGenerator {
|
|
5
5
|
constructor(tagName, _params) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const classNameGenerator = require("../class-name-generator-
|
|
3
|
+
const classNameGenerator = require("../class-name-generator-DZcz_NT4.cjs");
|
|
4
4
|
const classNameInstance = (params) => {
|
|
5
5
|
const generator = new classNameGenerator.ClassNameGenerator(params);
|
|
6
6
|
const createClass = (classNameStr) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ClassNameGenerator } from "../class-name-generator-
|
|
1
|
+
import { C as ClassNameGenerator } from "../class-name-generator-zQ8zLbPI.js";
|
|
2
2
|
const classNameInstance = (params) => {
|
|
3
3
|
const generator = new ClassNameGenerator(params);
|
|
4
4
|
const createClass = (classNameStr) => {
|
package/package.json
CHANGED
|
@@ -94,6 +94,170 @@ const reportParserIssue = (strict, message) => {
|
|
|
94
94
|
const pseudoTypoRegex = /^&(hover|focus(-(visible|within))?|active|visited|checked|disabled|enabled|empty|target|first-child|last-child|first-of-type|last-of-type|placeholder|placeholder-shown|root)\b/;
|
|
95
95
|
const templateLiteralLeftoverRegex = /\$\{[^}]+\}/;
|
|
96
96
|
const bareAtRuleRegex = /^@(media|supports|container|layer)\s*$/;
|
|
97
|
+
const isRichTemplateNode = (node) => {
|
|
98
|
+
if (!node || typeof node !== "object") return false;
|
|
99
|
+
if (Array.isArray(node)) return false;
|
|
100
|
+
const keys = Object.keys(node);
|
|
101
|
+
return keys.includes("base") || keys.includes("variants");
|
|
102
|
+
};
|
|
103
|
+
const parseTemplateCallSite = (value) => {
|
|
104
|
+
if (typeof value === "string") {
|
|
105
|
+
const [rawPath, rawQuery] = value.split("@", 2);
|
|
106
|
+
const path = rawPath.split(".").filter(Boolean);
|
|
107
|
+
if (!path.length) return void 0;
|
|
108
|
+
const variants = {};
|
|
109
|
+
if (rawQuery) {
|
|
110
|
+
for (const segment of rawQuery.split("&")) {
|
|
111
|
+
if (!segment) continue;
|
|
112
|
+
const eq = segment.indexOf("=");
|
|
113
|
+
if (eq === -1) {
|
|
114
|
+
variants[segment.trim()] = true;
|
|
115
|
+
} else {
|
|
116
|
+
const axis = segment.slice(0, eq).trim();
|
|
117
|
+
const raw = segment.slice(eq + 1).trim();
|
|
118
|
+
if (!axis) continue;
|
|
119
|
+
if (raw === "true") variants[axis] = true;
|
|
120
|
+
else if (raw === "false") variants[axis] = false;
|
|
121
|
+
else variants[axis] = raw;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { path, variants };
|
|
126
|
+
}
|
|
127
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
128
|
+
const obj = value;
|
|
129
|
+
const name = obj["name"];
|
|
130
|
+
if (typeof name !== "string") return void 0;
|
|
131
|
+
const path = name.split(".").filter(Boolean);
|
|
132
|
+
if (!path.length) return void 0;
|
|
133
|
+
const variants = {};
|
|
134
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
135
|
+
if (k === "name") continue;
|
|
136
|
+
if (typeof v === "string" || typeof v === "boolean") variants[k] = v;
|
|
137
|
+
}
|
|
138
|
+
return { path, variants };
|
|
139
|
+
}
|
|
140
|
+
return void 0;
|
|
141
|
+
};
|
|
142
|
+
const normalizeAxisValue = (v) => {
|
|
143
|
+
if (v === void 0) return void 0;
|
|
144
|
+
return typeof v === "boolean" ? String(v) : v;
|
|
145
|
+
};
|
|
146
|
+
const buildPathStack = (root, path) => {
|
|
147
|
+
const stack = [{ node: root, isRich: isRichTemplateNode(root) }];
|
|
148
|
+
let cursor = root;
|
|
149
|
+
for (const segment of path) {
|
|
150
|
+
if (cursor == null || typeof cursor !== "object") return void 0;
|
|
151
|
+
const next = cursor[segment];
|
|
152
|
+
if (next === void 0) return void 0;
|
|
153
|
+
stack.push({ node: next, isRich: isRichTemplateNode(next) });
|
|
154
|
+
cursor = next;
|
|
155
|
+
}
|
|
156
|
+
return stack;
|
|
157
|
+
};
|
|
158
|
+
const pathHasRichNode = (root, path) => {
|
|
159
|
+
const stack = buildPathStack(root, path);
|
|
160
|
+
if (!stack) return false;
|
|
161
|
+
return stack.some((entry) => entry.isRich);
|
|
162
|
+
};
|
|
163
|
+
const matchesAll = (entry, effective) => {
|
|
164
|
+
for (const [axis, raw] of Object.entries(entry)) {
|
|
165
|
+
if (axis === "css") continue;
|
|
166
|
+
if (effective[axis] !== normalizeAxisValue(raw)) return false;
|
|
167
|
+
}
|
|
168
|
+
return true;
|
|
169
|
+
};
|
|
170
|
+
const matchesAny = (entry, effective) => {
|
|
171
|
+
let any = false;
|
|
172
|
+
for (const [axis, raw] of Object.entries(entry)) {
|
|
173
|
+
if (axis === "css") continue;
|
|
174
|
+
any = true;
|
|
175
|
+
if (effective[axis] === normalizeAxisValue(raw)) return true;
|
|
176
|
+
}
|
|
177
|
+
return !any;
|
|
178
|
+
};
|
|
179
|
+
const resolveRichTemplate = (root, path, callSiteVariants, templateName) => {
|
|
180
|
+
var _a, _b, _c, _d;
|
|
181
|
+
const stack = buildPathStack(root, path);
|
|
182
|
+
if (!stack) return void 0;
|
|
183
|
+
const rich = stack.map((entry) => {
|
|
184
|
+
if (entry.isRich) return entry.node;
|
|
185
|
+
if (entry.node && typeof entry.node === "object" && !Array.isArray(entry.node)) {
|
|
186
|
+
const onlyChildKeys = Object.keys(entry.node).every((k) => entry.node[k] && typeof entry.node[k] === "object" && !isRichTemplateNode(entry.node[k]));
|
|
187
|
+
return onlyChildKeys ? {} : { base: entry.node };
|
|
188
|
+
}
|
|
189
|
+
return {};
|
|
190
|
+
});
|
|
191
|
+
const declaredAxes = /* @__PURE__ */ new Set();
|
|
192
|
+
for (const r of rich) {
|
|
193
|
+
if (r.variants) for (const k of Object.keys(r.variants)) declaredAxes.add(k);
|
|
194
|
+
}
|
|
195
|
+
for (const r of rich) {
|
|
196
|
+
if (r.defaultVariants) for (const k of Object.keys(r.defaultVariants)) declaredAxes.add(k);
|
|
197
|
+
}
|
|
198
|
+
const effective = {};
|
|
199
|
+
for (const axis of declaredAxes) {
|
|
200
|
+
if (axis in callSiteVariants) {
|
|
201
|
+
effective[axis] = normalizeAxisValue(callSiteVariants[axis]);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
for (let i = rich.length - 1; i >= 0; i--) {
|
|
205
|
+
const d = (_a = rich[i].defaultVariants) == null ? void 0 : _a[axis];
|
|
206
|
+
if (d !== void 0) {
|
|
207
|
+
effective[axis] = normalizeAxisValue(d);
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
for (const [axis, raw] of Object.entries(callSiteVariants)) {
|
|
213
|
+
if (!declaredAxes.has(axis)) {
|
|
214
|
+
console.warn(`Template "${templateName}" path "${path.join(".")}" has no variant axis "${axis}"; ignored.`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
const wanted = normalizeAxisValue(raw);
|
|
218
|
+
let found = false;
|
|
219
|
+
for (const r of rich) {
|
|
220
|
+
if (((_b = r.variants) == null ? void 0 : _b[axis]) && wanted !== void 0 && wanted in r.variants[axis]) {
|
|
221
|
+
found = true;
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (!found && wanted !== void 0) {
|
|
226
|
+
const anyBundle = rich.some((r) => r.variants && axis in r.variants);
|
|
227
|
+
if (anyBundle) {
|
|
228
|
+
console.warn(`Template "${templateName}" axis "${axis}" has no value "${wanted}" on path "${path.join(".")}"; ignored.`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const acc = {};
|
|
233
|
+
for (const r of rich) {
|
|
234
|
+
if (r.base) Object.assign(acc, r.base);
|
|
235
|
+
}
|
|
236
|
+
for (const axis of Object.keys(effective)) {
|
|
237
|
+
const value = effective[axis];
|
|
238
|
+
if (value === void 0) continue;
|
|
239
|
+
for (let i = rich.length - 1; i >= 0; i--) {
|
|
240
|
+
const bundle = (_d = (_c = rich[i].variants) == null ? void 0 : _c[axis]) == null ? void 0 : _d[value];
|
|
241
|
+
if (bundle) {
|
|
242
|
+
Object.assign(acc, bundle);
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const r of rich) {
|
|
248
|
+
if (r.compoundVariants) {
|
|
249
|
+
for (const entry of r.compoundVariants) {
|
|
250
|
+
if (matchesAll(entry, effective) && entry.css) Object.assign(acc, entry.css);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (r.anyOfVariants) {
|
|
254
|
+
for (const entry of r.anyOfVariants) {
|
|
255
|
+
if (matchesAny(entry, effective) && entry.css) Object.assign(acc, entry.css);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return acc;
|
|
260
|
+
};
|
|
97
261
|
const parseStyles = async (styles, currentScope = "", config, omitTemplates = false) => {
|
|
98
262
|
if (!styles) throw new Error("No styles provided to parseStyles function!");
|
|
99
263
|
const cssStyles = /* @__PURE__ */ new Set();
|
|
@@ -137,13 +301,29 @@ const parseStyles = async (styles, currentScope = "", config, omitTemplates = fa
|
|
|
137
301
|
}
|
|
138
302
|
if ((config == null ? void 0 : config.templates) && config.templates[_key]) {
|
|
139
303
|
if (omitTemplates) return void 0;
|
|
140
|
-
const
|
|
141
|
-
const
|
|
142
|
-
if (
|
|
143
|
-
const
|
|
144
|
-
|
|
304
|
+
const root = config.templates[_key];
|
|
305
|
+
const callSite = parseTemplateCallSite(value);
|
|
306
|
+
if (callSite) {
|
|
307
|
+
const { path, variants } = callSite;
|
|
308
|
+
const hasCallSiteVariants = Object.keys(variants).length > 0;
|
|
309
|
+
if (hasCallSiteVariants || pathHasRichNode(root, path)) {
|
|
310
|
+
const resolved2 = resolveRichTemplate(root, path, variants, _key);
|
|
311
|
+
if (resolved2) {
|
|
312
|
+
const [result] = await parseStyles(resolved2, "");
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
console.warn(`Template "${_key}" with path of "${path.join(".")}" was not found in config!`);
|
|
316
|
+
return void 0;
|
|
317
|
+
}
|
|
318
|
+
const templateStyles = path.reduce((acc, key2) => acc == null ? void 0 : acc[key2], root);
|
|
319
|
+
if (templateStyles) {
|
|
320
|
+
const [result] = await parseStyles(templateStyles, "");
|
|
321
|
+
return result;
|
|
322
|
+
}
|
|
323
|
+
console.warn(`Template "${_key}" with path of "${path.join(".")}" was not found in config!`);
|
|
324
|
+
return void 0;
|
|
145
325
|
}
|
|
146
|
-
console.warn(`Template "${_key}"
|
|
326
|
+
console.warn(`Template "${_key}" received an unsupported call-site value.`);
|
|
147
327
|
return void 0;
|
|
148
328
|
}
|
|
149
329
|
const isVariantArrayKey = _key === "compoundVariants" || _key === "anyOfVariants";
|
|
@@ -323,6 +503,7 @@ const combineSelectors = (currentScope, key) => {
|
|
|
323
503
|
}
|
|
324
504
|
return combos.join(", ");
|
|
325
505
|
};
|
|
506
|
+
exports.isRichTemplateNode = isRichTemplateNode;
|
|
326
507
|
exports.parseAndJoinStyles = parseAndJoinStyles;
|
|
327
508
|
exports.parseStyles = parseStyles;
|
|
328
509
|
exports.parseValueModifiers = parseValueModifiers;
|
|
@@ -93,6 +93,170 @@ const reportParserIssue = (strict, message) => {
|
|
|
93
93
|
const pseudoTypoRegex = /^&(hover|focus(-(visible|within))?|active|visited|checked|disabled|enabled|empty|target|first-child|last-child|first-of-type|last-of-type|placeholder|placeholder-shown|root)\b/;
|
|
94
94
|
const templateLiteralLeftoverRegex = /\$\{[^}]+\}/;
|
|
95
95
|
const bareAtRuleRegex = /^@(media|supports|container|layer)\s*$/;
|
|
96
|
+
const isRichTemplateNode = (node) => {
|
|
97
|
+
if (!node || typeof node !== "object") return false;
|
|
98
|
+
if (Array.isArray(node)) return false;
|
|
99
|
+
const keys = Object.keys(node);
|
|
100
|
+
return keys.includes("base") || keys.includes("variants");
|
|
101
|
+
};
|
|
102
|
+
const parseTemplateCallSite = (value) => {
|
|
103
|
+
if (typeof value === "string") {
|
|
104
|
+
const [rawPath, rawQuery] = value.split("@", 2);
|
|
105
|
+
const path = rawPath.split(".").filter(Boolean);
|
|
106
|
+
if (!path.length) return void 0;
|
|
107
|
+
const variants = {};
|
|
108
|
+
if (rawQuery) {
|
|
109
|
+
for (const segment of rawQuery.split("&")) {
|
|
110
|
+
if (!segment) continue;
|
|
111
|
+
const eq = segment.indexOf("=");
|
|
112
|
+
if (eq === -1) {
|
|
113
|
+
variants[segment.trim()] = true;
|
|
114
|
+
} else {
|
|
115
|
+
const axis = segment.slice(0, eq).trim();
|
|
116
|
+
const raw = segment.slice(eq + 1).trim();
|
|
117
|
+
if (!axis) continue;
|
|
118
|
+
if (raw === "true") variants[axis] = true;
|
|
119
|
+
else if (raw === "false") variants[axis] = false;
|
|
120
|
+
else variants[axis] = raw;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return { path, variants };
|
|
125
|
+
}
|
|
126
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
127
|
+
const obj = value;
|
|
128
|
+
const name = obj["name"];
|
|
129
|
+
if (typeof name !== "string") return void 0;
|
|
130
|
+
const path = name.split(".").filter(Boolean);
|
|
131
|
+
if (!path.length) return void 0;
|
|
132
|
+
const variants = {};
|
|
133
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
134
|
+
if (k === "name") continue;
|
|
135
|
+
if (typeof v === "string" || typeof v === "boolean") variants[k] = v;
|
|
136
|
+
}
|
|
137
|
+
return { path, variants };
|
|
138
|
+
}
|
|
139
|
+
return void 0;
|
|
140
|
+
};
|
|
141
|
+
const normalizeAxisValue = (v) => {
|
|
142
|
+
if (v === void 0) return void 0;
|
|
143
|
+
return typeof v === "boolean" ? String(v) : v;
|
|
144
|
+
};
|
|
145
|
+
const buildPathStack = (root, path) => {
|
|
146
|
+
const stack = [{ node: root, isRich: isRichTemplateNode(root) }];
|
|
147
|
+
let cursor = root;
|
|
148
|
+
for (const segment of path) {
|
|
149
|
+
if (cursor == null || typeof cursor !== "object") return void 0;
|
|
150
|
+
const next = cursor[segment];
|
|
151
|
+
if (next === void 0) return void 0;
|
|
152
|
+
stack.push({ node: next, isRich: isRichTemplateNode(next) });
|
|
153
|
+
cursor = next;
|
|
154
|
+
}
|
|
155
|
+
return stack;
|
|
156
|
+
};
|
|
157
|
+
const pathHasRichNode = (root, path) => {
|
|
158
|
+
const stack = buildPathStack(root, path);
|
|
159
|
+
if (!stack) return false;
|
|
160
|
+
return stack.some((entry) => entry.isRich);
|
|
161
|
+
};
|
|
162
|
+
const matchesAll = (entry, effective) => {
|
|
163
|
+
for (const [axis, raw] of Object.entries(entry)) {
|
|
164
|
+
if (axis === "css") continue;
|
|
165
|
+
if (effective[axis] !== normalizeAxisValue(raw)) return false;
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
};
|
|
169
|
+
const matchesAny = (entry, effective) => {
|
|
170
|
+
let any = false;
|
|
171
|
+
for (const [axis, raw] of Object.entries(entry)) {
|
|
172
|
+
if (axis === "css") continue;
|
|
173
|
+
any = true;
|
|
174
|
+
if (effective[axis] === normalizeAxisValue(raw)) return true;
|
|
175
|
+
}
|
|
176
|
+
return !any;
|
|
177
|
+
};
|
|
178
|
+
const resolveRichTemplate = (root, path, callSiteVariants, templateName) => {
|
|
179
|
+
var _a, _b, _c, _d;
|
|
180
|
+
const stack = buildPathStack(root, path);
|
|
181
|
+
if (!stack) return void 0;
|
|
182
|
+
const rich = stack.map((entry) => {
|
|
183
|
+
if (entry.isRich) return entry.node;
|
|
184
|
+
if (entry.node && typeof entry.node === "object" && !Array.isArray(entry.node)) {
|
|
185
|
+
const onlyChildKeys = Object.keys(entry.node).every((k) => entry.node[k] && typeof entry.node[k] === "object" && !isRichTemplateNode(entry.node[k]));
|
|
186
|
+
return onlyChildKeys ? {} : { base: entry.node };
|
|
187
|
+
}
|
|
188
|
+
return {};
|
|
189
|
+
});
|
|
190
|
+
const declaredAxes = /* @__PURE__ */ new Set();
|
|
191
|
+
for (const r of rich) {
|
|
192
|
+
if (r.variants) for (const k of Object.keys(r.variants)) declaredAxes.add(k);
|
|
193
|
+
}
|
|
194
|
+
for (const r of rich) {
|
|
195
|
+
if (r.defaultVariants) for (const k of Object.keys(r.defaultVariants)) declaredAxes.add(k);
|
|
196
|
+
}
|
|
197
|
+
const effective = {};
|
|
198
|
+
for (const axis of declaredAxes) {
|
|
199
|
+
if (axis in callSiteVariants) {
|
|
200
|
+
effective[axis] = normalizeAxisValue(callSiteVariants[axis]);
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
for (let i = rich.length - 1; i >= 0; i--) {
|
|
204
|
+
const d = (_a = rich[i].defaultVariants) == null ? void 0 : _a[axis];
|
|
205
|
+
if (d !== void 0) {
|
|
206
|
+
effective[axis] = normalizeAxisValue(d);
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
for (const [axis, raw] of Object.entries(callSiteVariants)) {
|
|
212
|
+
if (!declaredAxes.has(axis)) {
|
|
213
|
+
console.warn(`Template "${templateName}" path "${path.join(".")}" has no variant axis "${axis}"; ignored.`);
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const wanted = normalizeAxisValue(raw);
|
|
217
|
+
let found = false;
|
|
218
|
+
for (const r of rich) {
|
|
219
|
+
if (((_b = r.variants) == null ? void 0 : _b[axis]) && wanted !== void 0 && wanted in r.variants[axis]) {
|
|
220
|
+
found = true;
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (!found && wanted !== void 0) {
|
|
225
|
+
const anyBundle = rich.some((r) => r.variants && axis in r.variants);
|
|
226
|
+
if (anyBundle) {
|
|
227
|
+
console.warn(`Template "${templateName}" axis "${axis}" has no value "${wanted}" on path "${path.join(".")}"; ignored.`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const acc = {};
|
|
232
|
+
for (const r of rich) {
|
|
233
|
+
if (r.base) Object.assign(acc, r.base);
|
|
234
|
+
}
|
|
235
|
+
for (const axis of Object.keys(effective)) {
|
|
236
|
+
const value = effective[axis];
|
|
237
|
+
if (value === void 0) continue;
|
|
238
|
+
for (let i = rich.length - 1; i >= 0; i--) {
|
|
239
|
+
const bundle = (_d = (_c = rich[i].variants) == null ? void 0 : _c[axis]) == null ? void 0 : _d[value];
|
|
240
|
+
if (bundle) {
|
|
241
|
+
Object.assign(acc, bundle);
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
for (const r of rich) {
|
|
247
|
+
if (r.compoundVariants) {
|
|
248
|
+
for (const entry of r.compoundVariants) {
|
|
249
|
+
if (matchesAll(entry, effective) && entry.css) Object.assign(acc, entry.css);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (r.anyOfVariants) {
|
|
253
|
+
for (const entry of r.anyOfVariants) {
|
|
254
|
+
if (matchesAny(entry, effective) && entry.css) Object.assign(acc, entry.css);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return acc;
|
|
259
|
+
};
|
|
96
260
|
const parseStyles = async (styles, currentScope = "", config, omitTemplates = false) => {
|
|
97
261
|
if (!styles) throw new Error("No styles provided to parseStyles function!");
|
|
98
262
|
const cssStyles = /* @__PURE__ */ new Set();
|
|
@@ -136,13 +300,29 @@ const parseStyles = async (styles, currentScope = "", config, omitTemplates = fa
|
|
|
136
300
|
}
|
|
137
301
|
if ((config == null ? void 0 : config.templates) && config.templates[_key]) {
|
|
138
302
|
if (omitTemplates) return void 0;
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
if (
|
|
142
|
-
const
|
|
143
|
-
|
|
303
|
+
const root = config.templates[_key];
|
|
304
|
+
const callSite = parseTemplateCallSite(value);
|
|
305
|
+
if (callSite) {
|
|
306
|
+
const { path, variants } = callSite;
|
|
307
|
+
const hasCallSiteVariants = Object.keys(variants).length > 0;
|
|
308
|
+
if (hasCallSiteVariants || pathHasRichNode(root, path)) {
|
|
309
|
+
const resolved2 = resolveRichTemplate(root, path, variants, _key);
|
|
310
|
+
if (resolved2) {
|
|
311
|
+
const [result] = await parseStyles(resolved2, "");
|
|
312
|
+
return result;
|
|
313
|
+
}
|
|
314
|
+
console.warn(`Template "${_key}" with path of "${path.join(".")}" was not found in config!`);
|
|
315
|
+
return void 0;
|
|
316
|
+
}
|
|
317
|
+
const templateStyles = path.reduce((acc, key2) => acc == null ? void 0 : acc[key2], root);
|
|
318
|
+
if (templateStyles) {
|
|
319
|
+
const [result] = await parseStyles(templateStyles, "");
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
console.warn(`Template "${_key}" with path of "${path.join(".")}" was not found in config!`);
|
|
323
|
+
return void 0;
|
|
144
324
|
}
|
|
145
|
-
console.warn(`Template "${_key}"
|
|
325
|
+
console.warn(`Template "${_key}" received an unsupported call-site value.`);
|
|
146
326
|
return void 0;
|
|
147
327
|
}
|
|
148
328
|
const isVariantArrayKey = _key === "compoundVariants" || _key === "anyOfVariants";
|
|
@@ -327,6 +507,7 @@ export {
|
|
|
327
507
|
parseVariableTokens as b,
|
|
328
508
|
parseValueModifiers as c,
|
|
329
509
|
parseValueTokens as d,
|
|
510
|
+
isRichTemplateNode as i,
|
|
330
511
|
parseAndJoinStyles as p,
|
|
331
512
|
reportParserIssue as r
|
|
332
513
|
};
|
package/parsers/index.cjs
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const parseStyles = require("../parse-styles-
|
|
3
|
+
const parseStyles = require("../parse-styles-BFoV7HiL.cjs");
|
|
4
4
|
const dashCase = require("../dash-case-DIwKaYgE.cjs");
|
|
5
5
|
const toHash = require("../to-hash-C05Y906F.cjs");
|
|
6
|
+
const RICH_META_KEYS = /* @__PURE__ */ new Set(["base", "variants", "defaultVariants", "compoundVariants", "anyOfVariants"]);
|
|
7
|
+
const isChildEntry = (key, value) => {
|
|
8
|
+
if (RICH_META_KEYS.has(key)) return false;
|
|
9
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
10
|
+
};
|
|
6
11
|
const parseTemplates = async (obj, path = []) => {
|
|
7
12
|
if (!obj) return "";
|
|
8
13
|
const classes = [];
|
|
14
|
+
if (parseStyles.isRichTemplateNode(obj)) {
|
|
15
|
+
const rich = obj;
|
|
16
|
+
if (rich.base) {
|
|
17
|
+
const className = path.map((p) => dashCase.dashCase(String(p))).join("-");
|
|
18
|
+
const hashClass = "t_" + toHash.toHash(className, 4);
|
|
19
|
+
const result = await parseStyles.parseAndJoinStyles(rich.base, `.${className}, .${hashClass}`);
|
|
20
|
+
classes.push(result);
|
|
21
|
+
}
|
|
22
|
+
for (const [key, value] of Object.entries(rich)) {
|
|
23
|
+
if (!isChildEntry(key, value)) continue;
|
|
24
|
+
const result = await parseTemplates(value, [...path, key.trim()]);
|
|
25
|
+
classes.push(result);
|
|
26
|
+
}
|
|
27
|
+
return classes.join("\n");
|
|
28
|
+
}
|
|
9
29
|
const levelStyles = {};
|
|
10
30
|
for (const [key, value] of Object.entries(obj)) {
|
|
11
31
|
if (typeof value === "function") ;
|
|
@@ -18,7 +38,7 @@ const parseTemplates = async (obj, path = []) => {
|
|
|
18
38
|
}
|
|
19
39
|
}
|
|
20
40
|
if (Object.keys(levelStyles).length) {
|
|
21
|
-
const className = path.map(dashCase.dashCase).join("-");
|
|
41
|
+
const className = path.map((p) => dashCase.dashCase(String(p))).join("-");
|
|
22
42
|
const hashClass = "t_" + toHash.toHash(className, 4);
|
|
23
43
|
const result = await parseStyles.parseAndJoinStyles(levelStyles, `.${className}, .${hashClass}`);
|
|
24
44
|
classes.push(result);
|
|
@@ -40,13 +60,69 @@ const getTemplateTypes = (templates) => {
|
|
|
40
60
|
};
|
|
41
61
|
const getTemplateTokens = (templates, parent = "", templateTokens = /* @__PURE__ */ new Set()) => {
|
|
42
62
|
if (!templates) return [];
|
|
63
|
+
if (parseStyles.isRichTemplateNode(templates)) {
|
|
64
|
+
if (parent) templateTokens.add(parent);
|
|
65
|
+
Object.entries(templates).forEach(([key, value]) => {
|
|
66
|
+
if (!isChildEntry(key, value)) return;
|
|
67
|
+
const keyValue = parent ? `${parent}.${key}` : key;
|
|
68
|
+
getTemplateTokens(value, keyValue, templateTokens);
|
|
69
|
+
});
|
|
70
|
+
return [...templateTokens];
|
|
71
|
+
}
|
|
43
72
|
Object.entries(templates).forEach(([key, value]) => {
|
|
44
73
|
const keyValue = parent ? `${parent}.${key}` : key;
|
|
45
|
-
if (typeof value === "object") return getTemplateTokens(value, keyValue, templateTokens);
|
|
74
|
+
if (value && typeof value === "object") return getTemplateTokens(value, keyValue, templateTokens);
|
|
46
75
|
return templateTokens.add(parent);
|
|
47
76
|
});
|
|
48
77
|
return [...templateTokens];
|
|
49
78
|
};
|
|
79
|
+
const getTemplateVariantMaps = (templates) => {
|
|
80
|
+
const result = {};
|
|
81
|
+
if (!templates) return result;
|
|
82
|
+
for (const [topKey, topNode] of Object.entries(templates)) {
|
|
83
|
+
if (!topNode || typeof topNode !== "object" || typeof topNode === "function") continue;
|
|
84
|
+
walk(topNode, [], result[topKey] || (result[topKey] = {}), {});
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
};
|
|
88
|
+
const mergeAxes = (inherited, node) => {
|
|
89
|
+
const next = {};
|
|
90
|
+
for (const [axis, vals] of Object.entries(inherited)) {
|
|
91
|
+
next[axis] = { ...vals };
|
|
92
|
+
}
|
|
93
|
+
if (parseStyles.isRichTemplateNode(node) && node.variants) {
|
|
94
|
+
for (const [axis, valueMap] of Object.entries(node.variants)) {
|
|
95
|
+
next[axis] = next[axis] || {};
|
|
96
|
+
for (const value of Object.keys(valueMap)) next[axis][value] = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return next;
|
|
100
|
+
};
|
|
101
|
+
const walk = (node, path, out, inheritedAxes) => {
|
|
102
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return;
|
|
103
|
+
const axes = mergeAxes(inheritedAxes, node);
|
|
104
|
+
const dot = path.join(".");
|
|
105
|
+
if (path.length && (parseStyles.isRichTemplateNode(node) || Object.keys(axes).length)) {
|
|
106
|
+
const axisMap = {};
|
|
107
|
+
for (const [axis, valSet] of Object.entries(axes)) {
|
|
108
|
+
const values = Object.keys(valSet);
|
|
109
|
+
const isBooleanOnly = values.length === 1 && values[0] === "true";
|
|
110
|
+
axisMap[axis] = isBooleanOnly ? "boolean" : values.map((v) => `"${v}"`).join(" | ");
|
|
111
|
+
}
|
|
112
|
+
if (Object.keys(axisMap).length) out[dot] = axisMap;
|
|
113
|
+
}
|
|
114
|
+
if (parseStyles.isRichTemplateNode(node)) {
|
|
115
|
+
for (const [key, value] of Object.entries(node)) {
|
|
116
|
+
if (!isChildEntry(key, value)) continue;
|
|
117
|
+
walk(value, [...path, key.trim()], out, axes);
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
for (const [key, value] of Object.entries(node)) {
|
|
122
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
123
|
+
walk(value, [...path, key.trim()], out, axes);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
50
126
|
exports.parseAndJoinStyles = parseStyles.parseAndJoinStyles;
|
|
51
127
|
exports.parseStyles = parseStyles.parseStyles;
|
|
52
128
|
exports.parseValueModifiers = parseStyles.parseValueModifiers;
|
|
@@ -56,4 +132,5 @@ exports.reportParserIssue = parseStyles.reportParserIssue;
|
|
|
56
132
|
exports.getTemplateKeys = getTemplateKeys;
|
|
57
133
|
exports.getTemplateTokens = getTemplateTokens;
|
|
58
134
|
exports.getTemplateTypes = getTemplateTypes;
|
|
135
|
+
exports.getTemplateVariantMaps = getTemplateVariantMaps;
|
|
59
136
|
exports.parseTemplates = parseTemplates;
|
package/parsers/index.js
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
import { p as parseAndJoinStyles } from "../parse-styles
|
|
2
|
-
import { a, c, d, b, r } from "../parse-styles
|
|
1
|
+
import { i as isRichTemplateNode, p as parseAndJoinStyles } from "../parse-styles-CtA-RKqt.js";
|
|
2
|
+
import { a, c, d, b, r } from "../parse-styles-CtA-RKqt.js";
|
|
3
3
|
import { d as dashCase } from "../dash-case-DblXvymC.js";
|
|
4
4
|
import { t as toHash } from "../to-hash-DAN2LcHK.js";
|
|
5
|
+
const RICH_META_KEYS = /* @__PURE__ */ new Set(["base", "variants", "defaultVariants", "compoundVariants", "anyOfVariants"]);
|
|
6
|
+
const isChildEntry = (key, value) => {
|
|
7
|
+
if (RICH_META_KEYS.has(key)) return false;
|
|
8
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9
|
+
};
|
|
5
10
|
const parseTemplates = async (obj, path = []) => {
|
|
6
11
|
if (!obj) return "";
|
|
7
12
|
const classes = [];
|
|
13
|
+
if (isRichTemplateNode(obj)) {
|
|
14
|
+
const rich = obj;
|
|
15
|
+
if (rich.base) {
|
|
16
|
+
const className = path.map((p) => dashCase(String(p))).join("-");
|
|
17
|
+
const hashClass = "t_" + toHash(className, 4);
|
|
18
|
+
const result = await parseAndJoinStyles(rich.base, `.${className}, .${hashClass}`);
|
|
19
|
+
classes.push(result);
|
|
20
|
+
}
|
|
21
|
+
for (const [key, value] of Object.entries(rich)) {
|
|
22
|
+
if (!isChildEntry(key, value)) continue;
|
|
23
|
+
const result = await parseTemplates(value, [...path, key.trim()]);
|
|
24
|
+
classes.push(result);
|
|
25
|
+
}
|
|
26
|
+
return classes.join("\n");
|
|
27
|
+
}
|
|
8
28
|
const levelStyles = {};
|
|
9
29
|
for (const [key, value] of Object.entries(obj)) {
|
|
10
30
|
if (typeof value === "function") ;
|
|
@@ -17,7 +37,7 @@ const parseTemplates = async (obj, path = []) => {
|
|
|
17
37
|
}
|
|
18
38
|
}
|
|
19
39
|
if (Object.keys(levelStyles).length) {
|
|
20
|
-
const className = path.map(dashCase).join("-");
|
|
40
|
+
const className = path.map((p) => dashCase(String(p))).join("-");
|
|
21
41
|
const hashClass = "t_" + toHash(className, 4);
|
|
22
42
|
const result = await parseAndJoinStyles(levelStyles, `.${className}, .${hashClass}`);
|
|
23
43
|
classes.push(result);
|
|
@@ -39,17 +59,74 @@ const getTemplateTypes = (templates) => {
|
|
|
39
59
|
};
|
|
40
60
|
const getTemplateTokens = (templates, parent = "", templateTokens = /* @__PURE__ */ new Set()) => {
|
|
41
61
|
if (!templates) return [];
|
|
62
|
+
if (isRichTemplateNode(templates)) {
|
|
63
|
+
if (parent) templateTokens.add(parent);
|
|
64
|
+
Object.entries(templates).forEach(([key, value]) => {
|
|
65
|
+
if (!isChildEntry(key, value)) return;
|
|
66
|
+
const keyValue = parent ? `${parent}.${key}` : key;
|
|
67
|
+
getTemplateTokens(value, keyValue, templateTokens);
|
|
68
|
+
});
|
|
69
|
+
return [...templateTokens];
|
|
70
|
+
}
|
|
42
71
|
Object.entries(templates).forEach(([key, value]) => {
|
|
43
72
|
const keyValue = parent ? `${parent}.${key}` : key;
|
|
44
|
-
if (typeof value === "object") return getTemplateTokens(value, keyValue, templateTokens);
|
|
73
|
+
if (value && typeof value === "object") return getTemplateTokens(value, keyValue, templateTokens);
|
|
45
74
|
return templateTokens.add(parent);
|
|
46
75
|
});
|
|
47
76
|
return [...templateTokens];
|
|
48
77
|
};
|
|
78
|
+
const getTemplateVariantMaps = (templates) => {
|
|
79
|
+
const result = {};
|
|
80
|
+
if (!templates) return result;
|
|
81
|
+
for (const [topKey, topNode] of Object.entries(templates)) {
|
|
82
|
+
if (!topNode || typeof topNode !== "object" || typeof topNode === "function") continue;
|
|
83
|
+
walk(topNode, [], result[topKey] || (result[topKey] = {}), {});
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
};
|
|
87
|
+
const mergeAxes = (inherited, node) => {
|
|
88
|
+
const next = {};
|
|
89
|
+
for (const [axis, vals] of Object.entries(inherited)) {
|
|
90
|
+
next[axis] = { ...vals };
|
|
91
|
+
}
|
|
92
|
+
if (isRichTemplateNode(node) && node.variants) {
|
|
93
|
+
for (const [axis, valueMap] of Object.entries(node.variants)) {
|
|
94
|
+
next[axis] = next[axis] || {};
|
|
95
|
+
for (const value of Object.keys(valueMap)) next[axis][value] = true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return next;
|
|
99
|
+
};
|
|
100
|
+
const walk = (node, path, out, inheritedAxes) => {
|
|
101
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return;
|
|
102
|
+
const axes = mergeAxes(inheritedAxes, node);
|
|
103
|
+
const dot = path.join(".");
|
|
104
|
+
if (path.length && (isRichTemplateNode(node) || Object.keys(axes).length)) {
|
|
105
|
+
const axisMap = {};
|
|
106
|
+
for (const [axis, valSet] of Object.entries(axes)) {
|
|
107
|
+
const values = Object.keys(valSet);
|
|
108
|
+
const isBooleanOnly = values.length === 1 && values[0] === "true";
|
|
109
|
+
axisMap[axis] = isBooleanOnly ? "boolean" : values.map((v) => `"${v}"`).join(" | ");
|
|
110
|
+
}
|
|
111
|
+
if (Object.keys(axisMap).length) out[dot] = axisMap;
|
|
112
|
+
}
|
|
113
|
+
if (isRichTemplateNode(node)) {
|
|
114
|
+
for (const [key, value] of Object.entries(node)) {
|
|
115
|
+
if (!isChildEntry(key, value)) continue;
|
|
116
|
+
walk(value, [...path, key.trim()], out, axes);
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
for (const [key, value] of Object.entries(node)) {
|
|
121
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
122
|
+
walk(value, [...path, key.trim()], out, axes);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
49
125
|
export {
|
|
50
126
|
getTemplateKeys,
|
|
51
127
|
getTemplateTokens,
|
|
52
128
|
getTemplateTypes,
|
|
129
|
+
getTemplateVariantMaps,
|
|
53
130
|
parseAndJoinStyles,
|
|
54
131
|
a as parseStyles,
|
|
55
132
|
parseTemplates,
|
|
@@ -2,3 +2,13 @@ export declare const parseTemplates: <T extends object>(obj: T, path?: PropertyK
|
|
|
2
2
|
export declare const getTemplateKeys: <T extends object>(templates: T) => string[];
|
|
3
3
|
export declare const getTemplateTypes: <T extends object>(templates: T) => Record<string, string>;
|
|
4
4
|
export declare const getTemplateTokens: <T extends object>(templates: T, parent?: string, templateTokens?: Set<string>) => string[];
|
|
5
|
+
/**
|
|
6
|
+
* Walk every rich-template path in a templates root and emit, for each reachable dot-path, the set of
|
|
7
|
+
* variant axes valid at that path (axis name → union of value names, with `boolean` for axes whose only
|
|
8
|
+
* declared value is `true`).
|
|
9
|
+
*
|
|
10
|
+
* Inheritance: a leaf's axis enum is the union of its own values and every ancestor's values for the
|
|
11
|
+
* same axis. Matches the resolver's bottom-up lookup semantics — anything reachable via fallback is a
|
|
12
|
+
* valid call-site value.
|
|
13
|
+
*/
|
|
14
|
+
export declare const getTemplateVariantMaps: (templates: Record<string, any>) => Record<string, Record<string, Record<string, string>>>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RichTemplateNode } from '../types/config-types';
|
|
2
|
+
export type TemplateCallSite = {
|
|
3
|
+
path: string[];
|
|
4
|
+
variants: Record<string, string | boolean>;
|
|
5
|
+
};
|
|
6
|
+
export declare const isRichTemplateNode: (node: unknown) => node is RichTemplateNode;
|
|
7
|
+
/**
|
|
8
|
+
* Parse a template call-site value into its dot-path and the axis values requested at the call site.
|
|
9
|
+
*
|
|
10
|
+
* String form: `'heading.large@weight=heavy&emphasis=loud&italic'`
|
|
11
|
+
* Object form: `{ name: 'heading.large', weight: 'heavy', emphasis: 'loud', italic: true }`
|
|
12
|
+
*/
|
|
13
|
+
export declare const parseTemplateCallSite: (value: unknown) => TemplateCallSite | undefined;
|
|
14
|
+
export declare const pathHasRichNode: (root: any, path: string[]) => boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a rich-template invocation into a flat CSS-in-JS object.
|
|
17
|
+
* Implements docs/template-variants-spec.md §5 (parent-to-leaf inheritance, replace semantics).
|
|
18
|
+
*
|
|
19
|
+
* Returns `undefined` if the path doesn't resolve. Emits console.warn for unknown axes / values.
|
|
20
|
+
*/
|
|
21
|
+
export declare const resolveRichTemplate: (root: any, path: string[], callSiteVariants: Record<string, string | boolean>, templateName: string) => Record<string, any> | undefined;
|
package/runtime/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const parseStyles = require("../parse-styles-
|
|
3
|
+
const parseStyles = require("../parse-styles-BFoV7HiL.cjs");
|
|
4
4
|
const defineRuntime = (config) => {
|
|
5
5
|
const getDynamicStylesCss = async (styles, scope) => {
|
|
6
6
|
const parsed = await parseStyles.parseStyles(styles, scope, config);
|
package/runtime/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as parseStyles } from "../parse-styles
|
|
1
|
+
import { a as parseStyles } from "../parse-styles-CtA-RKqt.js";
|
|
2
2
|
const defineRuntime = (config) => {
|
|
3
3
|
const getDynamicStylesCss = async (styles, scope) => {
|
|
4
4
|
const parsed = await parseStyles(styles, scope, config);
|
package/types/config-types.d.ts
CHANGED
|
@@ -16,7 +16,38 @@ export interface SaltyVariables {
|
|
|
16
16
|
conditional?: CssConditionalVariables;
|
|
17
17
|
[key: string]: undefined | string | number | CssVariableTokensObject;
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* A variant axis value bundle: a map from axis name to a map from value name (string keys or `'true'`)
|
|
21
|
+
* to a CSS-in-JS block. `name` is reserved as the call-site object form's path key and cannot be used
|
|
22
|
+
* as an axis name (build-time error).
|
|
23
|
+
*/
|
|
24
|
+
export type CssVariantAxes = {
|
|
25
|
+
[axis: string]: {
|
|
26
|
+
[value: string]: CssStyles;
|
|
27
|
+
};
|
|
28
|
+
} & {
|
|
29
|
+
name?: never;
|
|
30
|
+
};
|
|
31
|
+
export interface CssCompoundVariant {
|
|
32
|
+
css: CssStyles;
|
|
33
|
+
[axis: string]: any;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A "rich" template node: declares its own base styles, named variant bundles, defaults, and compound rules.
|
|
37
|
+
* May coexist with child template nodes (descendants) as additional sibling keys.
|
|
38
|
+
*/
|
|
39
|
+
export type RichTemplateNode = {
|
|
40
|
+
base?: CssStyles;
|
|
41
|
+
variants?: CssVariantAxes;
|
|
42
|
+
defaultVariants?: {
|
|
43
|
+
[axis: string]: string | boolean;
|
|
44
|
+
};
|
|
45
|
+
compoundVariants?: CssCompoundVariant[];
|
|
46
|
+
anyOfVariants?: CssCompoundVariant[];
|
|
47
|
+
} & {
|
|
48
|
+
[key: PropertyKey]: any;
|
|
49
|
+
};
|
|
50
|
+
type CssTemplate = MediaQueryStyles | CssStyles | RichTemplateNode | {
|
|
20
51
|
[key: PropertyKey]: CssTemplate;
|
|
21
52
|
};
|
|
22
53
|
export interface CssTemplateObject {
|