@jxsuite/compiler 0.22.0 → 0.22.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxsuite/compiler",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "description": "Jx static HTML compiler, island detector, and site builder",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,8 +38,8 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@apidevtools/json-schema-ref-parser": "^15.3.5",
41
- "@jxsuite/parser": "^0.22.0",
42
- "@jxsuite/runtime": "^0.22.0",
41
+ "@jxsuite/parser": "^0.22.1",
42
+ "@jxsuite/runtime": "^0.22.1",
43
43
  "remark-gfm": "^4.0.1",
44
44
  "remark-stringify": "^11.0.0",
45
45
  "sharp": "^0.34.5",
package/src/shared.js CHANGED
@@ -518,11 +518,11 @@ export function compileStyles(doc, mediaQueries = {}, projectStyle = null) {
518
518
  for (const [key, val] of Object.entries(obj)) {
519
519
  if (val === null || typeof val !== "object" || Array.isArray(val)) continue;
520
520
  if (key.startsWith("@")) {
521
- const query = key.startsWith("@--")
522
- ? (mediaQueries[key.slice(1)] ?? key.slice(1))
523
- : key.slice(1);
521
+ const atRule = key.startsWith("@--")
522
+ ? `@media ${mediaQueries[key.slice(1)] ?? key.slice(1)}`
523
+ : key;
524
524
  const mProps = toCSSText(val);
525
- if (mProps) rules.push(`@media ${query} { ${selector} { ${mProps} } }`);
525
+ if (mProps) rules.push(`${atRule} { ${selector} { ${mProps} } }`);
526
526
  for (const [sel, sub] of Object.entries(/** @type {Record<string, unknown>} */ (val))) {
527
527
  if (sub === null || typeof sub !== "object" || Array.isArray(sub)) continue;
528
528
  if (sel.startsWith("@")) continue;
@@ -532,7 +532,7 @@ export function compileStyles(doc, mediaQueries = {}, projectStyle = null) {
532
532
  ? `${selector}${sel}`
533
533
  : `${selector} ${sel}`;
534
534
  const subProps = toCSSText(sub);
535
- if (subProps) rules.push(`@media ${query} { ${resolved} { ${subProps} } }`);
535
+ if (subProps) rules.push(`${atRule} { ${resolved} { ${subProps} } }`);
536
536
  }
537
537
  continue;
538
538
  }
@@ -558,10 +558,12 @@ export function compileStyles(doc, mediaQueries = {}, projectStyle = null) {
558
558
  emitProjectRules(key, val);
559
559
  } else if (key.startsWith("@")) {
560
560
  // @media block at top level
561
- const query = key.startsWith("@--")
562
- ? (mediaQueries[key.slice(1)] ?? key.slice(1))
563
- : key.slice(1);
564
- rules.push(`@media ${query} { body { ${toCSSText(/** @type {object} */ (val))} } }`);
561
+ const atRule = key.startsWith("@--")
562
+ ? `@media ${mediaQueries[key.slice(1)] ?? key.slice(1)}`
563
+ : key.startsWith("@(")
564
+ ? `@media ${key.slice(1)}`
565
+ : key;
566
+ rules.push(`${atRule} { body { ${toCSSText(/** @type {object} */ (val))} } }`);
565
567
  }
566
568
  }
567
569
  // Collect CSS custom properties into :root {}
@@ -610,11 +612,13 @@ function emitNestedElement(selector, obj, rules, mediaQueries) {
610
612
  for (const [key, val] of Object.entries(obj)) {
611
613
  if (val === null || typeof val !== "object" || Array.isArray(val)) continue;
612
614
  if (key.startsWith("@")) {
613
- const query = key.startsWith("@--")
614
- ? (mediaQueries[key.slice(1)] ?? key.slice(1))
615
- : key.slice(1);
615
+ const atRule = key.startsWith("@--")
616
+ ? `@media ${mediaQueries[key.slice(1)] ?? key.slice(1)}`
617
+ : key.startsWith("@(")
618
+ ? `@media ${key.slice(1)}`
619
+ : key;
616
620
  const mProps = toCSSText(val);
617
- if (mProps) rules.push(`@media ${query} { ${selector} { ${mProps} } }`);
621
+ if (mProps) rules.push(`${atRule} { ${selector} { ${mProps} } }`);
618
622
  for (const [sel, sub] of Object.entries(/** @type {Record<string, unknown>} */ (val))) {
619
623
  if (sub === null || typeof sub !== "object" || Array.isArray(sub)) continue;
620
624
  if (sel.startsWith("@")) continue;
@@ -624,7 +628,7 @@ function emitNestedElement(selector, obj, rules, mediaQueries) {
624
628
  ? `${selector}${sel}`
625
629
  : `${selector} ${sel}`;
626
630
  const subProps = toCSSText(sub);
627
- if (subProps) rules.push(`@media ${query} { ${resolved} { ${subProps} } }`);
631
+ if (subProps) rules.push(`${atRule} { ${resolved} { ${subProps} } }`);
628
632
  }
629
633
  continue;
630
634
  }
@@ -688,10 +692,13 @@ export function collectStyles(
688
692
  for (const [prop, val] of Object.entries(def.style)) {
689
693
  if (val === null || typeof val !== "object" || Array.isArray(val)) continue;
690
694
  if (prop.startsWith("@")) {
691
- const query = prop.startsWith("@--")
692
- ? (mediaQueries[prop.slice(1)] ?? prop.slice(1))
693
- : prop.slice(1);
694
- rules.push(`@media ${query} { ${selector} { ${toCSSText(val)} } }`);
695
+ const atRule = prop.startsWith("@--")
696
+ ? `@media ${mediaQueries[prop.slice(1)] ?? prop.slice(1)}`
697
+ : prop.startsWith("@(")
698
+ ? `@media ${prop.slice(1)}`
699
+ : prop;
700
+ const atBaseProps = toCSSText(val);
701
+ if (atBaseProps) rules.push(`${atRule} { ${selector} { ${atBaseProps} } }`);
695
702
  for (const [sel, nestedRules] of Object.entries(
696
703
  /** @type {Record<string, unknown>} */ (val),
697
704
  )) {
@@ -703,7 +710,7 @@ export function collectStyles(
703
710
  : sel.startsWith(":") || sel.startsWith(".") || sel.startsWith("[")
704
711
  ? `${selector}${sel}`
705
712
  : `${selector} ${sel}`;
706
- rules.push(`@media ${query} { ${resolved} { ${toCSSText(nestedRules)} } }`);
713
+ rules.push(`${atRule} { ${resolved} { ${toCSSText(nestedRules)} } }`);
707
714
  }
708
715
  } else {
709
716
  const resolved = prop.startsWith("&")
@@ -1038,10 +1045,12 @@ export function buildComponentCSS(tagName, styleDef, doc = null, mediaQueries =
1038
1045
 
1039
1046
  for (const [prop, val] of Object.entries(styleDef)) {
1040
1047
  if (prop.startsWith("@")) {
1041
- const query = prop.startsWith("@--")
1042
- ? (mediaQueries[prop.slice(1)] ?? prop.slice(1))
1043
- : prop.slice(1);
1044
- rules.push(`@media ${query} { ${tagName} { ${toCSSText(/** @type {object} */ (val))} } }`);
1048
+ const atRule = prop.startsWith("@--")
1049
+ ? `@media ${mediaQueries[prop.slice(1)] ?? prop.slice(1)}`
1050
+ : prop.startsWith("@(")
1051
+ ? `@media ${prop.slice(1)}`
1052
+ : prop;
1053
+ rules.push(`${atRule} { ${tagName} { ${toCSSText(/** @type {object} */ (val))} } }`);
1045
1054
  } else if (
1046
1055
  prop.startsWith(":") ||
1047
1056
  prop.startsWith(".") ||
@@ -134,7 +134,7 @@ export async function buildSite(projectRoot, options = {}) {
134
134
  for (const file of componentFiles) {
135
135
  try {
136
136
  const componentPath = resolve(componentsDir, file);
137
- const result = await compileElement(componentPath);
137
+ const result = await compileElement(componentPath, { $media: projectConfig.$media });
138
138
  for (const f of result.files) {
139
139
  const outName = f.path.includes("/")
140
140
  ? /** @type {string} */ (f.path.split("/").pop())
@@ -16,7 +16,7 @@ import { escapeHtml, tagNameToClassName, isSchemaOnly, collectStyles } from "../
16
16
  * @returns {Promise<{ files: { path: string; content: string; tagName: string }[] }>}
17
17
  */
18
18
  export async function compileElement(sourcePath, opts = {}) {
19
- const { resolveElementPath } = /** @type {JxMutableNode} */ (opts);
19
+ const { resolveElementPath, $media: optsMedia } = /** @type {JxMutableNode} */ (opts);
20
20
  /** @type {{ path: string; content: string; tagName: string }[]} */
21
21
  const files = [];
22
22
  /** @type {Set<string>} */
@@ -82,6 +82,9 @@ export async function compileElement(sourcePath, opts = {}) {
82
82
  }
83
83
 
84
84
  const className = tagNameToClassName(tagName);
85
+ if (optsMedia) {
86
+ doc.$media = { ...optsMedia, ...doc.$media };
87
+ }
85
88
  const jsContent = emitElementModule(doc, className, elementImports);
86
89
  const outputPath = filePath ? filePath.replace(/\.json$/, ".js") : `${tagName}.js`;
87
90
  files.push({ path: outputPath, content: jsContent, tagName });