@mhamz.01/easyflow-whiteboard 2.98.0 → 2.100.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,7 @@
1
+ import { Canvas } from "fabric";
2
+ interface LayerControlsProps {
3
+ fabricCanvas: React.RefObject<Canvas | null>;
4
+ }
5
+ export default function LayerControls({ fabricCanvas }: LayerControlsProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
1
7
  //# sourceMappingURL=layers-control.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layers-control.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/layers-control.tsx"],"names":[],"mappings":""}
1
+ {"version":3,"file":"layers-control.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/layers-control.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,UAAU,kBAAkB;IAC1B,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC9C;AAED,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,YAAY,EAAE,EAAE,kBAAkB,2CAkEzE"}
@@ -1,67 +1,29 @@
1
- "use strict";
2
- // // components/toolbar/layer-controls.tsx
3
- // "use client";
4
- // import { ArrowUp, ArrowDown, MoveUp, MoveDown } from "lucide-react";
5
- // import { Canvas } from "fabric";
6
- // import { useWhiteboardStore } from "../../store/whiteboard-store";
7
- // interface LayerControlsProps {
8
- // fabricCanvas: React.RefObject<Canvas | null>;
9
- // }
10
- // export default function LayerControls({ fabricCanvas }: LayerControlsProps) {
11
- // // const { bringToFront, sendToBack, bringForward, sendBackward } = useWhiteboardStore();
12
- // const handleBringToFront = () => {
13
- // const canvas = fabricCanvas.current;
14
- // if (canvas) bringToFront(canvas);
15
- // };
16
- // const handleSendToBack = () => {
17
- // const canvas = fabricCanvas.current;
18
- // if (canvas) sendToBack(canvas);
19
- // };
20
- // const handleBringForward = () => {
21
- // const canvas = fabricCanvas.current;
22
- // if (canvas) bringForward(canvas);
23
- // };
24
- // const handleSendBackward = () => {
25
- // const canvas = fabricCanvas.current;
26
- // if (canvas) sendBackward(canvas);
27
- // };
28
- // return (
29
- // <div className="flex flex-col gap-1 p-2 bg-black/90 rounded-lg border border-white/10">
30
- // <p className="text-xs text-white/60 mb-1">Layer Order</p>
31
- // <div className="flex gap-1">
32
- // {/* Bring to Front */}
33
- // <button
34
- // onClick={handleBringToFront}
35
- // className="p-2 hover:bg-white/10 rounded transition-colors"
36
- // title="Bring to Front"
37
- // >
38
- // <MoveUp size={16} className="text-white" />
39
- // </button>
40
- // {/* Bring Forward */}
41
- // <button
42
- // onClick={handleBringForward}
43
- // className="p-2 hover:bg-white/10 rounded transition-colors"
44
- // title="Bring Forward"
45
- // >
46
- // <ArrowUp size={16} className="text-white" />
47
- // </button>
48
- // {/* Send Backward */}
49
- // <button
50
- // onClick={handleSendBackward}
51
- // className="p-2 hover:bg-white/10 rounded transition-colors"
52
- // title="Send Backward"
53
- // >
54
- // <ArrowDown size={16} className="text-white" />
55
- // </button>
56
- // {/* Send to Back */}
57
- // <button
58
- // onClick={handleSendToBack}
59
- // className="p-2 hover:bg-white/10 rounded transition-colors"
60
- // title="Send to Back"
61
- // >
62
- // <MoveDown size={16} className="text-white" />
63
- // </button>
64
- // </div>
65
- // </div>
66
- // );
67
- // }
1
+ // components/toolbar/layer-controls.tsx
2
+ "use client";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { ArrowUp, ArrowDown, MoveUp, MoveDown } from "lucide-react";
5
+ import { useWhiteboardStore } from "../../store/whiteboard-store";
6
+ export default function LayerControls({ fabricCanvas }) {
7
+ const { bringToFront, sendToBack, bringForward, sendBackward } = useWhiteboardStore();
8
+ const handleBringToFront = () => {
9
+ const canvas = fabricCanvas.current;
10
+ if (canvas)
11
+ bringToFront(canvas);
12
+ };
13
+ const handleSendToBack = () => {
14
+ const canvas = fabricCanvas.current;
15
+ if (canvas)
16
+ sendToBack(canvas);
17
+ };
18
+ const handleBringForward = () => {
19
+ const canvas = fabricCanvas.current;
20
+ if (canvas)
21
+ bringForward(canvas);
22
+ };
23
+ const handleSendBackward = () => {
24
+ const canvas = fabricCanvas.current;
25
+ if (canvas)
26
+ sendBackward(canvas);
27
+ };
28
+ return (_jsxs("div", { className: "flex flex-col gap-1 p-2 bg-black/90 rounded-lg border border-white/10", children: [_jsx("p", { className: "text-xs text-white/60 mb-1", children: "Layer Order" }), _jsxs("div", { className: "flex gap-1", children: [_jsx("button", { onClick: handleBringToFront, className: "p-2 hover:bg-white/10 rounded transition-colors", title: "Bring to Front", children: _jsx(MoveUp, { size: 16, className: "text-white" }) }), _jsx("button", { onClick: handleBringForward, className: "p-2 hover:bg-white/10 rounded transition-colors", title: "Bring Forward", children: _jsx(ArrowUp, { size: 16, className: "text-white" }) }), _jsx("button", { onClick: handleSendBackward, className: "p-2 hover:bg-white/10 rounded transition-colors", title: "Send Backward", children: _jsx(ArrowDown, { size: 16, className: "text-white" }) }), _jsx("button", { onClick: handleSendToBack, className: "p-2 hover:bg-white/10 rounded transition-colors", title: "Send to Back", children: _jsx(MoveDown, { size: 16, className: "text-white" }) })] })] }));
29
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"tooloptions-panel.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/tooloptions-panel.tsx"],"names":[],"mappings":"AAGA,OAAc,EAAE,SAAS,EAAwC,MAAM,OAAO,CAAC;AAU/E,OAAO,MAA2C,MAAM,QAAQ,CAAC;AAIjE,UAAU,qBAAqB;IAC7B,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,YAAY,GACb,EAAE,qBAAqB,2CA8NvB"}
1
+ {"version":3,"file":"tooloptions-panel.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/tooloptions-panel.tsx"],"names":[],"mappings":"AAGA,OAAc,EAAE,SAAS,EAAgC,MAAM,OAAO,CAAC;AAUvE,OAAO,MAA2C,MAAM,QAAQ,CAAC;AAIjE,UAAU,qBAAqB;IAC7B,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,YAAY,GACb,EAAE,qBAAqB,2CA0MvB"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useEffect, useMemo, useRef, useState } from "react";
3
+ import { useEffect, useMemo, useState } from "react";
4
4
  import { cn } from "../../lib/utils";
