fix(builder): improve menu anchor targeting and free-drop placement

This commit is contained in:
komkida91
2026-02-24 16:21:25 +01:00
parent b37d2d4bec
commit 68aa6fe025

View File

@@ -1030,23 +1030,36 @@ const state = {
</div>`; </div>`;
} }
const manualItems = Array.isArray(block.data?.items) ? block.data.items.map((x)=>String(x || "").trim()).filter(Boolean) : []; const manualItems = Array.isArray(block.data?.items) ? block.data.items.map((x)=>String(x || "").trim()).filter(Boolean) : [];
const contentBlocks = state.blocks
.filter((b)=>b.type!=="menu")
.map((b, i)=>{
const title = (b.data && (b.data.title || b.data.text || b.type)) || b.type;
return { id: b.id, label: String(title).slice(0, 24), index: i+1 };
});
const norm = (v)=>String(v || "")
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.replace(/[^a-z0-9]+/g, " ")
.trim();
const items = manualItems.length const items = manualItems.length
? (manualItems.length >= 3 ? (manualItems.length >= 3
? manualItems.map((label, i)=>({ id: `menu_item_${i+1}`, label: String(label).slice(0, 24), index: i+1 })) ? manualItems.map((label, i)=>{
const key = norm(label);
const exact = contentBlocks.find((b)=>norm(b.label) === key);
const byIndex = contentBlocks[i];
const target = exact || byIndex || null;
return { id: target ? target.id : "", label: String(label).slice(0, 24), index: i+1 };
})
: []) : [])
: state.blocks : contentBlocks;
.filter(b=>b.type!=="menu")
.map((b, i)=>{
const title = (b.data && (b.data.title || b.data.text || b.type)) || b.type;
return { id: b.id, label: String(title).slice(0, 24), index: i+1 };
});
const safeItems = items.length ? items : [ const safeItems = items.length ? items : [
{ id: "menu_item_1", label: "Inicio", index: 1 }, { id: "menu_item_1", label: "Inicio", index: 1 },
{ id: "menu_item_2", label: "Productos", index: 2 }, { id: "menu_item_2", label: "Productos", index: 2 },
{ id: "menu_item_3", label: "Contacto", index: 3 } { id: "menu_item_3", label: "Contacto", index: 3 }
]; ];
const links = safeItems.map(it=>`<a class="site-nav-link" href="#${it.id}">${escapeHtml(it.label)}</a>`).join(""); const links = safeItems.map(it=>`<a class="site-nav-link" href="${it.id ? `#${it.id}` : "#"}">${escapeHtml(it.label)}</a>`).join("");
const mobileLinks = safeItems.map(it=>`<a class="site-nav-link" href="#${it.id}" data-drawer-link="1">${escapeHtml(it.label)}</a>`).join(""); const mobileLinks = safeItems.map(it=>`<a class="site-nav-link" href="${it.id ? `#${it.id}` : "#"}" data-drawer-link="1">${escapeHtml(it.label)}</a>`).join("");
const siteName = String(state.settings.site_name || "GKACHELE"); const siteName = String(state.settings.site_name || "GKACHELE");
const initial = escapeHtml(siteName.slice(0, 1).toUpperCase()); const initial = escapeHtml(siteName.slice(0, 1).toUpperCase());
const logo = state.settings.logo_url const logo = state.settings.logo_url
@@ -2142,6 +2155,20 @@ const state = {
} }
function wirePreviewDrop(){ function wirePreviewDrop(){
const canvas=document.getElementById("previewCanvas"); const canvas=document.getElementById("previewCanvas");
const getDropPosition = (block, clientX, clientY)=>{
const rect = canvas.getBoundingClientRect();
const widthPct = Math.max(20, Math.min(100, Number(block?.data?.width || 60)));
const estWidth = Math.max(120, (rect.width * widthPct) / 100);
const estHeight = Math.max(80, Number(block?.data?.height || 160));
const left = snap(clientX - rect.left - (estWidth / 2));
const top = snap(clientY - rect.top - (estHeight / 2));
const maxX = Math.max(0, rect.width - estWidth);
const maxY = Math.max(0, rect.height - estHeight);
return {
x: Math.max(0, Math.min(maxX, left)),
y: Math.max(0, Math.min(maxY, top))
};
};
canvas.addEventListener("dragover",(e)=>{ canvas.addEventListener("dragover",(e)=>{
e.preventDefault(); e.preventDefault();
if (!state.settings.free_drag){ if (!state.settings.free_drag){
@@ -2159,8 +2186,7 @@ const state = {
const b={ id: makeId(), type, data: defaultData(type) }; const b={ id: makeId(), type, data: defaultData(type) };
if (typeof b.data.width === "undefined") b.data.width = snapBlockWidth(type, 100); if (typeof b.data.width === "undefined") b.data.width = snapBlockWidth(type, 100);
if (state.settings.free_drag){ if (state.settings.free_drag){
const rect = canvas.getBoundingClientRect(); b.pos = getDropPosition(b, e.clientX, e.clientY);
b.pos = { x: Math.max(0, e.clientX - rect.left - 20), y: Math.max(0, e.clientY - rect.top - 20) };
} else { } else {
const container=getCanvasContainer(canvas); const container=getCanvasContainer(canvas);
if (!container) return; if (!container) return;