@1urso/generic-editor 0.1.12 → 0.1.14
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 +76 -33
- package/dist/generic-editor.umd.cjs +3 -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,13 +14329,13 @@ const Preview = () => {
|
|
|
14329
14329
|
})
|
|
14330
14330
|
});
|
|
14331
14331
|
}, EditorSettings = () => {
|
|
14332
|
-
let { state: s, updateListSettings: d, setCanvasHeight: w } = useEditor(), [k, F] = useState(""), [L, V] = useState("150");
|
|
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("");
|
|
14333
14333
|
return useEffect(() => {
|
|
14334
|
-
F(s.listSettings.sortProp || "__none__"), V(String(s.canvasHeight || 150));
|
|
14335
|
-
}, [s.listSettings
|
|
14336
|
-
let s = parseInt(
|
|
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
14337
|
!isNaN(s) && s > 0 && w(s);
|
|
14338
|
-
}, [
|
|
14338
|
+
}, [$, w]), /* @__PURE__ */ jsxs(s$2, { children: [/* @__PURE__ */ jsx(n$2, { children: /* @__PURE__ */ jsxs(o, {
|
|
14339
14339
|
variant: "soft",
|
|
14340
14340
|
color: "gray",
|
|
14341
14341
|
style: {
|
|
@@ -14394,8 +14394,8 @@ const Preview = () => {
|
|
|
14394
14394
|
as: "div",
|
|
14395
14395
|
children: "Direção"
|
|
14396
14396
|
}), /* @__PURE__ */ jsxs(C, {
|
|
14397
|
-
value:
|
|
14398
|
-
onValueChange: (s) =>
|
|
14397
|
+
value: L,
|
|
14398
|
+
onValueChange: (s) => V(s),
|
|
14399
14399
|
children: [/* @__PURE__ */ jsx(u$2, {}), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
|
|
14400
14400
|
value: "asc",
|
|
14401
14401
|
children: "Crescente (A-Z)"
|
|
@@ -14416,8 +14416,8 @@ const Preview = () => {
|
|
|
14416
14416
|
as: "div",
|
|
14417
14417
|
children: "Posição do Recente"
|
|
14418
14418
|
}), /* @__PURE__ */ jsxs(C, {
|
|
14419
|
-
value:
|
|
14420
|
-
onValueChange: (s) =>
|
|
14419
|
+
value: U,
|
|
14420
|
+
onValueChange: (s) => K(s),
|
|
14421
14421
|
children: [/* @__PURE__ */ jsx(u$2, { style: { width: "100%" } }), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
|
|
14422
14422
|
value: "top",
|
|
14423
14423
|
children: "Topo (Início)"
|
|
@@ -14434,8 +14434,8 @@ const Preview = () => {
|
|
|
14434
14434
|
as: "div",
|
|
14435
14435
|
children: "Comportamento de Rolagem"
|
|
14436
14436
|
}), /* @__PURE__ */ jsxs(C, {
|
|
14437
|
-
value:
|
|
14438
|
-
onValueChange: (s) =>
|
|
14437
|
+
value: q,
|
|
14438
|
+
onValueChange: (s) => J(s),
|
|
14439
14439
|
children: [/* @__PURE__ */ jsx(u$2, { style: { width: "100%" } }), /* @__PURE__ */ jsxs(g, { children: [/* @__PURE__ */ jsx(v$1, {
|
|
14440
14440
|
value: "down",
|
|
14441
14441
|
children: "Descer (Padrão)"
|
|
@@ -14446,25 +14446,60 @@ const Preview = () => {
|
|
|
14446
14446
|
})]
|
|
14447
14447
|
})]
|
|
14448
14448
|
}),
|
|
14449
|
-
/* @__PURE__ */
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
|
|
14455
|
-
|
|
14456
|
-
|
|
14457
|
-
|
|
14458
|
-
|
|
14459
|
-
|
|
14460
|
-
|
|
14461
|
-
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
|
|
14467
|
-
|
|
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, {
|
|
14462
|
+
size: "1",
|
|
14463
|
+
mb: "1",
|
|
14464
|
+
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, {
|
|
14483
|
+
size: "1",
|
|
14484
|
+
mb: "1",
|
|
14485
|
+
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
|
+
}),
|
|
14468
14503
|
/* @__PURE__ */ jsx(p$2, {
|
|
14469
14504
|
size: "1",
|
|
14470
14505
|
color: "gray",
|
|
@@ -14483,7 +14518,14 @@ const Preview = () => {
|
|
|
14483
14518
|
children: "Cancelar"
|
|
14484
14519
|
}) }), /* @__PURE__ */ jsx(D$1, { children: /* @__PURE__ */ jsx(o, {
|
|
14485
14520
|
onClick: () => {
|
|
14486
|
-
|
|
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
|
+
});
|
|
14487
14529
|
},
|
|
14488
14530
|
children: "Salvar Alterações"
|
|
14489
14531
|
}) })]
|
|
@@ -14590,7 +14632,8 @@ var EditorContent = ({ layout: s, initialState: w, onSave: k, theme: F = "light"
|
|
|
14590
14632
|
isList: X.isList,
|
|
14591
14633
|
mockData: X.mockData,
|
|
14592
14634
|
singleMockData: X.singleMockData,
|
|
14593
|
-
listSettings: X.listSettings
|
|
14635
|
+
listSettings: X.listSettings,
|
|
14636
|
+
canvasHeight: X.canvasHeight
|
|
14594
14637
|
};
|
|
14595
14638
|
k(JSON.stringify(s, null, 2));
|
|
14596
14639
|
}
|
|
@@ -14746,5 +14789,5 @@ const GenericEditor = (s) => /* @__PURE__ */ jsx(EditorProvider, {
|
|
|
14746
14789
|
availableProps: s.layout.props,
|
|
14747
14790
|
theme: s.theme,
|
|
14748
14791
|
children: /* @__PURE__ */ jsx(EditorContent, { ...s })
|
|
14749
|
-
}), 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:
|
|
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";
|
|
14750
14793
|
export { GenericEditor as EditorContent, generateHTML };
|