@1urso/generic-editor 0.1.13 → 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.
- package/README.md +2 -1
- package/dist/editor/context.d.ts +1 -0
- package/dist/generic-editor.js +198 -146
- package/dist/generic-editor.umd.cjs +13 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -210,7 +210,8 @@ The output of `onSave` is a JSON ready to be stored.
|
|
|
210
210
|
"sortProp": "nome",
|
|
211
211
|
"sortOrder": "asc",
|
|
212
212
|
"newestPosition": "bottom",
|
|
213
|
-
"scrollDirection": "down"
|
|
213
|
+
"scrollDirection": "down",
|
|
214
|
+
"containerHeight": 400 // Optional: Limits the list height (scrollable)
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
217
|
```
|
package/dist/editor/context.d.ts
CHANGED
package/dist/generic-editor.js
CHANGED
|
@@ -14329,167 +14329,219 @@ const Preview = () => {
|
|
|
14329
14329
|
})
|
|
14330
14330
|
});
|
|
14331
14331
|
}, EditorSettings = () => {
|
|
14332
|
-
let { state: s, updateListSettings: d, setCanvasHeight: w } = useEditor(), [k, F] = 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
|
-
|
|
14335
|
-
}, [
|
|
14336
|
-
|
|
14337
|
-
|
|
14338
|
-
|
|
14339
|
-
|
|
14340
|
-
|
|
14341
|
-
|
|
14342
|
-
|
|
14343
|
-
|
|
14344
|
-
|
|
14345
|
-
|
|
14346
|
-
|
|
14347
|
-
|
|
14348
|
-
|
|
14349
|
-
|
|
14350
|
-
|
|
14351
|
-
|
|
14352
|
-
|
|
14353
|
-
|
|
14354
|
-
|
|
14355
|
-
}),
|
|
14356
|
-
|
|
14357
|
-
|
|
14358
|
-
|
|
14359
|
-
|
|
14360
|
-
|
|
14361
|
-
|
|
14362
|
-
|
|
14363
|
-
|
|
14364
|
-
|
|
14365
|
-
|
|
14366
|
-
|
|
14367
|
-
|
|
14368
|
-
|
|
14369
|
-
|
|
14370
|
-
|
|
14371
|
-
|
|
14372
|
-
|
|
14373
|
-
|
|
14374
|
-
|
|
14375
|
-
|
|
14376
|
-
|
|
14377
|
-
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
14381
|
-
|
|
14382
|
-
|
|
14383
|
-
|
|
14384
|
-
|
|
14385
|
-
children: "(
|
|
14386
|
-
}),
|
|
14387
|
-
value:
|
|
14388
|
-
|
|
14389
|
-
|
|
14390
|
-
|
|
14391
|
-
|
|
14392
|
-
|
|
14393
|
-
|
|
14394
|
-
|
|
14395
|
-
|
|
14396
|
-
|
|
14397
|
-
|
|
14398
|
-
|
|
14399
|
-
|
|
14400
|
-
|
|
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, {
|
|
14414
|
-
size: "1",
|
|
14415
|
-
mb: "1",
|
|
14416
|
-
as: "div",
|
|
14417
|
-
children: "Posição do Recente"
|
|
14418
|
-
}), /* @__PURE__ */ jsxs(C, {
|
|
14419
|
-
value: s.listSettings.newestPosition || "bottom",
|
|
14420
|
-
onValueChange: (s) => d({ newestPosition: 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, {
|
|
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, {
|
|
14432
14401
|
size: "1",
|
|
14433
14402
|
mb: "1",
|
|
14434
14403
|
as: "div",
|
|
14435
|
-
children: "
|
|
14404
|
+
children: "Direção"
|
|
14436
14405
|
}), /* @__PURE__ */ jsxs(C, {
|
|
14437
|
-
value:
|
|
14438
|
-
onValueChange: (s) =>
|
|
14439
|
-
children: [/* @__PURE__ */ jsx(u$2, {
|
|
14440
|
-
value: "
|
|
14441
|
-
children: "
|
|
14406
|
+
value: U,
|
|
14407
|
+
onValueChange: (s) => K(s),
|
|
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: "
|
|
14444
|
-
children: "
|
|
14412
|
+
value: "desc",
|
|
14413
|
+
children: "Decrescente (Z-A)"
|
|
14445
14414
|
})] })]
|
|
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, {
|
|
14423
|
+
size: "1",
|
|
14424
|
+
mb: "1",
|
|
14425
|
+
as: "div",
|
|
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, {
|
|
14441
|
+
size: "1",
|
|
14442
|
+
mb: "1",
|
|
14443
|
+
as: "div",
|
|
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
|
+
})]
|
|
14446
14456
|
})]
|
|
14447
|
-
})
|
|
14448
|
-
}),
|
|
14449
|
-
/* @__PURE__ */ jsxs(p$1, { children: [
|
|
14457
|
+
}),
|
|
14450
14458
|
/* @__PURE__ */ jsx(p$2, {
|
|
14451
|
-
size: "
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
children: "
|
|
14459
|
+
size: "2",
|
|
14460
|
+
weight: "bold",
|
|
14461
|
+
mt: "2",
|
|
14462
|
+
children: "Dimensões"
|
|
14455
14463
|
}),
|
|
14456
|
-
/* @__PURE__ */
|
|
14457
|
-
|
|
14458
|
-
|
|
14459
|
-
|
|
14460
|
-
|
|
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
|
+
})]
|
|
14461
14511
|
}),
|
|
14462
14512
|
/* @__PURE__ */ jsx(p$2, {
|
|
14463
14513
|
size: "1",
|
|
14464
14514
|
color: "gray",
|
|
14465
|
-
children: "
|
|
14515
|
+
children: "Essa propriedade será usada para ordenar os itens no modo lista."
|
|
14466
14516
|
})
|
|
14467
|
-
]
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
|
|
14472
|
-
|
|
14473
|
-
|
|
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
|
+
}) })]
|
|
14474
14541
|
})
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
mt: "4",
|
|
14479
|
-
justify: "end",
|
|
14480
|
-
children: [/* @__PURE__ */ jsx(D$1, { children: /* @__PURE__ */ jsx(o, {
|
|
14481
|
-
variant: "soft",
|
|
14482
|
-
color: "gray",
|
|
14483
|
-
children: "Cancelar"
|
|
14484
|
-
}) }), /* @__PURE__ */ jsx(D$1, { children: /* @__PURE__ */ jsx(o, {
|
|
14485
|
-
onClick: () => {
|
|
14486
|
-
d({ sortProp: k === "__none__" ? "" : k });
|
|
14487
|
-
},
|
|
14488
|
-
children: "Salvar Alterações"
|
|
14489
|
-
}) })]
|
|
14490
|
-
})
|
|
14491
|
-
]
|
|
14492
|
-
})] });
|
|
14542
|
+
]
|
|
14543
|
+
})]
|
|
14544
|
+
});
|
|
14493
14545
|
};
|
|
14494
14546
|
var EditorContent = ({ layout: s, initialState: w, onSave: k, theme: F = "light" }) => {
|
|
14495
14547
|
let [L, V] = useState(!0), [U, K] = useState(!0), { addElement: q, loadState: J, state: X } = useEditor();
|
|
@@ -14747,5 +14799,5 @@ const GenericEditor = (s) => /* @__PURE__ */ jsx(EditorProvider, {
|
|
|
14747
14799
|
availableProps: s.layout.props,
|
|
14748
14800
|
theme: s.theme,
|
|
14749
14801
|
children: /* @__PURE__ */ jsx(EditorContent, { ...s })
|
|
14750
|
-
}), 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 \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:
|
|
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";
|
|
14751
14803
|
export { GenericEditor as EditorContent, generateHTML };
|