@1urso/generic-editor 0.1.14 → 0.1.15

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.
@@ -14329,209 +14329,219 @@ const Preview = () => {
14329
14329
  })
14330
14330
  });
14331
14331
  }, EditorSettings = () => {
14332
- let { state: s, updateListSettings: d, setCanvasHeight: w } = useEditor(), [k, F] = useState(""), [L, V] = useState("asc"), [U, K] = useState("bottom"), [q, J] = useState("down"), [$, pA] = useState("150"), [mA, hA] = useState("");
14332
+ let { state: s, updateListSettings: d, setCanvasHeight: w } = useEditor(), [k, F] = useState(!1), [L, V] = useState(""), [U, K] = useState("asc"), [q, J] = useState("bottom"), [$, pA] = useState("down"), [mA, hA] = useState("150"), [gA, _A] = useState("");
14333
14333
  return useEffect(() => {
14334
- F(s.listSettings.sortProp || "__none__"), V(s.listSettings.sortOrder || "asc"), K(s.listSettings.newestPosition || "bottom"), J(s.listSettings.scrollDirection || "down"), hA(s.listSettings.containerHeight ? String(s.listSettings.containerHeight) : ""), pA(String(s.canvasHeight || 150));
14335
- }, [s.listSettings, s.canvasHeight]), useEffect(() => {
14336
- let s = parseInt($, 10);
14337
- !isNaN(s) && s > 0 && w(s);
14338
- }, [$, w]), /* @__PURE__ */ jsxs(s$2, { children: [/* @__PURE__ */ jsx(n$2, { children: /* @__PURE__ */ jsxs(o, {
14339
- variant: "soft",
14340
- color: "gray",
14341
- style: {
14342
- width: "100%",
14343
- justifyContent: "center",
14344
- cursor: "pointer"
14345
- },
14346
- children: [/* @__PURE__ */ jsx(GearIcon, {}), " Configurações"]
14347
- }) }), /* @__PURE__ */ jsxs(p$6, {
14348
- style: { maxWidth: 600 },
14349
- children: [
14350
- /* @__PURE__ */ jsx(g$2, { children: "Configurações do Editor" }),
14351
- /* @__PURE__ */ jsx(m, {
14352
- size: "2",
14353
- mb: "4",
14354
- children: "Configure o comportamento da lista."
14355
- }),
14356
- /* @__PURE__ */ jsx(p$1, {
14357
- pt: "3",
14358
- children: /* @__PURE__ */ jsxs(p, {
14359
- direction: "column",
14360
- gap: "3",
14361
- children: [
14362
- /* @__PURE__ */ jsx(p$2, {
14363
- size: "2",
14364
- weight: "bold",
14365
- children: "Ordenação"
14366
- }),
14367
- /* @__PURE__ */ jsxs(p, {
14368
- gap: "3",
14369
- align: "center",
14370
- children: [/* @__PURE__ */ jsxs(p$1, {
14371
- flexGrow: "1",
14372
- children: [/* @__PURE__ */ jsx(p$2, {
14373
- size: "1",
14374
- mb: "1",
14375
- as: "div",
14376
- children: "Propriedade para Ordenar (ex: data, id)"
14377
- }), /* @__PURE__ */ jsxs(C, {
14378
- value: k,
14379
- onValueChange: (s) => F(s),
14380
- children: [/* @__PURE__ */ jsx(u$2, {
14381
- style: { width: "100%" },
14382
- placeholder: "Selecione..."
14383
- }), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
14384
- value: "__none__",
14385
- children: "(Nenhum)"
14386
- }), s.availableProps.map((s) => /* @__PURE__ */ jsx(v$1, {
14387
- value: s.dataName,
14388
- children: s.name
14389
- }, s.dataName))] })]
14390
- })]
14391
- }), /* @__PURE__ */ jsxs(p$1, { children: [/* @__PURE__ */ jsx(p$2, {
14392
- size: "1",
14393
- mb: "1",
14394
- as: "div",
14395
- children: "Direção"
14396
- }), /* @__PURE__ */ jsxs(C, {
14397
- value: L,
14398
- onValueChange: (s) => V(s),
14399
- children: [/* @__PURE__ */ jsx(u$2, {}), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
14400
- value: "asc",
14401
- children: "Crescente (A-Z)"
14402
- }), /* @__PURE__ */ jsx(v$1, {
14403
- value: "desc",
14404
- children: "Decrescente (Z-A)"
14405
- })] })]
14406
- })] })]
14407
- }),
14408
- /* @__PURE__ */ jsxs(p, {
14409
- gap: "3",
14410
- align: "center",
14411
- children: [/* @__PURE__ */ jsxs(p$1, {
14412
- flexGrow: "1",
14413
- children: [/* @__PURE__ */ jsx(p$2, {
14334
+ k && (V(s.listSettings.sortProp || "__none__"), K(s.listSettings.sortOrder || "asc"), J(s.listSettings.newestPosition || "bottom"), pA(s.listSettings.scrollDirection || "down"), _A(s.listSettings.containerHeight ? String(s.listSettings.containerHeight) : ""), hA(String(s.canvasHeight || 150)));
14335
+ }, [k]), useEffect(() => {
14336
+ if (!k) return;
14337
+ let d = parseInt(mA, 10);
14338
+ !isNaN(d) && d > 0 && s.canvasHeight !== d && w(d);
14339
+ }, [
14340
+ mA,
14341
+ k,
14342
+ w,
14343
+ s.canvasHeight
14344
+ ]), /* @__PURE__ */ jsxs(s$2, {
14345
+ open: k,
14346
+ onOpenChange: F,
14347
+ children: [/* @__PURE__ */ jsx(n$2, { children: /* @__PURE__ */ jsxs(o, {
14348
+ variant: "soft",
14349
+ color: "gray",
14350
+ style: {
14351
+ width: "100%",
14352
+ justifyContent: "center",
14353
+ cursor: "pointer"
14354
+ },
14355
+ children: [/* @__PURE__ */ jsx(GearIcon, {}), " Configurações"]
14356
+ }) }), /* @__PURE__ */ jsxs(p$6, {
14357
+ style: { maxWidth: 600 },
14358
+ children: [
14359
+ /* @__PURE__ */ jsx(g$2, { children: "Configurações do Editor" }),
14360
+ /* @__PURE__ */ jsx(m, {
14361
+ size: "2",
14362
+ mb: "4",
14363
+ children: "Configure o comportamento da lista."
14364
+ }),
14365
+ /* @__PURE__ */ jsx(p$1, {
14366
+ pt: "3",
14367
+ children: /* @__PURE__ */ jsxs(p, {
14368
+ direction: "column",
14369
+ gap: "3",
14370
+ children: [
14371
+ /* @__PURE__ */ jsx(p$2, {
14372
+ size: "2",
14373
+ weight: "bold",
14374
+ children: "Ordenação"
14375
+ }),
14376
+ /* @__PURE__ */ jsxs(p, {
14377
+ gap: "3",
14378
+ align: "center",
14379
+ children: [/* @__PURE__ */ jsxs(p$1, {
14380
+ flexGrow: "1",
14381
+ children: [/* @__PURE__ */ jsx(p$2, {
14382
+ size: "1",
14383
+ mb: "1",
14384
+ as: "div",
14385
+ children: "Propriedade para Ordenar (ex: data, id)"
14386
+ }), /* @__PURE__ */ jsxs(C, {
14387
+ value: L,
14388
+ onValueChange: (s) => V(s),
14389
+ children: [/* @__PURE__ */ jsx(u$2, {
14390
+ style: { width: "100%" },
14391
+ placeholder: "Selecione..."
14392
+ }), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
14393
+ value: "__none__",
14394
+ children: "(Nenhum)"
14395
+ }), s.availableProps.map((s) => /* @__PURE__ */ jsx(v$1, {
14396
+ value: s.dataName,
14397
+ children: s.name
14398
+ }, s.dataName))] })]
14399
+ })]
14400
+ }), /* @__PURE__ */ jsxs(p$1, { children: [/* @__PURE__ */ jsx(p$2, {
14414
14401
  size: "1",
14415
14402
  mb: "1",
14416
14403
  as: "div",
14417
- children: "Posição do Recente"
14404
+ children: "Direção"
14418
14405
  }), /* @__PURE__ */ jsxs(C, {
14419
14406
  value: U,
14420
14407
  onValueChange: (s) => K(s),
14421
- children: [/* @__PURE__ */ jsx(u$2, { style: { width: "100%" } }), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
14422
- value: "top",
14423
- children: "Topo (Início)"
14424
- }), /* @__PURE__ */ jsx(v$1, {
14425
- value: "bottom",
14426
- children: "Base (Final)"
14427
- })] })]
14428
- })]
14429
- }), /* @__PURE__ */ jsxs(p$1, {
14430
- flexGrow: "1",
14431
- children: [/* @__PURE__ */ jsx(p$2, {
14432
- size: "1",
14433
- mb: "1",
14434
- as: "div",
14435
- children: "Comportamento de Rolagem"
14436
- }), /* @__PURE__ */ jsxs(C, {
14437
- value: q,
14438
- onValueChange: (s) => J(s),
14439
- children: [/* @__PURE__ */ jsx(u$2, { style: { width: "100%" } }), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
14440
- value: "down",
14441
- children: "Descer (Padrão)"
14408
+ children: [/* @__PURE__ */ jsx(u$2, {}), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
14409
+ value: "asc",
14410
+ children: "Crescente (A-Z)"
14442
14411
  }), /* @__PURE__ */ jsx(v$1, {
14443
- value: "up",
14444
- children: "Subir (Chat)"
14412
+ value: "desc",
14413
+ children: "Decrescente (Z-A)"
14445
14414
  })] })]
14446
- })]
14447
- })]
14448
- }),
14449
- /* @__PURE__ */ jsx(p$2, {
14450
- size: "2",
14451
- weight: "bold",
14452
- mt: "2",
14453
- children: "Dimensões"
14454
- }),
14455
- /* @__PURE__ */ jsxs(p, {
14456
- gap: "3",
14457
- align: "center",
14458
- children: [/* @__PURE__ */ jsxs(p$1, {
14459
- flexGrow: "1",
14460
- children: [
14461
- /* @__PURE__ */ jsx(p$2, {
14415
+ })] })]
14416
+ }),
14417
+ /* @__PURE__ */ jsxs(p, {
14418
+ gap: "3",
14419
+ align: "center",
14420
+ children: [/* @__PURE__ */ jsxs(p$1, {
14421
+ flexGrow: "1",
14422
+ children: [/* @__PURE__ */ jsx(p$2, {
14462
14423
  size: "1",
14463
14424
  mb: "1",
14464
14425
  as: "div",
14465
- children: "Altura do Item (Template) (px)"
14466
- }),
14467
- /* @__PURE__ */ jsx(u, {
14468
- type: "number",
14469
- min: "10",
14470
- value: $,
14471
- onChange: (s) => pA(s.target.value)
14472
- }),
14473
- /* @__PURE__ */ jsx(p$2, {
14474
- size: "1",
14475
- color: "gray",
14476
- children: "Altura de cada item individual na lista."
14477
- })
14478
- ]
14479
- }), /* @__PURE__ */ jsxs(p$1, {
14480
- flexGrow: "1",
14481
- children: [
14482
- /* @__PURE__ */ jsx(p$2, {
14426
+ children: "Posição do Recente"
14427
+ }), /* @__PURE__ */ jsxs(C, {
14428
+ value: q,
14429
+ onValueChange: (s) => J(s),
14430
+ children: [/* @__PURE__ */ jsx(u$2, { style: { width: "100%" } }), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
14431
+ value: "top",
14432
+ children: "Topo (Início)"
14433
+ }), /* @__PURE__ */ jsx(v$1, {
14434
+ value: "bottom",
14435
+ children: "Base (Final)"
14436
+ })] })]
14437
+ })]
14438
+ }), /* @__PURE__ */ jsxs(p$1, {
14439
+ flexGrow: "1",
14440
+ children: [/* @__PURE__ */ jsx(p$2, {
14483
14441
  size: "1",
14484
14442
  mb: "1",
14485
14443
  as: "div",
14486
- children: "Altura da Lista (Container) (px)"
14487
- }),
14488
- /* @__PURE__ */ jsx(u, {
14489
- type: "number",
14490
- min: "0",
14491
- placeholder: "Auto (100%)",
14492
- value: mA,
14493
- onChange: (s) => hA(s.target.value)
14494
- }),
14495
- /* @__PURE__ */ jsx(p$2, {
14496
- size: "1",
14497
- color: "gray",
14498
- children: "Altura total da lista. Se exceder, rola. Vazio = 100%."
14499
- })
14500
- ]
14501
- })]
14502
- }),
14503
- /* @__PURE__ */ jsx(p$2, {
14504
- size: "1",
14505
- color: "gray",
14506
- children: "Essa propriedade será usada para ordenar os itens no modo lista."
14507
- })
14508
- ]
14444
+ children: "Comportamento de Rolagem"
14445
+ }), /* @__PURE__ */ jsxs(C, {
14446
+ value: $,
14447
+ onValueChange: (s) => pA(s),
14448
+ children: [/* @__PURE__ */ jsx(u$2, { style: { width: "100%" } }), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
14449
+ value: "down",
14450
+ children: "Descer (Padrão)"
14451
+ }), /* @__PURE__ */ jsx(v$1, {
14452
+ value: "up",
14453
+ children: "Subir (Chat)"
14454
+ })] })]
14455
+ })]
14456
+ })]
14457
+ }),
14458
+ /* @__PURE__ */ jsx(p$2, {
14459
+ size: "2",
14460
+ weight: "bold",
14461
+ mt: "2",
14462
+ children: "Dimensões"
14463
+ }),
14464
+ /* @__PURE__ */ jsxs(p, {
14465
+ gap: "3",
14466
+ align: "center",
14467
+ children: [/* @__PURE__ */ jsxs(p$1, {
14468
+ flexGrow: "1",
14469
+ children: [
14470
+ /* @__PURE__ */ jsx(p$2, {
14471
+ size: "1",
14472
+ mb: "1",
14473
+ as: "div",
14474
+ children: "Altura do Item (Template) (px)"
14475
+ }),
14476
+ /* @__PURE__ */ jsx(u, {
14477
+ type: "number",
14478
+ min: "10",
14479
+ value: mA,
14480
+ onChange: (s) => hA(s.target.value)
14481
+ }),
14482
+ /* @__PURE__ */ jsx(p$2, {
14483
+ size: "1",
14484
+ color: "gray",
14485
+ children: "Altura de cada item individual na lista."
14486
+ })
14487
+ ]
14488
+ }), /* @__PURE__ */ jsxs(p$1, {
14489
+ flexGrow: "1",
14490
+ children: [
14491
+ /* @__PURE__ */ jsx(p$2, {
14492
+ size: "1",
14493
+ mb: "1",
14494
+ as: "div",
14495
+ children: "Altura da Lista (Container) (px)"
14496
+ }),
14497
+ /* @__PURE__ */ jsx(u, {
14498
+ type: "number",
14499
+ min: "0",
14500
+ placeholder: "Auto (100%)",
14501
+ value: gA,
14502
+ onChange: (s) => _A(s.target.value)
14503
+ }),
14504
+ /* @__PURE__ */ jsx(p$2, {
14505
+ size: "1",
14506
+ color: "gray",
14507
+ children: "Altura total da lista. Se exceder, rola. Vazio = 100%."
14508
+ })
14509
+ ]
14510
+ })]
14511
+ }),
14512
+ /* @__PURE__ */ jsx(p$2, {
14513
+ size: "1",
14514
+ color: "gray",
14515
+ children: "Essa propriedade será usada para ordenar os itens no modo lista."
14516
+ })
14517
+ ]
14518
+ })
14519
+ }),
14520
+ /* @__PURE__ */ jsxs(p, {
14521
+ gap: "3",
14522
+ mt: "4",
14523
+ justify: "end",
14524
+ children: [/* @__PURE__ */ jsx(D$1, { children: /* @__PURE__ */ jsx(o, {
14525
+ variant: "soft",
14526
+ color: "gray",
14527
+ children: "Cancelar"
14528
+ }) }), /* @__PURE__ */ jsx(D$1, { children: /* @__PURE__ */ jsx(o, {
14529
+ onClick: () => {
14530
+ let s = parseInt(gA, 10);
14531
+ d({
14532
+ sortProp: L === "__none__" ? "" : L,
14533
+ sortOrder: U,
14534
+ newestPosition: q,
14535
+ scrollDirection: $,
14536
+ containerHeight: !isNaN(s) && s > 0 ? s : void 0
14537
+ }), F(!1);
14538
+ },
14539
+ children: "Salvar Alterações"
14540
+ }) })]
14509
14541
  })
