@pixldocs/canvas-renderer 0.3.9 → 0.3.11

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.cjs CHANGED
@@ -8575,6 +8575,47 @@ const PreviewCanvas$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
8575
8575
  __proto__: null,
8576
8576
  PreviewCanvas
8577
8577
  }, Symbol.toStringTag, { value: "Module" }));
8578
+ function applyThemeToConfig(config, themeOverrides) {
8579
+ var _a, _b, _c;
8580
+ if (!themeOverrides || Object.keys(themeOverrides).length === 0) return config;
8581
+ const cloned = JSON.parse(JSON.stringify(config));
8582
+ if ((_a = cloned.themeConfig) == null ? void 0 : _a.variables) {
8583
+ for (const [key, value] of Object.entries(themeOverrides)) {
8584
+ if (cloned.themeConfig.variables[key]) {
8585
+ cloned.themeConfig.variables[key].value = value;
8586
+ }
8587
+ }
8588
+ }
8589
+ const varMap = /* @__PURE__ */ new Map();
8590
+ if ((_b = cloned.themeConfig) == null ? void 0 : _b.variables) {
8591
+ for (const [key, def] of Object.entries(cloned.themeConfig.variables)) {
8592
+ varMap.set(key, themeOverrides[key] ?? def.value);
8593
+ }
8594
+ }
8595
+ function walkAndApply(nodes) {
8596
+ if (!nodes) return;
8597
+ for (const node of nodes) {
8598
+ const bindings = node.themeBindings;
8599
+ if (bindings) {
8600
+ for (const [prop, varName] of Object.entries(bindings)) {
8601
+ const value = varMap.get(varName);
8602
+ if (value !== void 0) {
8603
+ node[prop] = value;
8604
+ }
8605
+ }
8606
+ }
8607
+ if (node.children) walkAndApply(node.children);
8608
+ }
8609
+ }
8610
+ for (const page of cloned.pages || []) {
8611
+ const bgBinding = (_c = page.themeBindings) == null ? void 0 : _c.backgroundColor;
8612
+ if (bgBinding && varMap.has(bgBinding) && page.settings) {
8613
+ page.settings.backgroundColor = varMap.get(bgBinding);
8614
+ }
8615
+ walkAndApply(page.children || []);
8616
+ }
8617
+ return cloned;
8618
+ }
8578
8619
  function mapFormDefFieldType(t) {
8579
8620
  if (["text", "email", "tel", "textarea", "date", "url", "number", "toggle", "color", "image"].includes(t)) return t;
8580
8621
  if (t === "currency") return "number";
@@ -10055,7 +10096,7 @@ async function resolveTemplateData(options) {
10055
10096
  return { config, templateName: template.name || "Untitled", templateId };
10056
10097
  }
10057
10098
  async function resolveFromForm(options) {
10058
- var _a, _b, _c, _d, _e;
10099
+ var _a, _b, _c, _d;
10059
10100
  const { templateId, formSchemaId, sectionState, themeId, supabaseUrl, supabaseAnonKey } = options;
10060
10101
  const [templateRow, formSchemaRow, defaultForm] = await Promise.all([
10061
10102
  fetchRow(supabaseUrl, supabaseAnonKey, "templates", templateId),
@@ -10180,36 +10221,15 @@ async function resolveFromForm(options) {
10180
10221
  Object.keys(repeatableNestedEntryCounts).length > 0 ? repeatableNestedEntryCounts : void 0,
10181
10222
  displayFormatMap.size > 0 ? displayFormatMap : void 0
10182
10223
  );
10183
- if (themeId && themeId !== "default" && templateConfig.themeConfig) {
10184
- const tc = templateConfig.themeConfig;
10185
- const variant = (_d = tc.variants) == null ? void 0 : _d.find((v) => v.id === themeId);
10186
- if (variant && tc.properties) {
10187
- const themed = JSON.parse(JSON.stringify(resolvedConfig));
10188
- for (const prop of tc.properties) {
10189
- const value = (_e = variant.values) == null ? void 0 : _e[prop.id];
10190
- if (value === void 0) continue;
10191
- if (prop.targetProperty === "backgroundColor" && prop.elementId === "__pageBackground__") {
10192
- themed.pages.forEach((p) => {
10193
- p.settings.backgroundColor = value;
10194
- });
10195
- continue;
10196
- }
10197
- for (const page of themed.pages) {
10198
- const els = flattenAll(page.children || []);
10199
- for (const el of els) {
10200
- if (el.id === prop.elementId || baseId(el.id) === baseId(prop.elementId)) {
10201
- if (prop.svgColorKey && el.svgColorMap) {
10202
- el.svgColorMap = { ...el.svgColorMap, [prop.svgColorKey]: value };
10203
- } else {
10204
- el[prop.targetProperty] = value;
10205
- }
10206
- }
10207
- }
10208
- }
10209
- }
10210
- resolvedConfig = themed;
10224
+ if ((_d = resolvedConfig.themeConfig) == null ? void 0 : _d.variables) {
10225
+ const baseOverrides = {};
10226
+ for (const [key, def] of Object.entries(resolvedConfig.themeConfig.variables)) {
10227
+ baseOverrides[key] = def.value;
10211
10228
  }
10229
+ resolvedConfig = applyThemeToConfig(resolvedConfig, baseOverrides);
10212
10230
  }
10231
+ resolvedConfig = applyThemeVariantToConfig(resolvedConfig, templateConfig.themeConfig, themeId);
10232
+ normalizeConfigForEC2Parity(resolvedConfig);
10213
10233
  resolvedConfig = applyContentBoundsPagination(resolvedConfig);
10214
10234
  return {
10215
10235
  config: resolvedConfig,
@@ -10225,6 +10245,101 @@ function flattenAll(nodes) {
10225
10245
  }
10226
10246
  return result;
10227
10247
  }
10248
+ function themeBaseId(id) {
10249
+ if (!id) return id ?? "";
10250
+ let out = id;
10251
+ out = out.replace(/_inner\d+_\d+_/g, "");
10252
+ out = out.replace(/_clone\d+_/g, "");
10253
+ out = out.replace(/_clone_\d+/g, "");
10254
+ while (/_\d+$/.test(out)) out = out.replace(/_\d+$/, "");
10255
+ return out;
10256
+ }
10257
+ function applyThemeVariantToConfig(config, themeConfig, themeId) {
10258
+ var _a, _b, _c, _d;
10259
+ if (!themeConfig) return config;
10260
+ const variant = themeId && themeId !== "default" ? (_a = themeConfig.variants) == null ? void 0 : _a.find((v) => v.id === themeId) : null;
10261
+ const shouldApplyDefaults = !variant && ((_b = themeConfig.properties) == null ? void 0 : _b.length);
10262
+ if (!variant && !shouldApplyDefaults) return config;
10263
+ if (!((_c = themeConfig.properties) == null ? void 0 : _c.length)) return config;
10264
+ const result = JSON.parse(JSON.stringify(config));
10265
+ const cloneIdMap = config.__cloneIdMap || {};
10266
+ const pageElements = result.pages.map((page) => flattenAll(page.children || []));
10267
+ for (const prop of themeConfig.properties) {
10268
+ const value = variant ? (_d = variant.values) == null ? void 0 : _d[prop.id] : prop.defaultValue;
10269
+ if (value === void 0) continue;
10270
+ if (prop.targetProperty === "backgroundColor" && prop.elementId === "__pageBackground__") {
10271
+ result.pages.forEach((p) => {
10272
+ p.settings.backgroundColor = value;
10273
+ });
10274
+ continue;
10275
+ }
10276
+ if (prop.targetProperty === "backgroundGradient" && prop.elementId === "__pageBackground__" && prop.svgColorKey) {
10277
+ const stopMatch = prop.svgColorKey.match(/^stop:(\d+)$/);
10278
+ if (stopMatch) {
10279
+ const stopIndex = parseInt(stopMatch[1], 10);
10280
+ result.pages.forEach((p) => {
10281
+ var _a2, _b2;
10282
+ if ((_b2 = (_a2 = p.settings.backgroundGradient) == null ? void 0 : _a2.stops) == null ? void 0 : _b2[stopIndex]) {
10283
+ p.settings.backgroundGradient = {
10284
+ ...p.settings.backgroundGradient,
10285
+ stops: p.settings.backgroundGradient.stops.map(
10286
+ (s, i) => i === stopIndex ? { ...s, color: value } : s
10287
+ )
10288
+ };
10289
+ }
10290
+ });
10291
+ }
10292
+ continue;
10293
+ }
10294
+ const propBase = themeBaseId(prop.elementId);
10295
+ const targetIds = /* @__PURE__ */ new Set([prop.elementId, propBase]);
10296
+ for (const [mapKey, mappedId] of Object.entries(cloneIdMap)) {
10297
+ if (mapKey.endsWith(`_${prop.elementId}`) || mapKey.endsWith(`_${propBase}`)) {
10298
+ targetIds.add(mappedId);
10299
+ }
10300
+ }
10301
+ for (const els of pageElements) {
10302
+ for (const el of els) {
10303
+ const elBase = themeBaseId(el.id);
10304
+ const sourceId = el.__sourceId;
10305
+ const sourceBase = sourceId ? themeBaseId(sourceId) : void 0;
10306
+ const cloneBase = el.__baseNodeId;
10307
+ const cloneBaseNorm = cloneBase ? themeBaseId(cloneBase) : void 0;
10308
+ const match = targetIds.has(el.id) || targetIds.has(elBase) || (sourceId ? targetIds.has(sourceId) : false) || (sourceBase ? targetIds.has(sourceBase) : false) || (cloneBase ? targetIds.has(cloneBase) : false) || (cloneBaseNorm ? targetIds.has(cloneBaseNorm) : false);
10309
+ if (!match) continue;
10310
+ if (prop.svgColorKey && el.svgColorMap) {
10311
+ el.svgColorMap = { ...el.svgColorMap, [prop.svgColorKey]: value };
10312
+ } else {
10313
+ el[prop.targetProperty] = value;
10314
+ }
10315
+ }
10316
+ }
10317
+ }
10318
+ return result;
10319
+ }
10320
+ function normalizeConfigForEC2Parity(config) {
10321
+ function walk(node) {
10322
+ if (node.layoutMode === "stack" || node.layoutMode === "stacked") {
10323
+ node.layoutMode = "vertical-stack";
10324
+ }
10325
+ const layoutMode = String(node.layoutMode ?? "");
10326
+ const isStack = isVerticalStackLayoutMode(layoutMode) || layoutMode === "horizontal-stack" || layoutMode === "horizontal-fill";
10327
+ if (isStack && node.stackSpacing == null) node.stackSpacing = 8;
10328
+ if (node.type === "text") {
10329
+ const overflowPolicy = String(node.overflowPolicy ?? "grow-and-push");
10330
+ const fontSize = typeof node.fontSize === "number" ? node.fontSize : 16;
10331
+ if (overflowPolicy === "auto-shrink" && fontSize >= 24) node.overflowPolicy = "grow-and-push";
10332
+ delete node.height;
10333
+ }
10334
+ if (Array.isArray(node.children)) {
10335
+ delete node.height;
10336
+ for (const child of node.children) walk(child);
10337
+ }
10338
+ }
10339
+ for (const page of config.pages ?? []) {
10340
+ for (const child of page.children ?? []) walk(child);
10341
+ }
10342
+ }
10228
10343
  function normalizeLayoutModes(config) {
10229
10344
  function walk(node) {
10230
10345
  if (node.layoutMode === "stack" || node.layoutMode === "stacked") {
@@ -10392,20 +10507,30 @@ async function loadGoogleFontCSS(rawFontFamily) {
10392
10507
  loadingPromises.delete(fontFamily);
10393
10508
  }
10394
10509
  function collectFontsFromConfig(config) {
10510
+ var _a;
10395
10511
  const fonts = /* @__PURE__ */ new Set();
10396
10512
  fonts.add("Open Sans");
10397
10513
  function walk(nodes) {
10398
- var _a;
10514
+ var _a2;
10399
10515
  if (!nodes) return;
10400
10516
  for (const node of nodes) {
10401
- if (node.fontFamily) fonts.add(node.fontFamily);
10402
- if ((_a = node.smartProps) == null ? void 0 : _a.fontFamily) fonts.add(node.smartProps.fontFamily);
10517
+ if (node.fontFamily) fonts.add(normalizeFontFamily(node.fontFamily));
10518
+ if ((_a2 = node.smartProps) == null ? void 0 : _a2.fontFamily) fonts.add(normalizeFontFamily(node.smartProps.fontFamily));
10403
10519
  if (node.children) walk(node.children);
10404
10520
  }
10405
10521
  }
10406
10522
  for (const page of config.pages || []) {
10407
10523
  walk(page.children || []);
10408
10524
  }
10525
+ if ((_a = config.themeConfig) == null ? void 0 : _a.variables) {
10526
+ for (const def of Object.values(config.themeConfig.variables)) {
10527
+ if (def.value && typeof def.value === "string" && !def.value.startsWith("#") && !def.value.startsWith("rgb")) {
10528
+ if (def.label && /font/i.test(def.label)) {
10529
+ fonts.add(normalizeFontFamily(def.value));
10530
+ }
10531
+ }
10532
+ }
10533
+ }
10409
10534
  return fonts;
10410
10535
  }
10411
10536
  class PixldocsRenderer {
@@ -10653,47 +10778,6 @@ class PixldocsRenderer {
10653
10778
  });
10654
10779
  }
10655
10780
  }
10656
- function applyThemeToConfig(config, themeOverrides) {
10657
- var _a, _b, _c;
10658
- if (!themeOverrides || Object.keys(themeOverrides).length === 0) return config;
10659
- const cloned = JSON.parse(JSON.stringify(config));
10660
- if ((_a = cloned.themeConfig) == null ? void 0 : _a.variables) {
10661
- for (const [key, value] of Object.entries(themeOverrides)) {
10662
- if (cloned.themeConfig.variables[key]) {
10663
- cloned.themeConfig.variables[key].value = value;
10664
- }
10665
- }
10666
- }
10667
- const varMap = /* @__PURE__ */ new Map();
10668
- if ((_b = cloned.themeConfig) == null ? void 0 : _b.variables) {
10669
- for (const [key, def] of Object.entries(cloned.themeConfig.variables)) {
10670
- varMap.set(key, themeOverrides[key] ?? def.value);
10671
- }
10672
- }
10673
- function walkAndApply(nodes) {
10674
- if (!nodes) return;
10675
- for (const node of nodes) {
10676
- const bindings = node.themeBindings;
10677
- if (bindings) {
10678
- for (const [prop, varName] of Object.entries(bindings)) {
10679
- const value = varMap.get(varName);
10680
- if (value !== void 0) {
10681
- node[prop] = value;
10682
- }
10683
- }
10684
- }
10685
- if (node.children) walkAndApply(node.children);
10686
- }
10687
- }
10688
- for (const page of cloned.pages || []) {
10689
- const bgBinding = (_c = page.themeBindings) == null ? void 0 : _c.backgroundColor;
10690
- if (bgBinding && varMap.has(bgBinding) && page.settings) {
10691
- page.settings.backgroundColor = varMap.get(bgBinding);
10692
- }
10693
- walkAndApply(page.children || []);
10694
- }
10695
- return cloned;
10696
- }
10697
10781
  exports.PixldocsPreview = PixldocsPreview;
10698
10782
  exports.PixldocsRenderer = PixldocsRenderer;
10699
10783
  exports.applyThemeToConfig = applyThemeToConfig;