@maayan-albert/moab-sdk 1.0.0 → 1.0.2
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.
- package/dist/components/Button.d.ts +17 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Card.d.ts +12 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/DrawingTool.d.ts +13 -0
- package/dist/components/DrawingTool.d.ts.map +1 -0
- package/dist/components/Input.d.ts +16 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components.d.ts +12 -52
- package/dist/components.d.ts.map +1 -0
- package/dist/index.d.ts +19 -10
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +619 -684
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +608 -684
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/components.d.mts +0 -53
- package/dist/index.d.mts +0 -16
package/dist/index.mjs
CHANGED
|
@@ -4,574 +4,614 @@ import { Trash2, X } from 'lucide-react';
|
|
|
4
4
|
import html2canvas from 'html2canvas';
|
|
5
5
|
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
|
|
9
|
+
var Button = ({
|
|
10
|
+
children,
|
|
11
|
+
variant = "primary",
|
|
12
|
+
size = "medium",
|
|
13
|
+
disabled = false,
|
|
14
|
+
onClick,
|
|
15
|
+
className = "",
|
|
16
|
+
...props
|
|
17
|
+
}) => {
|
|
18
|
+
const baseStyles = "font-semibold rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2";
|
|
19
|
+
const variantStyles = {
|
|
20
|
+
primary: "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500",
|
|
21
|
+
secondary: "bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500",
|
|
22
|
+
outline: "border-2 border-blue-600 text-blue-600 hover:bg-blue-50 focus:ring-blue-500"
|
|
23
|
+
};
|
|
24
|
+
const sizeStyles = {
|
|
25
|
+
small: "px-3 py-1.5 text-sm",
|
|
26
|
+
medium: "px-4 py-2 text-base",
|
|
27
|
+
large: "px-6 py-3 text-lg"
|
|
28
|
+
};
|
|
29
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer";
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
"button",
|
|
32
|
+
{
|
|
33
|
+
className: `${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${disabledStyles} ${className}`,
|
|
34
|
+
disabled,
|
|
35
|
+
onClick,
|
|
36
|
+
...props,
|
|
37
|
+
children
|
|
38
|
+
}
|
|
39
|
+
);
|
|
15
40
|
};
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
41
|
+
var Button_default = Button;
|
|
42
|
+
var Card = ({
|
|
43
|
+
children,
|
|
44
|
+
title,
|
|
45
|
+
className = "",
|
|
46
|
+
...props
|
|
47
|
+
}) => {
|
|
48
|
+
return /* @__PURE__ */ jsxs(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
className: `bg-white rounded-lg shadow-md p-6 border border-gray-200 ${className}`,
|
|
52
|
+
...props,
|
|
53
|
+
children: [
|
|
54
|
+
title && /* @__PURE__ */ jsx("h3", { className: "text-xl font-semibold mb-4 text-gray-800", children: title }),
|
|
55
|
+
children
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
);
|
|
19
59
|
};
|
|
20
|
-
var
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
60
|
+
var Card_default = Card;
|
|
61
|
+
var Input = ({
|
|
62
|
+
label,
|
|
63
|
+
type = "text",
|
|
64
|
+
placeholder,
|
|
65
|
+
value,
|
|
66
|
+
onChange,
|
|
67
|
+
required = false,
|
|
68
|
+
className = "",
|
|
69
|
+
...props
|
|
70
|
+
}) => {
|
|
71
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
72
|
+
label && /* @__PURE__ */ jsxs("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: [
|
|
73
|
+
label,
|
|
74
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1", children: "*" })
|
|
75
|
+
] }),
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
"input",
|
|
78
|
+
{
|
|
79
|
+
type,
|
|
80
|
+
placeholder,
|
|
81
|
+
value,
|
|
82
|
+
onChange,
|
|
83
|
+
required,
|
|
84
|
+
className: `w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent ${className}`,
|
|
85
|
+
...props
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
] });
|
|
27
89
|
};
|
|
28
|
-
var
|
|
29
|
-
var
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
90
|
+
var Input_default = Input;
|
|
91
|
+
var DrawingTool = ({
|
|
92
|
+
width,
|
|
93
|
+
height,
|
|
94
|
+
className = "",
|
|
95
|
+
overlay = true,
|
|
96
|
+
...props
|
|
97
|
+
}) => {
|
|
98
|
+
const canvasRef = useRef(null);
|
|
99
|
+
const toolbarRef = useRef(null);
|
|
100
|
+
const [isDrawing, setIsDrawing] = useState(false);
|
|
101
|
+
const brushColor = "#EF4444";
|
|
102
|
+
const brushSize = 5;
|
|
103
|
+
const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 });
|
|
104
|
+
const [enabled, setEnabled] = useState(false);
|
|
105
|
+
const [hasContent, setHasContent] = useState(false);
|
|
106
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
107
|
+
const [corner, setCorner] = useState("bottom-right");
|
|
108
|
+
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
|
|
109
|
+
const [showClearTooltip, setShowClearTooltip] = useState(false);
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (overlay) {
|
|
112
|
+
const updateSize = () => {
|
|
113
|
+
setCanvasSize({
|
|
114
|
+
width: window.innerWidth,
|
|
115
|
+
height: window.innerHeight
|
|
116
|
+
});
|
|
51
117
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
118
|
+
updateSize();
|
|
119
|
+
window.addEventListener("resize", updateSize);
|
|
120
|
+
return () => window.removeEventListener("resize", updateSize);
|
|
121
|
+
} else {
|
|
122
|
+
setCanvasSize({
|
|
123
|
+
width: width || 800,
|
|
124
|
+
height: height || 600
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}, [overlay, width, height]);
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
const canvas = canvasRef.current;
|
|
130
|
+
if (!canvas || canvasSize.width === 0 || canvasSize.height === 0) return;
|
|
131
|
+
const ctx = canvas.getContext("2d");
|
|
132
|
+
if (!ctx) return;
|
|
133
|
+
canvas.width = canvasSize.width;
|
|
134
|
+
canvas.height = canvasSize.height;
|
|
135
|
+
ctx.strokeStyle = brushColor;
|
|
136
|
+
ctx.lineWidth = brushSize;
|
|
137
|
+
ctx.lineCap = "round";
|
|
138
|
+
ctx.lineJoin = "round";
|
|
139
|
+
setHasContent(false);
|
|
140
|
+
}, [canvasSize, brushColor, brushSize]);
|
|
141
|
+
const getCoordinates = useCallback(
|
|
142
|
+
(e) => {
|
|
143
|
+
const canvas = canvasRef.current;
|
|
144
|
+
if (!canvas) return { x: 0, y: 0 };
|
|
145
|
+
const rect = canvas.getBoundingClientRect();
|
|
146
|
+
const scaleX = canvas.width / rect.width;
|
|
147
|
+
const scaleY = canvas.height / rect.height;
|
|
148
|
+
if ("touches" in e) {
|
|
149
|
+
return {
|
|
150
|
+
x: (e.touches[0].clientX - rect.left) * scaleX,
|
|
151
|
+
y: (e.touches[0].clientY - rect.top) * scaleY
|
|
152
|
+
};
|
|
153
|
+
} else {
|
|
154
|
+
return {
|
|
155
|
+
x: (e.clientX - rect.left) * scaleX,
|
|
156
|
+
y: (e.clientY - rect.top) * scaleY
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
[]
|
|
161
|
+
);
|
|
162
|
+
const startDrawing = useCallback(
|
|
163
|
+
(e) => {
|
|
164
|
+
if (!enabled) return;
|
|
165
|
+
e.preventDefault();
|
|
166
|
+
const canvas = canvasRef.current;
|
|
167
|
+
const ctx = canvas?.getContext("2d");
|
|
168
|
+
if (!canvas || !ctx) return;
|
|
169
|
+
const { x, y } = getCoordinates(e);
|
|
170
|
+
ctx.beginPath();
|
|
171
|
+
ctx.moveTo(x, y);
|
|
172
|
+
setIsDrawing(true);
|
|
173
|
+
},
|
|
174
|
+
[enabled, getCoordinates]
|
|
175
|
+
);
|
|
176
|
+
const draw = useCallback(
|
|
177
|
+
(e) => {
|
|
178
|
+
if (!isDrawing) return;
|
|
179
|
+
e.preventDefault();
|
|
180
|
+
const canvas = canvasRef.current;
|
|
181
|
+
const ctx = canvas?.getContext("2d");
|
|
182
|
+
if (!canvas || !ctx) return;
|
|
183
|
+
const { x, y } = getCoordinates(e);
|
|
184
|
+
ctx.lineTo(x, y);
|
|
185
|
+
ctx.stroke();
|
|
186
|
+
setHasContent(true);
|
|
187
|
+
},
|
|
188
|
+
[isDrawing, getCoordinates]
|
|
189
|
+
);
|
|
190
|
+
const stopDrawing = useCallback(() => {
|
|
191
|
+
setIsDrawing(false);
|
|
192
|
+
}, []);
|
|
193
|
+
const clearCanvas = useCallback(() => {
|
|
194
|
+
const canvas = canvasRef.current;
|
|
195
|
+
const ctx = canvas?.getContext("2d");
|
|
196
|
+
if (!canvas || !ctx) return;
|
|
197
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
198
|
+
setHasContent(false);
|
|
199
|
+
}, []);
|
|
200
|
+
const takeScreenshot = useCallback(async () => {
|
|
201
|
+
try {
|
|
202
|
+
const toolbar = toolbarRef.current;
|
|
203
|
+
if (toolbar) {
|
|
204
|
+
toolbar.style.opacity = "0";
|
|
205
|
+
}
|
|
206
|
+
const canvas = await html2canvas(document.body, {
|
|
207
|
+
useCORS: true,
|
|
208
|
+
logging: false,
|
|
209
|
+
windowWidth: window.innerWidth,
|
|
210
|
+
windowHeight: window.innerHeight
|
|
211
|
+
});
|
|
212
|
+
if (toolbar) {
|
|
213
|
+
toolbar.style.opacity = "";
|
|
214
|
+
}
|
|
215
|
+
canvas.toBlob(async (blob) => {
|
|
216
|
+
if (!blob) return;
|
|
217
|
+
try {
|
|
218
|
+
await navigator.clipboard.write([
|
|
219
|
+
new ClipboardItem({
|
|
220
|
+
"image/png": blob
|
|
221
|
+
})
|
|
222
|
+
]);
|
|
223
|
+
} catch (err) {
|
|
224
|
+
console.error("Failed to copy to clipboard:", err);
|
|
225
|
+
const url = URL.createObjectURL(blob);
|
|
226
|
+
const a = document.createElement("a");
|
|
227
|
+
a.href = url;
|
|
228
|
+
a.download = "screenshot.png";
|
|
229
|
+
a.click();
|
|
230
|
+
URL.revokeObjectURL(url);
|
|
61
231
|
}
|
|
232
|
+
}, "image/png");
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error("Failed to take screenshot:", error);
|
|
235
|
+
}
|
|
236
|
+
}, []);
|
|
237
|
+
useEffect(() => {
|
|
238
|
+
const canvas = canvasRef.current;
|
|
239
|
+
const ctx = canvas?.getContext("2d");
|
|
240
|
+
if (!ctx) return;
|
|
241
|
+
ctx.strokeStyle = brushColor;
|
|
242
|
+
ctx.lineWidth = brushSize;
|
|
243
|
+
}, [brushColor, brushSize]);
|
|
244
|
+
const getTargetCorner = useCallback(
|
|
245
|
+
(startX, startY, currentX, currentY) => {
|
|
246
|
+
const deltaX = currentX - startX;
|
|
247
|
+
const deltaY = currentY - startY;
|
|
248
|
+
const threshold = 50;
|
|
249
|
+
if (Math.abs(deltaX) < threshold && Math.abs(deltaY) < threshold) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
const viewportWidth = window.innerWidth;
|
|
253
|
+
const viewportHeight = window.innerHeight;
|
|
254
|
+
const horizontal = currentX < viewportWidth / 2 ? "left" : "right";
|
|
255
|
+
const vertical = currentY < viewportHeight / 2 ? "top" : "bottom";
|
|
256
|
+
if (vertical === "top" && horizontal === "left") return "top-left";
|
|
257
|
+
if (vertical === "top" && horizontal === "right") return "top-right";
|
|
258
|
+
if (vertical === "bottom" && horizontal === "left") return "bottom-left";
|
|
259
|
+
if (vertical === "bottom" && horizontal === "right")
|
|
260
|
+
return "bottom-right";
|
|
261
|
+
return null;
|
|
262
|
+
},
|
|
263
|
+
[]
|
|
264
|
+
);
|
|
265
|
+
const handleMouseDown = useCallback((e) => {
|
|
266
|
+
if (e.target.closest("button")) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
e.preventDefault();
|
|
270
|
+
e.stopPropagation();
|
|
271
|
+
setIsDragging(true);
|
|
272
|
+
setDragStart({
|
|
273
|
+
x: e.clientX,
|
|
274
|
+
y: e.clientY
|
|
275
|
+
});
|
|
276
|
+
}, []);
|
|
277
|
+
useEffect(() => {
|
|
278
|
+
const handleMouseMove = (e) => {
|
|
279
|
+
if (!isDragging) return;
|
|
280
|
+
e.preventDefault();
|
|
281
|
+
e.stopPropagation();
|
|
282
|
+
const targetCorner = getTargetCorner(
|
|
283
|
+
dragStart.x,
|
|
284
|
+
dragStart.y,
|
|
285
|
+
e.clientX,
|
|
286
|
+
e.clientY
|
|
62
287
|
);
|
|
288
|
+
if (targetCorner) {
|
|
289
|
+
setCorner(targetCorner);
|
|
290
|
+
} else {
|
|
291
|
+
const viewportWidth = window.innerWidth;
|
|
292
|
+
const viewportHeight = window.innerHeight;
|
|
293
|
+
const horizontal = e.clientX < viewportWidth / 2 ? "left" : "right";
|
|
294
|
+
const vertical = e.clientY < viewportHeight / 2 ? "top" : "bottom";
|
|
295
|
+
if (vertical === "top" && horizontal === "left") setCorner("top-left");
|
|
296
|
+
else if (vertical === "top" && horizontal === "right")
|
|
297
|
+
setCorner("top-right");
|
|
298
|
+
else if (vertical === "bottom" && horizontal === "left")
|
|
299
|
+
setCorner("bottom-left");
|
|
300
|
+
else setCorner("bottom-right");
|
|
301
|
+
}
|
|
63
302
|
};
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
var init_Card = __esm({
|
|
69
|
-
"src/components/Card.tsx"() {
|
|
70
|
-
Card = ({
|
|
71
|
-
children,
|
|
72
|
-
title,
|
|
73
|
-
className = "",
|
|
74
|
-
...props
|
|
75
|
-
}) => {
|
|
76
|
-
return /* @__PURE__ */ jsxs(
|
|
77
|
-
"div",
|
|
78
|
-
{
|
|
79
|
-
className: `bg-white rounded-lg shadow-md p-6 border border-gray-200 ${className}`,
|
|
80
|
-
...props,
|
|
81
|
-
children: [
|
|
82
|
-
title && /* @__PURE__ */ jsx("h3", { className: "text-xl font-semibold mb-4 text-gray-800", children: title }),
|
|
83
|
-
children
|
|
84
|
-
]
|
|
85
|
-
}
|
|
86
|
-
);
|
|
303
|
+
const handleMouseUp = (e) => {
|
|
304
|
+
e.preventDefault();
|
|
305
|
+
e.stopPropagation();
|
|
306
|
+
setIsDragging(false);
|
|
87
307
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
placeholder,
|
|
98
|
-
value,
|
|
99
|
-
onChange,
|
|
100
|
-
required = false,
|
|
101
|
-
className = "",
|
|
102
|
-
...props
|
|
103
|
-
}) => {
|
|
104
|
-
return /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
105
|
-
label && /* @__PURE__ */ jsxs("label", { className: "block text-sm font-medium text-gray-700 mb-1", children: [
|
|
106
|
-
label,
|
|
107
|
-
required && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1", children: "*" })
|
|
108
|
-
] }),
|
|
109
|
-
/* @__PURE__ */ jsx(
|
|
110
|
-
"input",
|
|
111
|
-
{
|
|
112
|
-
type,
|
|
113
|
-
placeholder,
|
|
114
|
-
value,
|
|
115
|
-
onChange,
|
|
116
|
-
required,
|
|
117
|
-
className: `w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent ${className}`,
|
|
118
|
-
...props
|
|
119
|
-
}
|
|
120
|
-
)
|
|
121
|
-
] });
|
|
308
|
+
if (isDragging) {
|
|
309
|
+
document.addEventListener("mousemove", handleMouseMove, {
|
|
310
|
+
passive: false
|
|
311
|
+
});
|
|
312
|
+
document.addEventListener("mouseup", handleMouseUp, { passive: false });
|
|
313
|
+
}
|
|
314
|
+
return () => {
|
|
315
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
316
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
122
317
|
};
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 });
|
|
142
|
-
const [enabled, setEnabled] = useState(false);
|
|
143
|
-
const [hasContent, setHasContent] = useState(false);
|
|
144
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
145
|
-
const [corner, setCorner] = useState("bottom-right");
|
|
146
|
-
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
|
|
147
|
-
const [showClearTooltip, setShowClearTooltip] = useState(false);
|
|
148
|
-
useEffect(() => {
|
|
149
|
-
if (overlay) {
|
|
150
|
-
const updateSize = () => {
|
|
151
|
-
setCanvasSize({
|
|
152
|
-
width: window.innerWidth,
|
|
153
|
-
height: window.innerHeight
|
|
154
|
-
});
|
|
155
|
-
};
|
|
156
|
-
updateSize();
|
|
157
|
-
window.addEventListener("resize", updateSize);
|
|
158
|
-
return () => window.removeEventListener("resize", updateSize);
|
|
159
|
-
} else {
|
|
160
|
-
setCanvasSize({
|
|
161
|
-
width: width || 800,
|
|
162
|
-
height: height || 600
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
}, [overlay, width, height]);
|
|
166
|
-
useEffect(() => {
|
|
167
|
-
const canvas = canvasRef.current;
|
|
168
|
-
if (!canvas || canvasSize.width === 0 || canvasSize.height === 0) return;
|
|
169
|
-
const ctx = canvas.getContext("2d");
|
|
170
|
-
if (!ctx) return;
|
|
171
|
-
canvas.width = canvasSize.width;
|
|
172
|
-
canvas.height = canvasSize.height;
|
|
173
|
-
ctx.strokeStyle = brushColor;
|
|
174
|
-
ctx.lineWidth = brushSize;
|
|
175
|
-
ctx.lineCap = "round";
|
|
176
|
-
ctx.lineJoin = "round";
|
|
177
|
-
setHasContent(false);
|
|
178
|
-
}, [canvasSize, brushColor, brushSize]);
|
|
179
|
-
const getCoordinates = useCallback(
|
|
180
|
-
(e) => {
|
|
181
|
-
const canvas = canvasRef.current;
|
|
182
|
-
if (!canvas) return { x: 0, y: 0 };
|
|
183
|
-
const rect = canvas.getBoundingClientRect();
|
|
184
|
-
const scaleX = canvas.width / rect.width;
|
|
185
|
-
const scaleY = canvas.height / rect.height;
|
|
186
|
-
if ("touches" in e) {
|
|
187
|
-
return {
|
|
188
|
-
x: (e.touches[0].clientX - rect.left) * scaleX,
|
|
189
|
-
y: (e.touches[0].clientY - rect.top) * scaleY
|
|
190
|
-
};
|
|
191
|
-
} else {
|
|
192
|
-
return {
|
|
193
|
-
x: (e.clientX - rect.left) * scaleX,
|
|
194
|
-
y: (e.clientY - rect.top) * scaleY
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
[]
|
|
199
|
-
);
|
|
200
|
-
const startDrawing = useCallback(
|
|
201
|
-
(e) => {
|
|
202
|
-
if (!enabled) return;
|
|
203
|
-
e.preventDefault();
|
|
204
|
-
const canvas = canvasRef.current;
|
|
205
|
-
const ctx = canvas?.getContext("2d");
|
|
206
|
-
if (!canvas || !ctx) return;
|
|
207
|
-
const { x, y } = getCoordinates(e);
|
|
208
|
-
ctx.beginPath();
|
|
209
|
-
ctx.moveTo(x, y);
|
|
210
|
-
setIsDrawing(true);
|
|
211
|
-
},
|
|
212
|
-
[enabled, getCoordinates]
|
|
213
|
-
);
|
|
214
|
-
const draw = useCallback(
|
|
215
|
-
(e) => {
|
|
216
|
-
if (!isDrawing) return;
|
|
217
|
-
e.preventDefault();
|
|
218
|
-
const canvas = canvasRef.current;
|
|
219
|
-
const ctx = canvas?.getContext("2d");
|
|
220
|
-
if (!canvas || !ctx) return;
|
|
221
|
-
const { x, y } = getCoordinates(e);
|
|
222
|
-
ctx.lineTo(x, y);
|
|
223
|
-
ctx.stroke();
|
|
224
|
-
setHasContent(true);
|
|
225
|
-
},
|
|
226
|
-
[isDrawing, getCoordinates]
|
|
227
|
-
);
|
|
228
|
-
const stopDrawing = useCallback(() => {
|
|
229
|
-
setIsDrawing(false);
|
|
230
|
-
}, []);
|
|
231
|
-
const clearCanvas = useCallback(() => {
|
|
232
|
-
const canvas = canvasRef.current;
|
|
233
|
-
const ctx = canvas?.getContext("2d");
|
|
234
|
-
if (!canvas || !ctx) return;
|
|
235
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
236
|
-
setHasContent(false);
|
|
237
|
-
}, []);
|
|
238
|
-
const takeScreenshot = useCallback(async () => {
|
|
239
|
-
try {
|
|
240
|
-
const toolbar = toolbarRef.current;
|
|
241
|
-
if (toolbar) {
|
|
242
|
-
toolbar.style.opacity = "0";
|
|
243
|
-
}
|
|
244
|
-
const canvas = await html2canvas(document.body, {
|
|
245
|
-
useCORS: true,
|
|
246
|
-
logging: false,
|
|
247
|
-
windowWidth: window.innerWidth,
|
|
248
|
-
windowHeight: window.innerHeight
|
|
249
|
-
});
|
|
250
|
-
if (toolbar) {
|
|
251
|
-
toolbar.style.opacity = "";
|
|
252
|
-
}
|
|
253
|
-
canvas.toBlob(async (blob) => {
|
|
254
|
-
if (!blob) return;
|
|
255
|
-
try {
|
|
256
|
-
await navigator.clipboard.write([
|
|
257
|
-
new ClipboardItem({
|
|
258
|
-
"image/png": blob
|
|
259
|
-
})
|
|
260
|
-
]);
|
|
261
|
-
} catch (err) {
|
|
262
|
-
console.error("Failed to copy to clipboard:", err);
|
|
263
|
-
const url = URL.createObjectURL(blob);
|
|
264
|
-
const a = document.createElement("a");
|
|
265
|
-
a.href = url;
|
|
266
|
-
a.download = "screenshot.png";
|
|
267
|
-
a.click();
|
|
268
|
-
URL.revokeObjectURL(url);
|
|
269
|
-
}
|
|
270
|
-
}, "image/png");
|
|
271
|
-
} catch (error) {
|
|
272
|
-
console.error("Failed to take screenshot:", error);
|
|
273
|
-
}
|
|
274
|
-
}, []);
|
|
275
|
-
useEffect(() => {
|
|
276
|
-
const canvas = canvasRef.current;
|
|
277
|
-
const ctx = canvas?.getContext("2d");
|
|
278
|
-
if (!ctx) return;
|
|
279
|
-
ctx.strokeStyle = brushColor;
|
|
280
|
-
ctx.lineWidth = brushSize;
|
|
281
|
-
}, [brushColor, brushSize]);
|
|
282
|
-
const getTargetCorner = useCallback(
|
|
283
|
-
(startX, startY, currentX, currentY) => {
|
|
284
|
-
const deltaX = currentX - startX;
|
|
285
|
-
const deltaY = currentY - startY;
|
|
286
|
-
const threshold = 50;
|
|
287
|
-
if (Math.abs(deltaX) < threshold && Math.abs(deltaY) < threshold) {
|
|
288
|
-
return null;
|
|
289
|
-
}
|
|
290
|
-
const viewportWidth = window.innerWidth;
|
|
291
|
-
const viewportHeight = window.innerHeight;
|
|
292
|
-
const horizontal = currentX < viewportWidth / 2 ? "left" : "right";
|
|
293
|
-
const vertical = currentY < viewportHeight / 2 ? "top" : "bottom";
|
|
294
|
-
if (vertical === "top" && horizontal === "left") return "top-left";
|
|
295
|
-
if (vertical === "top" && horizontal === "right") return "top-right";
|
|
296
|
-
if (vertical === "bottom" && horizontal === "left") return "bottom-left";
|
|
297
|
-
if (vertical === "bottom" && horizontal === "right")
|
|
298
|
-
return "bottom-right";
|
|
299
|
-
return null;
|
|
300
|
-
},
|
|
301
|
-
[]
|
|
302
|
-
);
|
|
303
|
-
const handleMouseDown = useCallback((e) => {
|
|
304
|
-
if (e.target.closest("button")) {
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
e.preventDefault();
|
|
308
|
-
e.stopPropagation();
|
|
309
|
-
setIsDragging(true);
|
|
310
|
-
setDragStart({
|
|
311
|
-
x: e.clientX,
|
|
312
|
-
y: e.clientY
|
|
313
|
-
});
|
|
314
|
-
}, []);
|
|
315
|
-
useEffect(() => {
|
|
316
|
-
const handleMouseMove = (e) => {
|
|
317
|
-
if (!isDragging) return;
|
|
318
|
-
e.preventDefault();
|
|
319
|
-
e.stopPropagation();
|
|
320
|
-
const targetCorner = getTargetCorner(
|
|
321
|
-
dragStart.x,
|
|
322
|
-
dragStart.y,
|
|
323
|
-
e.clientX,
|
|
324
|
-
e.clientY
|
|
325
|
-
);
|
|
326
|
-
if (targetCorner) {
|
|
327
|
-
setCorner(targetCorner);
|
|
328
|
-
} else {
|
|
329
|
-
const viewportWidth = window.innerWidth;
|
|
330
|
-
const viewportHeight = window.innerHeight;
|
|
331
|
-
const horizontal = e.clientX < viewportWidth / 2 ? "left" : "right";
|
|
332
|
-
const vertical = e.clientY < viewportHeight / 2 ? "top" : "bottom";
|
|
333
|
-
if (vertical === "top" && horizontal === "left") setCorner("top-left");
|
|
334
|
-
else if (vertical === "top" && horizontal === "right")
|
|
335
|
-
setCorner("top-right");
|
|
336
|
-
else if (vertical === "bottom" && horizontal === "left")
|
|
337
|
-
setCorner("bottom-left");
|
|
338
|
-
else setCorner("bottom-right");
|
|
318
|
+
}, [isDragging, dragStart, getTargetCorner]);
|
|
319
|
+
if (overlay) {
|
|
320
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
321
|
+
/* @__PURE__ */ jsx(
|
|
322
|
+
"canvas",
|
|
323
|
+
{
|
|
324
|
+
ref: canvasRef,
|
|
325
|
+
onMouseDown: startDrawing,
|
|
326
|
+
onMouseMove: draw,
|
|
327
|
+
onMouseUp: stopDrawing,
|
|
328
|
+
onMouseLeave: stopDrawing,
|
|
329
|
+
onTouchStart: startDrawing,
|
|
330
|
+
onTouchMove: draw,
|
|
331
|
+
onTouchEnd: stopDrawing,
|
|
332
|
+
className: `fixed top-0 left-0 touch-none z-50 transition-opacity ${enabled && !isDragging ? "cursor-crosshair pointer-events-auto opacity-100" : "pointer-events-none opacity-0"}`,
|
|
333
|
+
style: {
|
|
334
|
+
width: `${canvasSize.width}px`,
|
|
335
|
+
height: `${canvasSize.height}px`
|
|
339
336
|
}
|
|
340
|
-
};
|
|
341
|
-
const handleMouseUp = (e) => {
|
|
342
|
-
e.preventDefault();
|
|
343
|
-
e.stopPropagation();
|
|
344
|
-
setIsDragging(false);
|
|
345
|
-
};
|
|
346
|
-
if (isDragging) {
|
|
347
|
-
document.addEventListener("mousemove", handleMouseMove, {
|
|
348
|
-
passive: false
|
|
349
|
-
});
|
|
350
|
-
document.addEventListener("mouseup", handleMouseUp, { passive: false });
|
|
351
337
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
"
|
|
361
|
-
{
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
"div",
|
|
379
|
-
{
|
|
380
|
-
ref: toolbarRef,
|
|
381
|
-
className: `fixed flex flex-row items-center px-2 py-1.5 bg-neutral-800 rounded-full shadow-lg z-[60] ${isDragging ? "cursor-grabbing" : "cursor-grab"} ${className}`,
|
|
382
|
-
style: {
|
|
383
|
-
gap: enabled ? "8px" : "0px",
|
|
384
|
-
transition: "gap 300ms ease-in-out",
|
|
385
|
-
...corner === "top-left" ? { top: "16px", left: "16px", bottom: "auto", right: "auto" } : corner === "top-right" ? { top: "16px", right: "16px", bottom: "auto", left: "auto" } : corner === "bottom-left" ? { bottom: "16px", left: "16px", top: "auto", right: "auto" } : { bottom: "16px", right: "16px", top: "auto", left: "auto" }
|
|
386
|
-
},
|
|
387
|
-
onMouseDown: handleMouseDown,
|
|
388
|
-
...props,
|
|
389
|
-
onClick: (e) => e.stopPropagation(),
|
|
390
|
-
children: [
|
|
391
|
-
/* @__PURE__ */ jsx(
|
|
392
|
-
"div",
|
|
338
|
+
),
|
|
339
|
+
/* @__PURE__ */ jsxs(
|
|
340
|
+
"div",
|
|
341
|
+
{
|
|
342
|
+
ref: toolbarRef,
|
|
343
|
+
className: `fixed flex flex-row items-center px-2 py-1.5 bg-neutral-800 rounded-full shadow-lg z-[60] ${isDragging ? "cursor-grabbing" : "cursor-grab"} ${className}`,
|
|
344
|
+
style: {
|
|
345
|
+
gap: enabled ? "8px" : "0px",
|
|
346
|
+
transition: "gap 300ms ease-in-out",
|
|
347
|
+
...corner === "top-left" ? { top: "16px", left: "16px", bottom: "auto", right: "auto" } : corner === "top-right" ? { top: "16px", right: "16px", bottom: "auto", left: "auto" } : corner === "bottom-left" ? { bottom: "16px", left: "16px", top: "auto", right: "auto" } : { bottom: "16px", right: "16px", top: "auto", left: "auto" }
|
|
348
|
+
},
|
|
349
|
+
onMouseDown: handleMouseDown,
|
|
350
|
+
...props,
|
|
351
|
+
onClick: (e) => e.stopPropagation(),
|
|
352
|
+
children: [
|
|
353
|
+
/* @__PURE__ */ jsx(
|
|
354
|
+
"div",
|
|
355
|
+
{
|
|
356
|
+
className: "overflow-hidden flex-shrink-0",
|
|
357
|
+
style: {
|
|
358
|
+
maxWidth: enabled ? "100px" : "0px",
|
|
359
|
+
opacity: enabled ? 1 : 0,
|
|
360
|
+
transition: "max-width 300ms ease-in-out, opacity 300ms ease-in-out"
|
|
361
|
+
},
|
|
362
|
+
children: /* @__PURE__ */ jsx(
|
|
363
|
+
"button",
|
|
393
364
|
{
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
opacity: enabled ? 1 : 0,
|
|
398
|
-
transition: "max-width 300ms ease-in-out, opacity 300ms ease-in-out"
|
|
365
|
+
onClick: (e) => {
|
|
366
|
+
e.stopPropagation();
|
|
367
|
+
takeScreenshot();
|
|
399
368
|
},
|
|
400
|
-
|
|
401
|
-
|
|
369
|
+
className: "p-2 text-white hover:bg-neutral-600/30 rounded-full transition-colors focus:outline-none whitespace-nowrap",
|
|
370
|
+
"aria-label": "Take screenshot",
|
|
371
|
+
children: /* @__PURE__ */ jsxs(
|
|
372
|
+
"svg",
|
|
402
373
|
{
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
stroke: "currentColor",
|
|
418
|
-
strokeWidth: "2",
|
|
419
|
-
strokeLinecap: "round",
|
|
420
|
-
strokeLinejoin: "round",
|
|
421
|
-
className: "lucide lucide-camera",
|
|
422
|
-
children: [
|
|
423
|
-
/* @__PURE__ */ jsx("path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }),
|
|
424
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "13", r: "3" })
|
|
425
|
-
]
|
|
426
|
-
}
|
|
427
|
-
)
|
|
374
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
375
|
+
width: "18",
|
|
376
|
+
height: "18",
|
|
377
|
+
viewBox: "0 0 24 24",
|
|
378
|
+
fill: "none",
|
|
379
|
+
stroke: "currentColor",
|
|
380
|
+
strokeWidth: "2",
|
|
381
|
+
strokeLinecap: "round",
|
|
382
|
+
strokeLinejoin: "round",
|
|
383
|
+
className: "lucide lucide-camera",
|
|
384
|
+
children: [
|
|
385
|
+
/* @__PURE__ */ jsx("path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }),
|
|
386
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "13", r: "3" })
|
|
387
|
+
]
|
|
428
388
|
}
|
|
429
389
|
)
|
|
430
390
|
}
|
|
431
|
-
)
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
391
|
+
)
|
|
392
|
+
}
|
|
393
|
+
),
|
|
394
|
+
/* @__PURE__ */ jsxs(
|
|
395
|
+
"div",
|
|
396
|
+
{
|
|
397
|
+
className: "overflow-hidden flex-shrink-0 relative",
|
|
398
|
+
style: {
|
|
399
|
+
maxWidth: enabled ? "100px" : "0px",
|
|
400
|
+
opacity: enabled ? 1 : 0,
|
|
401
|
+
transition: "max-width 300ms ease-in-out, opacity 300ms ease-in-out"
|
|
402
|
+
},
|
|
403
|
+
children: [
|
|
404
|
+
/* @__PURE__ */ jsxs(
|
|
405
|
+
"button",
|
|
406
|
+
{
|
|
407
|
+
onClick: (e) => {
|
|
408
|
+
e.stopPropagation();
|
|
409
|
+
clearCanvas();
|
|
410
|
+
setShowClearTooltip(false);
|
|
411
|
+
},
|
|
412
|
+
onMouseEnter: () => {
|
|
413
|
+
if (hasContent) {
|
|
414
|
+
setShowClearTooltip(true);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
onMouseLeave: () => setShowClearTooltip(false),
|
|
418
|
+
disabled: !hasContent,
|
|
419
|
+
className: "p-2 text-white rounded-full focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed relative group",
|
|
420
|
+
"aria-label": "Clear canvas",
|
|
421
|
+
children: [
|
|
422
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-full bg-red-600/30 opacity-0 group-hover:opacity-100 transition-opacity disabled:group-hover:opacity-0" }),
|
|
423
|
+
/* @__PURE__ */ jsx(
|
|
424
|
+
Trash2,
|
|
425
|
+
{
|
|
426
|
+
size: 18,
|
|
427
|
+
strokeWidth: 2,
|
|
428
|
+
className: "relative z-10 group-hover:text-red-600 transition-colors"
|
|
429
|
+
}
|
|
430
|
+
)
|
|
431
|
+
]
|
|
432
|
+
}
|
|
433
|
+
),
|
|
434
|
+
showClearTooltip && hasContent && /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-1.5 bg-neutral-800 rounded-full shadow-lg whitespace-nowrap z-[70]", children: [
|
|
435
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
436
|
+
/* @__PURE__ */ jsx("span", { className: "text-white text-sm", children: "Clear all" }),
|
|
437
|
+
/* @__PURE__ */ jsx(
|
|
443
438
|
"button",
|
|
444
439
|
{
|
|
445
440
|
onClick: (e) => {
|
|
446
441
|
e.stopPropagation();
|
|
447
|
-
clearCanvas();
|
|
448
442
|
setShowClearTooltip(false);
|
|
449
443
|
},
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
},
|
|
455
|
-
onMouseLeave: () => setShowClearTooltip(false),
|
|
456
|
-
disabled: !hasContent,
|
|
457
|
-
className: "p-2 text-white rounded-full focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed relative group",
|
|
458
|
-
"aria-label": "Clear canvas",
|
|
459
|
-
children: [
|
|
460
|
-
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-full bg-red-600/30 opacity-0 group-hover:opacity-100 transition-opacity disabled:group-hover:opacity-0" }),
|
|
461
|
-
/* @__PURE__ */ jsx(
|
|
462
|
-
Trash2,
|
|
463
|
-
{
|
|
464
|
-
size: 18,
|
|
465
|
-
strokeWidth: 2,
|
|
466
|
-
className: "relative z-10 group-hover:text-red-600 transition-colors"
|
|
467
|
-
}
|
|
468
|
-
)
|
|
469
|
-
]
|
|
444
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
445
|
+
className: "text-white hover:text-neutral-300 transition-colors rounded-full",
|
|
446
|
+
"aria-label": "Dismiss tooltip",
|
|
447
|
+
children: /* @__PURE__ */ jsx(X, { size: 14, strokeWidth: 2 })
|
|
470
448
|
}
|
|
471
|
-
)
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
449
|
+
)
|
|
450
|
+
] }),
|
|
451
|
+
/* @__PURE__ */ jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 -mt-1", children: /* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-neutral-800 rotate-45" }) })
|
|
452
|
+
] })
|
|
453
|
+
]
|
|
454
|
+
}
|
|
455
|
+
),
|
|
456
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex-shrink-0", children: [
|
|
457
|
+
/* @__PURE__ */ jsx(
|
|
458
|
+
"button",
|
|
459
|
+
{
|
|
460
|
+
onClick: (e) => {
|
|
461
|
+
e.stopPropagation();
|
|
462
|
+
setEnabled(!enabled);
|
|
463
|
+
},
|
|
464
|
+
className: "p-1.5 text-white hover:bg-neutral-600/30 rounded-full transition-all focus:outline-none",
|
|
465
|
+
style: {
|
|
466
|
+
opacity: enabled ? 0 : 1,
|
|
467
|
+
pointerEvents: enabled ? "none" : "auto",
|
|
468
|
+
transition: "opacity 300ms ease-in-out"
|
|
469
|
+
},
|
|
470
|
+
"aria-label": "Turn on drawing",
|
|
471
|
+
children: /* @__PURE__ */ jsxs(
|
|
472
|
+
"svg",
|
|
473
|
+
{
|
|
474
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
475
|
+
width: "18",
|
|
476
|
+
height: "18",
|
|
477
|
+
viewBox: "0 0 24 24",
|
|
478
|
+
fill: "none",
|
|
479
|
+
stroke: "currentColor",
|
|
480
|
+
strokeWidth: "2",
|
|
481
|
+
strokeLinecap: "round",
|
|
482
|
+
strokeLinejoin: "round",
|
|
483
|
+
className: "lucide lucide-brush",
|
|
484
|
+
children: [
|
|
485
|
+
/* @__PURE__ */ jsx("path", { d: "m11 10 3 3" }),
|
|
486
|
+
/* @__PURE__ */ jsx("path", { d: "M6.5 21A3.5 3.5 0 1 0 3 17.5a2.62 2.62 0 0 1-.708 1.792A1 1 0 0 0 3 21z" }),
|
|
487
|
+
/* @__PURE__ */ jsx("path", { d: "M9.969 17.031 21.378 5.624a1 1 0 0 0-3.002-3.002L6.967 14.031" })
|
|
488
|
+
]
|
|
489
|
+
}
|
|
490
|
+
)
|
|
491
|
+
}
|
|
492
|
+
),
|
|
493
|
+
/* @__PURE__ */ jsx(
|
|
494
|
+
"button",
|
|
495
|
+
{
|
|
496
|
+
onClick: (e) => {
|
|
497
|
+
e.stopPropagation();
|
|
498
|
+
setEnabled(false);
|
|
499
|
+
},
|
|
500
|
+
className: "absolute inset-0 p-1.5 text-white hover:bg-neutral-600/30 rounded-full transition-all focus:outline-none",
|
|
501
|
+
style: {
|
|
502
|
+
opacity: enabled ? 1 : 0,
|
|
503
|
+
pointerEvents: enabled ? "auto" : "none",
|
|
504
|
+
transition: "opacity 300ms ease-in-out"
|
|
505
|
+
},
|
|
506
|
+
"aria-label": "Close",
|
|
507
|
+
children: /* @__PURE__ */ jsx(X, { size: 18, strokeWidth: 2.5 })
|
|
508
|
+
}
|
|
509
|
+
)
|
|
510
|
+
] })
|
|
511
|
+
]
|
|
512
|
+
}
|
|
513
|
+
)
|
|
514
|
+
] });
|
|
515
|
+
}
|
|
516
|
+
return /* @__PURE__ */ jsxs(
|
|
517
|
+
"div",
|
|
518
|
+
{
|
|
519
|
+
className: `flex flex-col items-center gap-4 p-6 bg-white rounded-full shadow-lg border border-gray-200 ${className}`,
|
|
520
|
+
...props,
|
|
521
|
+
children: [
|
|
522
|
+
/* @__PURE__ */ jsxs(
|
|
523
|
+
"div",
|
|
524
|
+
{
|
|
525
|
+
className: "flex flex-row items-center w-full justify-center transition-all duration-300 ease-in-out",
|
|
526
|
+
style: {
|
|
527
|
+
gap: enabled ? "12px" : "0px"
|
|
528
|
+
},
|
|
529
|
+
children: [
|
|
530
|
+
/* @__PURE__ */ jsx(
|
|
531
|
+
"button",
|
|
532
|
+
{
|
|
533
|
+
onClick: () => setEnabled(!enabled),
|
|
534
|
+
className: `p-3 rounded-xl transition-all duration-200 focus:outline-none shadow-md hover:shadow-lg active:scale-95 ${enabled ? "bg-emerald-500 text-white hover:bg-emerald-600 active:bg-emerald-700" : "bg-slate-500 text-white hover:bg-slate-600 active:bg-slate-700"}`,
|
|
535
|
+
"aria-label": enabled ? "Turn off drawing" : "Turn on drawing",
|
|
536
|
+
children: enabled ? /* @__PURE__ */ jsx(X, { size: 20, strokeWidth: 2.5 }) : /* @__PURE__ */ jsxs(
|
|
537
|
+
"svg",
|
|
538
|
+
{
|
|
539
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
540
|
+
width: "20",
|
|
541
|
+
height: "20",
|
|
542
|
+
viewBox: "0 0 24 24",
|
|
543
|
+
fill: "none",
|
|
544
|
+
stroke: "currentColor",
|
|
545
|
+
strokeWidth: "2",
|
|
546
|
+
strokeLinecap: "round",
|
|
547
|
+
strokeLinejoin: "round",
|
|
548
|
+
className: "lucide lucide-brush",
|
|
549
|
+
children: [
|
|
550
|
+
/* @__PURE__ */ jsx("path", { d: "m11 10 3 3" }),
|
|
551
|
+
/* @__PURE__ */ jsx("path", { d: "M6.5 21A3.5 3.5 0 1 0 3 17.5a2.62 2.62 0 0 1-.708 1.792A1 1 0 0 0 3 21z" }),
|
|
552
|
+
/* @__PURE__ */ jsx("path", { d: "M9.969 17.031 21.378 5.624a1 1 0 0 0-3.002-3.002L6.967 14.031" })
|
|
553
|
+
]
|
|
554
|
+
}
|
|
555
|
+
)
|
|
556
|
+
}
|
|
557
|
+
),
|
|
558
|
+
/* @__PURE__ */ jsx(
|
|
559
|
+
"div",
|
|
560
|
+
{
|
|
561
|
+
className: "transition-all duration-300 ease-in-out overflow-hidden flex-shrink-0",
|
|
562
|
+
style: {
|
|
563
|
+
width: enabled ? "52px" : "0px",
|
|
564
|
+
minWidth: enabled ? "52px" : "0px",
|
|
565
|
+
opacity: enabled ? 1 : 0
|
|
566
|
+
},
|
|
567
|
+
children: /* @__PURE__ */ jsx(
|
|
496
568
|
"button",
|
|
497
569
|
{
|
|
498
|
-
onClick:
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
className: "p-1.5 text-white hover:bg-neutral-600/30 rounded-full transition-all focus:outline-none",
|
|
503
|
-
style: {
|
|
504
|
-
opacity: enabled ? 0 : 1,
|
|
505
|
-
pointerEvents: enabled ? "none" : "auto",
|
|
506
|
-
transition: "opacity 300ms ease-in-out"
|
|
507
|
-
},
|
|
508
|
-
"aria-label": "Turn on drawing",
|
|
570
|
+
onClick: clearCanvas,
|
|
571
|
+
disabled: !hasContent,
|
|
572
|
+
className: "p-3 bg-red-500 text-white hover:text-red-200 rounded-xl hover:bg-red-600 active:bg-red-700 transition-all duration-200 focus:outline-none shadow-md hover:shadow-lg active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-red-500 disabled:hover:shadow-md disabled:active:scale-100 whitespace-nowrap",
|
|
573
|
+
"aria-label": "Clear canvas",
|
|
509
574
|
children: /* @__PURE__ */ jsxs(
|
|
510
575
|
"svg",
|
|
511
576
|
{
|
|
512
577
|
xmlns: "http://www.w3.org/2000/svg",
|
|
513
|
-
width: "
|
|
514
|
-
height: "
|
|
578
|
+
width: "20",
|
|
579
|
+
height: "20",
|
|
515
580
|
viewBox: "0 0 24 24",
|
|
516
581
|
fill: "none",
|
|
517
582
|
stroke: "currentColor",
|
|
518
583
|
strokeWidth: "2",
|
|
519
584
|
strokeLinecap: "round",
|
|
520
585
|
strokeLinejoin: "round",
|
|
521
|
-
className: "lucide lucide-brush",
|
|
586
|
+
className: "lucide lucide-brush-cleaning",
|
|
522
587
|
children: [
|
|
523
|
-
/* @__PURE__ */ jsx("path", { d: "
|
|
524
|
-
/* @__PURE__ */ jsx("path", { d: "
|
|
525
|
-
/* @__PURE__ */ jsx("path", { d: "
|
|
588
|
+
/* @__PURE__ */ jsx("path", { d: "m16 22-1-4" }),
|
|
589
|
+
/* @__PURE__ */ jsx("path", { d: "M19 14a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v1a1 1 0 0 0 1 1" }),
|
|
590
|
+
/* @__PURE__ */ jsx("path", { d: "M19 14H5l-1.973 6.767A1 1 0 0 0 4 22h16a1 1 0 0 0 .973-1.233z" }),
|
|
591
|
+
/* @__PURE__ */ jsx("path", { d: "m8 22 1-4" })
|
|
526
592
|
]
|
|
527
593
|
}
|
|
528
594
|
)
|
|
529
595
|
}
|
|
530
|
-
),
|
|
531
|
-
/* @__PURE__ */ jsx(
|
|
532
|
-
"button",
|
|
533
|
-
{
|
|
534
|
-
onClick: (e) => {
|
|
535
|
-
e.stopPropagation();
|
|
536
|
-
setEnabled(false);
|
|
537
|
-
},
|
|
538
|
-
className: "absolute inset-0 p-1.5 text-white hover:bg-neutral-600/30 rounded-full transition-all focus:outline-none",
|
|
539
|
-
style: {
|
|
540
|
-
opacity: enabled ? 1 : 0,
|
|
541
|
-
pointerEvents: enabled ? "auto" : "none",
|
|
542
|
-
transition: "opacity 300ms ease-in-out"
|
|
543
|
-
},
|
|
544
|
-
"aria-label": "Close",
|
|
545
|
-
children: /* @__PURE__ */ jsx(X, { size: 18, strokeWidth: 2.5 })
|
|
546
|
-
}
|
|
547
596
|
)
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
/* @__PURE__ */ jsxs(
|
|
561
|
-
"div",
|
|
562
|
-
{
|
|
563
|
-
className: "flex flex-row items-center w-full justify-center transition-all duration-300 ease-in-out",
|
|
564
|
-
style: {
|
|
565
|
-
gap: enabled ? "12px" : "0px"
|
|
566
|
-
},
|
|
567
|
-
children: [
|
|
568
|
-
/* @__PURE__ */ jsx(
|
|
597
|
+
}
|
|
598
|
+
),
|
|
599
|
+
/* @__PURE__ */ jsx(
|
|
600
|
+
"div",
|
|
601
|
+
{
|
|
602
|
+
className: "transition-all duration-300 ease-in-out overflow-hidden flex-shrink-0",
|
|
603
|
+
style: {
|
|
604
|
+
width: enabled ? "52px" : "0px",
|
|
605
|
+
minWidth: enabled ? "52px" : "0px",
|
|
606
|
+
opacity: enabled ? 1 : 0
|
|
607
|
+
},
|
|
608
|
+
children: /* @__PURE__ */ jsx(
|
|
569
609
|
"button",
|
|
570
610
|
{
|
|
571
|
-
onClick:
|
|
572
|
-
className:
|
|
573
|
-
"aria-label":
|
|
574
|
-
children:
|
|
611
|
+
onClick: takeScreenshot,
|
|
612
|
+
className: "p-3 bg-neutral-500 text-white rounded-xl hover:bg-neutral-600 active:bg-neutral-700 transition-all duration-200 focus:outline-none shadow-md hover:shadow-lg active:scale-95 whitespace-nowrap",
|
|
613
|
+
"aria-label": "Take screenshot",
|
|
614
|
+
children: /* @__PURE__ */ jsxs(
|
|
575
615
|
"svg",
|
|
576
616
|
{
|
|
577
617
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -583,176 +623,60 @@ var init_DrawingTool = __esm({
|
|
|
583
623
|
strokeWidth: "2",
|
|
584
624
|
strokeLinecap: "round",
|
|
585
625
|
strokeLinejoin: "round",
|
|
586
|
-
className: "lucide lucide-
|
|
626
|
+
className: "lucide lucide-camera",
|
|
587
627
|
children: [
|
|
588
|
-
/* @__PURE__ */ jsx("path", { d: "
|
|
589
|
-
/* @__PURE__ */ jsx("
|
|
590
|
-
/* @__PURE__ */ jsx("path", { d: "M9.969 17.031 21.378 5.624a1 1 0 0 0-3.002-3.002L6.967 14.031" })
|
|
628
|
+
/* @__PURE__ */ jsx("path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }),
|
|
629
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "13", r: "3" })
|
|
591
630
|
]
|
|
592
631
|
}
|
|
593
632
|
)
|
|
594
633
|
}
|
|
595
|
-
),
|
|
596
|
-
/* @__PURE__ */ jsx(
|
|
597
|
-
"div",
|
|
598
|
-
{
|
|
599
|
-
className: "transition-all duration-300 ease-in-out overflow-hidden flex-shrink-0",
|
|
600
|
-
style: {
|
|
601
|
-
width: enabled ? "52px" : "0px",
|
|
602
|
-
minWidth: enabled ? "52px" : "0px",
|
|
603
|
-
opacity: enabled ? 1 : 0
|
|
604
|
-
},
|
|
605
|
-
children: /* @__PURE__ */ jsx(
|
|
606
|
-
"button",
|
|
607
|
-
{
|
|
608
|
-
onClick: clearCanvas,
|
|
609
|
-
disabled: !hasContent,
|
|
610
|
-
className: "p-3 bg-red-500 text-white hover:text-red-200 rounded-xl hover:bg-red-600 active:bg-red-700 transition-all duration-200 focus:outline-none shadow-md hover:shadow-lg active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-red-500 disabled:hover:shadow-md disabled:active:scale-100 whitespace-nowrap",
|
|
611
|
-
"aria-label": "Clear canvas",
|
|
612
|
-
children: /* @__PURE__ */ jsxs(
|
|
613
|
-
"svg",
|
|
614
|
-
{
|
|
615
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
616
|
-
width: "20",
|
|
617
|
-
height: "20",
|
|
618
|
-
viewBox: "0 0 24 24",
|
|
619
|
-
fill: "none",
|
|
620
|
-
stroke: "currentColor",
|
|
621
|
-
strokeWidth: "2",
|
|
622
|
-
strokeLinecap: "round",
|
|
623
|
-
strokeLinejoin: "round",
|
|
624
|
-
className: "lucide lucide-brush-cleaning",
|
|
625
|
-
children: [
|
|
626
|
-
/* @__PURE__ */ jsx("path", { d: "m16 22-1-4" }),
|
|
627
|
-
/* @__PURE__ */ jsx("path", { d: "M19 14a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v1a1 1 0 0 0 1 1" }),
|
|
628
|
-
/* @__PURE__ */ jsx("path", { d: "M19 14H5l-1.973 6.767A1 1 0 0 0 4 22h16a1 1 0 0 0 .973-1.233z" }),
|
|
629
|
-
/* @__PURE__ */ jsx("path", { d: "m8 22 1-4" })
|
|
630
|
-
]
|
|
631
|
-
}
|
|
632
|
-
)
|
|
633
|
-
}
|
|
634
|
-
)
|
|
635
|
-
}
|
|
636
|
-
),
|
|
637
|
-
/* @__PURE__ */ jsx(
|
|
638
|
-
"div",
|
|
639
|
-
{
|
|
640
|
-
className: "transition-all duration-300 ease-in-out overflow-hidden flex-shrink-0",
|
|
641
|
-
style: {
|
|
642
|
-
width: enabled ? "52px" : "0px",
|
|
643
|
-
minWidth: enabled ? "52px" : "0px",
|
|
644
|
-
opacity: enabled ? 1 : 0
|
|
645
|
-
},
|
|
646
|
-
children: /* @__PURE__ */ jsx(
|
|
647
|
-
"button",
|
|
648
|
-
{
|
|
649
|
-
onClick: takeScreenshot,
|
|
650
|
-
className: "p-3 bg-neutral-500 text-white rounded-xl hover:bg-neutral-600 active:bg-neutral-700 transition-all duration-200 focus:outline-none shadow-md hover:shadow-lg active:scale-95 whitespace-nowrap",
|
|
651
|
-
"aria-label": "Take screenshot",
|
|
652
|
-
children: /* @__PURE__ */ jsxs(
|
|
653
|
-
"svg",
|
|
654
|
-
{
|
|
655
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
656
|
-
width: "20",
|
|
657
|
-
height: "20",
|
|
658
|
-
viewBox: "0 0 24 24",
|
|
659
|
-
fill: "none",
|
|
660
|
-
stroke: "currentColor",
|
|
661
|
-
strokeWidth: "2",
|
|
662
|
-
strokeLinecap: "round",
|
|
663
|
-
strokeLinejoin: "round",
|
|
664
|
-
className: "lucide lucide-camera",
|
|
665
|
-
children: [
|
|
666
|
-
/* @__PURE__ */ jsx("path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }),
|
|
667
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "13", r: "3" })
|
|
668
|
-
]
|
|
669
|
-
}
|
|
670
|
-
)
|
|
671
|
-
}
|
|
672
|
-
)
|
|
673
|
-
}
|
|
674
634
|
)
|
|
675
|
-
]
|
|
676
|
-
}
|
|
677
|
-
),
|
|
678
|
-
/* @__PURE__ */ jsx(
|
|
679
|
-
"canvas",
|
|
680
|
-
{
|
|
681
|
-
ref: canvasRef,
|
|
682
|
-
onMouseDown: startDrawing,
|
|
683
|
-
onMouseMove: draw,
|
|
684
|
-
onMouseUp: stopDrawing,
|
|
685
|
-
onMouseLeave: stopDrawing,
|
|
686
|
-
onTouchStart: startDrawing,
|
|
687
|
-
onTouchMove: draw,
|
|
688
|
-
onTouchEnd: stopDrawing,
|
|
689
|
-
className: `border border-gray-300 rounded touch-none transition-opacity ${enabled ? "cursor-crosshair pointer-events-auto opacity-100" : "pointer-events-none opacity-0"}`,
|
|
690
|
-
style: {
|
|
691
|
-
width: `${canvasSize.width}px`,
|
|
692
|
-
height: `${canvasSize.height}px`,
|
|
693
|
-
maxWidth: "100%"
|
|
694
635
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
636
|
+
)
|
|
637
|
+
]
|
|
638
|
+
}
|
|
639
|
+
),
|
|
640
|
+
/* @__PURE__ */ jsx(
|
|
641
|
+
"canvas",
|
|
642
|
+
{
|
|
643
|
+
ref: canvasRef,
|
|
644
|
+
onMouseDown: startDrawing,
|
|
645
|
+
onMouseMove: draw,
|
|
646
|
+
onMouseUp: stopDrawing,
|
|
647
|
+
onMouseLeave: stopDrawing,
|
|
648
|
+
onTouchStart: startDrawing,
|
|
649
|
+
onTouchMove: draw,
|
|
650
|
+
onTouchEnd: stopDrawing,
|
|
651
|
+
className: `border border-gray-300 rounded touch-none transition-opacity ${enabled ? "cursor-crosshair pointer-events-auto opacity-100" : "pointer-events-none opacity-0"}`,
|
|
652
|
+
style: {
|
|
653
|
+
width: `${canvasSize.width}px`,
|
|
654
|
+
height: `${canvasSize.height}px`,
|
|
655
|
+
maxWidth: "100%"
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
)
|
|
659
|
+
]
|
|
660
|
+
}
|
|
661
|
+
);
|
|
662
|
+
};
|
|
663
|
+
var DrawingTool_default = DrawingTool;
|
|
704
664
|
|
|
705
|
-
// src/
|
|
706
|
-
var
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
Card: () => Card,
|
|
711
|
-
CardDefault: () => Card_default,
|
|
712
|
-
DrawingTool: () => DrawingTool,
|
|
713
|
-
DrawingToolDefault: () => DrawingTool_default,
|
|
714
|
-
Input: () => Input,
|
|
715
|
-
InputDefault: () => Input_default
|
|
716
|
-
});
|
|
717
|
-
var init_components = __esm({
|
|
718
|
-
"src/components.ts"() {
|
|
719
|
-
init_Button();
|
|
720
|
-
init_Card();
|
|
721
|
-
init_Input();
|
|
722
|
-
init_DrawingTool();
|
|
723
|
-
init_Button();
|
|
724
|
-
init_Card();
|
|
725
|
-
init_Input();
|
|
726
|
-
init_DrawingTool();
|
|
665
|
+
// src/index.ts
|
|
666
|
+
var MoabSDK = class {
|
|
667
|
+
constructor(options = {}) {
|
|
668
|
+
__publicField(this, "options");
|
|
669
|
+
this.options = options;
|
|
727
670
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
var MoabSDK = class {
|
|
734
|
-
constructor(options = {}) {
|
|
735
|
-
this.options = options;
|
|
736
|
-
}
|
|
737
|
-
/**
|
|
738
|
-
* Example method - replace with your SDK functionality
|
|
739
|
-
*/
|
|
740
|
-
hello() {
|
|
741
|
-
return "Hello from Moab SDK!";
|
|
742
|
-
}
|
|
743
|
-
};
|
|
744
|
-
module.exports = MoabSDK;
|
|
745
|
-
module.exports.default = MoabSDK;
|
|
746
|
-
if (typeof module !== "undefined" && module.exports) {
|
|
747
|
-
try {
|
|
748
|
-
module.exports.components = (init_components(), __toCommonJS(components_exports));
|
|
749
|
-
} catch (e) {
|
|
750
|
-
}
|
|
751
|
-
}
|
|
671
|
+
/**
|
|
672
|
+
* Example method - replace with your SDK functionality
|
|
673
|
+
*/
|
|
674
|
+
hello() {
|
|
675
|
+
return "Hello from Moab SDK!";
|
|
752
676
|
}
|
|
753
|
-
}
|
|
754
|
-
var
|
|
677
|
+
};
|
|
678
|
+
var src_default = MoabSDK;
|
|
755
679
|
|
|
756
|
-
export {
|
|
680
|
+
export { Button, Button_default as ButtonDefault, Card, Card_default as CardDefault, DrawingTool, DrawingTool_default as DrawingToolDefault, Input, Input_default as InputDefault, MoabSDK, src_default as default };
|
|
757
681
|
//# sourceMappingURL=index.mjs.map
|
|
758
682
|
//# sourceMappingURL=index.mjs.map
|