@mhamz.01/easyflow-whiteboard 2.141.0 → 2.142.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":"whiteboard-test.d.ts","sourceRoot":"","sources":["../../../src/components/whiteboard/whiteboard-test.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAkB5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAIxE,UAAU,IAAI;IACZ,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,qBAAqB;IAC7B,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QACf,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;KACxB,CAAC;IACF,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,GAAG,EAAE,CAAC;QACb,SAAS,EAAE,GAAG,EAAE,CAAC;KAClB,KAAK,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA2HD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,WAAW,EACX,MAAM,EACN,cAAc,EACd,cAAmB,EACnB,kBAAuB,EACvB,aAAqB,GACtB,EAAE,qBAAqB,2CAiRvB"}
1
+ {"version":3,"file":"whiteboard-test.d.ts","sourceRoot":"","sources":["../../../src/components/whiteboard/whiteboard-test.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAkB5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAIxE,UAAU,IAAI;IACZ,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,qBAAqB;IAC7B,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QACf,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;KACxB,CAAC;IACF,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,GAAG,EAAE,CAAC;QACb,SAAS,EAAE,GAAG,EAAE,CAAC;KAClB,KAAK,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiHD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,WAAW,EACX,MAAM,EACN,cAAc,EACd,cAAmB,EACnB,kBAAuB,EACvB,aAAqB,GACtB,EAAE,qBAAqB,2CAyRvB"}
@@ -30,15 +30,13 @@ const MemoizedToolbarWrapper = React.memo(function ToolbarWrapper({ canvasReady,
30
30
  // ── Memoized Overlay wrapper (Issue 11) ───────────────────────────────────────
31
31
  // This wrapper only updates when tasks/documents/canvasReady change
32
32
  // Not on every pan/zoom frame
33
- const MemoizedOverlayWrapper = React.memo(function OverlayWrapper({ tasks, documents, canvasReady, fabricCanvasRef, onTasksUpdate, onDocumentsUpdate, }) {
34
- // Issue 11: Read zoom/viewport directly from fabricCanvas instead of prop drilling
35
- // This prevents re-renders on every pan/zoom frame
33
+ const MemoizedOverlayWrapper = React.memo(function OverlayWrapper({ tasks, documents, canvasReady, fabricCanvasRef, onTasksUpdate, onDocumentsUpdate, selectionBox, // ← destructure from props
34
+ selectedCanvasObjects, // destructure from props
35
+ }) {
36
+ // Only zoom/viewport are read from canvas internally — these two have no external source
36
37
  const [canvasZoom, setCanvasZoom] = useState(1);
37
38
  const [canvasViewport, setCanvasViewport] = useState({ x: 0, y: 0 });
38
- const [selectionBox, setSelectionBox] = useState(null);
39
- const [selectedCanvasObjects, setSelectedCanvasObjects] = useState([]);
40
- // Effect to sync zoom/viewport from fabric canvas
41
- // This keeps the overlay in sync without prop drilling
39
+ // ← Remove the two useState calls for selectionBox and selectedCanvasObjects entirely
42
40
  React.useEffect(() => {
43
41
  const canvas = fabricCanvasRef.current;
44
42
  if (!canvas)
@@ -47,29 +45,25 @@ const MemoizedOverlayWrapper = React.memo(function OverlayWrapper({ tasks, docum
47
45
  const vpt = canvas.viewportTransform;
48
46
  if (!vpt)
49
47
  return;
50
- // Extract zoom (scale) from viewport transform
51
- const zoom = vpt[0];
52
- const vpX = vpt[4];
53
- const vpY = vpt[5];
54
- setCanvasZoom(zoom);
55
- setCanvasViewport({ x: vpX, y: vpY });
48
+ setCanvasZoom(vpt[0]);
49
+ setCanvasViewport({ x: vpt[4], y: vpt[5] });
56
50
  };
57
- // Update on viewport change
58
51
  canvas.on("after:render", updateViewport);
59
- updateViewport(); // Initial sync
52
+ updateViewport();
60
53
  return () => {
61
- canvas.off("after:render", updateViewport); // ← was "viewport:changed", must match registration
54
+ canvas.off("after:render", updateViewport);
62
55
  };
63
56
  }, [fabricCanvasRef, canvasReady]);
64
- return (_jsx(CanvasOverlayLayer, { tasks: tasks, documents: documents, onTasksUpdate: onTasksUpdate, onDocumentsUpdate: onDocumentsUpdate, canvasZoom: canvasZoom, canvasViewport: canvasViewport, selectionBox: selectionBox, selectedCanvasObjects: selectedCanvasObjects, fabricCanvas: fabricCanvasRef, canvasReady: canvasReady }));
57
+ return (_jsx(CanvasOverlayLayer, { tasks: tasks, documents: documents, onTasksUpdate: onTasksUpdate, onDocumentsUpdate: onDocumentsUpdate, canvasZoom: canvasZoom, canvasViewport: canvasViewport, fabricCanvas: fabricCanvasRef, canvasReady: canvasReady, selectionBox: selectionBox, selectedCanvasObjects: selectedCanvasObjects }));
65
58
  }, (prev, next) => {
66
- // Custom comparator — only re-render if these props change
67
59
  return (prev.tasks === next.tasks &&
68
60
  prev.documents === next.documents &&
69
61
  prev.canvasReady === next.canvasReady &&
70
62
  prev.fabricCanvasRef === next.fabricCanvasRef &&
71
63
  prev.onTasksUpdate === next.onTasksUpdate &&
72
- prev.onDocumentsUpdate === next.onDocumentsUpdate);
64
+ prev.onDocumentsUpdate === next.onDocumentsUpdate &&
65
+ prev.selectionBox === next.selectionBox &&
66
+ prev.selectedCanvasObjects === next.selectedCanvasObjects);
73
67
  });
74
68
  export default function FabricWhiteboard({ initialData, onSave, saveDebounceMs, availableTasks = [], availableDocuments = [], isLoadingData = false, }) {
75
69
  // Refs
@@ -96,6 +90,8 @@ export default function FabricWhiteboard({ initialData, onSave, saveDebounceMs,
96
90
  const [tasks, setTasks] = useState([]);
97
91
  const [canvasReady, setCanvasReady] = useState(false);
98
92
  const [documents, setDocuments] = useState([]);
93
+ const [selectionBox, setSelectionBox] = useState(null);
94
+ const [selectedCanvasObjects, setSelectedCanvasObjects] = useState([]);
99
95
  const MIN_ZOOM = 0.1;
100
96
  const MAX_ZOOM = 5;
101
97
  const ZOOM_STEP = 0.1;
@@ -183,8 +179,8 @@ export default function FabricWhiteboard({ initialData, onSave, saveDebounceMs,
183
179
  activeTool,
184
180
  canvasZoom: 1, // Read from canvas instead
185
181
  canvasViewport: { x: 0, y: 0 },
186
- setSelectionBox: () => { }, // Not used anymore
187
- setSelectedCanvasObjects: () => { }, // Not used anymore
182
+ setSelectionBox, // Not used anymore
183
+ setSelectedCanvasObjects, // Not used anymore
188
184
  isDrawingRef,
189
185
  });
190
186
  // Text style updates
@@ -274,5 +270,5 @@ export default function FabricWhiteboard({ initialData, onSave, saveDebounceMs,
274
270
  backgroundImage: `radial-gradient(circle, rgba(255,255,255,0.2) 1.2px, transparent 1.2px)`,
275
271
  backgroundSize: "40px 40px",
276
272
  zIndex: 0,
277
- } }), _jsx("canvas", { ref: canvasRef, className: "absolute inset-0", style: { zIndex: 1 } }), _jsx(MemoizedOverlayWrapper, { tasks: tasks, documents: documents, canvasReady: canvasReady, fabricCanvasRef: fabricCanvasRef, onTasksUpdate: setTasks, onDocumentsUpdate: setDocuments }), _jsxs("div", { className: "absolute inset-0 pointer-events-none", style: { zIndex: 100 }, children: [_jsx("div", { className: "pointer-events-auto", children: _jsx(MemoizedToolbarWrapper, { canvasReady: canvasReady, fabricCanvasRef: fabricCanvasRef, isRestoringRef: isRestoringRef, onAddTask: handleAddTaskFromDropdown, onAddDocument: handleAddDocumentFromDropdown, availableDocuments: availableDocuments, availableTasks: availableTasks, isLoadingData: isLoadingData }) }), _jsx("div", { className: "pointer-events-auto", children: _jsx(ToolOptionsPanel, { fabricCanvas: fabricCanvasRef }) }), _jsx("div", { className: "pointer-events-auto", children: _jsx(ZoomControls, { zoom: 1, onZoomIn: handleZoomIn, onZoomOut: handleZoomOut, onResetZoom: handleResetZoom }) })] })] }) }));
273
+ } }), _jsx("canvas", { ref: canvasRef, className: "absolute inset-0", style: { zIndex: 1 } }), _jsx(MemoizedOverlayWrapper, { tasks: tasks, documents: documents, canvasReady: canvasReady, fabricCanvasRef: fabricCanvasRef, onTasksUpdate: setTasks, onDocumentsUpdate: setDocuments, selectionBox: selectionBox, selectedCanvasObjects: selectedCanvasObjects }), _jsxs("div", { className: "absolute inset-0 pointer-events-none", style: { zIndex: 100 }, children: [_jsx("div", { className: "pointer-events-auto", children: _jsx(MemoizedToolbarWrapper, { canvasReady: canvasReady, fabricCanvasRef: fabricCanvasRef, isRestoringRef: isRestoringRef, onAddTask: handleAddTaskFromDropdown, onAddDocument: handleAddDocumentFromDropdown, availableDocuments: availableDocuments, availableTasks: availableTasks, isLoadingData: isLoadingData }) }), _jsx("div", { className: "pointer-events-auto", children: _jsx(ToolOptionsPanel, { fabricCanvas: fabricCanvasRef }) }), _jsx("div", { className: "pointer-events-auto", children: _jsx(ZoomControls, { zoom: 1, onZoomIn: handleZoomIn, onZoomOut: handleZoomOut, onResetZoom: handleResetZoom }) })] })] }) }));
278
274
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhamz.01/easyflow-whiteboard",
3
- "version": "2.141.0",
3
+ "version": "2.142.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",