linoyts HF Staff commited on
Commit
2004cc0
·
verified ·
1 Parent(s): 3db1cbc

Canvas UX: draggable boxes from anywhere + click-to-edit desc; hide empty hint

Browse files
Files changed (1) hide show
  1. app.py +15 -4
app.py CHANGED
@@ -423,7 +423,9 @@ SCRIPT = r"""
423
  NS.el.ratios.style.display = S.step===1?'flex':'none';
424
  }
425
  function renderAll(){ layoutBoard(); renderBoxes(); renderSummary(); renderTable(); renderSteps();
426
- NS.el.ratioChips.forEach(c=>c.classList.toggle('sel', c.dataset.r===S.aspect)); syncState(); }
 
 
427
  function esc(s){return (s||'').replace(/[&<>]/g,m=>({'&':'&amp;','<':'&lt;','>':'&gt;'}[m]));}
428
 
429
  function select(e){ sel=e; NS.el.board.querySelectorAll('.box').forEach(d=>
@@ -437,9 +439,18 @@ SCRIPT = r"""
437
  function wireBox(d,e){
438
  const idEl=d.querySelector('.id'), descEl=d.querySelector('.desc');
439
  d.addEventListener('mousedown',ev=>{
440
- if(ev.target.classList.contains('h')||ev.target.classList.contains('rm')||
441
- ev.target.isContentEditable) { select(e); return; }
442
- ev.preventDefault(); select(e); startMove(ev,e,d);
 
 
 
 
 
 
 
 
 
443
  });
444
  d.querySelectorAll('.h').forEach(h=>h.addEventListener('mousedown',ev=>{
445
  ev.preventDefault(); ev.stopPropagation(); select(e);
 
423
  NS.el.ratios.style.display = S.step===1?'flex':'none';
424
  }
425
  function renderAll(){ layoutBoard(); renderBoxes(); renderSummary(); renderTable(); renderSteps();
426
+ NS.el.ratioChips.forEach(c=>c.classList.toggle('sel', c.dataset.r===S.aspect));
427
+ const hint=NS.el.board.querySelector('.hint'); if(hint) hint.style.display=(!S.rendered && S.elements.length===0)?'flex':'none';
428
+ syncState(); }
429
  function esc(s){return (s||'').replace(/[&<>]/g,m=>({'&':'&amp;','<':'&lt;','>':'&gt;'}[m]));}
430
 
431
  function select(e){ sel=e; NS.el.board.querySelectorAll('.box').forEach(d=>
 
439
  function wireBox(d,e){
440
  const idEl=d.querySelector('.id'), descEl=d.querySelector('.desc');
441
  d.addEventListener('mousedown',ev=>{
442
+ if(ev.target.classList.contains('h')||ev.target.classList.contains('rm')||ev.target.classList.contains('id')) { select(e); return; }
443
+ if(ev.target.classList.contains('desc') && document.activeElement===ev.target) return; // editing: allow caret
444
+ select(e); ev.preventDefault();
445
+ const sx=ev.clientX, sy=ev.clientY; let moved=false; const isDesc=ev.target.classList.contains('desc');
446
+ const b=e.bbox.slice(); const p=px2norm(ev); const oy=p[0]-b[0], ox=p[1]-b[1];
447
+ const w=b[3]-b[1], h=b[2]-b[0];
448
+ function mv(ev2){ if(!moved && Math.abs(ev2.clientX-sx)+Math.abs(ev2.clientY-sy)>3) moved=true;
449
+ if(moved){ const q=px2norm(ev2); let x0=clamp(q[1]-ox,0,1000-w), y0=clamp(q[0]-oy,0,1000-h);
450
+ e.bbox=[y0,x0,y0+h,x0+w]; posBox(d,e); liveMeta(e); } }
451
+ function up(){ document.removeEventListener('mousemove',mv); document.removeEventListener('mouseup',up);
452
+ if(moved) renderAll(); else if(isDesc) descEl.focus(); }
453
+ document.addEventListener('mousemove',mv); document.addEventListener('mouseup',up);
454
  });
455
  d.querySelectorAll('.h').forEach(h=>h.addEventListener('mousedown',ev=>{
456
  ev.preventDefault(); ev.stopPropagation(); select(e);