5
5
  import { useWhiteboardStore } from "../../store/whiteboard-store";
6
6
  import PenOptions from "./options/pen-option";
@@ -11,13 +11,13 @@ import LineOptions from "./options/line-options";
11
11
  import ArrowOptions from "./options/arrow-options";
12
12
  import { Rect, Circle, IText } from "fabric";
13
13
  import { Settings2, ChevronDown } from "lucide-react";
14
+ import LayerControls from "./layers-control";
14
15
  export default function ToolOptionsPanel({ fabricCanvas, }) {
15
16
  const activeTool = useWhiteboardStore((state) => state.activeTool);
16
17
  const selectedObjectType = useWhiteboardStore((state) => state.selectedObjectType);
17
18
  const toolOptions = useWhiteboardStore((state) => state.toolOptions);
18
19
  const [isMobileExpanded, setIsMobileExpanded] = useState(false);
19
20
  const displayTool = selectedObjectType || activeTool;
20
- const isUpdatingRef = useRef(false);
21
21
  // Real-time fabric updates
22
22
  useEffect(() => {
23
23
  const canvas = fabricCanvas.current;
@@ -26,27 +26,10 @@ export default function ToolOptionsPanel({ fabricCanvas, }) {
26
26
  const selectedObject = canvas.getActiveObject();
27
27
  if (!selectedObject || !selectedObjectType)
28
28
  return;
29
- // ⚠️ CRITICAL CHECK:
30
- // We only want to push Store -> Canvas if the Store values
31
- // are different from the Object's current values.
32
- const updateIfChanged = (props) => {
33
- let hasChanged = false;
34
- Object.entries(props).forEach(([key, value]) => {
35
- if (selectedObject.get(key) !== value) {
36
- hasChanged = true;
37
- }
38
- });
39
- if (hasChanged) {
40
- selectedObject.set(props);
41
- canvas.renderAll();
42
- // Only push history if a real change happened
43
- // pushHistory(JSON.stringify(canvas.toJSON(['fill', 'stroke', 'strokeWidth', 'id'])));
44
- }
45
- };
46
29
  switch (selectedObjectType) {
47
30
  case "rectangle":
48
31
  if (selectedObject instanceof Rect) {
49
- updateIfChanged({
32
+ selectedObject.set({
50
33
  fill: toolOptions.rectangle.fillColor,
51
34
  stroke: toolOptions.rectangle.strokeColor,
52
35
  strokeWidth: toolOptions.rectangle.strokeWidth,
@@ -55,7 +38,7 @@ export default function ToolOptionsPanel({ fabricCanvas, }) {
55
38
  break;
56
39
  case "circle":
57
40
  if (selectedObject instanceof Circle) {
58
- updateIfChanged({
41
+ selectedObject.set({
59
42
  fill: toolOptions.circle.fillColor,
60
43
  stroke: toolOptions.circle.strokeColor,
61
44
  strokeWidth: toolOptions.circle.strokeWidth,
@@ -64,7 +47,7 @@ export default function ToolOptionsPanel({ fabricCanvas, }) {
64
47
  break;
65
48
  case "text":
66
49
  if (selectedObject instanceof IText) {
67
- updateIfChanged({
50
+ selectedObject.set({
68
51
  fill: toolOptions.text.color,
69
52
  fontSize: toolOptions.text.fontSize,
70
53
  fontFamily: toolOptions.text.fontFamily,
@@ -72,6 +55,7 @@ export default function ToolOptionsPanel({ fabricCanvas, }) {
72
55
  }
73
56
  break;
74
57
  }
58
+ canvas.renderAll();
75
59
  }, [toolOptions, selectedObjectType, fabricCanvas]);
76
60
  const toolsWithoutOptions = ["select", "pan", "undo", "redo", "eraser"];
77
61
  const isOpen = useMemo(() => {
@@ -85,7 +69,7 @@ export default function ToolOptionsPanel({ fabricCanvas, }) {
85
69
  }, [isOpen]);
86
70
  return (_jsxs(_Fragment, { children: [_jsxs("aside", { className: cn("hidden md:flex", "absolute left-4 top-1/2 -translate-y-1/2 z-40", "flex-col", "w-64 max-h-[85vh]", "bg-[#1A1A1E]/90 backdrop-blur-xl", "border border-white/10", "shadow-[0_20px_50px_rgba(0,0,0,0.5)]", "rounded-[24px]", "transition-all duration-500 cubic-bezier(0.16, 1, 0.3, 1)", isOpen
87
71
  ? "translate-x-0 opacity-100 visible scale-100"
88
- : "-translate-x-12 opacity-0 invisible scale-95 pointer-events-none"), children: [_jsx("div", { className: "absolute -left-[1px] top-1/2 -translate-y-1/2 w-[3px] h-12 bg-[#029AFF] rounded-r-full shadow-[0_0_15px_#029AFF]" }), _jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-white/5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Settings2, { className: "w-4 h-4 text-[#029AFF]" }), _jsx("h3", { className: "text-[11px] font-bold uppercase tracking-[0.1em] text-neutral-400", children: "Properties" })] }), _jsx("div", { className: "text-[10px] px-2 py-0.5 rounded-full bg-white/5 text-white/40 border border-white/5", children: displayTool })] }), _jsx("div", { className: "flex-1 overflow-y-auto p-5 custom-scrollbar scroll-smooth", children: _jsxs("div", { className: "space-y-6 text-neutral-200", children: [displayTool === "pen" && _jsx(PenOptions, {}), (displayTool === "rectangle" || displayTool === "circle" || displayTool === "frame") && (_jsx(ShapeOptions, { shapeType: displayTool })), displayTool === "text" && _jsx(TextOptions, {}), displayTool === "image" && _jsx(ImageOptions, {}), displayTool === "line" && _jsx(LineOptions, {}), displayTool === "arrow" && _jsx(ArrowOptions, { fabricCanvas: fabricCanvas })] }) }), _jsx("div", { className: "p-3 flex justify-center", children: _jsx("div", { className: "w-8 h-1 rounded-full bg-white/10" }) })] }), isOpen && (_jsxs("div", { className: cn("md:hidden", "fixed left-3 top-4 z-40", // Positioned Top-Left to stay clear of Top-Right zoom
72
+ : "-translate-x-12 opacity-0 invisible scale-95 pointer-events-none"), children: [_jsx("div", { className: "absolute -left-[1px] top-1/2 -translate-y-1/2 w-[3px] h-12 bg-[#029AFF] rounded-r-full shadow-[0_0_15px_#029AFF]" }), _jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-white/5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Settings2, { className: "w-4 h-4 text-[#029AFF]" }), _jsx("h3", { className: "text-[11px] font-bold uppercase tracking-[0.1em] text-neutral-400", children: "Properties" })] }), _jsx("div", { className: "text-[10px] px-2 py-0.5 rounded-full bg-white/5 text-white/40 border border-white/5", children: displayTool })] }), _jsx("div", { className: "flex-1 overflow-y-auto p-5 custom-scrollbar scroll-smooth", children: _jsxs("div", { className: "space-y-6 text-neutral-200", children: [displayTool === "pen" && _jsx(PenOptions, {}), (displayTool === "rectangle" || displayTool === "circle" || displayTool === "frame") && (_jsx(ShapeOptions, { shapeType: displayTool })), displayTool === "text" && _jsx(TextOptions, {}), displayTool === "image" && _jsx(ImageOptions, {}), displayTool === "line" && _jsx(LineOptions, {}), displayTool === "arrow" && _jsx(ArrowOptions, { fabricCanvas: fabricCanvas }), selectedObjectType && (_jsx(LayerControls, { fabricCanvas: fabricCanvas }))] }) }), _jsx("div", { className: "p-3 flex justify-center", children: _jsx("div", { className: "w-8 h-1 rounded-full bg-white/10" }) })] }), isOpen && (_jsxs("div", { className: cn("md:hidden", "fixed left-3 top-4 z-40", // Positioned Top-Left to stay clear of Top-Right zoom
89
73
  "w-[calc(100%-80px)] max-w-[180px]", // Leave room on the right to tap canvas
90
74
  "bg-[#1A1A1E]/95 backdrop-blur-xl", "border border-white/10", "rounded-2xl shadow-2xl", "transition-all duration-300 ease-in-out", isMobileExpanded ? "max-h-[70vh]" : "h-[48px]"), children: [_jsxs("div", { className: "flex items-center justify-between px-4 h-[48px] cursor-pointer", onClick: () => setIsMobileExpanded(!isMobileExpanded), children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Settings2, { className: "w-4 h-4 text-[#029AFF]" }), _jsxs("span", { className: "text-[10px] font-bold uppercase tracking-wider text-neutral-300", children: [displayTool, " Settings"] })] }), _jsx("div", { className: "flex items-center gap-2", children: _jsx("div", { className: cn("transition-transform duration-300", isMobileExpanded ? "rotate-180" : "rotate-0"), children: _jsx(ChevronDown, { className: "w-4 h-4 text-white/50" }) }) })] }), _jsx("div", { className: cn("overflow-hidden transition-all duration-300", isMobileExpanded ? "opacity-100 h-auto" : "opacity-0 h-0"), children: _jsxs("div", { className: "px-4 pb-5 pt-2 space-y-4 overflow-y-auto max-h-[60vh] custom-scrollbar", children: [_jsx("div", { className: "h-[1px] w-full bg-white/5 mb-4" }), displayTool === "pen" && _jsx(PenOptions, {}), (displayTool === "rectangle" || displayTool === "circle" || displayTool === "frame") && (_jsx(ShapeOptions, { shapeType: displayTool })), displayTool === "text" && _jsx(TextOptions, {}), displayTool === "image" && _jsx(ImageOptions, {}), displayTool === "line" && _jsx(LineOptions, {}), displayTool === "arrow" && _jsx(ArrowOptions, { fabricCanvas: fabricCanvas })] }) })] })), _jsx("style", { children: `
91
75
  .custom-scrollbar::-webkit-scrollbar {
@@ -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;AAMjE,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,wFAM1B,iBAAiB,SAuJnB,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;AAMjE,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,wFAM1B,iBAAiB,SAsKnB,CAAC"}
@@ -103,6 +103,20 @@ export const useSelection = ({ fabricCanvas, activeTool, setSelectionBox, setSel
103
103
  : sel instanceof BidirectionalArrow ? "arrow"
104
104
  : typeMap[sel.type] ?? null;
105
105
  setSelectedObjectType(t);
106
+ if (t && sel.type !== "activeSelection") {
107
+ const store = useWhiteboardStore.getState();
108
+ if (t === "rectangle" && sel.fill) {
109
+ store.setToolOption("rectangle", "fillColor", sel.fill);
110
+ store.setToolOption("rectangle", "strokeColor", sel.stroke || "#ffffff");
111
+ store.setToolOption("rectangle", "strokeWidth", sel.strokeWidth || 2);
112
+ }
113
+ else if (t === "circle" && sel.fill) {
114
+ store.setToolOption("circle", "fillColor", sel.fill);
115
+ store.setToolOption("circle", "strokeColor", sel.stroke || "#ffffff");
116
+ store.setToolOption("circle", "strokeWidth", sel.strokeWidth || 2);
117
+ }
118
+ // Add for other types as needed...
119
+ }
106
120
  };
107
121
  const onDeselected = () => {
108
122
  setSelectedObjectType(null);
@@ -1,4 +1,4 @@
1
- import { FabricObject } from "fabric";
1
+ import { Canvas, FabricObject } from "fabric";
2
2
  export type Tool = "select" | "pan" | "pen" | "rectangle" | "circle" | "line" | "arrow" | "frame" | "text" | "image" | "eraser" | "connector" | "undo" | "redo";
3
3
  export type ActiveDropdown = "task" | "document" | null;
4
4
  export interface ToolOptions {
@@ -62,6 +62,10 @@ interface WhiteboardState {
62
62
  addCanvasObject: (obj: FabricObject) => void;
63
63
  removeCanvasObject: (obj: FabricObject) => void;
64
64
  clearCanvasObjects: () => void;
65
+ bringToFront: (canvas: Canvas) => void;
66
+ sendToBack: (canvas: Canvas) => void;
67
+ bringForward: (canvas: Canvas) => void;
68
+ sendBackward: (canvas: Canvas) => void;
65
69
  selectedObjects: FabricObject[];
66
70
  setSelectedObjects: (objects: FabricObject[]) => void;
67
71
  toolOptions: ToolOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"whiteboard-store.d.ts","sourceRoot":"","sources":["../../src/store/whiteboard-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"whiteboard-store.d.ts","sourceRoot":"","sources":["../../src/store/whiteboard-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAI9C,MAAM,MAAM,IAAI,GACZ,QAAQ,GACR,KAAK,GACL,KAAK,GACL,WAAW,GACX,QAAQ,GACR,MAAM,GACN,OAAO,GACP,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,WAAW,GACX,MAAM,GACN,MAAM,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE;QACH,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KAClC,CAAC;IACF,SAAS,EAAE;QACT,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KAClC,CAAC;IACF,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KAClC,CAAC;IACF,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KAClC,CAAC;IACF,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KAClC,CAAC;IACF,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KAClC,CAAC;CACH;AAsBD,UAAU,eAAe;IACvB,UAAU,EAAE,IAAI,CAAC;IACjB,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAEpC,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC;IAEhD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAErD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,eAAe,EAAK,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAE/B,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC,eAAe,EAAE,YAAY,EAAE,CAAC;IAChC,kBAAkB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAEtD,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,CAAC,CAAC,SAAS,MAAM,WAAW,EACzC,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,MAAM,WAAW,CAAC,CAAC,CAAC,EAC5B,KAAK,EAAE,GAAG,KACP,IAAI,CAAC;IAEV,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAEjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAID,eAAO,MAAM,kBAAkB,8EAkH5B,CAAC"}
@@ -81,4 +81,33 @@ export const useWhiteboardStore = create()((set, get) => ({
81
81
  // ── Zoom ──────────────────────────────────────────────────────────────────
82
82
  zoom: 1,
83
83
  setZoom: (zoom) => set({ zoom }),
84
+ // ── Layer ordering ─────────────────────────────────────────────────────
85
+ bringToFront: (canvas) => {
86
+ const active = canvas.getActiveObject();
87
+ if (active) {
88
+ canvas.bringObjectToFront(active);
89
+ canvas.requestRenderAll();
90
+ }
91
+ },
92
+ sendToBack: (canvas) => {
93
+ const active = canvas.getActiveObject();
94
+ if (active) {
95
+ canvas.sendObjectToBack(active);
96
+ canvas.requestRenderAll();
97
+ }
98
+ },
99
+ bringForward: (canvas) => {
100
+ const active = canvas.getActiveObject();
101
+ if (active) {
102
+ canvas.bringObjectForward(active);
103
+ canvas.requestRenderAll();
104
+ }
105
+ },
106
+ sendBackward: (canvas) => {
107
+ const active = canvas.getActiveObject();
108
+ if (active) {
109
+ canvas.sendObjectBackwards(active);
110
+ canvas.requestRenderAll();
111
+ }
112
+ },
84
113
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhamz.01/easyflow-whiteboard",
3
- "version": "2.98.0",
3
+ "version": "2.100.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",