@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.js CHANGED
@@ -8556,6 +8556,47 @@ const PreviewCanvas$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
8556
8556
  __proto__: null,
8557
8557
  PreviewCanvas
8558
8558
  }, Symbol.toStringTag, { value: "Module" }));
8559
+ function applyThemeToConfig(config, themeOverrides) {
8560
+ var _a, _b, _c;
8561
+ if (!themeOverrides || Object.keys(themeOverrides).length === 0) return config;
8562
+ const cloned = JSON.parse(JSON.stringify(config));
8563
+ if ((_a = cloned.themeConfig) == null ? void 0 : _a.variables) {
8564
+ for (const [key, value] of Object.entries(themeOverrides)) {
8565
+ if (cloned.themeConfig.variables[key]) {
8566
+ cloned.themeConfig.variables[key].value = value;
8567
+ }
8568
+ }
8569
+ }
8570
+ const varMap = /* @__PURE__ */ new Map();
8571
+ if ((_b = cloned.themeConfig) == null ? void 0 : _b.variables) {
8572
+ for (const [key, def] of Object.entries(cloned.themeConfig.variables)) {
8573
+ varMap.set(key, themeOverrides[key] ?? def.value);
8574
+ }
8575
+ }
8576
+ function walkAndApply(nodes) {
8577
+ if (!nodes) return;
8578
+ for (const node of nodes) {
8579
+ const bindings = node.themeBindings;
8580
+ if (bindings) {
8581
+ for (const [prop, varName] of Object.entries(bindings)) {
8582
+ const value = varMap.get(varName);
8583
+ if (value !== void 0) {
8584
+ node[prop] = value;
8585
+ }
8586
+ }
8587
+ }
8588
+ if (node.children) walkAndApply(node.children);
8589
+ }
8590
+ }
8591
+ for (const page of cloned.pages || []) {
8592
+ const bgBinding = (_c = page.themeBindings) == null ? void 0 : _c.backgroundColor;
8593
+ if (bgBinding && varMap.has(bgBinding) && page.settings) {
8594
+ page.settings.backgroundColor = varMap.get(bgBinding);
8595
+ }
8596
+ walkAndApply(page.children || []);
8597
+ }
8598
+ return cloned;
8599
+ }
8559
8600
  function mapFormDefFieldType(t) {
8560
8601
  if (["text", "email", "tel", "textarea", "date", "url", "number", "toggle", "color", "image"].includes(t)) return t;
8561
8602
  if (t === "currency") return "number";
@@ -10036,7 +10077,7 @@ async function resolveTemplateData(options) {
10036
10077
  return { config, templateName: template.name || "Untitled", templateId };
10037
10078
  }
10038
10079
  async function resolveFromForm(options) {
10039
- var _a, _b, _c, _d, _e;
10080
+ var _a, _b, _c, _d;
10040
10081
  const { templateId, formSchemaId, sectionState, themeId, supabaseUrl, supabaseAnonKey } = options;
10041
10082
  const [templateRow, formSchemaRow, defaultForm] = await Promise.all([
10042
10083
  fetchRow(supabaseUrl, supabaseAnonKey, "templates", templateId),
@@ -10161,36 +10202,15 @@ async function resolveFromForm(options) {
10161
10202
  Object.keys(repeatableNestedEntryCounts).length > 0 ? repeatableNestedEntryCounts : void 0,
10162
10203
  displayFormatMap.size > 0 ? displayFormatMap : void 0
10163
10204
  );
10164
- if (themeId && themeId !== "default" && templateConfig.themeConfig) {
10165
- const tc = templateConfig.themeConfig;
10166
- const variant = (_d = tc.variants) == null ? void 0 : _d.find((v) => v.id === themeId);
10167
- if (variant && tc.properties) {
10168
- const themed = JSON.parse(JSON.stringify(resolvedConfig));
10169
- for (const prop of tc.properties) {
10170
- const value = (_e = variant.values) == null ? void 0 : _e[prop.id];
10171
- if (value === void 0) continue;
10172
- if (prop.targetProperty === "backgroundColor" && prop.elementId === "__pageBackground__") {
10173
- themed.pages.forEach((p) => {
10174
- p.settings.backgroundColor = value;
10175
- });
10176
- continue;
10177
- }
10178
- for (const page of themed.pages) {
10179
- const els = flattenAll(page.children || []);
10180
- for (const el of els) {
10181
- if (el.id === prop.elementId || baseId(el.id) === baseId(prop.elementId)) {
10182
- if (prop.svgColorKey && el.svgColorMap) {
10183
- el.svgColorMap = { ...el.svgColorMap, [prop.svgColorKey]: value };
10184
- } else {
10185
- el[prop.targetProperty] = value;
10186
- }
10187
- }
10188
- }
10189
- }
10190
- }
10191
- resolvedConfig = themed;
10205
+ if ((_d = resolvedConfig.themeConfig) == null ? void 0 : _d.variables) {
10206
+ const baseOverrides = {};
10207
+ for (const [key, def] of Object.entries(resolvedConfig.themeConfig.variables)) {
10208
+ baseOverrides[key] = def.value;
10192
10209
  }
10210
+ resolvedConfig = applyThemeToConfig(resolvedConfig, baseOverrides);
10193
10211
  }
10212
+ resolvedConfig = applyThemeVariantToConfig(resolvedConfig, templateConfig.themeConfig, themeId);
10213
+ normalizeConfigForEC2Parity(resolvedConfig);
10194
10214
  resolvedConfig = applyContentBoundsPagination(resolvedConfig);
10195
10215
  return {
10196
10216
  config: resolvedConfig,
@@ -10206,6 +10226,101 @@ function flattenAll(nodes) {
10206
10226
  }
10207
10227
  return result;
10208
10228
  }
10229
+ function themeBaseId(id) {
10230
+ if (!id) return id ?? "";
10231
+ let out = id;
10232
+ out = out.replace(/_inner\d+_\d+_/g, "");
10233
+ out = out.replace(/_clone\d+_/g, "");
10234
+ out = out.replace(/_clone_\d+/g, "");
10235
+ while (/_\d+$/.test(out)) out = out.replace(/_\d+$/, "");
10236
+ return out;
10237
+ }
10238
+ function applyThemeVariantToConfig(config, themeConfig, themeId) {
10239
+ var _a, _b, _c, _d;
10240
+ if (!themeConfig) return config;
10241
+ const variant = themeId && themeId !== "default" ? (_a = themeConfig.variants) == null ? void 0 : _a.find((v) => v.id === themeId) : null;
10242
+ const shouldApplyDefaults = !variant && ((_b = themeConfig.properties) == null ? void 0 : _b.length);
10243
+ if (!variant && !shouldApplyDefaults) return config;
10244
+ if (!((_c = themeConfig.properties) == null ? void 0 : _c.length)) return config;
10245
+ const result = JSON.parse(JSON.stringify(config));
10246
+ const cloneIdMap = config.__cloneIdMap || {};
10247
+ const pageElements = result.pages.map((page) => flattenAll(page.children || []));
10248
+ for (const prop of themeConfig.properties) {
10249
+ const value = variant ? (_d = variant.values) == null ? void 0 : _d[prop.id] : prop.defaultValue;
10250
+ if (value === void 0) continue;
10251
+ if (prop.targetProperty === "backgroundColor" && prop.elementId === "__pageBackground__") {
10252
+ result.pages.forEach((p) => {
10253
+ p.settings.backgroundColor = value;
10254
+ });
10255
+ continue;
10256
+ }
10257
+ if (prop.targetProperty === "backgroundGradient" && prop.elementId === "__pageBackground__" && prop.svgColorKey) {
10258
+ const stopMatch = prop.svgColorKey.match(/^stop:(\d+)$/);
10259
+ if (stopMatch) {
10260
+ const stopIndex = parseInt(stopMatch[1], 10);
10261
+ result.pages.forEach((p) => {
10262
+ var _a2, _b2;
10263
+ if ((_b2 = (_a2 = p.settings.backgroundGradient) == null ? void 0 : _a2.stops) == null ? void 0 : _b2[stopIndex]) {
10264
+ p.settings.backgroundGradient = {
10265
+ ...p.settings.backgroundGradient,
10266
+ stops: p.settings.backgroundGradient.stops.map(
10267
+ (s, i) => i === stopIndex ? { ...s, color: value } : s
10268
+ )
10269
+ };
10270
+ }
10271
+ });
10272
+ }
10273
+ continue;
10274
+ }
10275
+ const propBase = themeBaseId(prop.elementId);
10276
+ const targetIds = /* @__PURE__ */ new Set([prop.elementId, propBase]);
10277
+ for (const [mapKey, mappedId] of Object.entries(cloneIdMap)) {
10278
+ if (mapKey.endsWith(`_${prop.elementId}`) || mapKey.endsWith(`_${propBase}`)) {
10279
+ targetIds.add(mappedId);
10280
+ }
10281
+ }
10282
+ for (const els of pageElements) {
10283
+ for (const el of els) {
10284
+ const elBase = themeBaseId(el.id);
10285
+ const sourceId = el.__sourceId;
10286
+ const sourceBase = sourceId ? themeBaseId(sourceId) : void 0;
10287
+ const cloneBase = el.__baseNodeId;
10288
+ const cloneBaseNorm = cloneBase ? themeBaseId(cloneBase) : void 0;
10289
+ 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);
10290
+ if (!match) continue;
10291
+ if (prop.svgColorKey && el.svgColorMap) {
10292
+ el.svgColorMap = { ...el.svgColorMap, [prop.svgColorKey]: value };
10293
+ } else {
10294
+ el[prop.targetProperty] = value;
10295
+ }
10296
+ }
10297
+ }
10298
+ }
10299
+ return result;
10300
+ }
10301
+ function normalizeConfigForEC2Parity(config) {
10302
+ function walk(node) {
10303
+ if (node.layoutMode === "stack" || node.layoutMode === "stacked") {
10304
+ node.layoutMode = "vertical-stack";
10305
+ }
10306
+ const layoutMode = String(node.layoutMode ?? "");
10307
+ const isStack = isVerticalStackLayoutMode(layoutMode) || layoutMode === "horizontal-stack" || layoutMode === "horizontal-fill";
10308
+ if (isStack && node.stackSpacing == null) node.stackSpacing = 8;
10309
+ if (node.type === "text") {
10310
+ const overflowPolicy = String(node.overflowPolicy ?? "grow-and-push");
10311
+ const fontSize = typeof node.fontSize === "number" ? node.fontSize : 16;
10312
+ if (overflowPolicy === "auto-shrink" && fontSize >= 24) node.overflowPolicy = "grow-and-push";
10313
+ delete node.height;
10314
+ }
10315
+ if (Array.isArray(node.children)) {
10316
+ delete node.height;
10317
+ for (const child of node.children) walk(child);
10318
+ }
10319
+ }
10320
+ for (const page of config.pages ?? []) {
10321
+ for (const child of page.children ?? []) walk(child);
10322
+ }
10323
+ }
10209
10324
  function normalizeLayoutModes(config) {
10210
10325
  function walk(node) {
10211
10326
  if (node.layoutMode === "stack" || node.layoutMode === "stacked") {
@@ -10373,20 +10488,30 @@ async function loadGoogleFontCSS(rawFontFamily) {
10373
10488
  loadingPromises.delete(fontFamily);
10374
10489
  }
10375
10490
  function collectFontsFromConfig(config) {
10491
+ var _a;
10376
10492
  const fonts = /* @__PURE__ */ new Set();
10377
10493
  fonts.add("Open Sans");
10378
10494
  function walk(nodes) {
10379
- var _a;
10495
+ var _a2;
10380
10496
  if (!nodes) return;
10381
10497
  for (const node of nodes) {
10382
- if (node.fontFamily) fonts.add(node.fontFamily);
10383
- if ((_a = node.smartProps) == null ? void 0 : _a.fontFamily) fonts.add(node.smartProps.fontFamily);
10498
+ if (node.fontFamily) fonts.add(normalizeFontFamily(node.fontFamily));
10499
+ if ((_a2 = node.smartProps) == null ? void 0 : _a2.fontFamily) fonts.add(normalizeFontFamily(node.smartProps.fontFamily));
10384
10500
  if (node.children) walk(node.children);
10385
10501
  }
10386
10502
  }
10387
10503
  for (const page of config.pages || []) {
10388
10504
  walk(page.children || []);
10389
10505
  }
10506
+ if ((_a = config.themeConfig) == null ? void 0 : _a.variables) {
10507
+ for (const def of Object.values(config.themeConfig.variables)) {
10508
+ if (def.value && typeof def.value === "string" && !def.value.startsWith("#") && !def.value.startsWith("rgb")) {
10509
+ if (def.label && /font/i.test(def.label)) {
10510
+ fonts.add(normalizeFontFamily(def.value));
10511
+ }
10512
+ }
10513
+ }
10514
+ }
10390
10515
  return fonts;
10391
10516
  }
10392
10517
  class PixldocsRenderer {
@@ -10634,47 +10759,6 @@ class PixldocsRenderer {
10634
10759
  });
10635
10760
  }
10636
10761
  }
10637
- function applyThemeToConfig(config, themeOverrides) {
10638
- var _a, _b, _c;
10639
- if (!themeOverrides || Object.keys(themeOverrides).length === 0) return config;
10640
- const cloned = JSON.parse(JSON.stringify(config));
10641
- if ((_a = cloned.themeConfig) == null ? void 0 : _a.variables) {
10642
- for (const [key, value] of Object.entries(themeOverrides)) {
10643
- if (cloned.themeConfig.variables[key]) {
10644
- cloned.themeConfig.variables[key].value = value;
10645
- }
10646
- }
10647
- }
10648
- const varMap = /* @__PURE__ */ new Map();
10649
- if ((_b = cloned.themeConfig) == null ? void 0 : _b.variables) {
10650
- for (const [key, def] of Object.entries(cloned.themeConfig.variables)) {
10651
- varMap.set(key, themeOverrides[key] ?? def.value);
10652
- }
10653
- }
10654
- function walkAndApply(nodes) {
10655
- if (!nodes) return;
10656
- for (const node of nodes) {
10657
- const bindings = node.themeBindings;
10658
- if (bindings) {
10659
- for (const [prop, varName] of Object.entries(bindings)) {
10660
- const value = varMap.get(varName);
10661
- if (value !== void 0) {
10662
- node[prop] = value;
10663
- }
10664
- }
10665
- }
10666
- if (node.children) walkAndApply(node.children);
10667
- }
10668
- }
10669
- for (const page of cloned.pages || []) {
10670
- const bgBinding = (_c = page.themeBindings) == null ? void 0 : _c.backgroundColor;
10671
- if (bgBinding && varMap.has(bgBinding) && page.settings) {
10672
- page.settings.backgroundColor = varMap.get(bgBinding);
10673
- }
10674
- walkAndApply(page.children || []);
10675
- }
10676
- return cloned;
10677
- }
10678
10762
  export {
10679
10763
  PixldocsPreview,
10680
10764
  PixldocsRenderer,