@jxsuite/studio 1.1.0 → 1.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.
@@ -2626,11 +2626,21 @@ function applyStyle(el, styleDef, mediaQueries = {}, state = {}) {
2626
2626
  if (key === "@--") {
2627
2627
  continue;
2628
2628
  }
2629
- const atRule = key.startsWith("@--") ? `@media ${mediaQueries[key.slice(1)] ?? key.slice(1)}` : key.startsWith("@(") ? `@media ${key.slice(1)}` : key;
2629
+ const query = key.startsWith("@--") ? mediaQueries[key.slice(1)] ?? key.slice(1) : key.startsWith("@(") ? key.slice(1) : null;
2630
+ const atRule = query === null ? key : `@media ${query}`;
2630
2631
  const scope = `[data-jx="${uid}"]`;
2631
- css += `${atRule} { ${scope} { ${toCSSText(rules)} } }
2632
+ const scheme = query === null ? null : pureSchemeOf(query);
2633
+ if (scheme) {
2634
+ const { auto, forced } = schemeSelectors(scope, scheme);
2635
+ css += `${atRule} { ${auto} { ${toCSSText(rules)} } }
2632
2636
  `;
2633
- emitMediaNested(atRule, scope, rules);
2637
+ emitMediaNested(atRule, auto, rules);
2638
+ emitNested(forced, rules);
2639
+ } else {
2640
+ css += `${atRule} { ${scope} { ${toCSSText(rules)} } }
2641
+ `;
2642
+ emitMediaNested(atRule, scope, rules);
2643
+ }
2634
2644
  }
2635
2645
  const tag = document.createElement("style");
2636
2646
  tag.textContent = css;
@@ -3318,6 +3328,23 @@ function camelToKebab(s) {
3318
3328
  function toCSSText(rules) {
3319
3329
  return Object.entries(rules).filter(([k, v]) => !isNestedSelector(k) && (v === null || typeof v !== "object")).map(([p, v]) => `${camelToKebab(p)}: ${transposeCanvasUnits(String(v))}`).join("; ");
3320
3330
  }
3331
+ var COLOR_SCHEME_ATTR = "data-color-scheme";
3332
+ function pureSchemeOf(query) {
3333
+ const m = /^\(\s*prefers-color-scheme\s*:\s*(light|dark)\s*\)$/.exec(query.trim());
3334
+ return m?.[1] ?? null;
3335
+ }
3336
+ function schemeSelectors(selector, scheme) {
3337
+ if (selector === ":root" || selector === "html") {
3338
+ return {
3339
+ auto: `${selector}:where(:not([${COLOR_SCHEME_ATTR}]))`,
3340
+ forced: `${selector}:where([${COLOR_SCHEME_ATTR}="${scheme}"])`
3341
+ };
3342
+ }
3343
+ return {
3344
+ auto: `:where(:root:not([${COLOR_SCHEME_ATTR}])) ${selector}`,
3345
+ forced: `:where(:root[${COLOR_SCHEME_ATTR}="${scheme}"]) ${selector}`
3346
+ };
3347
+ }
3321
3348
  var _rootMedia = {};
3322
3349
  var _elementDefs = new Map;
3323
3350
  function setRootMedia(map) {
@@ -3573,6 +3600,86 @@ function parseJxPath(serialized) {
3573
3600
  return JSON.parse(serialized);
3574
3601
  }
3575
3602
 
3603
+ // src/canvas/site-style-css.ts
3604
+ var SITE_STYLE_ID = "jx-site-style";
3605
+ function toDecls(props, transpose) {
3606
+ return Object.entries(props).map(([key, value]) => `${camelToKebab(key)}: ${transpose(String(value))}`).join("; ");
3607
+ }
3608
+ function buildSiteStyleCSS(siteStyle, mediaQueries, transpose) {
3609
+ const rules = [];
3610
+ const rootProps = {};
3611
+ const bodyProps = {};
3612
+ const condBlocks = [];
3613
+ for (const [key, value] of Object.entries(siteStyle)) {
3614
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
3615
+ if (key.startsWith("@")) {
3616
+ condBlocks.push([key, value]);
3617
+ }
3618
+ continue;
3619
+ }
3620
+ if (key.startsWith(":") || key.startsWith(".") || key.startsWith("[") || key.startsWith("@")) {
3621
+ continue;
3622
+ }
3623
+ if (key.startsWith("--")) {
3624
+ rootProps[key] = value;
3625
+ } else {
3626
+ bodyProps[key] = value;
3627
+ }
3628
+ }
3629
+ const rootCSS = toDecls(rootProps, transpose);
3630
+ if (rootCSS) {
3631
+ rules.push(`:root { ${rootCSS} }`);
3632
+ }
3633
+ const bodyCSS = toDecls(bodyProps, transpose);
3634
+ if (bodyCSS) {
3635
+ rules.push(`body { ${bodyCSS} }`);
3636
+ }
3637
+ for (const [atKey, block] of condBlocks) {
3638
+ const query = atKey.startsWith("@--") ? mediaQueries[atKey.slice(1)] ?? atKey.slice(1) : atKey.startsWith("@(") ? atKey.slice(1) : null;
3639
+ if (query === null) {
3640
+ continue;
3641
+ }
3642
+ const scheme = pureSchemeOf(query);
3643
+ const emit = (selector, props) => {
3644
+ if (!props) {
3645
+ return;
3646
+ }
3647
+ if (scheme) {
3648
+ const { auto, forced } = schemeSelectors(selector, scheme);
3649
+ rules.push(`@media ${query} { ${auto} { ${props} } }`, `${forced} { ${props} }`);
3650
+ } else {
3651
+ rules.push(`@media ${query} { ${selector} { ${props} } }`);
3652
+ }
3653
+ };
3654
+ const condRoot = {};
3655
+ const condBody = {};
3656
+ const condSubs = [];
3657
+ for (const [k, v] of Object.entries(block)) {
3658
+ if (v !== null && typeof v === "object" && !Array.isArray(v)) {
3659
+ if (!k.startsWith("@")) {
3660
+ condSubs.push([k, v]);
3661
+ }
3662
+ continue;
3663
+ }
3664
+ if (k.startsWith("--")) {
3665
+ condRoot[k] = v;
3666
+ } else {
3667
+ condBody[k] = v;
3668
+ }
3669
+ }
3670
+ emit(":root", toDecls(condRoot, transpose));
3671
+ emit("body", toDecls(condBody, transpose));
3672
+ for (const [sel, sub] of condSubs) {
3673
+ emit(sel, toDecls(sub, transpose));
3674
+ }
3675
+ }
3676
+ if (Object.values(mediaQueries).some((q) => pureSchemeOf(q) !== null)) {
3677
+ rules.push(":root { color-scheme: light dark }");
3678
+ }
3679
+ return rules.join(`
3680
+ `);
3681
+ }
3682
+
3576
3683
  // src/canvas/iframe-render.ts
3577
3684
  async function registerElements2(doc, docBase) {
3578
3685
  const elements = doc.$elements;
@@ -3772,21 +3879,27 @@ function syncStylebookCss(doc, mode) {
3772
3879
  style.textContent = STYLEBOOK_CSS;
3773
3880
  doc.head.append(style);
3774
3881
  }
3775
- function applySiteStyle(siteStyle) {
3882
+ function applySiteStyle(siteStyle, mediaQueries = {}) {
3883
+ const existing = document.head.querySelector(`#${SITE_STYLE_ID}`);
3776
3884
  if (!siteStyle || typeof siteStyle !== "object") {
3885
+ existing?.remove();
3777
3886
  return;
3778
3887
  }
3779
- const rootStyle = document.documentElement.style;
3780
- const bodyStyle = document.body.style;
3781
- for (const [key, value] of Object.entries(siteStyle)) {
3782
- if (value !== null && typeof value === "object" && !Array.isArray(value)) {
3783
- continue;
3784
- }
3785
- if (key.startsWith("--")) {
3786
- rootStyle.setProperty(key, transposeCanvasUnits(String(value)));
3787
- } else {
3788
- bodyStyle[key] = transposeCanvasUnits(String(value));
3789
- }
3888
+ const css = buildSiteStyleCSS(siteStyle, mediaQueries, transposeCanvasUnits);
3889
+ if (existing) {
3890
+ existing.textContent = css;
3891
+ return;
3892
+ }
3893
+ const tag = document.createElement("style");
3894
+ tag.id = SITE_STYLE_ID;
3895
+ tag.textContent = css;
3896
+ document.head.append(tag);
3897
+ }
3898
+ function applyPreviewColorScheme(doc, scheme) {
3899
+ if (scheme) {
3900
+ doc.documentElement.dataset.colorScheme = scheme;
3901
+ } else {
3902
+ delete doc.documentElement.dataset.colorScheme;
3790
3903
  }
3791
3904
  }
3792
3905
  function injectHead(doc) {
@@ -3868,7 +3981,7 @@ async function renderResolvedDocument(opts) {
3868
3981
  setCanvasViewportTranspose(true);
3869
3982
  setCanvasDelinkAnchors(opts.mode !== "preview");
3870
3983
  setStampPropBindings(opts.mode === "design" || opts.mode === "edit");
3871
- applySiteStyle(opts.siteStyle);
3984
+ applySiteStyle(opts.siteStyle, opts.doc.$media ?? {});
3872
3985
  injectHead(opts.doc);
3873
3986
  syncEditModeCss(opts.container.ownerDocument, opts.mode);
3874
3987
  syncStylebookCss(opts.container.ownerDocument, opts.mode);
@@ -6718,9 +6831,18 @@ function startCanvasIframe(opts) {
6718
6831
  clearIframeDrag();
6719
6832
  return;
6720
6833
  }
6834
+ if (msg.kind === "setColorScheme") {
6835
+ applyPreviewColorScheme(container.ownerDocument, msg.scheme);
6836
+ return;
6837
+ }
6838
+ if (msg.kind === "siteStyleUpdate") {
6839
+ applySiteStyle(msg.siteStyle, msg.media);
6840
+ return;
6841
+ }
6721
6842
  if (msg.kind !== "render" || msg.gen < latestGen) {
6722
6843
  return;
6723
6844
  }
6845
+ applyPreviewColorScheme(container.ownerDocument, msg.colorScheme ?? null);
6724
6846
  if (isEditing()) {
6725
6847
  stopEditing();
6726
6848
  }
@@ -6816,5 +6938,5 @@ export {
6816
6938
  bootCanvasIframe
6817
6939
  };
6818
6940
 
6819
- //# debugId=861006CEFE04044264756E2164756E21
6941
+ //# debugId=4938332B50832C2764756E2164756E21
6820
6942
  //# sourceMappingURL=iframe-entry.js.map