14510
- }),
14511
- /* @__PURE__ */ jsxs(p, {
14512
- gap: "3",
14513
- mt: "4",
14514
- justify: "end",
14515
- children: [/* @__PURE__ */ jsx(D$1, { children: /* @__PURE__ */ jsx(o, {
14516
- variant: "soft",
14517
- color: "gray",
14518
- children: "Cancelar"
14519
- }) }), /* @__PURE__ */ jsx(D$1, { children: /* @__PURE__ */ jsx(o, {
14520
- onClick: () => {
14521
- let s = parseInt(mA, 10);
14522
- d({
14523
- sortProp: k === "__none__" ? "" : k,
14524
- sortOrder: L,
14525
- newestPosition: U,
14526
- scrollDirection: q,
14527
- containerHeight: !isNaN(s) && s > 0 ? s : void 0
14528
- });
14529
- },
14530
- children: "Salvar Alterações"
14531
- }) })]
14532
- })
14533
- ]
14534
- })] });
14542
+ ]
14543
+ })]
14544
+ });
14535
14545
  };
14536
14546
  var EditorContent = ({ layout: s, initialState: w, onSave: k, theme: F = "light" }) => {
14537
14547
  let [L, V] = useState(!0), [U, K] = useState(!0), { addElement: q, loadState: J, state: X } = useEditor();
@@ -14789,5 +14799,5 @@ const GenericEditor = (s) => /* @__PURE__ */ jsx(EditorProvider, {
14789
14799
  availableProps: s.layout.props,
14790
14800
  theme: s.theme,
14791
14801
  children: /* @__PURE__ */ jsx(EditorContent, { ...s })
14792
- }), generateHTML = (s, d, w = {}) => Function("elements", "data", "options", getRendererCode() + "\nreturn renderTemplate(elements, data, options);")(s, d, w), getRendererCode = () => "\n/**\n * Render Template\n * @param {Array} elements - The JSON configuration of elements\n * @param {Object|Array} data - The data object to inject (Object for single, Array for list)\n * @param {Object} options - { isList: boolean, listSettings: { sortProp: string, sortOrder: 'asc'|'desc', newestPosition: 'top'|'bottom', scrollDirection: 'up'|'down' }, canvasHeight: number }\n * @returns {string} - The generated HTML string\n */\nfunction renderTemplate(elements, data, options = {}) {\n const { isList, listSettings, canvasHeight } = options;\n\n const camelToKebab = (string) => {\n return string.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();\n };\n\n const styleObjectToString = (style) => {\n if (!style) return '';\n const pxProps = ['width', 'height', 'top', 'left', 'right', 'bottom', 'fontSize', 'borderRadius', 'padding', 'margin', 'borderWidth'];\n \n return Object.entries(style)\n .map(([key, value]) => {\n if (value === undefined || value === null) return '';\n const cssKey = camelToKebab(key);\n const cssValue = (typeof value === 'number' && pxProps.includes(key)) ? value + 'px' : value;\n return `${cssKey}: ${cssValue}`;\n })\n .filter(Boolean)\n .join('; ');\n };\n\n const renderItem = (itemData, index = 0, offsetY = 0) => {\n return elements.map(element => {\n let content = element.content;\n let imgSrc = '';\n\n if (element.type === 'text') {\n content = content.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => {\n const val = itemData[key.trim()];\n return val !== undefined && val !== null ? String(val) : match;\n });\n } else if (element.type === 'image') {\n if (element.dataBinding) {\n const val = itemData[element.dataBinding];\n if (val !== undefined && val !== null) {\n imgSrc = String(val);\n } else {\n imgSrc = content;\n }\n } else {\n imgSrc = content.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => {\n const val = itemData[key.trim()];\n return val !== undefined && val !== null ? String(val) : match;\n });\n }\n }\n\n const baseStyle = {\n position: 'absolute',\n left: element.x,\n top: element.y + offsetY,\n width: element.width,\n height: element.height,\n transform: element.rotation ? `rotate(${element.rotation}deg)` : undefined,\n overflow: 'hidden',\n ...element.style\n };\n \n // Fix: remove padding if it's not explicitly set, or handle it for text\n if (element.type === 'text' && !baseStyle.padding) {\n // baseStyle.padding = '8px'; // Removed default padding to respect resize box\n }\n \n const styleString = styleObjectToString(baseStyle);\n\n if (element.type === 'text') {\n return `<div style=\"${styleString}\">${content}</div>`;\n } else if (element.type === 'image') {\n const imgStyle = styleObjectToString({\n width: '100%',\n height: '100%',\n objectFit: element.style?.objectFit || 'cover',\n display: 'block'\n });\n return `<div style=\"${styleString}\"><img src=\"${imgSrc}\" alt=\"Element\" style=\"${imgStyle}\" /></div>`;\n } else if (element.type === 'box') {\n return `<div style=\"${styleString}\"></div>`;\n }\n return '';\n }).join('\\n');\n };\n\n if (isList && Array.isArray(data)) {\n // Calculate item height\n const itemHeight = canvasHeight || Math.max(...elements.map(el => el.y + el.height));\n\n // Sort data\n let listData = [...data];\n if (listSettings && listSettings.sortProp) {\n const prop = listSettings.sortProp;\n const order = listSettings.sortOrder === 'asc' ? 1 : -1;\n listData.sort((a, b) => {\n const valA = a[prop];\n const valB = b[prop];\n if (valA < valB) return -1 * order;\n if (valA > valB) return 1 * order;\n return 0;\n });\n }\n \n // Handle newest position\n if (listSettings && listSettings.newestPosition === 'top') {\n listData.reverse();\n }\n\n // Generate HTML for all items\n const itemsHtml = listData.map((item, index) => {\n const itemHtml = renderItem(item, index, 0); \n const itemContainerStyle = styleObjectToString({\n position: 'relative',\n height: itemHeight,\n width: '100%',\n marginBottom: 0\n });\n \n return `<div class=\"list-item\" style=\"${itemContainerStyle}\">${itemHtml}</div>`;\n }).join('\\n');\n\n // Animation Styles based on settings\n const scrollDirection = (listSettings && listSettings.scrollDirection) || 'down';\n const containerHeight = (listSettings && listSettings.containerHeight) ? listSettings.containerHeight + 'px' : '100%';\n \n const justify = (listSettings && listSettings.newestPosition === 'top') ? 'flex-start' : 'flex-end';\n\n const animationCss = `\n @keyframes slideIn {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .list-wrapper {\n display: flex;\n flex-direction: column;\n justify-content: ${justify};\n height: ${containerHeight};\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n box-sizing: border-box;\n padding: 10px;\n }\n .list-item {\n flex-shrink: 0;\n animation: slideIn 0.3s ease-out;\n margin-bottom: 10px;\n width: 100%;\n position: relative;\n }\n `;\n\n return `\n <style>${animationCss}</style>\n <div class=\"list-wrapper\">\n ${itemsHtml}\n </div>\n `;\n }\n\n // Single Item\n const contentHtml = renderItem(data);\n return `<div style=\"position: relative; width: 100%; height: 100%; overflow: hidden;\">${contentHtml}</div>`;\n}\n";
14802
+ }), generateHTML = (s, d, w = {}) => Function("elements", "data", "options", getRendererCode() + "\nreturn renderTemplate(elements, data, options);")(s, d, w), getRendererCode = () => "\n/**\n * Render Template\n * @param {Array} elements - The JSON configuration of elements\n * @param {Object|Array} data - The data object to inject (Object for single, Array for list)\n * @param {Object} options - { isList: boolean, listSettings: { sortProp: string, sortOrder: 'asc'|'desc', newestPosition: 'top'|'bottom', scrollDirection: 'up'|'down' }, canvasHeight: number }\n * @returns {string} - The generated HTML string\n */\nfunction renderTemplate(elements, data, options = {}) {\n const { isList, listSettings, canvasHeight } = options;\n\n const camelToKebab = (string) => {\n return string.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();\n };\n\n const styleObjectToString = (style) => {\n if (!style) return '';\n const pxProps = ['width', 'height', 'top', 'left', 'right', 'bottom', 'fontSize', 'borderRadius', 'padding', 'margin', 'borderWidth'];\n \n return Object.entries(style)\n .map(([key, value]) => {\n if (value === undefined || value === null) return '';\n const cssKey = camelToKebab(key);\n const cssValue = (typeof value === 'number' && pxProps.includes(key)) ? value + 'px' : value;\n return `${cssKey}: ${cssValue}`;\n })\n .filter(Boolean)\n .join('; ');\n };\n\n const renderItem = (itemData, index = 0, offsetY = 0) => {\n return elements.map(element => {\n let content = element.content;\n let imgSrc = '';\n\n if (element.type === 'text') {\n content = content.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => {\n const val = itemData[key.trim()];\n return val !== undefined && val !== null ? String(val) : match;\n });\n } else if (element.type === 'image') {\n if (element.dataBinding) {\n const val = itemData[element.dataBinding];\n if (val !== undefined && val !== null) {\n imgSrc = String(val);\n } else {\n imgSrc = content;\n }\n } else {\n imgSrc = content.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => {\n const val = itemData[key.trim()];\n return val !== undefined && val !== null ? String(val) : match;\n });\n }\n }\n\n const baseStyle = {\n position: 'absolute',\n left: element.x,\n top: element.y + offsetY,\n width: element.width,\n height: element.height,\n transform: element.rotation ? `rotate(${element.rotation}deg)` : undefined,\n overflow: 'hidden',\n ...element.style\n };\n \n // Fix: remove padding if it's not explicitly set, or handle it for text\n if (element.type === 'text' && !baseStyle.padding) {\n // baseStyle.padding = '8px'; // Removed default padding to respect resize box\n }\n \n const styleString = styleObjectToString(baseStyle);\n\n if (element.type === 'text') {\n return `<div style=\"${styleString}\">${content}</div>`;\n } else if (element.type === 'image') {\n const imgStyle = styleObjectToString({\n width: '100%',\n height: '100%',\n objectFit: element.style?.objectFit || 'cover',\n display: 'block'\n });\n return `<div style=\"${styleString}\"><img src=\"${imgSrc}\" alt=\"Element\" style=\"${imgStyle}\" /></div>`;\n } else if (element.type === 'box') {\n return `<div style=\"${styleString}\"></div>`;\n }\n return '';\n }).join('\\n');\n };\n\n if (isList && Array.isArray(data)) {\n // Calculate item height\n const itemHeight = canvasHeight || Math.max(...elements.map(el => el.y + el.height));\n\n // Sort data\n let listData = [...data];\n if (listSettings && listSettings.sortProp) {\n const prop = listSettings.sortProp;\n const order = listSettings.sortOrder === 'asc' ? 1 : -1;\n listData.sort((a, b) => {\n const valA = a[prop];\n const valB = b[prop];\n if (valA < valB) return -1 * order;\n if (valA > valB) return 1 * order;\n return 0;\n });\n }\n \n // Handle newest position\n if (listSettings && listSettings.newestPosition === 'top') {\n listData.reverse();\n }\n\n // Generate HTML for all items\n const itemsHtml = listData.map((item, index) => {\n const itemHtml = renderItem(item, index, 0); \n const itemContainerStyle = styleObjectToString({\n position: 'relative',\n height: itemHeight,\n width: '100%',\n marginBottom: 0\n });\n \n return `<div class=\"list-item\" style=\"${itemContainerStyle}\">${itemHtml}</div>`;\n }).join('\\n');\n\n // Animation Styles based on settings\n const scrollDirection = (listSettings && listSettings.scrollDirection) || 'down';\n const containerHeight = (listSettings && listSettings.containerHeight) ? listSettings.containerHeight + 'px' : '100%';\n \n const justify = (listSettings && listSettings.newestPosition === 'top') ? 'flex-start' : 'flex-end';\n\n const animationCss = `\n @keyframes slideIn {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .list-wrapper {\n display: flex;\n flex-direction: column;\n justify-content: ${justify};\n height: ${containerHeight};\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n box-sizing: border-box;\n padding: 10px;\n }\n .list-item {\n flex-shrink: 0;\n animation: slideIn 0.3s ease-out;\n margin-bottom: 10px;\n width: 100%;\n position: relative;\n }\n `;\n \n const scrollScript = scrollDirection === 'up' \n ? `<script>\n document.addEventListener('DOMContentLoaded', () => {\n const wrapper = document.querySelector('.list-wrapper');\n if(wrapper) wrapper.scrollTop = wrapper.scrollHeight;\n });\n <\/script>`\n : '';\n\n return `\n <style>${animationCss}</style>\n <div class=\"list-wrapper\">\n ${itemsHtml}\n </div>\n ${scrollScript}\n `;\n }\n\n // Single Item\n const contentHtml = renderItem(data);\n return `<div style=\"position: relative; width: 100%; height: 100%; overflow: hidden;\">${contentHtml}</div>`;\n}\n";
14793
14803
  export { GenericEditor as EditorContent, generateHTML };