afterbefore 0.2.16 → 0.2.18
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/overlay/index.js +912 -847
- package/dist/overlay/index.js.map +1 -1
- package/package.json +1 -1
package/dist/overlay/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/overlay/index.tsx
|
|
4
|
-
import { useState as useState5, useCallback as
|
|
4
|
+
import { useState as useState5, useCallback as useCallback4, useEffect as useEffect4 } from "react";
|
|
5
5
|
|
|
6
6
|
// src/overlay/state.ts
|
|
7
7
|
import { useState, useCallback } from "react";
|
|
@@ -177,457 +177,304 @@ function loadImage(src) {
|
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
// src/overlay/ui/icon.tsx
|
|
181
|
-
import { useRef, useCallback as useCallback2, useEffect, useState as useState2 } from "react";
|
|
182
|
-
import { Camera, Check, LoaderCircle } from "lucide-react";
|
|
183
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
184
|
-
var CONTAINER_SIZE = 38;
|
|
185
|
-
var ICON_SIZE = CONTAINER_SIZE;
|
|
186
|
-
var EDGE_MARGIN = 24;
|
|
187
|
-
function Icon({ phase, onClick, loading, onPositionChange }) {
|
|
188
|
-
const ref = useRef(null);
|
|
189
|
-
const [pos, setPos] = useState2({ x: -1, y: -1 });
|
|
190
|
-
const [dragging, setDragging] = useState2(false);
|
|
191
|
-
const [hovered, setHovered] = useState2(false);
|
|
192
|
-
const dragState = useRef(null);
|
|
193
|
-
useEffect(() => {
|
|
194
|
-
setPos((prev) => {
|
|
195
|
-
if (prev.x === -1 || prev.y === -1) {
|
|
196
|
-
return {
|
|
197
|
-
x: window.innerWidth - ICON_SIZE - EDGE_MARGIN,
|
|
198
|
-
y: window.innerHeight - ICON_SIZE - EDGE_MARGIN
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
return prev;
|
|
202
|
-
});
|
|
203
|
-
}, []);
|
|
204
|
-
useEffect(() => {
|
|
205
|
-
const handleResize = () => {
|
|
206
|
-
setPos((prev) => {
|
|
207
|
-
if (prev.x === -1 || prev.y === -1) return prev;
|
|
208
|
-
const clampedX = Math.max(0, Math.min(prev.x, window.innerWidth - ICON_SIZE));
|
|
209
|
-
const clampedY = Math.max(0, Math.min(prev.y, window.innerHeight - ICON_SIZE));
|
|
210
|
-
if (clampedX === prev.x && clampedY === prev.y) return prev;
|
|
211
|
-
return { x: clampedX, y: clampedY };
|
|
212
|
-
});
|
|
213
|
-
};
|
|
214
|
-
window.addEventListener("resize", handleResize);
|
|
215
|
-
return () => window.removeEventListener("resize", handleResize);
|
|
216
|
-
}, []);
|
|
217
|
-
useEffect(() => {
|
|
218
|
-
if (pos.x !== -1 && pos.y !== -1) {
|
|
219
|
-
onPositionChange?.({ x: pos.x, y: pos.y });
|
|
220
|
-
}
|
|
221
|
-
}, [pos, onPositionChange]);
|
|
222
|
-
const handleMouseDown = useCallback2(
|
|
223
|
-
(e) => {
|
|
224
|
-
e.preventDefault();
|
|
225
|
-
setDragging(true);
|
|
226
|
-
dragState.current = {
|
|
227
|
-
dragging: true,
|
|
228
|
-
startX: e.clientX,
|
|
229
|
-
startY: e.clientY,
|
|
230
|
-
origX: pos.x,
|
|
231
|
-
origY: pos.y,
|
|
232
|
-
distance: 0
|
|
233
|
-
};
|
|
234
|
-
},
|
|
235
|
-
[pos]
|
|
236
|
-
);
|
|
237
|
-
useEffect(() => {
|
|
238
|
-
const handleMouseMove = (e) => {
|
|
239
|
-
const ds = dragState.current;
|
|
240
|
-
if (!ds || !ds.dragging) return;
|
|
241
|
-
const dx = e.clientX - ds.startX;
|
|
242
|
-
const dy = e.clientY - ds.startY;
|
|
243
|
-
ds.distance = Math.sqrt(dx * dx + dy * dy);
|
|
244
|
-
const newX = Math.max(
|
|
245
|
-
0,
|
|
246
|
-
Math.min(window.innerWidth - ICON_SIZE, ds.origX + dx)
|
|
247
|
-
);
|
|
248
|
-
const newY = Math.max(
|
|
249
|
-
0,
|
|
250
|
-
Math.min(window.innerHeight - ICON_SIZE, ds.origY + dy)
|
|
251
|
-
);
|
|
252
|
-
setPos({ x: newX, y: newY });
|
|
253
|
-
};
|
|
254
|
-
const handleMouseUp = () => {
|
|
255
|
-
const ds = dragState.current;
|
|
256
|
-
if (!ds) return;
|
|
257
|
-
if (ds.distance < 5) {
|
|
258
|
-
onClick();
|
|
259
|
-
}
|
|
260
|
-
setDragging(false);
|
|
261
|
-
dragState.current = null;
|
|
262
|
-
};
|
|
263
|
-
window.addEventListener("mousemove", handleMouseMove);
|
|
264
|
-
window.addEventListener("mouseup", handleMouseUp);
|
|
265
|
-
return () => {
|
|
266
|
-
window.removeEventListener("mousemove", handleMouseMove);
|
|
267
|
-
window.removeEventListener("mouseup", handleMouseUp);
|
|
268
|
-
};
|
|
269
|
-
}, [onClick]);
|
|
270
|
-
if (pos.x === -1 || pos.y === -1) return null;
|
|
271
|
-
return /* @__PURE__ */ jsxs(
|
|
272
|
-
"div",
|
|
273
|
-
{
|
|
274
|
-
ref,
|
|
275
|
-
"data-afterbefore": "true",
|
|
276
|
-
onMouseDown: handleMouseDown,
|
|
277
|
-
style: {
|
|
278
|
-
position: "fixed",
|
|
279
|
-
left: pos.x,
|
|
280
|
-
top: pos.y,
|
|
281
|
-
width: CONTAINER_SIZE,
|
|
282
|
-
height: CONTAINER_SIZE,
|
|
283
|
-
borderRadius: "50%",
|
|
284
|
-
background: hovered ? "rgb(38, 38, 42)" : "rgb(32, 32, 36)",
|
|
285
|
-
border: "none",
|
|
286
|
-
display: "flex",
|
|
287
|
-
alignItems: "center",
|
|
288
|
-
justifyContent: "center",
|
|
289
|
-
cursor: dragging ? "grabbing" : "pointer",
|
|
290
|
-
zIndex: 2147483647,
|
|
291
|
-
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
|
292
|
-
transition: "background 0.15s",
|
|
293
|
-
userSelect: "none"
|
|
294
|
-
},
|
|
295
|
-
onMouseEnter: () => setHovered(true),
|
|
296
|
-
onMouseLeave: () => setHovered(false),
|
|
297
|
-
children: [
|
|
298
|
-
/* @__PURE__ */ jsx(
|
|
299
|
-
"style",
|
|
300
|
-
{
|
|
301
|
-
dangerouslySetInnerHTML: {
|
|
302
|
-
__html: `
|
|
303
|
-
@keyframes ab-spin {
|
|
304
|
-
0% { transform: rotate(0deg); }
|
|
305
|
-
100% { transform: rotate(360deg); }
|
|
306
|
-
}`
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
),
|
|
310
|
-
loading ? /* @__PURE__ */ jsx(
|
|
311
|
-
LoaderCircle,
|
|
312
|
-
{
|
|
313
|
-
size: 16,
|
|
314
|
-
strokeWidth: 2,
|
|
315
|
-
style: { animation: "ab-spin 0.8s linear infinite", color: "white" }
|
|
316
|
-
}
|
|
317
|
-
) : phase === "ready" ? /* @__PURE__ */ jsx(Check, { size: 16, strokeWidth: 2.6, color: "#4ade80" }) : /* @__PURE__ */ jsx(
|
|
318
|
-
Camera,
|
|
319
|
-
{
|
|
320
|
-
size: 16,
|
|
321
|
-
strokeWidth: 1.9,
|
|
322
|
-
color: hovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)"
|
|
323
|
-
}
|
|
324
|
-
)
|
|
325
|
-
]
|
|
326
|
-
}
|
|
327
|
-
);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
180
|
// src/overlay/ui/toolbar.tsx
|
|
331
|
-
import { useCallback as
|
|
181
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
332
182
|
import {
|
|
333
183
|
ArrowUp,
|
|
334
|
-
|
|
184
|
+
Camera,
|
|
185
|
+
Check,
|
|
186
|
+
ChevronDown as ChevronDown2,
|
|
335
187
|
Clock,
|
|
336
|
-
|
|
188
|
+
Eye,
|
|
337
189
|
FolderOpen,
|
|
338
|
-
|
|
339
|
-
|
|
190
|
+
LoaderCircle,
|
|
191
|
+
Maximize,
|
|
340
192
|
Monitor,
|
|
341
193
|
MousePointer2,
|
|
342
|
-
Palette,
|
|
343
194
|
Settings,
|
|
195
|
+
Trash2 as Trash22,
|
|
196
|
+
X as X2
|
|
197
|
+
} from "lucide-react";
|
|
198
|
+
|
|
199
|
+
// src/overlay/ui/settings-panel.tsx
|
|
200
|
+
import { useEffect, useRef, useState as useState2 } from "react";
|
|
201
|
+
import {
|
|
202
|
+
ChevronDown,
|
|
203
|
+
ImageIcon,
|
|
204
|
+
Palette,
|
|
344
205
|
Trash2,
|
|
345
206
|
Upload,
|
|
346
207
|
X
|
|
347
208
|
} from "lucide-react";
|
|
348
|
-
import { Fragment, jsx
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
{ mode: "fullpage", label: "Full Page", icon: Maximize }
|
|
353
|
-
];
|
|
354
|
-
function Toolbar({
|
|
209
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
210
|
+
function SettingsPanel({
|
|
211
|
+
style,
|
|
212
|
+
onClose,
|
|
355
213
|
selectedMode,
|
|
356
|
-
onModeChange,
|
|
357
|
-
onCapture,
|
|
358
|
-
onCancel,
|
|
359
214
|
frameSettings,
|
|
360
215
|
onFrameSettingsChange
|
|
361
216
|
}) {
|
|
362
|
-
const [
|
|
363
|
-
const [
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
217
|
+
const [saveDir, setSaveDir] = useState2(null);
|
|
218
|
+
const [picking, setPicking] = useState2(false);
|
|
219
|
+
useEffect(() => {
|
|
220
|
+
fetch("/__afterbefore/config").then((r) => r.json()).then((data) => setSaveDir(data.saveDir)).catch(() => {
|
|
221
|
+
});
|
|
222
|
+
}, []);
|
|
223
|
+
const handlePickFolder = async () => {
|
|
224
|
+
setPicking(true);
|
|
225
|
+
try {
|
|
226
|
+
const res = await fetch("/__afterbefore/pick-folder", { method: "POST" });
|
|
227
|
+
const data = await res.json();
|
|
228
|
+
if (data.folder) {
|
|
229
|
+
await fetch("/__afterbefore/config", {
|
|
230
|
+
method: "POST",
|
|
231
|
+
headers: { "Content-Type": "application/json" },
|
|
232
|
+
body: JSON.stringify({ saveDir: data.folder })
|
|
233
|
+
});
|
|
234
|
+
setSaveDir(data.folder);
|
|
380
235
|
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
236
|
+
} catch {
|
|
237
|
+
} finally {
|
|
238
|
+
setPicking(false);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
const shortDir = saveDir ? saveDir.replace(/^\/Users\/[^/]+/, "~") : "~/Desktop";
|
|
242
|
+
return /* @__PURE__ */ jsxs(
|
|
386
243
|
"div",
|
|
387
244
|
{
|
|
388
|
-
"data-afterbefore": "true",
|
|
389
245
|
style: {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
transform: "translateX(-50%)",
|
|
394
|
-
zIndex: 2147483647,
|
|
395
|
-
display: "flex",
|
|
396
|
-
alignItems: "center",
|
|
397
|
-
gap: 10,
|
|
398
|
-
flexWrap: "wrap",
|
|
399
|
-
justifyContent: "center",
|
|
400
|
-
maxWidth: "min(calc(100vw - 32px), 1120px)",
|
|
246
|
+
minWidth: 300,
|
|
247
|
+
padding: "12px 16px",
|
|
248
|
+
borderRadius: 12,
|
|
401
249
|
background: "rgb(32, 32, 36)",
|
|
402
|
-
border: "
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
|
406
|
-
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
250
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
251
|
+
boxShadow: "0 14px 36px rgba(0, 0, 0, 0.32)",
|
|
252
|
+
...style
|
|
407
253
|
},
|
|
408
|
-
children:
|
|
409
|
-
/* @__PURE__ */
|
|
410
|
-
/* @__PURE__ */
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
254
|
+
children: [
|
|
255
|
+
/* @__PURE__ */ jsx(SettingsHeader, { onClose }),
|
|
256
|
+
/* @__PURE__ */ jsx(SettingsDivider, {}),
|
|
257
|
+
selectedMode === "component" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
258
|
+
/* @__PURE__ */ jsx(
|
|
259
|
+
SettingsRow,
|
|
260
|
+
{
|
|
261
|
+
title: "Frame",
|
|
262
|
+
description: "Wrap in a sized canvas with background",
|
|
263
|
+
control: /* @__PURE__ */ jsx(
|
|
264
|
+
ToggleSwitch,
|
|
265
|
+
{
|
|
266
|
+
enabled: frameSettings.enabled,
|
|
267
|
+
onChange: () => onFrameSettingsChange({ ...frameSettings, enabled: !frameSettings.enabled })
|
|
268
|
+
}
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
),
|
|
272
|
+
frameSettings.enabled && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
273
|
+
/* @__PURE__ */ jsx(SettingsDivider, {}),
|
|
274
|
+
/* @__PURE__ */ jsx(
|
|
275
|
+
FrameSizeControl,
|
|
276
|
+
{
|
|
277
|
+
size: frameSettings.size,
|
|
278
|
+
onChange: (size) => onFrameSettingsChange({ ...frameSettings, size })
|
|
423
279
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
),
|
|
443
|
-
/* @__PURE__ */ jsx2(
|
|
444
|
-
HistoryButton,
|
|
280
|
+
),
|
|
281
|
+
/* @__PURE__ */ jsx(SettingsDivider, {}),
|
|
282
|
+
/* @__PURE__ */ jsx(
|
|
283
|
+
FrameBackgroundControl,
|
|
284
|
+
{
|
|
285
|
+
bgType: frameSettings.bgType,
|
|
286
|
+
bgColor: frameSettings.bgColor,
|
|
287
|
+
bgImage: frameSettings.bgImage,
|
|
288
|
+
frameSize: frameSettings.size,
|
|
289
|
+
onChange: (updates) => onFrameSettingsChange({ ...frameSettings, ...updates })
|
|
290
|
+
}
|
|
291
|
+
)
|
|
292
|
+
] }),
|
|
293
|
+
/* @__PURE__ */ jsx(SettingsDivider, {})
|
|
294
|
+
] }),
|
|
295
|
+
/* @__PURE__ */ jsx(
|
|
296
|
+
SettingsRow,
|
|
445
297
|
{
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
298
|
+
title: "Save Location",
|
|
299
|
+
description: /* @__PURE__ */ jsx(
|
|
300
|
+
"span",
|
|
301
|
+
{
|
|
302
|
+
style: {
|
|
303
|
+
overflow: "hidden",
|
|
304
|
+
textOverflow: "ellipsis",
|
|
305
|
+
whiteSpace: "nowrap",
|
|
306
|
+
display: "block"
|
|
307
|
+
},
|
|
308
|
+
title: shortDir,
|
|
309
|
+
children: shortDir
|
|
310
|
+
}
|
|
311
|
+
),
|
|
312
|
+
control: /* @__PURE__ */ jsx(SmallButton, { onClick: handlePickFolder, children: picking ? "..." : "Change" })
|
|
451
313
|
}
|
|
452
314
|
)
|
|
453
|
-
]
|
|
315
|
+
]
|
|
454
316
|
}
|
|
455
317
|
);
|
|
456
318
|
}
|
|
457
|
-
function
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}) {
|
|
463
|
-
const [hovered, setHovered] = useState3(false);
|
|
464
|
-
return /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
|
|
465
|
-
tooltip && hovered && /* @__PURE__ */ jsx2(
|
|
466
|
-
"div",
|
|
467
|
-
{
|
|
468
|
-
style: {
|
|
469
|
-
position: "absolute",
|
|
470
|
-
left: "50%",
|
|
471
|
-
bottom: "calc(100% + 16px)",
|
|
472
|
-
transform: "translateX(-50%)",
|
|
473
|
-
background: "rgb(32, 32, 36)",
|
|
474
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
475
|
-
borderRadius: 6,
|
|
476
|
-
padding: "3px 8px",
|
|
477
|
-
color: "rgba(255, 255, 255, 0.88)",
|
|
478
|
-
fontSize: 11,
|
|
479
|
-
whiteSpace: "nowrap",
|
|
480
|
-
boxShadow: "0 8px 28px rgba(0, 0, 0, 0.28)",
|
|
481
|
-
pointerEvents: "none"
|
|
482
|
-
},
|
|
483
|
-
children: tooltip
|
|
484
|
-
}
|
|
485
|
-
),
|
|
486
|
-
/* @__PURE__ */ jsx2(
|
|
319
|
+
function SettingsHeader({ onClose }) {
|
|
320
|
+
const [hovered, setHovered] = useState2(false);
|
|
321
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", paddingBottom: 8 }, children: [
|
|
322
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 14, fontWeight: 600, color: "rgba(255, 255, 255, 0.92)" }, children: "Settings" }),
|
|
323
|
+
/* @__PURE__ */ jsx(
|
|
487
324
|
"button",
|
|
488
325
|
{
|
|
489
|
-
onClick,
|
|
326
|
+
onClick: onClose,
|
|
490
327
|
onMouseEnter: () => setHovered(true),
|
|
491
328
|
onMouseLeave: () => setHovered(false),
|
|
492
329
|
style: {
|
|
493
|
-
width:
|
|
494
|
-
height:
|
|
495
|
-
borderRadius:
|
|
330
|
+
width: 24,
|
|
331
|
+
height: 24,
|
|
332
|
+
borderRadius: 6,
|
|
496
333
|
border: "none",
|
|
497
|
-
background:
|
|
334
|
+
background: hovered ? "rgba(255, 255, 255, 0.1)" : "transparent",
|
|
498
335
|
display: "flex",
|
|
499
336
|
alignItems: "center",
|
|
500
337
|
justifyContent: "center",
|
|
501
338
|
cursor: "pointer",
|
|
339
|
+
color: hovered ? "rgba(255, 255, 255, 0.8)" : "rgba(255, 255, 255, 0.46)",
|
|
502
340
|
padding: 0,
|
|
503
|
-
color: active || hovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)",
|
|
504
341
|
transition: "background 0.12s ease, color 0.12s ease"
|
|
505
342
|
},
|
|
506
|
-
children
|
|
343
|
+
children: /* @__PURE__ */ jsx(X, { size: 14, strokeWidth: 2 })
|
|
507
344
|
}
|
|
508
345
|
)
|
|
509
346
|
] });
|
|
510
347
|
}
|
|
511
|
-
function
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
frameSettings,
|
|
516
|
-
onFrameSettingsChange
|
|
348
|
+
function SettingsRow({
|
|
349
|
+
title,
|
|
350
|
+
description,
|
|
351
|
+
control
|
|
517
352
|
}) {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
})
|
|
524
|
-
}, [open]);
|
|
525
|
-
const handlePickFolder = async () => {
|
|
526
|
-
setPicking(true);
|
|
527
|
-
try {
|
|
528
|
-
const res = await fetch("/__afterbefore/pick-folder", { method: "POST" });
|
|
529
|
-
const data = await res.json();
|
|
530
|
-
if (data.folder) {
|
|
531
|
-
await fetch("/__afterbefore/config", {
|
|
532
|
-
method: "POST",
|
|
533
|
-
headers: { "Content-Type": "application/json" },
|
|
534
|
-
body: JSON.stringify({ saveDir: data.folder })
|
|
535
|
-
});
|
|
536
|
-
setSaveDir(data.folder);
|
|
537
|
-
}
|
|
538
|
-
} catch {
|
|
539
|
-
} finally {
|
|
540
|
-
setPicking(false);
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
const shortDir = saveDir ? saveDir.replace(/^\/Users\/[^/]+/, "~") : "~/Desktop";
|
|
544
|
-
return /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
|
|
545
|
-
/* @__PURE__ */ jsx2(IconButton, { active: open, tooltip: !open ? "Settings" : void 0, onClick, children: /* @__PURE__ */ jsx2(Settings, { size: 16, strokeWidth: 1.7 }) }),
|
|
546
|
-
open && /* @__PURE__ */ jsxs2(
|
|
547
|
-
"div",
|
|
548
|
-
{
|
|
549
|
-
style: {
|
|
550
|
-
position: "absolute",
|
|
551
|
-
left: "50%",
|
|
552
|
-
bottom: "calc(100% + 12px)",
|
|
553
|
-
transform: "translateX(-50%)",
|
|
554
|
-
minWidth: 260,
|
|
555
|
-
padding: "10px 12px",
|
|
556
|
-
borderRadius: 12,
|
|
557
|
-
background: "rgb(32, 32, 36)",
|
|
558
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
559
|
-
boxShadow: "0 14px 36px rgba(0, 0, 0, 0.32)"
|
|
560
|
-
},
|
|
561
|
-
children: [
|
|
562
|
-
/* @__PURE__ */ jsx2(
|
|
563
|
-
"div",
|
|
564
|
-
{
|
|
565
|
-
style: {
|
|
566
|
-
fontSize: 11,
|
|
567
|
-
color: "rgba(255, 255, 255, 0.46)",
|
|
568
|
-
letterSpacing: "0.03em",
|
|
569
|
-
textTransform: "uppercase",
|
|
570
|
-
marginBottom: 10
|
|
571
|
-
},
|
|
572
|
-
children: "Settings"
|
|
573
|
-
}
|
|
574
|
-
),
|
|
575
|
-
selectedMode === "component" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
576
|
-
/* @__PURE__ */ jsx2(
|
|
577
|
-
ToggleRow,
|
|
578
|
-
{
|
|
579
|
-
icon: /* @__PURE__ */ jsx2(Frame, { size: 15, strokeWidth: 1.8 }),
|
|
580
|
-
label: "Frame",
|
|
581
|
-
hint: "Wrap component in a sized canvas with background",
|
|
582
|
-
enabled: frameSettings.enabled,
|
|
583
|
-
onChange: () => onFrameSettingsChange({ ...frameSettings, enabled: !frameSettings.enabled })
|
|
584
|
-
}
|
|
585
|
-
),
|
|
586
|
-
frameSettings.enabled && /* @__PURE__ */ jsxs2("div", { style: { marginTop: 8, display: "flex", flexDirection: "column", gap: 10 }, children: [
|
|
587
|
-
/* @__PURE__ */ jsx2(
|
|
588
|
-
FrameSizeControl,
|
|
589
|
-
{
|
|
590
|
-
size: frameSettings.size,
|
|
591
|
-
onChange: (size) => onFrameSettingsChange({ ...frameSettings, size })
|
|
592
|
-
}
|
|
593
|
-
),
|
|
594
|
-
/* @__PURE__ */ jsx2(
|
|
595
|
-
FrameBackgroundControl,
|
|
596
|
-
{
|
|
597
|
-
bgType: frameSettings.bgType,
|
|
598
|
-
bgColor: frameSettings.bgColor,
|
|
599
|
-
bgImage: frameSettings.bgImage,
|
|
600
|
-
frameSize: frameSettings.size,
|
|
601
|
-
onChange: (updates) => onFrameSettingsChange({ ...frameSettings, ...updates })
|
|
602
|
-
}
|
|
603
|
-
)
|
|
604
|
-
] })
|
|
605
|
-
] }),
|
|
606
|
-
selectedMode === "component" && /* @__PURE__ */ jsx2("div", { style: { height: 1, background: "rgba(255,255,255,0.08)", margin: "8px 0" } }),
|
|
607
|
-
/* @__PURE__ */ jsx2(
|
|
608
|
-
SaveLocationRow,
|
|
609
|
-
{
|
|
610
|
-
dir: shortDir,
|
|
611
|
-
picking,
|
|
612
|
-
onPick: handlePickFolder
|
|
613
|
-
}
|
|
614
|
-
)
|
|
615
|
-
]
|
|
616
|
-
}
|
|
617
|
-
)
|
|
353
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, padding: "14px 0" }, children: [
|
|
354
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 3, flex: 1, minWidth: 0 }, children: [
|
|
355
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "rgba(255, 255, 255, 0.92)" }, children: title }),
|
|
356
|
+
description && /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: "rgba(255, 255, 255, 0.42)", lineHeight: 1.3 }, children: description })
|
|
357
|
+
] }),
|
|
358
|
+
/* @__PURE__ */ jsx("div", { style: { flexShrink: 0 }, children: control })
|
|
618
359
|
] });
|
|
619
360
|
}
|
|
361
|
+
function SettingsDivider() {
|
|
362
|
+
return /* @__PURE__ */ jsx("div", { style: { height: 1, background: "rgba(255, 255, 255, 0.08)" } });
|
|
363
|
+
}
|
|
364
|
+
function ToggleSwitch({
|
|
365
|
+
enabled,
|
|
366
|
+
onChange
|
|
367
|
+
}) {
|
|
368
|
+
return /* @__PURE__ */ jsx(
|
|
369
|
+
"button",
|
|
370
|
+
{
|
|
371
|
+
type: "button",
|
|
372
|
+
onClick: onChange,
|
|
373
|
+
style: {
|
|
374
|
+
width: 38,
|
|
375
|
+
height: 22,
|
|
376
|
+
borderRadius: 999,
|
|
377
|
+
border: "none",
|
|
378
|
+
background: enabled ? "#38bdf8" : "rgba(255, 255, 255, 0.18)",
|
|
379
|
+
position: "relative",
|
|
380
|
+
cursor: "pointer",
|
|
381
|
+
padding: 0,
|
|
382
|
+
flexShrink: 0,
|
|
383
|
+
transition: "background 0.12s ease"
|
|
384
|
+
},
|
|
385
|
+
children: /* @__PURE__ */ jsx(
|
|
386
|
+
"span",
|
|
387
|
+
{
|
|
388
|
+
style: {
|
|
389
|
+
position: "absolute",
|
|
390
|
+
top: 2,
|
|
391
|
+
left: enabled ? 18 : 2,
|
|
392
|
+
width: 18,
|
|
393
|
+
height: 18,
|
|
394
|
+
borderRadius: "50%",
|
|
395
|
+
background: "#fff",
|
|
396
|
+
transition: "left 0.12s ease"
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
)
|
|
400
|
+
}
|
|
401
|
+
);
|
|
402
|
+
}
|
|
620
403
|
function FrameSizeControl({
|
|
621
404
|
size,
|
|
622
405
|
onChange
|
|
623
406
|
}) {
|
|
624
|
-
const [sizeOpen, setSizeOpen] =
|
|
407
|
+
const [sizeOpen, setSizeOpen] = useState2(false);
|
|
625
408
|
const currentPreset = FRAME_SIZE_PRESETS.find((p) => p.w === size.w && p.h === size.h);
|
|
626
409
|
const isCustom = !currentPreset;
|
|
627
|
-
return /* @__PURE__ */
|
|
628
|
-
/* @__PURE__ */
|
|
629
|
-
|
|
630
|
-
|
|
410
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "14px 0" }, children: [
|
|
411
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16 }, children: [
|
|
412
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 3 }, children: [
|
|
413
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "rgba(255, 255, 255, 0.92)" }, children: "Size" }),
|
|
414
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: "rgba(255, 255, 255, 0.42)", lineHeight: 1.3 }, children: "Set the frame dimensions" })
|
|
415
|
+
] }),
|
|
416
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
417
|
+
/* @__PURE__ */ jsxs(
|
|
418
|
+
"button",
|
|
419
|
+
{
|
|
420
|
+
onClick: () => setSizeOpen((prev) => !prev),
|
|
421
|
+
style: {
|
|
422
|
+
display: "flex",
|
|
423
|
+
alignItems: "center",
|
|
424
|
+
gap: 6,
|
|
425
|
+
height: 30,
|
|
426
|
+
padding: "0 10px",
|
|
427
|
+
borderRadius: 7,
|
|
428
|
+
border: "1px solid rgba(255,255,255,0.1)",
|
|
429
|
+
background: "rgba(255,255,255,0.07)",
|
|
430
|
+
color: "rgba(255,255,255,0.88)",
|
|
431
|
+
cursor: "pointer",
|
|
432
|
+
fontSize: 12,
|
|
433
|
+
fontFamily: "inherit",
|
|
434
|
+
whiteSpace: "nowrap"
|
|
435
|
+
},
|
|
436
|
+
children: [
|
|
437
|
+
currentPreset ? currentPreset.label : "Custom",
|
|
438
|
+
/* @__PURE__ */ jsx(ChevronDown, { size: 12, strokeWidth: 2 })
|
|
439
|
+
]
|
|
440
|
+
}
|
|
441
|
+
),
|
|
442
|
+
sizeOpen && /* @__PURE__ */ jsx(
|
|
443
|
+
"div",
|
|
444
|
+
{
|
|
445
|
+
style: {
|
|
446
|
+
position: "absolute",
|
|
447
|
+
bottom: "calc(100% + 4px)",
|
|
448
|
+
right: 0,
|
|
449
|
+
minWidth: 180,
|
|
450
|
+
background: "rgb(32, 32, 36)",
|
|
451
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
452
|
+
borderRadius: 8,
|
|
453
|
+
padding: "4px 0",
|
|
454
|
+
boxShadow: "0 10px 30px rgba(0, 0, 0, 0.3)",
|
|
455
|
+
zIndex: 1
|
|
456
|
+
},
|
|
457
|
+
children: FRAME_SIZE_PRESETS.map((preset) => /* @__PURE__ */ jsxs(
|
|
458
|
+
DropItem,
|
|
459
|
+
{
|
|
460
|
+
active: !isCustom && preset.w === size.w && preset.h === size.h,
|
|
461
|
+
onClick: () => {
|
|
462
|
+
onChange({ w: preset.w, h: preset.h });
|
|
463
|
+
setSizeOpen(false);
|
|
464
|
+
},
|
|
465
|
+
children: [
|
|
466
|
+
/* @__PURE__ */ jsx("span", { children: preset.label }),
|
|
467
|
+
/* @__PURE__ */ jsx("span", { style: { marginLeft: 6, fontSize: 10, color: "rgba(255,255,255,0.34)" }, children: preset.hint })
|
|
468
|
+
]
|
|
469
|
+
},
|
|
470
|
+
preset.label
|
|
471
|
+
))
|
|
472
|
+
}
|
|
473
|
+
)
|
|
474
|
+
] })
|
|
475
|
+
] }),
|
|
476
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4, marginTop: 10 }, children: [
|
|
477
|
+
/* @__PURE__ */ jsx(
|
|
631
478
|
NumInput,
|
|
632
479
|
{
|
|
633
480
|
value: size.w,
|
|
@@ -637,8 +484,8 @@ function FrameSizeControl({
|
|
|
637
484
|
}
|
|
638
485
|
}
|
|
639
486
|
),
|
|
640
|
-
/* @__PURE__ */
|
|
641
|
-
/* @__PURE__ */
|
|
487
|
+
/* @__PURE__ */ jsx(StaticText, { children: "x" }),
|
|
488
|
+
/* @__PURE__ */ jsx(
|
|
642
489
|
NumInput,
|
|
643
490
|
{
|
|
644
491
|
value: size.h,
|
|
@@ -648,66 +495,6 @@ function FrameSizeControl({
|
|
|
648
495
|
}
|
|
649
496
|
}
|
|
650
497
|
)
|
|
651
|
-
] }),
|
|
652
|
-
/* @__PURE__ */ jsxs2("div", { style: { position: "relative", marginTop: 6 }, children: [
|
|
653
|
-
/* @__PURE__ */ jsxs2(
|
|
654
|
-
"button",
|
|
655
|
-
{
|
|
656
|
-
onClick: () => setSizeOpen((prev) => !prev),
|
|
657
|
-
style: {
|
|
658
|
-
display: "flex",
|
|
659
|
-
alignItems: "center",
|
|
660
|
-
justifyContent: "space-between",
|
|
661
|
-
gap: 6,
|
|
662
|
-
width: "100%",
|
|
663
|
-
height: 30,
|
|
664
|
-
padding: "0 8px",
|
|
665
|
-
borderRadius: 7,
|
|
666
|
-
border: "1px solid rgba(255,255,255,0.1)",
|
|
667
|
-
background: "rgba(255,255,255,0.07)",
|
|
668
|
-
color: "rgba(255,255,255,0.88)",
|
|
669
|
-
cursor: "pointer",
|
|
670
|
-
fontSize: 12,
|
|
671
|
-
fontFamily: "inherit"
|
|
672
|
-
},
|
|
673
|
-
children: [
|
|
674
|
-
currentPreset ? currentPreset.label : "Custom",
|
|
675
|
-
/* @__PURE__ */ jsx2(ChevronDown, { size: 12, strokeWidth: 2 })
|
|
676
|
-
]
|
|
677
|
-
}
|
|
678
|
-
),
|
|
679
|
-
sizeOpen && /* @__PURE__ */ jsx2(
|
|
680
|
-
"div",
|
|
681
|
-
{
|
|
682
|
-
style: {
|
|
683
|
-
position: "absolute",
|
|
684
|
-
bottom: "calc(100% + 4px)",
|
|
685
|
-
left: 0,
|
|
686
|
-
right: 0,
|
|
687
|
-
background: "rgb(32, 32, 36)",
|
|
688
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
689
|
-
borderRadius: 8,
|
|
690
|
-
padding: "4px 0",
|
|
691
|
-
boxShadow: "0 10px 30px rgba(0, 0, 0, 0.3)",
|
|
692
|
-
zIndex: 1
|
|
693
|
-
},
|
|
694
|
-
children: FRAME_SIZE_PRESETS.map((preset) => /* @__PURE__ */ jsxs2(
|
|
695
|
-
DropItem,
|
|
696
|
-
{
|
|
697
|
-
active: !isCustom && preset.w === size.w && preset.h === size.h,
|
|
698
|
-
onClick: () => {
|
|
699
|
-
onChange({ w: preset.w, h: preset.h });
|
|
700
|
-
setSizeOpen(false);
|
|
701
|
-
},
|
|
702
|
-
children: [
|
|
703
|
-
/* @__PURE__ */ jsx2("span", { children: preset.label }),
|
|
704
|
-
/* @__PURE__ */ jsx2("span", { style: { marginLeft: 6, fontSize: 10, color: "rgba(255,255,255,0.34)" }, children: preset.hint })
|
|
705
|
-
]
|
|
706
|
-
},
|
|
707
|
-
preset.label
|
|
708
|
-
))
|
|
709
|
-
}
|
|
710
|
-
)
|
|
711
498
|
] })
|
|
712
499
|
] });
|
|
713
500
|
}
|
|
@@ -718,7 +505,7 @@ function FrameBackgroundControl({
|
|
|
718
505
|
frameSize,
|
|
719
506
|
onChange
|
|
720
507
|
}) {
|
|
721
|
-
const fileInputRef =
|
|
508
|
+
const fileInputRef = useRef(null);
|
|
722
509
|
const handleFileSelect = (e) => {
|
|
723
510
|
const file = e.target.files?.[0];
|
|
724
511
|
if (!file) return;
|
|
@@ -736,40 +523,45 @@ function FrameBackgroundControl({
|
|
|
736
523
|
reader.readAsDataURL(file);
|
|
737
524
|
e.target.value = "";
|
|
738
525
|
};
|
|
739
|
-
return /* @__PURE__ */
|
|
740
|
-
/* @__PURE__ */
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
"
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
"
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
526
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "14px 0" }, children: [
|
|
527
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16 }, children: [
|
|
528
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 3 }, children: [
|
|
529
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "rgba(255, 255, 255, 0.92)" }, children: "Background" }),
|
|
530
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: "rgba(255, 255, 255, 0.42)", lineHeight: 1.3 }, children: "Frame background color or image" })
|
|
531
|
+
] }),
|
|
532
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 2, flexShrink: 0 }, children: [
|
|
533
|
+
/* @__PURE__ */ jsxs(
|
|
534
|
+
SegmentButton,
|
|
535
|
+
{
|
|
536
|
+
active: bgType === "color",
|
|
537
|
+
onClick: () => onChange({ bgType: "color" }),
|
|
538
|
+
style: { borderRadius: "6px 0 0 6px" },
|
|
539
|
+
children: [
|
|
540
|
+
/* @__PURE__ */ jsx(Palette, { size: 12, strokeWidth: 2 }),
|
|
541
|
+
"Color"
|
|
542
|
+
]
|
|
543
|
+
}
|
|
544
|
+
),
|
|
545
|
+
/* @__PURE__ */ jsxs(
|
|
546
|
+
SegmentButton,
|
|
547
|
+
{
|
|
548
|
+
active: bgType === "image",
|
|
549
|
+
onClick: () => onChange({ bgType: "image" }),
|
|
550
|
+
style: { borderRadius: "0 6px 6px 0" },
|
|
551
|
+
children: [
|
|
552
|
+
/* @__PURE__ */ jsx(ImageIcon, { size: 12, strokeWidth: 2 }),
|
|
553
|
+
"Image"
|
|
554
|
+
]
|
|
555
|
+
}
|
|
556
|
+
)
|
|
557
|
+
] })
|
|
766
558
|
] }),
|
|
767
|
-
bgType === "color" && /* @__PURE__ */
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
/* @__PURE__ */
|
|
559
|
+
bgType === "color" && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 10 }, children: [
|
|
560
|
+
/* @__PURE__ */ jsx(ColorSwatch, { color: bgColor, onChange: (c) => onChange({ bgColor: c }) }),
|
|
561
|
+
/* @__PURE__ */ jsx(HexInput, { value: bgColor, onChange: (c) => onChange({ bgColor: c }) })
|
|
770
562
|
] }),
|
|
771
|
-
bgType === "image" && /* @__PURE__ */
|
|
772
|
-
/* @__PURE__ */
|
|
563
|
+
bgType === "image" && /* @__PURE__ */ jsxs("div", { style: { marginTop: 10 }, children: [
|
|
564
|
+
/* @__PURE__ */ jsx(
|
|
773
565
|
"input",
|
|
774
566
|
{
|
|
775
567
|
ref: fileInputRef,
|
|
@@ -779,8 +571,8 @@ function FrameBackgroundControl({
|
|
|
779
571
|
style: { display: "none" }
|
|
780
572
|
}
|
|
781
573
|
),
|
|
782
|
-
bgImage ? /* @__PURE__ */
|
|
783
|
-
/* @__PURE__ */
|
|
574
|
+
bgImage ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
575
|
+
/* @__PURE__ */ jsx(
|
|
784
576
|
"img",
|
|
785
577
|
{
|
|
786
578
|
src: bgImage,
|
|
@@ -794,38 +586,25 @@ function FrameBackgroundControl({
|
|
|
794
586
|
}
|
|
795
587
|
}
|
|
796
588
|
),
|
|
797
|
-
/* @__PURE__ */
|
|
798
|
-
/* @__PURE__ */
|
|
589
|
+
/* @__PURE__ */ jsxs(SmallButton, { onClick: () => fileInputRef.current?.click(), children: [
|
|
590
|
+
/* @__PURE__ */ jsx(Upload, { size: 11, strokeWidth: 2 }),
|
|
799
591
|
"Replace"
|
|
800
592
|
] }),
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
] }) : /* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
593
|
+
/* @__PURE__ */ jsx(SmallButton, { onClick: () => onChange({ bgImage: null }), children: /* @__PURE__ */ jsx(Trash2, { size: 11, strokeWidth: 2 }) })
|
|
594
|
+
] }) : /* @__PURE__ */ jsxs(SmallButton, { onClick: () => fileInputRef.current?.click(), children: [
|
|
595
|
+
/* @__PURE__ */ jsx(Upload, { size: 11, strokeWidth: 2 }),
|
|
804
596
|
"Upload image"
|
|
805
597
|
] })
|
|
806
598
|
] })
|
|
807
599
|
] });
|
|
808
600
|
}
|
|
809
|
-
function SettingsLabel({ children }) {
|
|
810
|
-
return /* @__PURE__ */ jsx2(
|
|
811
|
-
"div",
|
|
812
|
-
{
|
|
813
|
-
style: {
|
|
814
|
-
fontSize: 11,
|
|
815
|
-
color: "rgba(255, 255, 255, 0.42)",
|
|
816
|
-
letterSpacing: "0.02em"
|
|
817
|
-
},
|
|
818
|
-
children
|
|
819
|
-
}
|
|
820
|
-
);
|
|
821
|
-
}
|
|
822
601
|
function SegmentButton({
|
|
823
602
|
children,
|
|
824
603
|
active,
|
|
825
604
|
onClick,
|
|
826
605
|
style
|
|
827
606
|
}) {
|
|
828
|
-
return /* @__PURE__ */
|
|
607
|
+
return /* @__PURE__ */ jsx(
|
|
829
608
|
"button",
|
|
830
609
|
{
|
|
831
610
|
onClick,
|
|
@@ -852,9 +631,9 @@ function ColorSwatch({
|
|
|
852
631
|
color,
|
|
853
632
|
onChange
|
|
854
633
|
}) {
|
|
855
|
-
const inputRef =
|
|
856
|
-
return /* @__PURE__ */
|
|
857
|
-
/* @__PURE__ */
|
|
634
|
+
const inputRef = useRef(null);
|
|
635
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
636
|
+
/* @__PURE__ */ jsx(
|
|
858
637
|
"button",
|
|
859
638
|
{
|
|
860
639
|
onClick: () => inputRef.current?.click(),
|
|
@@ -869,7 +648,7 @@ function ColorSwatch({
|
|
|
869
648
|
}
|
|
870
649
|
}
|
|
871
650
|
),
|
|
872
|
-
/* @__PURE__ */
|
|
651
|
+
/* @__PURE__ */ jsx(
|
|
873
652
|
"input",
|
|
874
653
|
{
|
|
875
654
|
ref: inputRef,
|
|
@@ -893,8 +672,8 @@ function SmallButton({
|
|
|
893
672
|
children,
|
|
894
673
|
onClick
|
|
895
674
|
}) {
|
|
896
|
-
const [hovered, setHovered] =
|
|
897
|
-
return /* @__PURE__ */
|
|
675
|
+
const [hovered, setHovered] = useState2(false);
|
|
676
|
+
return /* @__PURE__ */ jsx(
|
|
898
677
|
"button",
|
|
899
678
|
{
|
|
900
679
|
onClick,
|
|
@@ -918,6 +697,141 @@ function SmallButton({
|
|
|
918
697
|
}
|
|
919
698
|
);
|
|
920
699
|
}
|
|
700
|
+
function NumInput({
|
|
701
|
+
value,
|
|
702
|
+
onChange
|
|
703
|
+
}) {
|
|
704
|
+
const [editing, setEditing] = useState2(false);
|
|
705
|
+
const [text, setText] = useState2(String(value));
|
|
706
|
+
useEffect(() => {
|
|
707
|
+
if (!editing) {
|
|
708
|
+
setText(String(value));
|
|
709
|
+
}
|
|
710
|
+
}, [editing, value]);
|
|
711
|
+
return /* @__PURE__ */ jsx(
|
|
712
|
+
"input",
|
|
713
|
+
{
|
|
714
|
+
type: "text",
|
|
715
|
+
value: editing ? text : String(value),
|
|
716
|
+
onFocus: () => {
|
|
717
|
+
setEditing(true);
|
|
718
|
+
setText(String(value));
|
|
719
|
+
},
|
|
720
|
+
onBlur: () => {
|
|
721
|
+
setEditing(false);
|
|
722
|
+
onChange(text);
|
|
723
|
+
},
|
|
724
|
+
onChange: (e) => setText(e.target.value),
|
|
725
|
+
onKeyDown: (e) => {
|
|
726
|
+
if (e.key === "Enter") {
|
|
727
|
+
e.target.blur();
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
style: {
|
|
731
|
+
width: 54,
|
|
732
|
+
padding: "4px 6px",
|
|
733
|
+
background: "rgba(255, 255, 255, 0.07)",
|
|
734
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
735
|
+
borderRadius: 7,
|
|
736
|
+
color: "rgba(255, 255, 255, 0.9)",
|
|
737
|
+
fontSize: 12,
|
|
738
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
739
|
+
textAlign: "center",
|
|
740
|
+
outline: "none"
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
function HexInput({
|
|
746
|
+
value,
|
|
747
|
+
onChange
|
|
748
|
+
}) {
|
|
749
|
+
const [editing, setEditing] = useState2(false);
|
|
750
|
+
const [text, setText] = useState2(value);
|
|
751
|
+
useEffect(() => {
|
|
752
|
+
if (!editing) {
|
|
753
|
+
setText(value);
|
|
754
|
+
}
|
|
755
|
+
}, [editing, value]);
|
|
756
|
+
const commit = (raw) => {
|
|
757
|
+
const hex = raw.startsWith("#") ? raw : `#${raw}`;
|
|
758
|
+
if (/^#[0-9a-fA-F]{6}$/.test(hex)) {
|
|
759
|
+
onChange(hex);
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
return /* @__PURE__ */ jsx(
|
|
763
|
+
"input",
|
|
764
|
+
{
|
|
765
|
+
type: "text",
|
|
766
|
+
value: editing ? text : value,
|
|
767
|
+
onFocus: () => {
|
|
768
|
+
setEditing(true);
|
|
769
|
+
setText(value);
|
|
770
|
+
},
|
|
771
|
+
onBlur: () => {
|
|
772
|
+
setEditing(false);
|
|
773
|
+
commit(text);
|
|
774
|
+
},
|
|
775
|
+
onChange: (e) => setText(e.target.value),
|
|
776
|
+
onKeyDown: (e) => {
|
|
777
|
+
if (e.key === "Enter") {
|
|
778
|
+
e.target.blur();
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
style: {
|
|
782
|
+
width: 72,
|
|
783
|
+
padding: "4px 6px",
|
|
784
|
+
background: "rgba(255, 255, 255, 0.07)",
|
|
785
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
786
|
+
borderRadius: 7,
|
|
787
|
+
color: "rgba(255, 255, 255, 0.9)",
|
|
788
|
+
fontSize: 12,
|
|
789
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
790
|
+
textAlign: "left",
|
|
791
|
+
outline: "none"
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
function StaticText({ children }) {
|
|
797
|
+
return /* @__PURE__ */ jsx(
|
|
798
|
+
"span",
|
|
799
|
+
{
|
|
800
|
+
style: {
|
|
801
|
+
fontSize: 11,
|
|
802
|
+
color: "rgba(255,255,255,0.35)",
|
|
803
|
+
minWidth: 8,
|
|
804
|
+
textAlign: "center"
|
|
805
|
+
},
|
|
806
|
+
children
|
|
807
|
+
}
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
function DropItem({
|
|
811
|
+
children,
|
|
812
|
+
onClick,
|
|
813
|
+
active
|
|
814
|
+
}) {
|
|
815
|
+
return /* @__PURE__ */ jsx(
|
|
816
|
+
"button",
|
|
817
|
+
{
|
|
818
|
+
onClick,
|
|
819
|
+
style: {
|
|
820
|
+
display: "block",
|
|
821
|
+
width: "100%",
|
|
822
|
+
padding: "7px 12px",
|
|
823
|
+
background: active ? "rgba(255, 255, 255, 0.08)" : "transparent",
|
|
824
|
+
border: "none",
|
|
825
|
+
color: "rgba(255, 255, 255, 0.86)",
|
|
826
|
+
textAlign: "left",
|
|
827
|
+
cursor: "pointer",
|
|
828
|
+
fontSize: 13,
|
|
829
|
+
fontFamily: "inherit"
|
|
830
|
+
},
|
|
831
|
+
children
|
|
832
|
+
}
|
|
833
|
+
);
|
|
834
|
+
}
|
|
921
835
|
async function downscaleImage(dataUrl, maxW, maxH) {
|
|
922
836
|
return new Promise((resolve) => {
|
|
923
837
|
const img = new Image();
|
|
@@ -934,261 +848,407 @@ async function downscaleImage(dataUrl, maxW, maxH) {
|
|
|
934
848
|
img.src = dataUrl;
|
|
935
849
|
});
|
|
936
850
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
"
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
children: [
|
|
954
|
-
/* @__PURE__ */ jsx2(FolderOpen, { size: 15, strokeWidth: 1.8, style: { flexShrink: 0 } }),
|
|
955
|
-
/* @__PURE__ */ jsx2(
|
|
956
|
-
"span",
|
|
957
|
-
{
|
|
958
|
-
style: {
|
|
959
|
-
overflow: "hidden",
|
|
960
|
-
textOverflow: "ellipsis",
|
|
961
|
-
whiteSpace: "nowrap",
|
|
962
|
-
flex: 1,
|
|
963
|
-
minWidth: 0
|
|
964
|
-
},
|
|
965
|
-
title: dir,
|
|
966
|
-
children: dir
|
|
967
|
-
}
|
|
968
|
-
),
|
|
969
|
-
/* @__PURE__ */ jsx2(
|
|
970
|
-
"button",
|
|
971
|
-
{
|
|
972
|
-
onClick: onPick,
|
|
973
|
-
disabled: picking,
|
|
974
|
-
onMouseEnter: () => setBtnHovered(true),
|
|
975
|
-
onMouseLeave: () => setBtnHovered(false),
|
|
976
|
-
style: {
|
|
977
|
-
padding: "3px 8px",
|
|
978
|
-
borderRadius: 6,
|
|
979
|
-
border: "1px solid rgba(255,255,255,0.12)",
|
|
980
|
-
background: btnHovered ? "rgba(255,255,255,0.12)" : "rgba(255,255,255,0.06)",
|
|
981
|
-
color: "rgba(255,255,255,0.78)",
|
|
982
|
-
fontSize: 11,
|
|
983
|
-
cursor: picking ? "wait" : "pointer",
|
|
984
|
-
flexShrink: 0,
|
|
985
|
-
fontFamily: "inherit",
|
|
986
|
-
transition: "background 0.12s ease"
|
|
987
|
-
},
|
|
988
|
-
children: picking ? "..." : "Change"
|
|
989
|
-
}
|
|
990
|
-
)
|
|
991
|
-
]
|
|
992
|
-
}
|
|
993
|
-
) });
|
|
851
|
+
|
|
852
|
+
// src/overlay/ui/toolbar.tsx
|
|
853
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
854
|
+
var EDGE_MARGIN = 24;
|
|
855
|
+
var CONTAINER_SIZE = 38;
|
|
856
|
+
function getCornerStyle(corner) {
|
|
857
|
+
switch (corner) {
|
|
858
|
+
case "bottom-right":
|
|
859
|
+
return { bottom: EDGE_MARGIN, right: EDGE_MARGIN };
|
|
860
|
+
case "bottom-left":
|
|
861
|
+
return { bottom: EDGE_MARGIN, left: EDGE_MARGIN };
|
|
862
|
+
case "top-right":
|
|
863
|
+
return { top: EDGE_MARGIN, right: EDGE_MARGIN };
|
|
864
|
+
case "top-left":
|
|
865
|
+
return { top: EDGE_MARGIN, left: EDGE_MARGIN };
|
|
866
|
+
}
|
|
994
867
|
}
|
|
995
|
-
function
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
868
|
+
function isBottomCorner(corner) {
|
|
869
|
+
return corner === "bottom-right" || corner === "bottom-left";
|
|
870
|
+
}
|
|
871
|
+
function isRightCorner(corner) {
|
|
872
|
+
return corner === "bottom-right" || corner === "top-right";
|
|
873
|
+
}
|
|
874
|
+
function snapToCorner(x, y) {
|
|
875
|
+
const cx = window.innerWidth / 2;
|
|
876
|
+
const cy = window.innerHeight / 2;
|
|
877
|
+
if (x < cx) {
|
|
878
|
+
return y < cy ? "top-left" : "bottom-left";
|
|
879
|
+
}
|
|
880
|
+
return y < cy ? "top-right" : "bottom-right";
|
|
881
|
+
}
|
|
882
|
+
var MODES = [
|
|
883
|
+
{ mode: "component", label: "Component", icon: MousePointer2 },
|
|
884
|
+
{ mode: "viewport", label: "Viewport", icon: Monitor },
|
|
885
|
+
{ mode: "fullpage", label: "Full Page", icon: Maximize }
|
|
886
|
+
];
|
|
887
|
+
function Toolbar({
|
|
888
|
+
expanded,
|
|
889
|
+
onToggle,
|
|
890
|
+
phase,
|
|
891
|
+
loading,
|
|
892
|
+
selectedMode,
|
|
893
|
+
onModeChange,
|
|
894
|
+
onCapture,
|
|
895
|
+
onCancel,
|
|
896
|
+
frameSettings,
|
|
897
|
+
onFrameSettingsChange
|
|
1001
898
|
}) {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
899
|
+
const [settingsOpen, setSettingsOpen] = useState3(false);
|
|
900
|
+
const [historyOpen, setHistoryOpen] = useState3(false);
|
|
901
|
+
const [corner, setCorner] = useState3(() => {
|
|
902
|
+
try {
|
|
903
|
+
const stored = localStorage.getItem("ab-toolbar-corner");
|
|
904
|
+
if (stored && ["bottom-right", "bottom-left", "top-right", "top-left"].includes(stored)) {
|
|
905
|
+
return stored;
|
|
906
|
+
}
|
|
907
|
+
} catch {
|
|
908
|
+
}
|
|
909
|
+
return "bottom-right";
|
|
910
|
+
});
|
|
911
|
+
const [dragging, setDragging] = useState3(false);
|
|
912
|
+
const [dragPos, setDragPos] = useState3(null);
|
|
913
|
+
const dragState = useRef2(null);
|
|
914
|
+
const toolbarRef = useRef2(null);
|
|
915
|
+
const [cameraHovered, setCameraHovered] = useState3(false);
|
|
916
|
+
useEffect2(() => {
|
|
917
|
+
if (!expanded) return;
|
|
918
|
+
const onKey = (e) => {
|
|
919
|
+
if (e.target?.tagName === "INPUT") {
|
|
920
|
+
if (e.key === "Escape") {
|
|
921
|
+
e.target.blur();
|
|
922
|
+
}
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
if (e.key === "Escape") {
|
|
926
|
+
if (settingsOpen) {
|
|
927
|
+
setSettingsOpen(false);
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
onCancel();
|
|
931
|
+
} else if (e.key === "Enter") {
|
|
932
|
+
onCapture(selectedMode);
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
document.addEventListener("keydown", onKey);
|
|
936
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
937
|
+
}, [expanded, onCancel, onCapture, selectedMode, settingsOpen]);
|
|
938
|
+
const handleMouseDown = useCallback2(
|
|
939
|
+
(e) => {
|
|
940
|
+
e.preventDefault();
|
|
941
|
+
const el = toolbarRef.current;
|
|
942
|
+
if (!el) return;
|
|
943
|
+
const rect = el.getBoundingClientRect();
|
|
944
|
+
setDragging(true);
|
|
945
|
+
setDragPos({ x: rect.left, y: rect.top });
|
|
946
|
+
dragState.current = {
|
|
947
|
+
dragging: true,
|
|
948
|
+
startX: e.clientX,
|
|
949
|
+
startY: e.clientY,
|
|
950
|
+
origX: rect.left,
|
|
951
|
+
origY: rect.top,
|
|
952
|
+
distance: 0
|
|
953
|
+
};
|
|
954
|
+
},
|
|
955
|
+
[]
|
|
956
|
+
);
|
|
957
|
+
useEffect2(() => {
|
|
958
|
+
const handleMouseMove = (e) => {
|
|
959
|
+
const ds = dragState.current;
|
|
960
|
+
if (!ds || !ds.dragging) return;
|
|
961
|
+
const dx = e.clientX - ds.startX;
|
|
962
|
+
const dy = e.clientY - ds.startY;
|
|
963
|
+
ds.distance = Math.sqrt(dx * dx + dy * dy);
|
|
964
|
+
setDragPos({
|
|
965
|
+
x: ds.origX + dx,
|
|
966
|
+
y: ds.origY + dy
|
|
967
|
+
});
|
|
968
|
+
};
|
|
969
|
+
const handleMouseUp = (e) => {
|
|
970
|
+
const ds = dragState.current;
|
|
971
|
+
if (!ds) return;
|
|
972
|
+
if (ds.distance < 5) {
|
|
973
|
+
onToggle();
|
|
974
|
+
} else {
|
|
975
|
+
const el = toolbarRef.current;
|
|
976
|
+
const w = el?.offsetWidth ?? CONTAINER_SIZE;
|
|
977
|
+
const h = el?.offsetHeight ?? CONTAINER_SIZE;
|
|
978
|
+
const centerX = ds.origX + (e.clientX - ds.startX) + w / 2;
|
|
979
|
+
const centerY = ds.origY + (e.clientY - ds.startY) + h / 2;
|
|
980
|
+
const newCorner = snapToCorner(centerX, centerY);
|
|
981
|
+
setCorner(newCorner);
|
|
982
|
+
try {
|
|
983
|
+
localStorage.setItem("ab-toolbar-corner", newCorner);
|
|
984
|
+
} catch {
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
setDragging(false);
|
|
988
|
+
setDragPos(null);
|
|
989
|
+
dragState.current = null;
|
|
990
|
+
};
|
|
991
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
992
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
993
|
+
return () => {
|
|
994
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
995
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
996
|
+
};
|
|
997
|
+
}, [onToggle]);
|
|
998
|
+
const panelSide = isRightCorner(corner) ? "left" : "right";
|
|
999
|
+
const tooltipSide = panelSide;
|
|
1000
|
+
const bottom = isBottomCorner(corner);
|
|
1001
|
+
const positionStyle = dragging && dragPos ? { left: dragPos.x, top: dragPos.y } : getCornerStyle(corner);
|
|
1002
|
+
const cameraTooltipLabel = expanded ? "Close" : void 0;
|
|
1003
|
+
const cameraTooltipStyle = cameraTooltipLabel ? tooltipSide === "left" ? { right: "calc(100% + 10px)", top: "50%", transform: "translateY(-50%)" } : { left: "calc(100% + 10px)", top: "50%", transform: "translateY(-50%)" } : void 0;
|
|
1004
|
+
const cameraButton = /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
|
|
1005
|
+
cameraTooltipLabel && cameraHovered && !dragging && /* @__PURE__ */ jsx2(
|
|
1006
|
+
"div",
|
|
1007
|
+
{
|
|
1008
|
+
style: {
|
|
1009
|
+
position: "absolute",
|
|
1010
|
+
...cameraTooltipStyle,
|
|
1011
|
+
background: "rgb(32, 32, 36)",
|
|
1012
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1013
|
+
borderRadius: 6,
|
|
1014
|
+
padding: "3px 8px",
|
|
1015
|
+
color: "rgba(255, 255, 255, 0.88)",
|
|
1016
|
+
fontSize: 11,
|
|
1017
|
+
whiteSpace: "nowrap",
|
|
1018
|
+
boxShadow: "0 8px 28px rgba(0, 0, 0, 0.28)",
|
|
1019
|
+
pointerEvents: "none"
|
|
1020
|
+
},
|
|
1021
|
+
children: cameraTooltipLabel
|
|
1022
|
+
}
|
|
1023
|
+
),
|
|
1024
|
+
/* @__PURE__ */ jsxs2(
|
|
1025
|
+
"div",
|
|
1026
|
+
{
|
|
1027
|
+
onMouseDown: handleMouseDown,
|
|
1028
|
+
onMouseEnter: () => setCameraHovered(true),
|
|
1029
|
+
onMouseLeave: () => setCameraHovered(false),
|
|
1030
|
+
style: {
|
|
1031
|
+
width: 36,
|
|
1032
|
+
height: 36,
|
|
1033
|
+
padding: 2,
|
|
1034
|
+
borderRadius: "50%",
|
|
1035
|
+
display: "flex",
|
|
1036
|
+
alignItems: "center",
|
|
1037
|
+
justifyContent: "center",
|
|
1038
|
+
cursor: dragging ? "grabbing" : "pointer",
|
|
1039
|
+
background: expanded && cameraHovered ? "rgba(255, 255, 255, 0.12)" : "transparent",
|
|
1040
|
+
transition: "background 0.12s ease"
|
|
1041
|
+
},
|
|
1042
|
+
children: [
|
|
1043
|
+
/* @__PURE__ */ jsx2(
|
|
1044
|
+
"style",
|
|
1016
1045
|
{
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
},
|
|
1025
|
-
children: [
|
|
1026
|
-
icon,
|
|
1027
|
-
label
|
|
1028
|
-
]
|
|
1046
|
+
dangerouslySetInnerHTML: {
|
|
1047
|
+
__html: `
|
|
1048
|
+
@keyframes ab-spin {
|
|
1049
|
+
0% { transform: rotate(0deg); }
|
|
1050
|
+
100% { transform: rotate(360deg); }
|
|
1051
|
+
}`
|
|
1052
|
+
}
|
|
1029
1053
|
}
|
|
1030
1054
|
),
|
|
1031
|
-
|
|
1032
|
-
|
|
1055
|
+
loading ? /* @__PURE__ */ jsx2(
|
|
1056
|
+
LoaderCircle,
|
|
1033
1057
|
{
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1058
|
+
size: 16,
|
|
1059
|
+
strokeWidth: 2,
|
|
1060
|
+
style: { animation: "ab-spin 0.8s linear infinite", color: "white" }
|
|
1061
|
+
}
|
|
1062
|
+
) : phase === "ready" ? /* @__PURE__ */ jsx2(Check, { size: 16, strokeWidth: 2.6, color: "#4ade80" }) : expanded ? /* @__PURE__ */ jsx2(
|
|
1063
|
+
X2,
|
|
1064
|
+
{
|
|
1065
|
+
size: 16,
|
|
1066
|
+
strokeWidth: 1.7,
|
|
1067
|
+
color: cameraHovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)"
|
|
1068
|
+
}
|
|
1069
|
+
) : /* @__PURE__ */ jsx2(
|
|
1070
|
+
Camera,
|
|
1071
|
+
{
|
|
1072
|
+
size: 16,
|
|
1073
|
+
strokeWidth: 1.9,
|
|
1074
|
+
color: "rgba(255, 255, 255, 0.52)"
|
|
1040
1075
|
}
|
|
1041
1076
|
)
|
|
1042
|
-
]
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
"span",
|
|
1062
|
-
{
|
|
1063
|
-
style: {
|
|
1064
|
-
position: "absolute",
|
|
1065
|
-
top: 2,
|
|
1066
|
-
left: enabled ? 18 : 2,
|
|
1067
|
-
width: 18,
|
|
1068
|
-
height: 18,
|
|
1069
|
-
borderRadius: "50%",
|
|
1070
|
-
background: "#fff",
|
|
1071
|
-
transition: "left 0.12s ease"
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
)
|
|
1077
|
+
]
|
|
1078
|
+
}
|
|
1079
|
+
)
|
|
1080
|
+
] });
|
|
1081
|
+
const toolbarButtons = expanded ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1082
|
+
/* @__PURE__ */ jsx2("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 2, padding: "4px 0" }, children: MODES.map(({ mode, label, icon: ModeIcon }) => /* @__PURE__ */ jsx2(
|
|
1083
|
+
IconButton,
|
|
1084
|
+
{
|
|
1085
|
+
active: selectedMode === mode,
|
|
1086
|
+
tooltipSide,
|
|
1087
|
+
tooltip: label,
|
|
1088
|
+
onClick: () => {
|
|
1089
|
+
setSettingsOpen(false);
|
|
1090
|
+
setHistoryOpen(false);
|
|
1091
|
+
if (mode === "viewport" || mode === "fullpage") {
|
|
1092
|
+
onModeChange(mode);
|
|
1093
|
+
onCapture(mode);
|
|
1094
|
+
} else {
|
|
1095
|
+
onModeChange(mode);
|
|
1075
1096
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1097
|
+
},
|
|
1098
|
+
children: /* @__PURE__ */ jsx2(ModeIcon, { size: 16, strokeWidth: 1.7 })
|
|
1099
|
+
},
|
|
1100
|
+
mode
|
|
1101
|
+
)) }),
|
|
1102
|
+
/* @__PURE__ */ jsx2(Separator, { vertical: false }),
|
|
1103
|
+
/* @__PURE__ */ jsx2(
|
|
1104
|
+
SettingsButton,
|
|
1105
|
+
{
|
|
1106
|
+
open: settingsOpen,
|
|
1107
|
+
onClick: () => {
|
|
1108
|
+
setSettingsOpen((prev) => !prev);
|
|
1109
|
+
setHistoryOpen(false);
|
|
1110
|
+
},
|
|
1111
|
+
selectedMode,
|
|
1112
|
+
frameSettings,
|
|
1113
|
+
onFrameSettingsChange,
|
|
1114
|
+
panelSide,
|
|
1115
|
+
tooltipSide,
|
|
1116
|
+
bottom
|
|
1117
|
+
}
|
|
1118
|
+
),
|
|
1119
|
+
/* @__PURE__ */ jsx2(
|
|
1120
|
+
HistoryButton,
|
|
1121
|
+
{
|
|
1122
|
+
open: historyOpen,
|
|
1123
|
+
onClick: () => {
|
|
1124
|
+
setHistoryOpen((prev) => !prev);
|
|
1125
|
+
setSettingsOpen(false);
|
|
1126
|
+
},
|
|
1127
|
+
panelSide,
|
|
1128
|
+
tooltipSide,
|
|
1129
|
+
bottom
|
|
1130
|
+
}
|
|
1131
|
+
),
|
|
1132
|
+
/* @__PURE__ */ jsx2(Separator, { vertical: false })
|
|
1133
|
+
] }) : null;
|
|
1092
1134
|
return /* @__PURE__ */ jsx2(
|
|
1093
|
-
"
|
|
1135
|
+
"div",
|
|
1094
1136
|
{
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
onFocus: () => {
|
|
1098
|
-
setEditing(true);
|
|
1099
|
-
setText(String(value));
|
|
1100
|
-
},
|
|
1101
|
-
onBlur: () => {
|
|
1102
|
-
setEditing(false);
|
|
1103
|
-
onChange(text);
|
|
1104
|
-
},
|
|
1105
|
-
onChange: (e) => setText(e.target.value),
|
|
1106
|
-
onKeyDown: (e) => {
|
|
1107
|
-
if (e.key === "Enter") {
|
|
1108
|
-
e.target.blur();
|
|
1109
|
-
}
|
|
1110
|
-
},
|
|
1137
|
+
ref: toolbarRef,
|
|
1138
|
+
"data-afterbefore": "true",
|
|
1111
1139
|
style: {
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1140
|
+
position: "fixed",
|
|
1141
|
+
...positionStyle,
|
|
1142
|
+
zIndex: 2147483647,
|
|
1143
|
+
display: "flex",
|
|
1144
|
+
flexDirection: "column",
|
|
1145
|
+
alignItems: "center",
|
|
1146
|
+
background: "rgb(32, 32, 36)",
|
|
1147
|
+
borderRadius: 999,
|
|
1148
|
+
padding: 6,
|
|
1149
|
+
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
|
1119
1150
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1151
|
+
userSelect: "none"
|
|
1152
|
+
},
|
|
1153
|
+
children: bottom ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1154
|
+
toolbarButtons,
|
|
1155
|
+
cameraButton
|
|
1156
|
+
] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1157
|
+
cameraButton,
|
|
1158
|
+
toolbarButtons
|
|
1159
|
+
] })
|
|
1123
1160
|
}
|
|
1124
1161
|
);
|
|
1125
1162
|
}
|
|
1126
|
-
function
|
|
1127
|
-
|
|
1128
|
-
|
|
1163
|
+
function IconButton({
|
|
1164
|
+
children,
|
|
1165
|
+
active,
|
|
1166
|
+
tooltip,
|
|
1167
|
+
tooltipSide = "left",
|
|
1168
|
+
onClick
|
|
1129
1169
|
}) {
|
|
1130
|
-
const [
|
|
1131
|
-
const
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
if (/^#[0-9a-fA-F]{6}$/.test(hex)) {
|
|
1140
|
-
onChange(hex);
|
|
1141
|
-
}
|
|
1170
|
+
const [hovered, setHovered] = useState3(false);
|
|
1171
|
+
const tooltipStyle = tooltipSide === "left" ? {
|
|
1172
|
+
right: "calc(100% + 10px)",
|
|
1173
|
+
top: "50%",
|
|
1174
|
+
transform: "translateY(-50%)"
|
|
1175
|
+
} : {
|
|
1176
|
+
left: "calc(100% + 10px)",
|
|
1177
|
+
top: "50%",
|
|
1178
|
+
transform: "translateY(-50%)"
|
|
1142
1179
|
};
|
|
1143
|
-
return /* @__PURE__ */
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
},
|
|
1162
|
-
style: {
|
|
1163
|
-
width: 72,
|
|
1164
|
-
padding: "4px 6px",
|
|
1165
|
-
background: "rgba(255, 255, 255, 0.07)",
|
|
1166
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1167
|
-
borderRadius: 7,
|
|
1168
|
-
color: "rgba(255, 255, 255, 0.9)",
|
|
1169
|
-
fontSize: 12,
|
|
1170
|
-
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1171
|
-
textAlign: "left",
|
|
1172
|
-
outline: "none"
|
|
1180
|
+
return /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
|
|
1181
|
+
tooltip && hovered && /* @__PURE__ */ jsx2(
|
|
1182
|
+
"div",
|
|
1183
|
+
{
|
|
1184
|
+
style: {
|
|
1185
|
+
position: "absolute",
|
|
1186
|
+
...tooltipStyle,
|
|
1187
|
+
background: "rgb(32, 32, 36)",
|
|
1188
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1189
|
+
borderRadius: 6,
|
|
1190
|
+
padding: "3px 8px",
|
|
1191
|
+
color: "rgba(255, 255, 255, 0.88)",
|
|
1192
|
+
fontSize: 11,
|
|
1193
|
+
whiteSpace: "nowrap",
|
|
1194
|
+
boxShadow: "0 8px 28px rgba(0, 0, 0, 0.28)",
|
|
1195
|
+
pointerEvents: "none"
|
|
1196
|
+
},
|
|
1197
|
+
children: tooltip
|
|
1173
1198
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1199
|
+
),
|
|
1200
|
+
/* @__PURE__ */ jsx2(
|
|
1201
|
+
"button",
|
|
1202
|
+
{
|
|
1203
|
+
onClick,
|
|
1204
|
+
onMouseEnter: () => setHovered(true),
|
|
1205
|
+
onMouseLeave: () => setHovered(false),
|
|
1206
|
+
style: {
|
|
1207
|
+
width: 32,
|
|
1208
|
+
height: 32,
|
|
1209
|
+
borderRadius: "50%",
|
|
1210
|
+
border: "none",
|
|
1211
|
+
background: active || hovered ? "rgba(255, 255, 255, 0.12)" : "transparent",
|
|
1212
|
+
display: "flex",
|
|
1213
|
+
alignItems: "center",
|
|
1214
|
+
justifyContent: "center",
|
|
1215
|
+
cursor: "pointer",
|
|
1216
|
+
padding: 0,
|
|
1217
|
+
color: active || hovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)",
|
|
1218
|
+
transition: "background 0.12s ease, color 0.12s ease"
|
|
1219
|
+
},
|
|
1220
|
+
children
|
|
1221
|
+
}
|
|
1222
|
+
)
|
|
1223
|
+
] });
|
|
1176
1224
|
}
|
|
1177
|
-
function
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1225
|
+
function SettingsButton({
|
|
1226
|
+
open,
|
|
1227
|
+
onClick,
|
|
1228
|
+
selectedMode,
|
|
1229
|
+
frameSettings,
|
|
1230
|
+
onFrameSettingsChange,
|
|
1231
|
+
panelSide,
|
|
1232
|
+
tooltipSide,
|
|
1233
|
+
bottom
|
|
1234
|
+
}) {
|
|
1235
|
+
const verticalAlign = bottom ? { bottom: 0 } : { top: 0 };
|
|
1236
|
+
const panelStyle = panelSide === "left" ? { right: "calc(100% + 10px)", ...verticalAlign } : { left: "calc(100% + 10px)", ...verticalAlign };
|
|
1237
|
+
return /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
|
|
1238
|
+
/* @__PURE__ */ jsx2(IconButton, { active: open, tooltipSide, tooltip: !open ? "Settings" : void 0, onClick, children: /* @__PURE__ */ jsx2(Settings, { size: 16, strokeWidth: 1.7 }) }),
|
|
1239
|
+
open && /* @__PURE__ */ jsx2(
|
|
1240
|
+
SettingsPanel,
|
|
1241
|
+
{
|
|
1242
|
+
style: { position: "absolute", ...panelStyle },
|
|
1243
|
+
onClose: onClick,
|
|
1244
|
+
selectedMode,
|
|
1245
|
+
frameSettings,
|
|
1246
|
+
onFrameSettingsChange
|
|
1247
|
+
}
|
|
1248
|
+
)
|
|
1249
|
+
] });
|
|
1190
1250
|
}
|
|
1191
|
-
function
|
|
1251
|
+
function DropItem2({
|
|
1192
1252
|
children,
|
|
1193
1253
|
onClick,
|
|
1194
1254
|
active,
|
|
@@ -1230,7 +1290,10 @@ function Separator({ vertical = true }) {
|
|
|
1230
1290
|
}
|
|
1231
1291
|
function HistoryButton({
|
|
1232
1292
|
open,
|
|
1233
|
-
onClick
|
|
1293
|
+
onClick,
|
|
1294
|
+
panelSide,
|
|
1295
|
+
tooltipSide,
|
|
1296
|
+
bottom
|
|
1234
1297
|
}) {
|
|
1235
1298
|
const [toast, setToast] = useState3(null);
|
|
1236
1299
|
const [pushing, setPushing] = useState3(false);
|
|
@@ -1245,6 +1308,7 @@ function HistoryButton({
|
|
|
1245
1308
|
const [lightboxSrc, setLightboxSrc] = useState3(null);
|
|
1246
1309
|
const [editingFile, setEditingFile] = useState3(null);
|
|
1247
1310
|
const [editValue, setEditValue] = useState3("");
|
|
1311
|
+
const [hoveredThumb, setHoveredThumb] = useState3(null);
|
|
1248
1312
|
useEffect2(() => {
|
|
1249
1313
|
if (!open) {
|
|
1250
1314
|
setRepoDropOpen(false);
|
|
@@ -1264,7 +1328,7 @@ function HistoryButton({
|
|
|
1264
1328
|
}).catch(() => {
|
|
1265
1329
|
}).finally(() => setLoading(false));
|
|
1266
1330
|
}, [open, selectedRepo, selectedBranch]);
|
|
1267
|
-
const showToast =
|
|
1331
|
+
const showToast = useCallback2((message, type) => {
|
|
1268
1332
|
setToast({ message, type });
|
|
1269
1333
|
setTimeout(() => setToast(null), 3e3);
|
|
1270
1334
|
}, []);
|
|
@@ -1347,16 +1411,16 @@ function HistoryButton({
|
|
|
1347
1411
|
setPushing(false);
|
|
1348
1412
|
}
|
|
1349
1413
|
};
|
|
1414
|
+
const verticalAlign = bottom ? { bottom: 0 } : { top: 0 };
|
|
1415
|
+
const panelStyle = panelSide === "left" ? { right: "calc(100% + 10px)", ...verticalAlign } : { left: "calc(100% + 10px)", ...verticalAlign };
|
|
1350
1416
|
return /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
|
|
1351
|
-
/* @__PURE__ */ jsx2(IconButton, { active: open, tooltip: !open ? "Screenshots" : void 0, onClick, children: /* @__PURE__ */ jsx2(Clock, { size: 16, strokeWidth: 1.7 }) }),
|
|
1417
|
+
/* @__PURE__ */ jsx2(IconButton, { active: open, tooltipSide, tooltip: !open ? "Screenshots" : void 0, onClick, children: /* @__PURE__ */ jsx2(Clock, { size: 16, strokeWidth: 1.7 }) }),
|
|
1352
1418
|
open && /* @__PURE__ */ jsxs2(
|
|
1353
1419
|
"div",
|
|
1354
1420
|
{
|
|
1355
1421
|
style: {
|
|
1356
1422
|
position: "absolute",
|
|
1357
|
-
|
|
1358
|
-
bottom: "calc(100% + 12px)",
|
|
1359
|
-
transform: "translateX(-50%)",
|
|
1423
|
+
...panelStyle,
|
|
1360
1424
|
minWidth: 300,
|
|
1361
1425
|
maxWidth: 360,
|
|
1362
1426
|
padding: "10px 12px",
|
|
@@ -1438,7 +1502,7 @@ function HistoryButton({
|
|
|
1438
1502
|
},
|
|
1439
1503
|
children: "No screenshots yet"
|
|
1440
1504
|
}
|
|
1441
|
-
) : /* @__PURE__ */ jsxs2(
|
|
1505
|
+
) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1442
1506
|
/* @__PURE__ */ jsx2(
|
|
1443
1507
|
"div",
|
|
1444
1508
|
{
|
|
@@ -1461,22 +1525,56 @@ function HistoryButton({
|
|
|
1461
1525
|
alignItems: "center"
|
|
1462
1526
|
},
|
|
1463
1527
|
children: [
|
|
1464
|
-
/* @__PURE__ */
|
|
1465
|
-
"
|
|
1528
|
+
/* @__PURE__ */ jsxs2(
|
|
1529
|
+
"div",
|
|
1466
1530
|
{
|
|
1467
|
-
src: imgUrl,
|
|
1468
|
-
alt: "",
|
|
1469
|
-
onClick: () => setLightboxSrc(imgUrl),
|
|
1470
1531
|
style: {
|
|
1532
|
+
position: "relative",
|
|
1471
1533
|
width: 56,
|
|
1472
1534
|
height: 36,
|
|
1473
|
-
borderRadius: 4,
|
|
1474
|
-
objectFit: "cover",
|
|
1475
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1476
1535
|
flexShrink: 0,
|
|
1477
|
-
|
|
1536
|
+
borderRadius: 4,
|
|
1537
|
+
overflow: "hidden",
|
|
1478
1538
|
cursor: "pointer"
|
|
1479
|
-
}
|
|
1539
|
+
},
|
|
1540
|
+
onMouseEnter: () => setHoveredThumb(shot.filename),
|
|
1541
|
+
onMouseLeave: () => setHoveredThumb(null),
|
|
1542
|
+
onClick: () => setLightboxSrc(imgUrl),
|
|
1543
|
+
children: [
|
|
1544
|
+
/* @__PURE__ */ jsx2(
|
|
1545
|
+
"img",
|
|
1546
|
+
{
|
|
1547
|
+
src: imgUrl,
|
|
1548
|
+
alt: "",
|
|
1549
|
+
style: {
|
|
1550
|
+
width: 56,
|
|
1551
|
+
height: 36,
|
|
1552
|
+
objectFit: "cover",
|
|
1553
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1554
|
+
borderRadius: 4,
|
|
1555
|
+
background: "rgba(255, 255, 255, 0.05)",
|
|
1556
|
+
display: "block"
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
),
|
|
1560
|
+
/* @__PURE__ */ jsx2(
|
|
1561
|
+
"div",
|
|
1562
|
+
{
|
|
1563
|
+
style: {
|
|
1564
|
+
position: "absolute",
|
|
1565
|
+
inset: 0,
|
|
1566
|
+
background: "rgba(0, 0, 0, 0.55)",
|
|
1567
|
+
display: "flex",
|
|
1568
|
+
alignItems: "center",
|
|
1569
|
+
justifyContent: "center",
|
|
1570
|
+
borderRadius: 4,
|
|
1571
|
+
opacity: hoveredThumb === shot.filename ? 1 : 0,
|
|
1572
|
+
transition: "opacity 0.15s ease"
|
|
1573
|
+
},
|
|
1574
|
+
children: /* @__PURE__ */ jsx2(Eye, { size: 16, strokeWidth: 1.8, color: "rgba(255, 255, 255, 0.9)" })
|
|
1575
|
+
}
|
|
1576
|
+
)
|
|
1577
|
+
]
|
|
1480
1578
|
}
|
|
1481
1579
|
),
|
|
1482
1580
|
/* @__PURE__ */ jsx2("div", { style: { flex: 1, minWidth: 0 }, children: isEditing ? /* @__PURE__ */ jsx2(
|
|
@@ -1548,7 +1646,7 @@ function HistoryButton({
|
|
|
1548
1646
|
e.currentTarget.style.color = "rgba(255, 255, 255, 0.35)";
|
|
1549
1647
|
e.currentTarget.style.background = "transparent";
|
|
1550
1648
|
},
|
|
1551
|
-
children: /* @__PURE__ */ jsx2(
|
|
1649
|
+
children: /* @__PURE__ */ jsx2(Trash22, { size: 13, strokeWidth: 1.8 })
|
|
1552
1650
|
}
|
|
1553
1651
|
)
|
|
1554
1652
|
]
|
|
@@ -1613,7 +1711,8 @@ function HistoryButton({
|
|
|
1613
1711
|
style: {
|
|
1614
1712
|
position: "fixed",
|
|
1615
1713
|
inset: 0,
|
|
1616
|
-
|
|
1714
|
+
bottom: 100,
|
|
1715
|
+
zIndex: 2147483646,
|
|
1617
1716
|
background: "rgba(0, 0, 0, 0.85)",
|
|
1618
1717
|
display: "flex",
|
|
1619
1718
|
alignItems: "center",
|
|
@@ -1629,7 +1728,7 @@ function HistoryButton({
|
|
|
1629
1728
|
onClick: (e) => e.stopPropagation(),
|
|
1630
1729
|
style: {
|
|
1631
1730
|
maxWidth: "90vw",
|
|
1632
|
-
maxHeight: "
|
|
1731
|
+
maxHeight: "calc(100% - 32px)",
|
|
1633
1732
|
borderRadius: 8,
|
|
1634
1733
|
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.5)",
|
|
1635
1734
|
cursor: "default"
|
|
@@ -1656,7 +1755,7 @@ function HistoryButton({
|
|
|
1656
1755
|
justifyContent: "center",
|
|
1657
1756
|
padding: 0
|
|
1658
1757
|
},
|
|
1659
|
-
children: /* @__PURE__ */ jsx2(
|
|
1758
|
+
children: /* @__PURE__ */ jsx2(X2, { size: 18, strokeWidth: 2 })
|
|
1660
1759
|
}
|
|
1661
1760
|
)
|
|
1662
1761
|
]
|
|
@@ -1718,7 +1817,7 @@ function FilterDropdown({
|
|
|
1718
1817
|
children: value || "\u2014"
|
|
1719
1818
|
}
|
|
1720
1819
|
),
|
|
1721
|
-
/* @__PURE__ */ jsx2(
|
|
1820
|
+
/* @__PURE__ */ jsx2(ChevronDown2, { size: 12, strokeWidth: 2 })
|
|
1722
1821
|
]
|
|
1723
1822
|
}
|
|
1724
1823
|
),
|
|
@@ -1740,7 +1839,7 @@ function FilterDropdown({
|
|
|
1740
1839
|
zIndex: 1
|
|
1741
1840
|
},
|
|
1742
1841
|
children: options.map((opt) => /* @__PURE__ */ jsx2(
|
|
1743
|
-
|
|
1842
|
+
DropItem2,
|
|
1744
1843
|
{
|
|
1745
1844
|
active: opt === value,
|
|
1746
1845
|
onClick: () => onSelect(opt),
|
|
@@ -1801,8 +1900,8 @@ function formatTimestamp(filename) {
|
|
|
1801
1900
|
}
|
|
1802
1901
|
|
|
1803
1902
|
// src/overlay/ui/inspector.tsx
|
|
1804
|
-
import { useEffect as useEffect3, useRef as useRef3, useCallback as
|
|
1805
|
-
import {
|
|
1903
|
+
import { useEffect as useEffect3, useRef as useRef3, useCallback as useCallback3, useState as useState4 } from "react";
|
|
1904
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1806
1905
|
function Inspector({ onSelect, onCancel }) {
|
|
1807
1906
|
const [highlight, setHighlight] = useState4(null);
|
|
1808
1907
|
const hoveredEl = useRef3(null);
|
|
@@ -1822,7 +1921,7 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1822
1921
|
style.remove();
|
|
1823
1922
|
};
|
|
1824
1923
|
}, []);
|
|
1825
|
-
const isOverlayElement =
|
|
1924
|
+
const isOverlayElement = useCallback3((el) => {
|
|
1826
1925
|
let node = el;
|
|
1827
1926
|
while (node) {
|
|
1828
1927
|
if (node instanceof HTMLElement && node.dataset.afterbefore) return true;
|
|
@@ -1830,7 +1929,7 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1830
1929
|
}
|
|
1831
1930
|
return false;
|
|
1832
1931
|
}, []);
|
|
1833
|
-
const handleMouseMove =
|
|
1932
|
+
const handleMouseMove = useCallback3(
|
|
1834
1933
|
(e) => {
|
|
1835
1934
|
const el = document.elementFromPoint(e.clientX, e.clientY);
|
|
1836
1935
|
if (!el || !(el instanceof HTMLElement) || isOverlayElement(el)) {
|
|
@@ -1844,13 +1943,12 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1844
1943
|
x: rect.x,
|
|
1845
1944
|
y: rect.y,
|
|
1846
1945
|
width: rect.width,
|
|
1847
|
-
height: rect.height
|
|
1848
|
-
tag: el.tagName.toLowerCase() + (el.className && typeof el.className === "string" ? `.${el.className.split(" ")[0]}` : "")
|
|
1946
|
+
height: rect.height
|
|
1849
1947
|
});
|
|
1850
1948
|
},
|
|
1851
1949
|
[isOverlayElement]
|
|
1852
1950
|
);
|
|
1853
|
-
const handleClick =
|
|
1951
|
+
const handleClick = useCallback3(
|
|
1854
1952
|
(e) => {
|
|
1855
1953
|
if (isOverlayElement(e.target)) return;
|
|
1856
1954
|
e.preventDefault();
|
|
@@ -1862,7 +1960,7 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1862
1960
|
},
|
|
1863
1961
|
[onSelect, isOverlayElement]
|
|
1864
1962
|
);
|
|
1865
|
-
const handleKeyDown =
|
|
1963
|
+
const handleKeyDown = useCallback3(
|
|
1866
1964
|
(e) => {
|
|
1867
1965
|
if (e.key === "Escape") {
|
|
1868
1966
|
onCancel();
|
|
@@ -1880,49 +1978,27 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1880
1978
|
document.removeEventListener("keydown", handleKeyDown);
|
|
1881
1979
|
};
|
|
1882
1980
|
}, [handleMouseMove, handleClick, handleKeyDown]);
|
|
1883
|
-
return /* @__PURE__ */ jsx3("div", { "data-afterbefore": "true", style: { position: "fixed", inset: 0, zIndex: 2147483646, pointerEvents: "none" }, children: highlight && /* @__PURE__ */
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
{
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
pointerEvents: "none"
|
|
1898
|
-
}
|
|
1899
|
-
}
|
|
1900
|
-
),
|
|
1901
|
-
/* @__PURE__ */ jsx3(
|
|
1902
|
-
"div",
|
|
1903
|
-
{
|
|
1904
|
-
style: {
|
|
1905
|
-
position: "fixed",
|
|
1906
|
-
left: highlight.x,
|
|
1907
|
-
top: Math.max(0, highlight.y - 24),
|
|
1908
|
-
background: "rgba(0, 0, 0, 0.8)",
|
|
1909
|
-
color: "#fff",
|
|
1910
|
-
fontSize: 11,
|
|
1911
|
-
fontFamily: "system-ui, -apple-system, monospace",
|
|
1912
|
-
padding: "2px 6px",
|
|
1913
|
-
borderRadius: 3,
|
|
1914
|
-
pointerEvents: "none",
|
|
1915
|
-
whiteSpace: "nowrap",
|
|
1916
|
-
lineHeight: "18px"
|
|
1917
|
-
},
|
|
1918
|
-
children: highlight.tag
|
|
1981
|
+
return /* @__PURE__ */ jsx3("div", { "data-afterbefore": "true", style: { position: "fixed", inset: 0, zIndex: 2147483646, pointerEvents: "none" }, children: highlight && /* @__PURE__ */ jsx3(
|
|
1982
|
+
"div",
|
|
1983
|
+
{
|
|
1984
|
+
style: {
|
|
1985
|
+
position: "fixed",
|
|
1986
|
+
left: highlight.x,
|
|
1987
|
+
top: highlight.y,
|
|
1988
|
+
width: highlight.width,
|
|
1989
|
+
height: highlight.height,
|
|
1990
|
+
background: "transparent",
|
|
1991
|
+
border: "1px solid #fff",
|
|
1992
|
+
borderRadius: 2,
|
|
1993
|
+
boxShadow: "0 0 0 9999px rgba(0, 0, 0, 0.5)",
|
|
1994
|
+
pointerEvents: "none"
|
|
1919
1995
|
}
|
|
1920
|
-
|
|
1921
|
-
|
|
1996
|
+
}
|
|
1997
|
+
) });
|
|
1922
1998
|
}
|
|
1923
1999
|
|
|
1924
2000
|
// src/overlay/index.tsx
|
|
1925
|
-
import { jsx as jsx4, jsxs as
|
|
2001
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1926
2002
|
async function saveCapture(mode, dataUrl) {
|
|
1927
2003
|
try {
|
|
1928
2004
|
const res = await fetch("/__afterbefore/save", {
|
|
@@ -1945,7 +2021,6 @@ function AfterBefore() {
|
|
|
1945
2021
|
const [loading, setLoading] = useState5(false);
|
|
1946
2022
|
const [selectedMode, setSelectedMode] = useState5("component");
|
|
1947
2023
|
const [frameSettings, setFrameSettings] = useState5(DEFAULT_FRAME_SETTINGS);
|
|
1948
|
-
const iconPos = useRef4({ x: 24, y: 0 });
|
|
1949
2024
|
useEffect4(() => {
|
|
1950
2025
|
try {
|
|
1951
2026
|
const stored = localStorage.getItem("ab-frame-settings");
|
|
@@ -1969,13 +2044,7 @@ function AfterBefore() {
|
|
|
1969
2044
|
return () => clearTimeout(timer);
|
|
1970
2045
|
}
|
|
1971
2046
|
}, [state.phase, reset]);
|
|
1972
|
-
const
|
|
1973
|
-
(pos) => {
|
|
1974
|
-
iconPos.current = pos;
|
|
1975
|
-
},
|
|
1976
|
-
[]
|
|
1977
|
-
);
|
|
1978
|
-
const handleIconClick = useCallback5(() => {
|
|
2047
|
+
const handleToggle = useCallback4(() => {
|
|
1979
2048
|
if (loading) return;
|
|
1980
2049
|
if (state.phase === "ready") {
|
|
1981
2050
|
reset();
|
|
@@ -1993,7 +2062,7 @@ function AfterBefore() {
|
|
|
1993
2062
|
}
|
|
1994
2063
|
}
|
|
1995
2064
|
}, [state.phase, loading, toolbarActive, inspectorActive, selectedMode, reset]);
|
|
1996
|
-
const performCapture =
|
|
2065
|
+
const performCapture = useCallback4(
|
|
1997
2066
|
async (mode, element) => {
|
|
1998
2067
|
setLoading(true);
|
|
1999
2068
|
try {
|
|
@@ -2012,7 +2081,7 @@ function AfterBefore() {
|
|
|
2012
2081
|
},
|
|
2013
2082
|
[captureComplete, frameSettings]
|
|
2014
2083
|
);
|
|
2015
|
-
const handleToolbarCapture =
|
|
2084
|
+
const handleToolbarCapture = useCallback4(
|
|
2016
2085
|
(mode) => {
|
|
2017
2086
|
if (mode === "viewport") {
|
|
2018
2087
|
setToolbarActive(false);
|
|
@@ -2026,10 +2095,11 @@ function AfterBefore() {
|
|
|
2026
2095
|
},
|
|
2027
2096
|
[performCapture]
|
|
2028
2097
|
);
|
|
2029
|
-
const handleToolbarCancel =
|
|
2098
|
+
const handleToolbarCancel = useCallback4(() => {
|
|
2030
2099
|
setToolbarActive(false);
|
|
2100
|
+
setInspectorActive(false);
|
|
2031
2101
|
}, []);
|
|
2032
|
-
const handleComponentSelect =
|
|
2102
|
+
const handleComponentSelect = useCallback4(
|
|
2033
2103
|
(element) => {
|
|
2034
2104
|
setInspectorActive(false);
|
|
2035
2105
|
setToolbarActive(false);
|
|
@@ -2037,34 +2107,29 @@ function AfterBefore() {
|
|
|
2037
2107
|
},
|
|
2038
2108
|
[performCapture]
|
|
2039
2109
|
);
|
|
2040
|
-
const handleComponentCancel =
|
|
2110
|
+
const handleComponentCancel = useCallback4(() => {
|
|
2041
2111
|
setInspectorActive(false);
|
|
2042
2112
|
setToolbarActive(true);
|
|
2043
2113
|
}, []);
|
|
2044
|
-
const handleFrameSettingsChange =
|
|
2114
|
+
const handleFrameSettingsChange = useCallback4((next) => {
|
|
2045
2115
|
setFrameSettings(next);
|
|
2046
2116
|
try {
|
|
2047
2117
|
localStorage.setItem("ab-frame-settings", JSON.stringify(next));
|
|
2048
2118
|
} catch {
|
|
2049
2119
|
}
|
|
2050
2120
|
}, []);
|
|
2051
|
-
const handleModeChange =
|
|
2121
|
+
const handleModeChange = useCallback4((mode) => {
|
|
2052
2122
|
setSelectedMode(mode);
|
|
2053
2123
|
setInspectorActive(mode === "component");
|
|
2054
2124
|
}, []);
|
|
2055
|
-
return /* @__PURE__ */
|
|
2125
|
+
return /* @__PURE__ */ jsxs3("div", { "data-afterbefore": "true", children: [
|
|
2056
2126
|
/* @__PURE__ */ jsx4(
|
|
2057
|
-
|
|
2127
|
+
Toolbar,
|
|
2058
2128
|
{
|
|
2129
|
+
expanded: toolbarActive,
|
|
2130
|
+
onToggle: handleToggle,
|
|
2059
2131
|
phase: state.phase,
|
|
2060
|
-
onClick: handleIconClick,
|
|
2061
2132
|
loading,
|
|
2062
|
-
onPositionChange: handlePositionChange
|
|
2063
|
-
}
|
|
2064
|
-
),
|
|
2065
|
-
toolbarActive && /* @__PURE__ */ jsx4(
|
|
2066
|
-
Toolbar,
|
|
2067
|
-
{
|
|
2068
2133
|
selectedMode,
|
|
2069
2134
|
onModeChange: handleModeChange,
|
|
2070
2135
|
onCapture: handleToolbarCapture,
|