@mhamz.01/easyflow-whiteboard 1.24.0 → 1.27.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACxC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qBAAqB,CAAC,EAAE,YAAY,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAaD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,KAAK,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,UAAc,EACd,cAA+B,EAC/B,YAAmB,EACnB,qBAA0B,EAC1B,YAAY,GACb,EAAE,uBAAuB,2CAqdzB"}
1
+ {"version":3,"file":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACxC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qBAAqB,CAAC,EAAE,YAAY,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAaD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,KAAK,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,UAAc,EACd,cAA+B,EAC/B,YAAmB,EACnB,qBAA0B,EAC1B,YAAY,GACb,EAAE,uBAAuB,2CA4dzB"}
@@ -128,39 +128,38 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
128
128
  return { x: doc.x, y: doc.y };
129
129
  return undefined;
130
130
  };
131
- const isItemInSelectionBox = (x, y, width, height, box) => {
132
- // Get FRESH overlay offset (recalculates on every check - handles sidebar)
133
- const overlayRect = overlayRef.current?.getBoundingClientRect();
134
- if (!overlayRect)
135
- return false;
136
- // Node's screen position (where it actually renders)
137
- const itemX1 = x * canvasZoom + canvasViewport.x;
138
- const itemY1 = y * canvasZoom + canvasViewport.y;
139
- const itemX2 = itemX1 + width * canvasZoom;
140
- const itemY2 = itemY1 + height * canvasZoom;
141
- // Selection box is in viewport coords, convert to overlay-relative
142
- const boxX1 = Math.min(box.x1, box.x2) - overlayRect.left;
143
- const boxY1 = Math.min(box.y1, box.y2) - overlayRect.top;
144
- const boxX2 = Math.max(box.x1, box.x2) - overlayRect.left;
145
- const boxY2 = Math.max(box.y1, box.y2) - overlayRect.top;
146
- // Check intersection
147
- return !(boxX2 < itemX1 || boxX1 > itemX2 || boxY2 < itemY1 || boxY1 > itemY2);
131
+ const isItemInSelectionBox = (nodeX, nodeY, width, height, box) => {
132
+ // EVERYTHING HERE IS NOW IN WORLD (SCENE) COORDINATES
133
+ // No canvasZoom or canvasViewport needed for the check!
134
+ const nodeX2 = nodeX + width;
135
+ const nodeY2 = nodeY + height;
136
+ return !(box.x2 < nodeX ||
137
+ box.x1 > nodeX2 ||
138
+ box.y2 < nodeY ||
139
+ box.y1 > nodeY2);
148
140
  };
149
141
  // ── Selection box detection ──────────────────────────────────────────────────
150
142
  useEffect(() => {
151
143
  if (!selectionBox)
152
144
  return;
153
145
  const newSelected = new Set();
154
- localTasks.forEach((task) => {
155
- if (isItemInSelectionBox(task.x, task.y, 300, 140, selectionBox))
156
- newSelected.add(task.id);
146
+ // Use the actual dimensions of your components
147
+ // Better yet: Pass these as props if they are dynamic
148
+ const NODE_WIDTH = 300;
149
+ const TASK_HEIGHT = 140;
150
+ const DOC_HEIGHT = 160;
151
+ localTasks.forEach((t) => {
152
+ if (isItemInSelectionBox(t.x, t.y, NODE_WIDTH, TASK_HEIGHT, selectionBox)) {
153
+ newSelected.add(t.id);
154
+ }
157
155
  });
158
- localDocuments.forEach((doc) => {
159
- if (isItemInSelectionBox(doc.x, doc.y, 300, 160, selectionBox))
160
- newSelected.add(doc.id);
156
+ localDocuments.forEach((d) => {
157
+ if (isItemInSelectionBox(d.x, d.y, NODE_WIDTH, DOC_HEIGHT, selectionBox)) {
158
+ newSelected.add(d.id);
159
+ }
161
160
  });
162
161
  setSelectedIds(newSelected);
163
- }, [selectionBox, localTasks, localDocuments, canvasZoom, canvasViewport]);
162
+ }, [selectionBox]);
164
163
  // ── Drag start (HTML Node side) ──────────────────────────────────────────────
165
164
  // Helper to extract coordinates regardless of event type
166
165
  const getPointerEvent = (e) => {
@@ -330,24 +329,25 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
330
329
  }, [localTasks, localDocuments, selectedIds, onTasksUpdate, onDocumentsUpdate]);
331
330
  // ── Render helper ────────────────────────────────────────────────────────────
332
331
  const renderItem = (id, x, y, children) => {
332
+ // We apply the viewport offset to the container,
333
+ // so here we only care about the scaled local position.
333
334
  const screenX = x * canvasZoom;
334
335
  const screenY = y * canvasZoom;
335
- // 1. Detect if the user is interacting with the canvas at all
336
- // 'dragging' is your existing state.
337
- // You might want to pass 'isZooming' or 'isPanning' from your main canvas component here.
338
336
  const isDragging = dragging?.itemIds.includes(id);
339
337
  return (_jsx("div", { className: "pointer-events-auto absolute", style: {
340
338
  left: 0,
341
339
  top: 0,
342
- // 2. Use translate3d for GPU performance
340
+ // Using translate3d(x, y, 0) is non-negotiable for 2026 performance
343
341
  transform: `translate3d(${screenX}px, ${screenY}px, 0) scale(${canvasZoom})`,
344
342
  transformOrigin: "top left",
345
- // 3. THE FIX: Remove transition entirely during any viewport change
346
- // Any 'ease' during zoom causes the "shaking" behavior.
343
+ // CRITICAL: Disable all transitions.
344
+ // Even a 100ms transition will cause the node to "float" away during zoom.
347
345
  transition: "none",
348
- // 4. Optimization
349
346
  willChange: "transform",
350
347
  zIndex: isDragging ? 1000 : 1,
348
+ // Added: Prevent browser from trying to optimize text rendering during move
349
+ // which causes the "shaking" text bug.
350
+ backfaceVisibility: "hidden",
351
351
  }, children: children }, id));
352
352
  };
353
353
  return (_jsx("div", { ref: overlayRef, className: "absolute inset-0 pointer-events-none", style: { zIndex: 50 }, onWheel: handleOverlayWheel, onClick: (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"document-node.d.ts","sourceRoot":"","sources":["../../../src/components/node/document-node.tsx"],"names":[],"mappings":"AAKA,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACtD,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC5E;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,EAAE,EACF,KAAK,EACL,OAAO,EACP,UAAe,EACf,OAAO,EACP,SAAS,EACT,UAAkB,EAClB,QAAQ,EACR,WAAW,GACZ,EAAE,iBAAiB,2CAuJnB"}
1
+ {"version":3,"file":"document-node.d.ts","sourceRoot":"","sources":["../../../src/components/node/document-node.tsx"],"names":[],"mappings":"AAKE,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACtD,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC5E;AAED,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,EAAE,EACF,KAAK,EACL,OAAO,EACP,UAAe,EACf,OAAO,EACP,SAAS,EACT,UAAkB,EAClB,QAAQ,EACR,WAAW,GACZ,EAAE,iBAAiB,2CAuJnB"}
@@ -36,23 +36,23 @@ export default function DocumentNode({ id, title, project, breadcrumb = [], prev
36
36
  }
37
37
  }, [isDragging]);
38
38
  return (_jsxs("div", { onMouseDown: handleStart, onTouchStart: handleStart, className: `
39
- relative w-[320px] bg-[#121214] rounded-2xl border transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)]
40
- ${isDragging ? "cursor-grabbing scale-[1.03] z-50 shadow-2xl" : "cursor-grab shadow-lg hover:border-[#3e3e42]"}
41
- ${isSelected ? "border-[#029AFF] ring-1 ring-[#029AFF]" : "border-[#28282b]"}
42
- ${isExpanded ? "w-[400px]" : "w-[320px]"}
43
- `, children: [isSelected && (_jsx("div", { className: "absolute -inset-px bg-gradient-to-r from-[#029AFF]/20 to-[#7000FF]/20 rounded-2xl blur-md -z-10" })), _jsxs("div", { className: "flex items-center justify-between p-3 pb-0", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "p-1.5 bg-[#029AFF]/10 rounded-lg", children: _jsx(Layers, { className: "w-3.5 h-3.5 text-[#029AFF]" }) }), _jsx("span", { className: "text-[10px] font-bold text-gray-500 tracking-tighter uppercase", children: project })] }), _jsx("button", { className: "interactive-element p-1 hover:bg-white/5 rounded-md text-gray-600 transition-colors", children: _jsx(MoreHorizontal, { className: "w-4 h-4" }) })] }), _jsxs("div", { className: "p-4 pt-2", children: [_jsxs("div", { onClick: () => setIsExpanded(!isExpanded), className: "interactive-element flex items-start justify-between group/title cursor-pointer", children: [_jsx("h3", { className: "text-[16px] font-semibold text-white leading-tight group-hover/title:text-[#029AFF] transition-colors pr-2", children: title }), _jsx("div", { className: "mt-1", children: isExpanded ?
39
+ relative w-[320px] bg-[#121214] rounded-2xl border transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)]
40
+ ${isDragging ? "cursor-grabbing scale-[1.03] z-50 shadow-2xl" : "cursor-grab shadow-lg hover:border-[#3e3e42]"}
41
+ ${isSelected ? "border-[#029AFF] ring-1 ring-[#029AFF]" : "border-[#28282b]"}
42
+ ${isExpanded ? "w-[400px]" : "w-[320px]"}
43
+ `, children: [isSelected && (_jsx("div", { className: "absolute -inset-px bg-gradient-to-r from-[#029AFF]/20 to-[#7000FF]/20 rounded-2xl blur-md -z-10" })), _jsxs("div", { className: "flex items-center justify-between p-3 pb-0", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "p-1.5 bg-[#029AFF]/10 rounded-lg", children: _jsx(Layers, { className: "w-3.5 h-3.5 text-[#029AFF]" }) }), _jsx("span", { className: "text-[10px] font-bold text-gray-500 tracking-tighter uppercase", children: project })] }), _jsx("button", { className: "interactive-element p-1 hover:bg-white/5 rounded-md text-gray-600 transition-colors", children: _jsx(MoreHorizontal, { className: "w-4 h-4" }) })] }), _jsxs("div", { className: "p-4 pt-2", children: [_jsxs("div", { onClick: () => setIsExpanded(!isExpanded), className: "interactive-element flex items-start justify-between group/title cursor-pointer", children: [_jsx("h3", { className: "text-[16px] font-semibold text-white leading-tight group-hover/title:text-[#029AFF] transition-colors pr-2", children: title }), _jsx("div", { className: "mt-1", children: isExpanded ?
44
44
  _jsx(ChevronUp, { className: "w-4 h-4 text-gray-500" }) :
45
45
  _jsx(ChevronDown, { className: "w-4 h-4 text-gray-500" }) })] }), _jsx("div", { className: "flex items-center gap-2 mt-2 overflow-x-auto no-scrollbar pb-1", children: breadcrumb.map((item, i) => (_jsx("div", { className: "flex items-center gap-2 flex-shrink-0", children: _jsx("span", { className: "text-[10px] px-2 py-0.5 bg-[#1C1C1E] border border-[#2C2C2E] text-gray-400 rounded-full", children: item }) }, i))) }), _jsxs("div", { className: `
46
- mt-4 relative transition-all duration-500 ease-in-out overflow-hidden
47
- ${isExpanded ? "h-[300px]" : "h-[100px]"}
48
- `, children: [_jsxs("div", { onMouseDown: (e) => e.stopPropagation(), className: "interactive-element h-full w-full bg-[#09090A] border border-[#232326] rounded-xl overflow-y-auto p-3 text-[13px] text-gray-400 leading-relaxed custom-scrollbar selection:bg-[#029AFF]/40", children: [preview, isExpanded && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[#232326] flex items-center justify-between", children: [_jsx("span", { className: "text-[11px] text-gray-500 italic", children: "End of document preview" }), _jsxs("button", { className: "flex items-center gap-2 text-[11px] text-[#029AFF] hover:underline font-medium", children: ["Open Full File ", _jsx(ExternalLink, { className: "w-3 h-3" })] })] }))] }), !isExpanded && (_jsx("div", { className: "absolute bottom-0 left-0 right-0 h-10 bg-gradient-to-t from-[#09090A] to-transparent pointer-events-none" }))] }), _jsxs("div", { className: "mt-4 flex items-center justify-between opacity-60", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-gray-400", children: [_jsx(Clock, { className: "w-3 h-3" }), _jsxs("span", { children: ["Updated ", updatedAt || "recently"] })] }), _jsx("div", { className: "flex -space-x-1.5", children: [1, 2].map(i => (_jsxs("div", { className: "w-5 h-5 rounded-full border-2 border-[#121214] bg-[#2C2C2E] flex items-center justify-center text-[8px] text-white", children: ["U", i] }, i))) })] })] }), _jsx("style", { children: `
49
- .no-scrollbar::-webkit-scrollbar { display: none; }
50
- .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
51
- .custom-scrollbar::-webkit-scrollbar { width: 5px; }
52
- .custom-scrollbar::-webkit-scrollbar-thumb {
53
- background: #232326;
54
- border-radius: 10px;
55
- }
56
- .custom-scrollbar::-webkit-scrollbar-thumb:hover { background: #029AFF; }
57
- ` })] }));
46
+ mt-4 relative transition-all duration-500 ease-in-out overflow-hidden
47
+ ${isExpanded ? "h-[300px]" : "h-[100px]"}
48
+ `, children: [_jsxs("div", { onMouseDown: (e) => e.stopPropagation(), className: "interactive-element h-full w-full bg-[#09090A] border border-[#232326] rounded-xl overflow-y-auto p-3 text-[13px] text-gray-400 leading-relaxed custom-scrollbar selection:bg-[#029AFF]/40", children: [preview, isExpanded && (_jsxs("div", { className: "mt-4 pt-4 border-t border-[#232326] flex items-center justify-between", children: [_jsx("span", { className: "text-[11px] text-gray-500 italic", children: "End of document preview" }), _jsxs("button", { className: "flex items-center gap-2 text-[11px] text-[#029AFF] hover:underline font-medium", children: ["Open Full File ", _jsx(ExternalLink, { className: "w-3 h-3" })] })] }))] }), !isExpanded && (_jsx("div", { className: "absolute bottom-0 left-0 right-0 h-10 bg-gradient-to-t from-[#09090A] to-transparent pointer-events-none" }))] }), _jsxs("div", { className: "mt-4 flex items-center justify-between opacity-60", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-gray-400", children: [_jsx(Clock, { className: "w-3 h-3" }), _jsxs("span", { children: ["Updated ", updatedAt || "recently"] })] }), _jsx("div", { className: "flex -space-x-1.5", children: [1, 2].map(i => (_jsxs("div", { className: "w-5 h-5 rounded-full border-2 border-[#121214] bg-[#2C2C2E] flex items-center justify-center text-[8px] text-white", children: ["U", i] }, i))) })] })] }), _jsx("style", { children: `
49
+ .no-scrollbar::-webkit-scrollbar { display: none; }
50
+ .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
51
+ .custom-scrollbar::-webkit-scrollbar { width: 5px; }
52
+ .custom-scrollbar::-webkit-scrollbar-thumb {
53
+ background: #232326;
54
+ border-radius: 10px;
55
+ }
56
+ .custom-scrollbar::-webkit-scrollbar-thumb:hover { background: #029AFF; }
57
+ ` })] }));
58
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useSelection.d.ts","sourceRoot":"","sources":["../../src/hooks/useSelection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAQ,YAAY,EAAe,MAAM,QAAQ,CAAC;AAOjE,UAAU,iBAAiB;IACzB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,eAAe,EAAE,CAAC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1F,wBAAwB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAC5D,YAAY,EAAE,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;CAC/C;AAED,eAAO,MAAM,YAAY,GAAI,oHAQ1B,iBAAiB,SA+JnB,CAAC"}
1
+ {"version":3,"file":"useSelection.d.ts","sourceRoot":"","sources":["../../src/hooks/useSelection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAQ,YAAY,EAAe,MAAM,QAAQ,CAAC;AAOjE,UAAU,iBAAiB;IACzB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,eAAe,EAAE,CAAC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1F,wBAAwB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAC5D,YAAY,EAAE,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;CAC/C;AAED,eAAO,MAAM,YAAY,GAAI,oHAQ1B,iBAAiB,SA2JnB,CAAC"}
@@ -37,6 +37,7 @@ export const useSelection = ({ fabricCanvas, activeTool, canvasZoom, canvasViewp
37
37
  canvas.add(selRect);
38
38
  canvas.renderAll();
39
39
  };
40
+ // hooks/useSelection.ts - UPDATED
40
41
  const onMove = (e) => {
41
42
  if (!isSelecting || !selRect)
42
43
  return;
@@ -46,23 +47,20 @@ export const useSelection = ({ fabricCanvas, activeTool, canvasZoom, canvasViewp
46
47
  const p = canvas.getScenePoint(e.e);
47
48
  const w = p.x - selStart.x;
48
49
  const h = p.y - selStart.y;
50
+ const x1 = Math.min(selStart.x, p.x);
51
+ const y1 = Math.min(selStart.y, p.y);
52
+ const x2 = Math.max(selStart.x, p.x);
53
+ const y2 = Math.max(selStart.y, p.y);
49
54
  selRect.set({
50
- left: w < 0 ? p.x : selStart.x,
51
- top: h < 0 ? p.y : selStart.y,
52
- width: Math.abs(w),
53
- height: Math.abs(h),
55
+ left: x1,
56
+ top: y1,
57
+ width: x2 - x1,
58
+ height: y2 - y1,
54
59
  });
55
60
  selRect.setCoords();
56
61
  canvas.renderAll();
57
- // FIX: Get FRESH canvas offset (accounts for navbar/sidebar)
58
- const canvasElement = canvas.getElement();
59
- const canvasRect = canvasElement.getBoundingClientRect();
60
- setSelectionBox({
61
- x1: Math.min(selStart.x, p.x) * canvasZoom + canvasViewport.x + canvasRect.left,
62
- y1: Math.min(selStart.y, p.y) * canvasZoom + canvasViewport.y + canvasRect.top,
63
- x2: Math.max(selStart.x, p.x) * canvasZoom + canvasViewport.x + canvasRect.left,
64
- y2: Math.max(selStart.y, p.y) * canvasZoom + canvasViewport.y + canvasRect.top,
65
- });
62
+ // PASS WORLD COORDINATES ONLY
63
+ setSelectionBox({ x1, y1, x2, y2 });
66
64
  });
67
65
  };
68
66
  const onUp = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhamz.01/easyflow-whiteboard",
3
- "version": "1.24.0",
3
+ "version": "1.27.0",
4
4
  "description": "A feature-rich whiteboard component built with Fabric.js and React",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",