@flowsterix/react 0.11.1 → 0.12.1
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/devtools/DevToolsProvider.d.ts.map +1 -1
- package/dist/devtools/components/FlowEditModal.d.ts.map +1 -1
- package/dist/devtools/components/FlowItem.d.ts.map +1 -1
- package/dist/devtools/components/FlowsTab.d.ts.map +1 -1
- package/dist/devtools/components/GrabberOverlay.d.ts +1 -0
- package/dist/devtools/components/GrabberOverlay.d.ts.map +1 -1
- package/dist/devtools/components/StepItem.d.ts.map +1 -1
- package/dist/devtools/components/StepList.d.ts.map +1 -1
- package/dist/devtools/components/TabNav.d.ts.map +1 -1
- package/dist/devtools/components/Toolbar.d.ts.map +1 -1
- package/dist/devtools/index.cjs +555 -227
- package/dist/devtools/index.mjs +607 -279
- package/dist/devtools/motion.d.ts +64 -0
- package/dist/devtools/motion.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/devtools/index.mjs
CHANGED
|
@@ -5,11 +5,82 @@ import {
|
|
|
5
5
|
} from "../chunk-AJZMUYBN.mjs";
|
|
6
6
|
|
|
7
7
|
// src/devtools/DevToolsProvider.tsx
|
|
8
|
-
import { useCallback as useCallback8, useEffect as
|
|
8
|
+
import { useCallback as useCallback8, useEffect as useEffect8, useRef as useRef2, useState as useState11 } from "react";
|
|
9
9
|
import { createPortal as createPortal3 } from "react-dom";
|
|
10
|
-
import {
|
|
10
|
+
import { motion as motion9 } from "motion/react";
|
|
11
|
+
|
|
12
|
+
// src/devtools/motion.ts
|
|
13
|
+
import { useEffect, useState } from "react";
|
|
14
|
+
var springs = {
|
|
15
|
+
snappy: {
|
|
16
|
+
type: "spring",
|
|
17
|
+
damping: 30,
|
|
18
|
+
stiffness: 500,
|
|
19
|
+
mass: 0.5
|
|
20
|
+
},
|
|
21
|
+
smooth: {
|
|
22
|
+
type: "spring",
|
|
23
|
+
damping: 30,
|
|
24
|
+
stiffness: 300,
|
|
25
|
+
mass: 0.8
|
|
26
|
+
},
|
|
27
|
+
bouncy: {
|
|
28
|
+
type: "spring",
|
|
29
|
+
damping: 15,
|
|
30
|
+
stiffness: 400,
|
|
31
|
+
mass: 0.5
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var stagger = {
|
|
35
|
+
fast: {
|
|
36
|
+
staggerChildren: 0.03,
|
|
37
|
+
delayChildren: 0.05
|
|
38
|
+
},
|
|
39
|
+
default: {
|
|
40
|
+
staggerChildren: 0.05,
|
|
41
|
+
delayChildren: 0.1
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var listItemVariants = {
|
|
45
|
+
hidden: {
|
|
46
|
+
opacity: 0,
|
|
47
|
+
y: 8,
|
|
48
|
+
scale: 0.98
|
|
49
|
+
},
|
|
50
|
+
visible: {
|
|
51
|
+
opacity: 1,
|
|
52
|
+
y: 0,
|
|
53
|
+
scale: 1
|
|
54
|
+
},
|
|
55
|
+
exit: {
|
|
56
|
+
opacity: 0,
|
|
57
|
+
scale: 0.95,
|
|
58
|
+
transition: { duration: 0.15 }
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var listContainerVariants = {
|
|
62
|
+
hidden: { opacity: 0 },
|
|
63
|
+
visible: {
|
|
64
|
+
opacity: 1,
|
|
65
|
+
transition: stagger.fast
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function useReducedMotion() {
|
|
69
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
72
|
+
setPrefersReducedMotion(mediaQuery.matches);
|
|
73
|
+
const handler = (event) => {
|
|
74
|
+
setPrefersReducedMotion(event.matches);
|
|
75
|
+
};
|
|
76
|
+
mediaQuery.addEventListener("change", handler);
|
|
77
|
+
return () => mediaQuery.removeEventListener("change", handler);
|
|
78
|
+
}, []);
|
|
79
|
+
return prefersReducedMotion;
|
|
80
|
+
}
|
|
11
81
|
|
|
12
82
|
// src/devtools/components/GrabberOverlay.tsx
|
|
83
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
13
84
|
import { createPortal } from "react-dom";
|
|
14
85
|
import { AnimatePresence, motion } from "motion/react";
|
|
15
86
|
|
|
@@ -125,6 +196,10 @@ var styles = {
|
|
|
125
196
|
pointerEvents: "none",
|
|
126
197
|
boxShadow: "0 0 0 4px hsl(217 91% 60% / 0.15), 0 4px 20px hsl(217 91% 60% / 0.2)"
|
|
127
198
|
},
|
|
199
|
+
highlightPulse: {
|
|
200
|
+
boxShadow: "0 0 0 8px hsl(142 71% 55% / 0.3), 0 4px 20px hsl(142 71% 55% / 0.4)",
|
|
201
|
+
borderColor: "hsl(142 71% 55%)"
|
|
202
|
+
},
|
|
128
203
|
label: {
|
|
129
204
|
position: "absolute",
|
|
130
205
|
bottom: "100%",
|
|
@@ -183,7 +258,6 @@ var styles = {
|
|
|
183
258
|
position: "fixed",
|
|
184
259
|
bottom: 20,
|
|
185
260
|
left: "50%",
|
|
186
|
-
transform: "translateX(-50%)",
|
|
187
261
|
display: "flex",
|
|
188
262
|
alignItems: "center",
|
|
189
263
|
gap: 12,
|
|
@@ -227,7 +301,24 @@ var springTransition = {
|
|
|
227
301
|
mass: 0.8
|
|
228
302
|
};
|
|
229
303
|
function GrabberOverlay(props) {
|
|
230
|
-
const { isGrabbing, hoveredInfo, container } = props;
|
|
304
|
+
const { isGrabbing, hoveredInfo, container, onElementSelected } = props;
|
|
305
|
+
const reducedMotion = useReducedMotion();
|
|
306
|
+
const [showPulse, setShowPulse] = useState2(false);
|
|
307
|
+
useEffect2(() => {
|
|
308
|
+
if (onElementSelected) {
|
|
309
|
+
}
|
|
310
|
+
}, [onElementSelected]);
|
|
311
|
+
useEffect2(() => {
|
|
312
|
+
const handlePulse = () => {
|
|
313
|
+
if (reducedMotion) return;
|
|
314
|
+
setShowPulse(true);
|
|
315
|
+
setTimeout(() => setShowPulse(false), 300);
|
|
316
|
+
};
|
|
317
|
+
window.__devtools_pulse = handlePulse;
|
|
318
|
+
return () => {
|
|
319
|
+
delete window.__devtools_pulse;
|
|
320
|
+
};
|
|
321
|
+
}, [reducedMotion]);
|
|
231
322
|
if (typeof window === "undefined") return null;
|
|
232
323
|
const portalContainer = container ?? document.body;
|
|
233
324
|
const labelStyle = {
|
|
@@ -243,12 +334,16 @@ function GrabberOverlay(props) {
|
|
|
243
334
|
labelStyle.left = "auto";
|
|
244
335
|
labelStyle.right = 0;
|
|
245
336
|
}
|
|
337
|
+
const highlightStyle = {
|
|
338
|
+
...styles.highlight,
|
|
339
|
+
...showPulse && styles.highlightPulse
|
|
340
|
+
};
|
|
246
341
|
return createPortal(
|
|
247
342
|
/* @__PURE__ */ jsxs("div", { style: styles.root, "data-devtools-panel": "", children: [
|
|
248
343
|
/* @__PURE__ */ jsx(AnimatePresence, { children: isGrabbing && hoveredInfo && /* @__PURE__ */ jsx(
|
|
249
344
|
motion.div,
|
|
250
345
|
{
|
|
251
|
-
style:
|
|
346
|
+
style: highlightStyle,
|
|
252
347
|
initial: {
|
|
253
348
|
top: hoveredInfo.rect.top,
|
|
254
349
|
left: hoveredInfo.rect.left,
|
|
@@ -261,19 +356,20 @@ function GrabberOverlay(props) {
|
|
|
261
356
|
left: hoveredInfo.rect.left,
|
|
262
357
|
width: hoveredInfo.rect.width,
|
|
263
358
|
height: hoveredInfo.rect.height,
|
|
264
|
-
opacity: 1
|
|
359
|
+
opacity: 1,
|
|
360
|
+
scale: showPulse ? 1.02 : 1
|
|
265
361
|
},
|
|
266
362
|
exit: {
|
|
267
363
|
opacity: 0
|
|
268
364
|
},
|
|
269
|
-
transition: springTransition,
|
|
365
|
+
transition: reducedMotion ? { duration: 0 } : springTransition,
|
|
270
366
|
children: /* @__PURE__ */ jsxs(
|
|
271
367
|
motion.div,
|
|
272
368
|
{
|
|
273
369
|
style: labelStyle,
|
|
274
|
-
initial: { opacity: 0, y: 4 },
|
|
370
|
+
initial: reducedMotion ? {} : { opacity: 0, y: 4 },
|
|
275
371
|
animate: { opacity: 1, y: 0 },
|
|
276
|
-
transition: { delay: 0.03, duration: 0.12 },
|
|
372
|
+
transition: reducedMotion ? { duration: 0 } : { delay: 0.03, duration: 0.12 },
|
|
277
373
|
children: [
|
|
278
374
|
/* @__PURE__ */ jsxs("div", { style: styles.labelTop, children: [
|
|
279
375
|
/* @__PURE__ */ jsxs("span", { style: styles.tagBadge, children: [
|
|
@@ -311,10 +407,10 @@ function GrabberOverlay(props) {
|
|
|
311
407
|
motion.div,
|
|
312
408
|
{
|
|
313
409
|
style: styles.hint,
|
|
314
|
-
initial: { opacity: 0, y: 10, scale: 0.95 },
|
|
315
|
-
animate: { opacity: 1, y: 0, scale: 1 },
|
|
316
|
-
exit: { opacity: 0, y: 10, scale: 0.95 },
|
|
317
|
-
transition: { duration: 0
|
|
410
|
+
initial: reducedMotion ? {} : { opacity: 0, y: 10, scale: 0.95, x: "-50%" },
|
|
411
|
+
animate: { opacity: 1, y: 0, scale: 1, x: "-50%" },
|
|
412
|
+
exit: reducedMotion ? {} : { opacity: 0, y: 10, scale: 0.95, x: "-50%" },
|
|
413
|
+
transition: reducedMotion ? { duration: 0 } : springs.smooth,
|
|
318
414
|
children: [
|
|
319
415
|
/* @__PURE__ */ jsxs("div", { style: styles.hintItem, children: [
|
|
320
416
|
/* @__PURE__ */ jsx("span", { style: styles.kbd, children: "Click" }),
|
|
@@ -340,7 +436,8 @@ function GrabberOverlay(props) {
|
|
|
340
436
|
}
|
|
341
437
|
|
|
342
438
|
// src/devtools/components/StepList.tsx
|
|
343
|
-
import { useCallback, useState as
|
|
439
|
+
import { useCallback, useState as useState5 } from "react";
|
|
440
|
+
import { motion as motion4, AnimatePresence as AnimatePresence3 } from "motion/react";
|
|
344
441
|
import {
|
|
345
442
|
DndContext,
|
|
346
443
|
DragOverlay,
|
|
@@ -357,8 +454,10 @@ import {
|
|
|
357
454
|
} from "@dnd-kit/sortable";
|
|
358
455
|
|
|
359
456
|
// src/devtools/components/StepItem.tsx
|
|
457
|
+
import { useState as useState3 } from "react";
|
|
360
458
|
import { useSortable } from "@dnd-kit/sortable";
|
|
361
459
|
import { CSS as CSS2 } from "@dnd-kit/utilities";
|
|
460
|
+
import { motion as motion2 } from "motion/react";
|
|
362
461
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
363
462
|
var styles2 = {
|
|
364
463
|
card: {
|
|
@@ -370,7 +469,12 @@ var styles2 = {
|
|
|
370
469
|
border: "1px solid hsl(215 20% 22%)",
|
|
371
470
|
fontSize: 12,
|
|
372
471
|
fontFamily: "inherit",
|
|
373
|
-
overflow: "hidden"
|
|
472
|
+
overflow: "hidden",
|
|
473
|
+
transition: "border-color 0.15s ease, box-shadow 0.15s ease"
|
|
474
|
+
},
|
|
475
|
+
cardHover: {
|
|
476
|
+
borderColor: "hsl(217 91% 55% / 0.4)",
|
|
477
|
+
boxShadow: "0 0 0 2px hsl(217 91% 55% / 0.1), 0 4px 12px rgba(0, 0, 0, 0.2)"
|
|
374
478
|
},
|
|
375
479
|
cardGhost: {
|
|
376
480
|
opacity: 0.4,
|
|
@@ -509,6 +613,8 @@ var styles2 = {
|
|
|
509
613
|
};
|
|
510
614
|
function SortableStepItem(props) {
|
|
511
615
|
const { step, index, onDelete, isBeingDragged = false } = props;
|
|
616
|
+
const [isHovered, setIsHovered] = useState3(false);
|
|
617
|
+
const reducedMotion = useReducedMotion();
|
|
512
618
|
const {
|
|
513
619
|
attributes,
|
|
514
620
|
listeners,
|
|
@@ -530,86 +636,108 @@ function SortableStepItem(props) {
|
|
|
530
636
|
};
|
|
531
637
|
const cardStyle = {
|
|
532
638
|
...styles2.card,
|
|
639
|
+
...isHovered && !isGhost && styles2.cardHover,
|
|
533
640
|
...isGhost && styles2.cardGhost
|
|
534
641
|
};
|
|
535
642
|
const handleStyle = {
|
|
536
643
|
...styles2.dragHandle
|
|
537
644
|
};
|
|
538
|
-
return /* @__PURE__ */ jsx2(
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
/* @__PURE__ */
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
"
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
),
|
|
578
|
-
/* @__PURE__ */ jsx2(
|
|
579
|
-
"button",
|
|
580
|
-
{
|
|
581
|
-
type: "button",
|
|
582
|
-
style: styles2.copyButton,
|
|
583
|
-
onClick: handleCopySource,
|
|
584
|
-
title: "Copy path",
|
|
585
|
-
children: /* @__PURE__ */ jsxs2(
|
|
645
|
+
return /* @__PURE__ */ jsx2(
|
|
646
|
+
"div",
|
|
647
|
+
{
|
|
648
|
+
ref: setNodeRef,
|
|
649
|
+
style: wrapperStyle,
|
|
650
|
+
onMouseEnter: () => setIsHovered(true),
|
|
651
|
+
onMouseLeave: () => setIsHovered(false),
|
|
652
|
+
children: /* @__PURE__ */ jsxs2("div", { style: cardStyle, children: [
|
|
653
|
+
/* @__PURE__ */ jsx2("div", { style: handleStyle, ...attributes, ...listeners, children: /* @__PURE__ */ jsxs2("svg", { width: "10", height: "16", viewBox: "0 0 10 16", fill: "currentColor", children: [
|
|
654
|
+
/* @__PURE__ */ jsx2("circle", { cx: "3", cy: "2", r: "1.5" }),
|
|
655
|
+
/* @__PURE__ */ jsx2("circle", { cx: "7", cy: "2", r: "1.5" }),
|
|
656
|
+
/* @__PURE__ */ jsx2("circle", { cx: "3", cy: "8", r: "1.5" }),
|
|
657
|
+
/* @__PURE__ */ jsx2("circle", { cx: "7", cy: "8", r: "1.5" }),
|
|
658
|
+
/* @__PURE__ */ jsx2("circle", { cx: "3", cy: "14", r: "1.5" }),
|
|
659
|
+
/* @__PURE__ */ jsx2("circle", { cx: "7", cy: "14", r: "1.5" })
|
|
660
|
+
] }) }),
|
|
661
|
+
/* @__PURE__ */ jsxs2("div", { style: styles2.content, children: [
|
|
662
|
+
/* @__PURE__ */ jsxs2("div", { style: styles2.header, children: [
|
|
663
|
+
/* @__PURE__ */ jsx2(
|
|
664
|
+
motion2.span,
|
|
665
|
+
{
|
|
666
|
+
style: styles2.order,
|
|
667
|
+
initial: reducedMotion ? {} : { scale: 1.2 },
|
|
668
|
+
animate: { scale: 1 },
|
|
669
|
+
transition: reducedMotion ? { duration: 0 } : springs.bouncy,
|
|
670
|
+
children: index + 1
|
|
671
|
+
},
|
|
672
|
+
`order-${index}`
|
|
673
|
+
),
|
|
674
|
+
/* @__PURE__ */ jsxs2("span", { style: styles2.tagBadge, children: [
|
|
675
|
+
"<",
|
|
676
|
+
step.elementTag,
|
|
677
|
+
">"
|
|
678
|
+
] }),
|
|
679
|
+
step.elementText && /* @__PURE__ */ jsx2("span", { style: styles2.text, children: step.elementText })
|
|
680
|
+
] }),
|
|
681
|
+
/* @__PURE__ */ jsx2("div", { style: styles2.selector, children: step.selector }),
|
|
682
|
+
step.source && /* @__PURE__ */ jsxs2("div", { style: styles2.sourceRow, children: [
|
|
683
|
+
/* @__PURE__ */ jsx2(
|
|
586
684
|
"svg",
|
|
587
685
|
{
|
|
588
686
|
width: "10",
|
|
589
687
|
height: "10",
|
|
590
688
|
viewBox: "0 0 16 16",
|
|
591
|
-
fill: "
|
|
592
|
-
children:
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
689
|
+
fill: "hsl(142 71% 55%)",
|
|
690
|
+
children: /* @__PURE__ */ jsx2("path", { d: "M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z" })
|
|
691
|
+
}
|
|
692
|
+
),
|
|
693
|
+
/* @__PURE__ */ jsx2(
|
|
694
|
+
"a",
|
|
695
|
+
{
|
|
696
|
+
href: getVSCodeLink({ source: step.source }),
|
|
697
|
+
style: styles2.sourceLink,
|
|
698
|
+
title: "Open in VS Code",
|
|
699
|
+
children: formatSourcePath({ source: step.source })
|
|
700
|
+
}
|
|
701
|
+
),
|
|
702
|
+
/* @__PURE__ */ jsx2(
|
|
703
|
+
"button",
|
|
704
|
+
{
|
|
705
|
+
type: "button",
|
|
706
|
+
style: styles2.copyButton,
|
|
707
|
+
onClick: handleCopySource,
|
|
708
|
+
title: "Copy path",
|
|
709
|
+
children: /* @__PURE__ */ jsxs2(
|
|
710
|
+
"svg",
|
|
711
|
+
{
|
|
712
|
+
width: "10",
|
|
713
|
+
height: "10",
|
|
714
|
+
viewBox: "0 0 16 16",
|
|
715
|
+
fill: "currentColor",
|
|
716
|
+
children: [
|
|
717
|
+
/* @__PURE__ */ jsx2("path", { d: "M10 2H4a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2zM4 1h6a3 3 0 0 1 3 3v8a3 3 0 0 1-3 3H4a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3z" }),
|
|
718
|
+
/* @__PURE__ */ jsx2("path", { d: "M14 5a1 1 0 0 1 1 1v8a2 2 0 0 1-2 2H6a1 1 0 0 1 0-2h7V6a1 1 0 0 1 1-1z" })
|
|
719
|
+
]
|
|
720
|
+
}
|
|
721
|
+
)
|
|
596
722
|
}
|
|
597
723
|
)
|
|
724
|
+
] })
|
|
725
|
+
] }),
|
|
726
|
+
/* @__PURE__ */ jsx2(
|
|
727
|
+
motion2.button,
|
|
728
|
+
{
|
|
729
|
+
type: "button",
|
|
730
|
+
style: styles2.deleteButton,
|
|
731
|
+
onClick: onDelete,
|
|
732
|
+
title: "Delete step",
|
|
733
|
+
whileHover: reducedMotion ? {} : { scale: 1.1, color: "hsl(0 70% 60%)" },
|
|
734
|
+
whileTap: reducedMotion ? {} : { scale: 0.9 },
|
|
735
|
+
children: /* @__PURE__ */ jsx2("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx2("path", { d: "M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" }) })
|
|
598
736
|
}
|
|
599
737
|
)
|
|
600
738
|
] })
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
"button",
|
|
604
|
-
{
|
|
605
|
-
type: "button",
|
|
606
|
-
style: styles2.deleteButton,
|
|
607
|
-
onClick: onDelete,
|
|
608
|
-
title: "Delete step",
|
|
609
|
-
children: /* @__PURE__ */ jsx2("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx2("path", { d: "M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" }) })
|
|
610
|
-
}
|
|
611
|
-
)
|
|
612
|
-
] }) });
|
|
739
|
+
}
|
|
740
|
+
);
|
|
613
741
|
}
|
|
614
742
|
function StepItemDragPreview(props) {
|
|
615
743
|
const { step, index } = props;
|
|
@@ -662,8 +790,8 @@ function StepItemDragPreview(props) {
|
|
|
662
790
|
}
|
|
663
791
|
|
|
664
792
|
// src/devtools/components/Toolbar.tsx
|
|
665
|
-
import { useState } from "react";
|
|
666
|
-
import { motion as
|
|
793
|
+
import { useState as useState4 } from "react";
|
|
794
|
+
import { motion as motion3, AnimatePresence as AnimatePresence2 } from "motion/react";
|
|
667
795
|
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
668
796
|
var styles3 = {
|
|
669
797
|
toolbar: {
|
|
@@ -698,7 +826,8 @@ var styles3 = {
|
|
|
698
826
|
backgroundColor: "rgba(59, 130, 246, 0.15)",
|
|
699
827
|
borderColor: "rgba(59, 130, 246, 0.4)",
|
|
700
828
|
color: "#60a5fa",
|
|
701
|
-
boxShadow: "0 0 0 2px rgba(59, 130, 246, 0.1)"
|
|
829
|
+
boxShadow: "0 0 0 2px rgba(59, 130, 246, 0.1), 0 0 12px rgba(59, 130, 246, 0.2)",
|
|
830
|
+
animation: "grabPulse 2s ease-in-out infinite"
|
|
702
831
|
},
|
|
703
832
|
actionRow: {
|
|
704
833
|
display: "flex",
|
|
@@ -755,11 +884,18 @@ var styles3 = {
|
|
|
755
884
|
fontWeight: 600,
|
|
756
885
|
borderRadius: 4,
|
|
757
886
|
boxShadow: "0 2px 8px rgba(0, 0, 0, 0.3)"
|
|
758
|
-
}
|
|
887
|
+
},
|
|
888
|
+
pulseKeyframes: `
|
|
889
|
+
@keyframes grabPulse {
|
|
890
|
+
0%, 100% { box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1), 0 0 12px rgba(59, 130, 246, 0.2); }
|
|
891
|
+
50% { box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.15), 0 0 20px rgba(59, 130, 246, 0.3); }
|
|
892
|
+
}
|
|
893
|
+
`
|
|
759
894
|
};
|
|
760
895
|
function Toolbar(props) {
|
|
761
896
|
const { mode, stepCount, onToggleGrab, onExport, onCopyForAI, onReset } = props;
|
|
762
|
-
const [copied, setCopied] =
|
|
897
|
+
const [copied, setCopied] = useState4(false);
|
|
898
|
+
const reducedMotion = useReducedMotion();
|
|
763
899
|
const isGrabbing = mode === "grabbing";
|
|
764
900
|
const hasSteps = stepCount > 0;
|
|
765
901
|
const handleCopy = async () => {
|
|
@@ -785,14 +921,15 @@ function Toolbar(props) {
|
|
|
785
921
|
...hasSteps && styles3.actionButtonDanger
|
|
786
922
|
};
|
|
787
923
|
return /* @__PURE__ */ jsxs3("div", { style: styles3.toolbar, children: [
|
|
924
|
+
/* @__PURE__ */ jsx3("style", { children: styles3.pulseKeyframes }),
|
|
788
925
|
/* @__PURE__ */ jsx3("div", { style: styles3.grabRow, children: /* @__PURE__ */ jsx3(
|
|
789
|
-
|
|
926
|
+
motion3.button,
|
|
790
927
|
{
|
|
791
928
|
type: "button",
|
|
792
929
|
style: grabButtonStyle,
|
|
793
930
|
onClick: onToggleGrab,
|
|
794
|
-
whileHover: { scale: 1.01 },
|
|
795
|
-
whileTap: { scale: 0.98 },
|
|
931
|
+
whileHover: reducedMotion ? {} : { scale: 1.01 },
|
|
932
|
+
whileTap: reducedMotion ? {} : { scale: 0.98 },
|
|
796
933
|
children: isGrabbing ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
797
934
|
/* @__PURE__ */ jsxs3(
|
|
798
935
|
"svg",
|
|
@@ -876,14 +1013,14 @@ function Toolbar(props) {
|
|
|
876
1013
|
) }),
|
|
877
1014
|
/* @__PURE__ */ jsxs3("div", { style: styles3.actionRow, children: [
|
|
878
1015
|
/* @__PURE__ */ jsxs3(
|
|
879
|
-
|
|
1016
|
+
motion3.button,
|
|
880
1017
|
{
|
|
881
1018
|
type: "button",
|
|
882
1019
|
style: exportButtonStyle,
|
|
883
1020
|
onClick: onExport,
|
|
884
1021
|
disabled: !hasSteps,
|
|
885
|
-
whileHover: hasSteps ? { scale: 1.02 } : {},
|
|
886
|
-
whileTap: hasSteps ? { scale: 0.98 } : {},
|
|
1022
|
+
whileHover: hasSteps && !reducedMotion ? { scale: 1.02 } : {},
|
|
1023
|
+
whileTap: hasSteps && !reducedMotion ? { scale: 0.98 } : {},
|
|
887
1024
|
title: "Download JSON file",
|
|
888
1025
|
children: [
|
|
889
1026
|
/* @__PURE__ */ jsxs3("svg", { width: "11", height: "11", viewBox: "0 0 16 16", fill: "currentColor", children: [
|
|
@@ -895,14 +1032,14 @@ function Toolbar(props) {
|
|
|
895
1032
|
}
|
|
896
1033
|
),
|
|
897
1034
|
/* @__PURE__ */ jsxs3(
|
|
898
|
-
|
|
1035
|
+
motion3.button,
|
|
899
1036
|
{
|
|
900
1037
|
type: "button",
|
|
901
1038
|
style: copyButtonStyle,
|
|
902
1039
|
onClick: handleCopy,
|
|
903
1040
|
disabled: !hasSteps,
|
|
904
|
-
whileHover: hasSteps ? { scale: 1.02 } : {},
|
|
905
|
-
whileTap: hasSteps ? { scale: 0.98 } : {},
|
|
1041
|
+
whileHover: hasSteps && !reducedMotion ? { scale: 1.02 } : {},
|
|
1042
|
+
whileTap: hasSteps && !reducedMotion ? { scale: 0.98 } : {},
|
|
906
1043
|
title: "Copy JSON to clipboard",
|
|
907
1044
|
children: [
|
|
908
1045
|
/* @__PURE__ */ jsxs3("svg", { width: "11", height: "11", viewBox: "0 0 16 16", fill: "currentColor", children: [
|
|
@@ -910,28 +1047,29 @@ function Toolbar(props) {
|
|
|
910
1047
|
/* @__PURE__ */ jsx3("path", { d: "M14 5a1 1 0 0 1 1 1v8a2 2 0 0 1-2 2H6a1 1 0 0 1 0-2h7V6a1 1 0 0 1 1-1z" })
|
|
911
1048
|
] }),
|
|
912
1049
|
"Copy",
|
|
913
|
-
copied && /* @__PURE__ */ jsx3(
|
|
914
|
-
|
|
1050
|
+
/* @__PURE__ */ jsx3(AnimatePresence2, { children: copied && /* @__PURE__ */ jsx3(
|
|
1051
|
+
motion3.span,
|
|
915
1052
|
{
|
|
916
1053
|
style: styles3.copiedBadge,
|
|
917
|
-
initial: { opacity: 0, scale: 0.
|
|
1054
|
+
initial: reducedMotion ? {} : { opacity: 0, scale: 0.5, y: 4 },
|
|
918
1055
|
animate: { opacity: 1, scale: 1, y: 0 },
|
|
919
|
-
exit: { opacity: 0, scale: 0.
|
|
1056
|
+
exit: reducedMotion ? {} : { opacity: 0, scale: 0.5, y: 4 },
|
|
1057
|
+
transition: reducedMotion ? { duration: 0 } : springs.bouncy,
|
|
920
1058
|
children: "Copied!"
|
|
921
1059
|
}
|
|
922
|
-
)
|
|
1060
|
+
) })
|
|
923
1061
|
]
|
|
924
1062
|
}
|
|
925
1063
|
),
|
|
926
1064
|
/* @__PURE__ */ jsxs3(
|
|
927
|
-
|
|
1065
|
+
motion3.button,
|
|
928
1066
|
{
|
|
929
1067
|
type: "button",
|
|
930
1068
|
style: resetButtonStyle,
|
|
931
1069
|
onClick: onReset,
|
|
932
1070
|
disabled: !hasSteps,
|
|
933
|
-
whileHover: hasSteps ? { scale: 1.02 } : {},
|
|
934
|
-
whileTap: hasSteps ? { scale: 0.98 } : {},
|
|
1071
|
+
whileHover: hasSteps && !reducedMotion ? { scale: 1.02 } : {},
|
|
1072
|
+
whileTap: hasSteps && !reducedMotion ? { scale: 0.98 } : {},
|
|
935
1073
|
title: "Clear all steps",
|
|
936
1074
|
children: [
|
|
937
1075
|
/* @__PURE__ */ jsxs3("svg", { width: "11", height: "11", viewBox: "0 0 16 16", fill: "currentColor", children: [
|
|
@@ -1012,7 +1150,8 @@ function StepList(props) {
|
|
|
1012
1150
|
onClearAll,
|
|
1013
1151
|
onExport
|
|
1014
1152
|
} = props;
|
|
1015
|
-
const [activeId, setActiveId] =
|
|
1153
|
+
const [activeId, setActiveId] = useState5(null);
|
|
1154
|
+
const reducedMotion = useReducedMotion();
|
|
1016
1155
|
const activeStep = activeId ? steps.find((s) => s.id === activeId) : null;
|
|
1017
1156
|
const activeIndex = activeId ? steps.findIndex((s) => s.id === activeId) : -1;
|
|
1018
1157
|
const sensors = useSensors(
|
|
@@ -1079,26 +1218,37 @@ function StepList(props) {
|
|
|
1079
1218
|
onReset: handleReset
|
|
1080
1219
|
}
|
|
1081
1220
|
),
|
|
1082
|
-
/* @__PURE__ */ jsx4("div", { style: styles4.scrollArea, children: steps.length === 0 ? /* @__PURE__ */ jsxs4(
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1221
|
+
/* @__PURE__ */ jsx4("div", { style: styles4.scrollArea, children: /* @__PURE__ */ jsx4(AnimatePresence3, { mode: "wait", children: steps.length === 0 ? /* @__PURE__ */ jsxs4(
|
|
1222
|
+
motion4.div,
|
|
1223
|
+
{
|
|
1224
|
+
style: styles4.empty,
|
|
1225
|
+
initial: reducedMotion ? {} : { opacity: 0 },
|
|
1226
|
+
animate: { opacity: 1 },
|
|
1227
|
+
exit: reducedMotion ? {} : { opacity: 0 },
|
|
1228
|
+
transition: { duration: 0.2 },
|
|
1229
|
+
children: [
|
|
1230
|
+
/* @__PURE__ */ jsx4("div", { style: styles4.emptyIcon, children: /* @__PURE__ */ jsx4(
|
|
1231
|
+
"svg",
|
|
1232
|
+
{
|
|
1233
|
+
width: "20",
|
|
1234
|
+
height: "20",
|
|
1235
|
+
viewBox: "0 0 16 16",
|
|
1236
|
+
fill: "hsl(215 20% 45%)",
|
|
1237
|
+
children: /* @__PURE__ */ jsx4("path", { d: "M14 0a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12zM5.904 10.803L10 6.707v2.768a.5.5 0 0 0 1 0V5.5a.5.5 0 0 0-.5-.5H6.525a.5.5 0 1 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 .707.707z" })
|
|
1238
|
+
}
|
|
1239
|
+
) }),
|
|
1240
|
+
/* @__PURE__ */ jsxs4("div", { style: styles4.emptyText, children: [
|
|
1241
|
+
/* @__PURE__ */ jsx4("div", { children: "No steps captured yet." }),
|
|
1242
|
+
/* @__PURE__ */ jsxs4("div", { style: { marginTop: 6 }, children: [
|
|
1243
|
+
"Press ",
|
|
1244
|
+
/* @__PURE__ */ jsx4("span", { style: styles4.kbd, children: "Ctrl+Shift+G" }),
|
|
1245
|
+
" to grab"
|
|
1246
|
+
] })
|
|
1247
|
+
] })
|
|
1248
|
+
]
|
|
1249
|
+
},
|
|
1250
|
+
"empty-state"
|
|
1251
|
+
) : /* @__PURE__ */ jsxs4(
|
|
1102
1252
|
DndContext,
|
|
1103
1253
|
{
|
|
1104
1254
|
sensors,
|
|
@@ -1112,34 +1262,56 @@ function StepList(props) {
|
|
|
1112
1262
|
{
|
|
1113
1263
|
items: steps.map((s) => s.id),
|
|
1114
1264
|
strategy: verticalListSortingStrategy,
|
|
1115
|
-
children: /* @__PURE__ */ jsx4(
|
|
1116
|
-
|
|
1265
|
+
children: /* @__PURE__ */ jsx4(
|
|
1266
|
+
motion4.div,
|
|
1117
1267
|
{
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1268
|
+
style: styles4.stepList,
|
|
1269
|
+
variants: reducedMotion ? void 0 : listContainerVariants,
|
|
1270
|
+
initial: "hidden",
|
|
1271
|
+
animate: "visible",
|
|
1272
|
+
children: /* @__PURE__ */ jsx4(AnimatePresence3, { mode: "popLayout", children: steps.map((step, index) => /* @__PURE__ */ jsx4(
|
|
1273
|
+
motion4.div,
|
|
1274
|
+
{
|
|
1275
|
+
variants: reducedMotion ? void 0 : listItemVariants,
|
|
1276
|
+
initial: "hidden",
|
|
1277
|
+
animate: "visible",
|
|
1278
|
+
exit: "exit",
|
|
1279
|
+
children: /* @__PURE__ */ jsx4(
|
|
1280
|
+
SortableStepItem,
|
|
1281
|
+
{
|
|
1282
|
+
step,
|
|
1283
|
+
index,
|
|
1284
|
+
onDelete: () => onDeleteStep({ id: step.id }),
|
|
1285
|
+
isDragActive: activeId !== null,
|
|
1286
|
+
isBeingDragged: step.id === activeId
|
|
1287
|
+
}
|
|
1288
|
+
)
|
|
1289
|
+
},
|
|
1290
|
+
step.id
|
|
1291
|
+
)) })
|
|
1123
1292
|
},
|
|
1124
|
-
step
|
|
1125
|
-
)
|
|
1293
|
+
"step-list"
|
|
1294
|
+
)
|
|
1126
1295
|
}
|
|
1127
1296
|
),
|
|
1128
1297
|
/* @__PURE__ */ jsx4(DragOverlay, { dropAnimation: null, children: activeStep && /* @__PURE__ */ jsx4(StepItemDragPreview, { step: activeStep, index: activeIndex }) })
|
|
1129
1298
|
]
|
|
1130
1299
|
}
|
|
1131
|
-
) })
|
|
1300
|
+
) }) })
|
|
1132
1301
|
] });
|
|
1133
1302
|
}
|
|
1134
1303
|
|
|
1135
1304
|
// src/devtools/components/TabNav.tsx
|
|
1305
|
+
import { AnimatePresence as AnimatePresence4, motion as motion5 } from "motion/react";
|
|
1306
|
+
import { useEffect as useEffect3, useRef } from "react";
|
|
1136
1307
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1137
1308
|
var styles5 = {
|
|
1138
1309
|
container: {
|
|
1139
1310
|
display: "flex",
|
|
1140
1311
|
gap: 2,
|
|
1141
1312
|
padding: "8px 10px 0",
|
|
1142
|
-
borderBottom: "1px solid hsl(215 20% 20%)"
|
|
1313
|
+
borderBottom: "1px solid hsl(215 20% 20%)",
|
|
1314
|
+
position: "relative"
|
|
1143
1315
|
},
|
|
1144
1316
|
tab: {
|
|
1145
1317
|
flex: 1,
|
|
@@ -1156,13 +1328,21 @@ var styles5 = {
|
|
|
1156
1328
|
fontWeight: 500,
|
|
1157
1329
|
fontFamily: "inherit",
|
|
1158
1330
|
cursor: "pointer",
|
|
1159
|
-
transition: "
|
|
1331
|
+
transition: "color 0.15s ease",
|
|
1160
1332
|
outline: "none",
|
|
1161
|
-
marginBottom: -1
|
|
1333
|
+
marginBottom: -1,
|
|
1334
|
+
position: "relative",
|
|
1335
|
+
zIndex: 1
|
|
1162
1336
|
},
|
|
1163
1337
|
tabActive: {
|
|
1164
|
-
color: "hsl(217 91% 70%)"
|
|
1165
|
-
|
|
1338
|
+
color: "hsl(217 91% 70%)"
|
|
1339
|
+
},
|
|
1340
|
+
indicator: {
|
|
1341
|
+
position: "absolute",
|
|
1342
|
+
bottom: -1,
|
|
1343
|
+
height: 2,
|
|
1344
|
+
backgroundColor: "hsl(217 91% 60%)",
|
|
1345
|
+
borderRadius: 1
|
|
1166
1346
|
},
|
|
1167
1347
|
badge: {
|
|
1168
1348
|
display: "inline-flex",
|
|
@@ -1184,6 +1364,17 @@ var styles5 = {
|
|
|
1184
1364
|
};
|
|
1185
1365
|
function TabNav(props) {
|
|
1186
1366
|
const { activeTab, onTabChange, stepCount, flowCount } = props;
|
|
1367
|
+
const reducedMotion = useReducedMotion();
|
|
1368
|
+
const prevStepCount = useRef(stepCount);
|
|
1369
|
+
const prevFlowCount = useRef(flowCount);
|
|
1370
|
+
const stepCountChanged = stepCount !== prevStepCount.current;
|
|
1371
|
+
const flowCountChanged = flowCount !== prevFlowCount.current;
|
|
1372
|
+
useEffect3(() => {
|
|
1373
|
+
prevStepCount.current = stepCount;
|
|
1374
|
+
}, [stepCount]);
|
|
1375
|
+
useEffect3(() => {
|
|
1376
|
+
prevFlowCount.current = flowCount;
|
|
1377
|
+
}, [flowCount]);
|
|
1187
1378
|
const stepsTabStyle = {
|
|
1188
1379
|
...styles5.tab,
|
|
1189
1380
|
...activeTab === "steps" && styles5.tabActive
|
|
@@ -1210,7 +1401,21 @@ function TabNav(props) {
|
|
|
1210
1401
|
children: [
|
|
1211
1402
|
/* @__PURE__ */ jsx5("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx5("path", { d: "M14 0a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12zM5.904 10.803L10 6.707v2.768a.5.5 0 0 0 1 0V5.5a.5.5 0 0 0-.5-.5H6.525a.5.5 0 1 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 .707.707z" }) }),
|
|
1212
1403
|
"Steps",
|
|
1213
|
-
|
|
1404
|
+
/* @__PURE__ */ jsx5(AnimatePresence4, { mode: "popLayout", children: stepCount > 0 && /* @__PURE__ */ jsx5(
|
|
1405
|
+
motion5.span,
|
|
1406
|
+
{
|
|
1407
|
+
style: stepsBadgeStyle,
|
|
1408
|
+
initial: stepCountChanged && !reducedMotion ? { scale: 1.3 } : { scale: 1 },
|
|
1409
|
+
animate: {
|
|
1410
|
+
scale: stepCountChanged && !reducedMotion ? [1.3, 1] : 1,
|
|
1411
|
+
opacity: 1
|
|
1412
|
+
},
|
|
1413
|
+
exit: { scale: 0.8, opacity: 0 },
|
|
1414
|
+
transition: reducedMotion ? { duration: 0 } : springs.bouncy,
|
|
1415
|
+
children: stepCount
|
|
1416
|
+
},
|
|
1417
|
+
"step-badge"
|
|
1418
|
+
) })
|
|
1214
1419
|
]
|
|
1215
1420
|
}
|
|
1216
1421
|
),
|
|
@@ -1223,19 +1428,44 @@ function TabNav(props) {
|
|
|
1223
1428
|
children: [
|
|
1224
1429
|
/* @__PURE__ */ jsx5("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx5("path", { d: "M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H14a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 2 7h5.5V6A1.5 1.5 0 0 1 6 4.5v-1zm-3 8A1.5 1.5 0 0 1 4.5 10h1A1.5 1.5 0 0 1 7 11.5v1A1.5 1.5 0 0 1 5.5 14h-1A1.5 1.5 0 0 1 3 12.5v-1zm6 0a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1A1.5 1.5 0 0 1 9 12.5v-1z" }) }),
|
|
1225
1430
|
"Flows",
|
|
1226
|
-
|
|
1431
|
+
/* @__PURE__ */ jsx5(AnimatePresence4, { mode: "popLayout", children: flowCount > 0 && /* @__PURE__ */ jsx5(
|
|
1432
|
+
motion5.span,
|
|
1433
|
+
{
|
|
1434
|
+
style: flowsBadgeStyle,
|
|
1435
|
+
initial: { scale: 0.8, opacity: 0 },
|
|
1436
|
+
animate: {
|
|
1437
|
+
scale: flowCountChanged && !reducedMotion ? [1.3, 1] : 1,
|
|
1438
|
+
opacity: 1
|
|
1439
|
+
},
|
|
1440
|
+
exit: { scale: 0.8, opacity: 0 },
|
|
1441
|
+
transition: reducedMotion ? { duration: 0 } : springs.bouncy,
|
|
1442
|
+
children: flowCount
|
|
1443
|
+
},
|
|
1444
|
+
"flow-badge"
|
|
1445
|
+
) })
|
|
1227
1446
|
]
|
|
1228
1447
|
}
|
|
1448
|
+
),
|
|
1449
|
+
/* @__PURE__ */ jsx5(
|
|
1450
|
+
"div",
|
|
1451
|
+
{
|
|
1452
|
+
style: {
|
|
1453
|
+
...styles5.indicator,
|
|
1454
|
+
left: activeTab === "steps" ? 10 : "50%",
|
|
1455
|
+
width: "calc(50% - 11px)",
|
|
1456
|
+
transition: reducedMotion ? "none" : "left 0.2s cubic-bezier(0.16, 1, 0.3, 1)"
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1229
1459
|
)
|
|
1230
1460
|
] });
|
|
1231
1461
|
}
|
|
1232
1462
|
|
|
1233
1463
|
// src/devtools/components/FlowsTab.tsx
|
|
1234
|
-
import { useCallback as useCallback4, useState as
|
|
1235
|
-
import { motion as
|
|
1464
|
+
import { useCallback as useCallback4, useState as useState9 } from "react";
|
|
1465
|
+
import { motion as motion8, AnimatePresence as AnimatePresence7 } from "motion/react";
|
|
1236
1466
|
|
|
1237
1467
|
// src/devtools/hooks/useFlowsData.ts
|
|
1238
|
-
import { useCallback as useCallback2, useEffect, useState as
|
|
1468
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useState as useState6, useSyncExternalStore } from "react";
|
|
1239
1469
|
|
|
1240
1470
|
// src/devtools/globalBridge.ts
|
|
1241
1471
|
var BRIDGE_KEY = "__FLOWSTERIX_DEVTOOLS_BRIDGE__";
|
|
@@ -1271,7 +1501,7 @@ function useBridge() {
|
|
|
1271
1501
|
}
|
|
1272
1502
|
function useFlowsData() {
|
|
1273
1503
|
const bridge = useBridge();
|
|
1274
|
-
const [flowsData, setFlowsData] =
|
|
1504
|
+
const [flowsData, setFlowsData] = useState6([]);
|
|
1275
1505
|
const loadFlowStates = useCallback2(async () => {
|
|
1276
1506
|
if (!bridge) {
|
|
1277
1507
|
setFlowsData([]);
|
|
@@ -1296,7 +1526,7 @@ function useFlowsData() {
|
|
|
1296
1526
|
const results = await Promise.all(flowDataPromises);
|
|
1297
1527
|
setFlowsData(results);
|
|
1298
1528
|
}, [bridge]);
|
|
1299
|
-
|
|
1529
|
+
useEffect4(() => {
|
|
1300
1530
|
void loadFlowStates();
|
|
1301
1531
|
}, [loadFlowStates]);
|
|
1302
1532
|
const deleteFlow = useCallback2(
|
|
@@ -1327,8 +1557,8 @@ function useFlowsData() {
|
|
|
1327
1557
|
}
|
|
1328
1558
|
|
|
1329
1559
|
// src/devtools/components/FlowItem.tsx
|
|
1330
|
-
import { useState as
|
|
1331
|
-
import { motion as
|
|
1560
|
+
import { useState as useState7 } from "react";
|
|
1561
|
+
import { motion as motion6, AnimatePresence as AnimatePresence5 } from "motion/react";
|
|
1332
1562
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1333
1563
|
var styles6 = {
|
|
1334
1564
|
card: {
|
|
@@ -1340,7 +1570,12 @@ var styles6 = {
|
|
|
1340
1570
|
borderRadius: 8,
|
|
1341
1571
|
border: "1px solid hsl(215 20% 22%)",
|
|
1342
1572
|
fontSize: 12,
|
|
1343
|
-
fontFamily: "inherit"
|
|
1573
|
+
fontFamily: "inherit",
|
|
1574
|
+
transition: "border-color 0.15s ease, box-shadow 0.15s ease"
|
|
1575
|
+
},
|
|
1576
|
+
cardHover: {
|
|
1577
|
+
borderColor: "hsl(215 20% 28%)",
|
|
1578
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)"
|
|
1344
1579
|
},
|
|
1345
1580
|
cardActive: {
|
|
1346
1581
|
borderColor: "hsl(217 91% 55% / 0.5)",
|
|
@@ -1460,7 +1695,9 @@ var statusStyles = {
|
|
|
1460
1695
|
function FlowItem(props) {
|
|
1461
1696
|
const { flow, onEdit, onDelete } = props;
|
|
1462
1697
|
const { flowId, definition, state, isActive } = flow;
|
|
1463
|
-
const [confirmDelete, setConfirmDelete] =
|
|
1698
|
+
const [confirmDelete, setConfirmDelete] = useState7(false);
|
|
1699
|
+
const [isHovered, setIsHovered] = useState7(false);
|
|
1700
|
+
const reducedMotion = useReducedMotion();
|
|
1464
1701
|
const handleDelete = () => {
|
|
1465
1702
|
if (confirmDelete) {
|
|
1466
1703
|
onDelete();
|
|
@@ -1472,6 +1709,7 @@ function FlowItem(props) {
|
|
|
1472
1709
|
};
|
|
1473
1710
|
const cardStyle = {
|
|
1474
1711
|
...styles6.card,
|
|
1712
|
+
...isHovered && styles6.cardHover,
|
|
1475
1713
|
...isActive && styles6.cardActive
|
|
1476
1714
|
};
|
|
1477
1715
|
const statusBadgeStyle = {
|
|
@@ -1483,84 +1721,117 @@ function FlowItem(props) {
|
|
|
1483
1721
|
...confirmDelete && styles6.actionButtonDanger
|
|
1484
1722
|
};
|
|
1485
1723
|
const stepInfo = state ? `Step ${state.stepIndex + 1}/${definition.steps.length}` : null;
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1724
|
+
const currentStatus = state?.status ?? "no state";
|
|
1725
|
+
return /* @__PURE__ */ jsxs6(
|
|
1726
|
+
"div",
|
|
1727
|
+
{
|
|
1728
|
+
style: cardStyle,
|
|
1729
|
+
onMouseEnter: () => setIsHovered(true),
|
|
1730
|
+
onMouseLeave: () => setIsHovered(false),
|
|
1731
|
+
children: [
|
|
1732
|
+
/* @__PURE__ */ jsxs6("div", { style: styles6.header, children: [
|
|
1733
|
+
/* @__PURE__ */ jsxs6("div", { style: styles6.titleGroup, children: [
|
|
1734
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.flowId, children: flowId }),
|
|
1735
|
+
/* @__PURE__ */ jsx6(AnimatePresence5, { mode: "wait", children: isActive && /* @__PURE__ */ jsx6(
|
|
1736
|
+
motion6.span,
|
|
1737
|
+
{
|
|
1738
|
+
style: { ...styles6.statusBadge, ...styles6.activeBadge },
|
|
1739
|
+
initial: reducedMotion ? {} : { scale: 0.8, opacity: 0 },
|
|
1740
|
+
animate: { scale: 1, opacity: 1 },
|
|
1741
|
+
exit: reducedMotion ? {} : { scale: 0.8, opacity: 0 },
|
|
1742
|
+
transition: reducedMotion ? { duration: 0 } : springs.bouncy,
|
|
1743
|
+
children: "Active"
|
|
1744
|
+
},
|
|
1745
|
+
"active-badge"
|
|
1746
|
+
) })
|
|
1747
|
+
] }),
|
|
1748
|
+
/* @__PURE__ */ jsx6(AnimatePresence5, { mode: "wait", children: /* @__PURE__ */ jsx6(
|
|
1749
|
+
motion6.span,
|
|
1750
|
+
{
|
|
1751
|
+
style: statusBadgeStyle,
|
|
1752
|
+
initial: reducedMotion ? {} : { scale: 0.9, opacity: 0 },
|
|
1753
|
+
animate: { scale: 1, opacity: 1 },
|
|
1754
|
+
exit: reducedMotion ? {} : { scale: 0.9, opacity: 0 },
|
|
1755
|
+
transition: reducedMotion ? { duration: 0 } : { duration: 0.15 },
|
|
1756
|
+
children: currentStatus
|
|
1757
|
+
},
|
|
1758
|
+
currentStatus
|
|
1759
|
+
) })
|
|
1760
|
+
] }),
|
|
1761
|
+
state ? /* @__PURE__ */ jsxs6("div", { style: styles6.infoRow, children: [
|
|
1762
|
+
stepInfo && /* @__PURE__ */ jsxs6("div", { style: styles6.infoItem, children: [
|
|
1763
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.label, children: "Step:" }),
|
|
1764
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.value, children: stepInfo })
|
|
1765
|
+
] }),
|
|
1766
|
+
/* @__PURE__ */ jsxs6("div", { style: styles6.infoItem, children: [
|
|
1767
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.label, children: "Version:" }),
|
|
1768
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.value, children: state.version })
|
|
1769
|
+
] }),
|
|
1770
|
+
state.stepId && /* @__PURE__ */ jsxs6("div", { style: styles6.infoItem, children: [
|
|
1771
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.label, children: "ID:" }),
|
|
1772
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.value, children: state.stepId })
|
|
1773
|
+
] })
|
|
1774
|
+
] }) : /* @__PURE__ */ jsx6("div", { style: styles6.noState, children: "No stored state" }),
|
|
1775
|
+
/* @__PURE__ */ jsxs6("div", { style: styles6.actions, children: [
|
|
1776
|
+
/* @__PURE__ */ jsxs6(
|
|
1777
|
+
motion6.button,
|
|
1778
|
+
{
|
|
1779
|
+
type: "button",
|
|
1780
|
+
style: styles6.actionButton,
|
|
1781
|
+
onClick: onEdit,
|
|
1782
|
+
disabled: !state,
|
|
1783
|
+
whileHover: state && !reducedMotion ? { scale: 1.02 } : {},
|
|
1784
|
+
whileTap: state && !reducedMotion ? { scale: 0.98 } : {},
|
|
1785
|
+
title: state ? "Edit flow state" : "No state to edit",
|
|
1786
|
+
children: [
|
|
1787
|
+
/* @__PURE__ */ jsx6("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx6("path", { d: "M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" }) }),
|
|
1788
|
+
"Edit"
|
|
1789
|
+
]
|
|
1790
|
+
}
|
|
1791
|
+
),
|
|
1792
|
+
/* @__PURE__ */ jsxs6(
|
|
1793
|
+
motion6.button,
|
|
1794
|
+
{
|
|
1795
|
+
type: "button",
|
|
1796
|
+
style: deleteButtonStyle,
|
|
1797
|
+
onClick: handleDelete,
|
|
1798
|
+
disabled: !state,
|
|
1799
|
+
whileHover: state && !reducedMotion ? { scale: 1.02 } : {},
|
|
1800
|
+
whileTap: state && !reducedMotion ? { scale: 0.98 } : {},
|
|
1801
|
+
title: confirmDelete ? "Click again to confirm deletion" : state ? "Delete flow state" : "No state to delete",
|
|
1802
|
+
children: [
|
|
1803
|
+
/* @__PURE__ */ jsxs6("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: [
|
|
1804
|
+
/* @__PURE__ */ jsx6("path", { d: "M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" }),
|
|
1805
|
+
/* @__PURE__ */ jsx6(
|
|
1806
|
+
"path",
|
|
1807
|
+
{
|
|
1808
|
+
fillRule: "evenodd",
|
|
1809
|
+
d: "M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"
|
|
1810
|
+
}
|
|
1811
|
+
)
|
|
1812
|
+
] }),
|
|
1813
|
+
confirmDelete ? "Confirm?" : "Delete"
|
|
1814
|
+
]
|
|
1815
|
+
}
|
|
1816
|
+
)
|
|
1817
|
+
] })
|
|
1818
|
+
]
|
|
1819
|
+
}
|
|
1820
|
+
);
|
|
1552
1821
|
}
|
|
1553
1822
|
|
|
1554
1823
|
// src/devtools/components/FlowEditModal.tsx
|
|
1555
|
-
import { useCallback as useCallback3, useEffect as
|
|
1824
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useState as useState8 } from "react";
|
|
1556
1825
|
import { createPortal as createPortal2 } from "react-dom";
|
|
1557
|
-
import { AnimatePresence as
|
|
1826
|
+
import { AnimatePresence as AnimatePresence6, motion as motion7 } from "motion/react";
|
|
1558
1827
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1559
1828
|
var styles7 = {
|
|
1560
1829
|
overlay: {
|
|
1561
1830
|
position: "fixed",
|
|
1562
1831
|
inset: 0,
|
|
1563
1832
|
backgroundColor: "rgba(0, 0, 0, 0.6)",
|
|
1833
|
+
backdropFilter: "blur(4px)",
|
|
1834
|
+
WebkitBackdropFilter: "blur(4px)",
|
|
1564
1835
|
display: "flex",
|
|
1565
1836
|
alignItems: "center",
|
|
1566
1837
|
justifyContent: "center",
|
|
@@ -1623,7 +1894,8 @@ var styles7 = {
|
|
|
1623
1894
|
fontFamily: "ui-monospace, monospace",
|
|
1624
1895
|
resize: "vertical",
|
|
1625
1896
|
outline: "none",
|
|
1626
|
-
lineHeight: 1.5
|
|
1897
|
+
lineHeight: 1.5,
|
|
1898
|
+
transition: "border-color 0.15s ease"
|
|
1627
1899
|
},
|
|
1628
1900
|
textareaError: {
|
|
1629
1901
|
borderColor: "hsl(0 70% 50%)"
|
|
@@ -1675,14 +1947,21 @@ var styles7 = {
|
|
|
1675
1947
|
};
|
|
1676
1948
|
function FlowEditModal(props) {
|
|
1677
1949
|
const { isOpen, flowId, initialState, onClose, onSave, container } = props;
|
|
1678
|
-
const [jsonValue, setJsonValue] =
|
|
1679
|
-
const [error, setError] =
|
|
1680
|
-
|
|
1950
|
+
const [jsonValue, setJsonValue] = useState8("");
|
|
1951
|
+
const [error, setError] = useState8(null);
|
|
1952
|
+
const [shake, setShake] = useState8(false);
|
|
1953
|
+
const reducedMotion = useReducedMotion();
|
|
1954
|
+
useEffect5(() => {
|
|
1681
1955
|
if (isOpen && initialState) {
|
|
1682
1956
|
setJsonValue(JSON.stringify(initialState, null, 2));
|
|
1683
1957
|
setError(null);
|
|
1684
1958
|
}
|
|
1685
1959
|
}, [isOpen, initialState]);
|
|
1960
|
+
const triggerShake = useCallback3(() => {
|
|
1961
|
+
if (reducedMotion) return;
|
|
1962
|
+
setShake(true);
|
|
1963
|
+
setTimeout(() => setShake(false), 400);
|
|
1964
|
+
}, [reducedMotion]);
|
|
1686
1965
|
const handleSave = useCallback3(() => {
|
|
1687
1966
|
try {
|
|
1688
1967
|
const parsed = JSON.parse(jsonValue);
|
|
@@ -1699,8 +1978,9 @@ function FlowEditModal(props) {
|
|
|
1699
1978
|
onClose();
|
|
1700
1979
|
} catch (err) {
|
|
1701
1980
|
setError(err instanceof Error ? err.message : "Invalid JSON");
|
|
1981
|
+
triggerShake();
|
|
1702
1982
|
}
|
|
1703
|
-
}, [jsonValue, onSave, onClose]);
|
|
1983
|
+
}, [jsonValue, onSave, onClose, triggerShake]);
|
|
1704
1984
|
const handleKeyDown = useCallback3(
|
|
1705
1985
|
(e) => {
|
|
1706
1986
|
if (e.key === "Escape") {
|
|
@@ -1725,26 +2005,31 @@ function FlowEditModal(props) {
|
|
|
1725
2005
|
...error && styles7.buttonDisabled
|
|
1726
2006
|
};
|
|
1727
2007
|
return createPortal2(
|
|
1728
|
-
/* @__PURE__ */ jsx7(
|
|
1729
|
-
|
|
2008
|
+
/* @__PURE__ */ jsx7(AnimatePresence6, { children: isOpen && /* @__PURE__ */ jsx7(
|
|
2009
|
+
motion7.div,
|
|
1730
2010
|
{
|
|
1731
2011
|
style: styles7.overlay,
|
|
1732
|
-
initial: { opacity: 0 },
|
|
2012
|
+
initial: reducedMotion ? {} : { opacity: 0 },
|
|
1733
2013
|
animate: { opacity: 1 },
|
|
1734
|
-
exit: { opacity: 0 },
|
|
1735
|
-
transition: { duration: 0.15 },
|
|
2014
|
+
exit: reducedMotion ? {} : { opacity: 0 },
|
|
2015
|
+
transition: reducedMotion ? { duration: 0 } : { duration: 0.15 },
|
|
1736
2016
|
onClick: (e) => {
|
|
1737
2017
|
if (e.target === e.currentTarget) onClose();
|
|
1738
2018
|
},
|
|
1739
2019
|
onKeyDown: handleKeyDown,
|
|
1740
2020
|
children: /* @__PURE__ */ jsxs7(
|
|
1741
|
-
|
|
2021
|
+
motion7.div,
|
|
1742
2022
|
{
|
|
1743
2023
|
style: styles7.modal,
|
|
1744
|
-
initial: { opacity: 0, scale: 0.95, y: 10 },
|
|
1745
|
-
animate: {
|
|
1746
|
-
|
|
1747
|
-
|
|
2024
|
+
initial: reducedMotion ? {} : { opacity: 0, scale: 0.95, y: 10 },
|
|
2025
|
+
animate: {
|
|
2026
|
+
opacity: 1,
|
|
2027
|
+
scale: 1,
|
|
2028
|
+
y: 0,
|
|
2029
|
+
x: shake ? [0, -8, 8, -6, 6, -4, 4, 0] : 0
|
|
2030
|
+
},
|
|
2031
|
+
exit: reducedMotion ? {} : { opacity: 0, scale: 0.95, y: 10 },
|
|
2032
|
+
transition: reducedMotion ? { duration: 0 } : springs.smooth,
|
|
1748
2033
|
onClick: (e) => e.stopPropagation(),
|
|
1749
2034
|
children: [
|
|
1750
2035
|
/* @__PURE__ */ jsxs7("div", { style: styles7.header, children: [
|
|
@@ -1753,12 +2038,14 @@ function FlowEditModal(props) {
|
|
|
1753
2038
|
flowId
|
|
1754
2039
|
] }),
|
|
1755
2040
|
/* @__PURE__ */ jsx7(
|
|
1756
|
-
|
|
2041
|
+
motion7.button,
|
|
1757
2042
|
{
|
|
1758
2043
|
type: "button",
|
|
1759
2044
|
style: styles7.closeButton,
|
|
1760
2045
|
onClick: onClose,
|
|
1761
2046
|
title: "Close",
|
|
2047
|
+
whileHover: reducedMotion ? {} : { scale: 1.1 },
|
|
2048
|
+
whileTap: reducedMotion ? {} : { scale: 0.9 },
|
|
1762
2049
|
children: /* @__PURE__ */ jsx7("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx7("path", { d: "M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" }) })
|
|
1763
2050
|
}
|
|
1764
2051
|
)
|
|
@@ -1777,27 +2064,39 @@ function FlowEditModal(props) {
|
|
|
1777
2064
|
autoFocus: true
|
|
1778
2065
|
}
|
|
1779
2066
|
),
|
|
1780
|
-
|
|
2067
|
+
/* @__PURE__ */ jsx7(AnimatePresence6, { children: error && /* @__PURE__ */ jsx7(
|
|
2068
|
+
motion7.div,
|
|
2069
|
+
{
|
|
2070
|
+
style: styles7.error,
|
|
2071
|
+
initial: reducedMotion ? {} : { opacity: 0, y: -4 },
|
|
2072
|
+
animate: { opacity: 1, y: 0 },
|
|
2073
|
+
exit: reducedMotion ? {} : { opacity: 0, y: -4 },
|
|
2074
|
+
transition: { duration: 0.15 },
|
|
2075
|
+
children: error
|
|
2076
|
+
}
|
|
2077
|
+
) })
|
|
1781
2078
|
] }),
|
|
1782
2079
|
/* @__PURE__ */ jsxs7("div", { style: styles7.footer, children: [
|
|
1783
2080
|
/* @__PURE__ */ jsx7(
|
|
1784
|
-
|
|
2081
|
+
motion7.button,
|
|
1785
2082
|
{
|
|
1786
2083
|
type: "button",
|
|
1787
2084
|
style: styles7.button,
|
|
1788
2085
|
onClick: onClose,
|
|
2086
|
+
whileHover: reducedMotion ? {} : { scale: 1.02 },
|
|
2087
|
+
whileTap: reducedMotion ? {} : { scale: 0.98 },
|
|
1789
2088
|
children: "Cancel"
|
|
1790
2089
|
}
|
|
1791
2090
|
),
|
|
1792
2091
|
/* @__PURE__ */ jsx7(
|
|
1793
|
-
|
|
2092
|
+
motion7.button,
|
|
1794
2093
|
{
|
|
1795
2094
|
type: "button",
|
|
1796
2095
|
style: saveButtonStyle,
|
|
1797
2096
|
onClick: handleSave,
|
|
1798
2097
|
disabled: !!error,
|
|
1799
|
-
whileHover: !error ? { scale: 1.02 } : {},
|
|
1800
|
-
whileTap: !error ? { scale: 0.98 } : {},
|
|
2098
|
+
whileHover: !error && !reducedMotion ? { scale: 1.02 } : {},
|
|
2099
|
+
whileTap: !error && !reducedMotion ? { scale: 0.98 } : {},
|
|
1801
2100
|
children: "Save"
|
|
1802
2101
|
}
|
|
1803
2102
|
)
|
|
@@ -1885,7 +2184,8 @@ var styles8 = {
|
|
|
1885
2184
|
function FlowsTab(props) {
|
|
1886
2185
|
const { container } = props;
|
|
1887
2186
|
const { flows, refreshFlows, deleteFlow, updateFlow } = useFlowsData();
|
|
1888
|
-
const
|
|
2187
|
+
const reducedMotion = useReducedMotion();
|
|
2188
|
+
const [editModal, setEditModal] = useState9({
|
|
1889
2189
|
isOpen: false,
|
|
1890
2190
|
flowId: "",
|
|
1891
2191
|
state: null
|
|
@@ -1940,7 +2240,7 @@ function FlowsTab(props) {
|
|
|
1940
2240
|
" registered"
|
|
1941
2241
|
] }),
|
|
1942
2242
|
/* @__PURE__ */ jsxs8(
|
|
1943
|
-
|
|
2243
|
+
motion8.button,
|
|
1944
2244
|
{
|
|
1945
2245
|
type: "button",
|
|
1946
2246
|
style: styles8.refreshButton,
|
|
@@ -1964,15 +2264,33 @@ function FlowsTab(props) {
|
|
|
1964
2264
|
}
|
|
1965
2265
|
)
|
|
1966
2266
|
] }),
|
|
1967
|
-
/* @__PURE__ */ jsx8(
|
|
1968
|
-
|
|
2267
|
+
/* @__PURE__ */ jsx8(
|
|
2268
|
+
motion8.div,
|
|
1969
2269
|
{
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
2270
|
+
style: styles8.flowList,
|
|
2271
|
+
variants: reducedMotion ? void 0 : listContainerVariants,
|
|
2272
|
+
initial: "hidden",
|
|
2273
|
+
animate: "visible",
|
|
2274
|
+
children: /* @__PURE__ */ jsx8(AnimatePresence7, { mode: "popLayout", children: flows.map((flow) => /* @__PURE__ */ jsx8(
|
|
2275
|
+
motion8.div,
|
|
2276
|
+
{
|
|
2277
|
+
variants: reducedMotion ? void 0 : listItemVariants,
|
|
2278
|
+
initial: "hidden",
|
|
2279
|
+
animate: "visible",
|
|
2280
|
+
exit: "exit",
|
|
2281
|
+
children: /* @__PURE__ */ jsx8(
|
|
2282
|
+
FlowItem,
|
|
2283
|
+
{
|
|
2284
|
+
flow,
|
|
2285
|
+
onEdit: () => handleEdit(flow.flowId, flow.state),
|
|
2286
|
+
onDelete: () => void handleDelete(flow.flowId)
|
|
2287
|
+
}
|
|
2288
|
+
)
|
|
2289
|
+
},
|
|
2290
|
+
flow.flowId
|
|
2291
|
+
)) })
|
|
2292
|
+
}
|
|
2293
|
+
),
|
|
1976
2294
|
editModal.state && /* @__PURE__ */ jsx8(
|
|
1977
2295
|
FlowEditModal,
|
|
1978
2296
|
{
|
|
@@ -1988,7 +2306,7 @@ function FlowsTab(props) {
|
|
|
1988
2306
|
}
|
|
1989
2307
|
|
|
1990
2308
|
// src/devtools/hooks/useGrabMode.ts
|
|
1991
|
-
import { useCallback as useCallback6, useEffect as
|
|
2309
|
+
import { useCallback as useCallback6, useEffect as useEffect6, useState as useState10 } from "react";
|
|
1992
2310
|
|
|
1993
2311
|
// src/devtools/hooks/useElementInfo.ts
|
|
1994
2312
|
import { useCallback as useCallback5 } from "react";
|
|
@@ -2125,8 +2443,8 @@ function isDevToolsElement(element) {
|
|
|
2125
2443
|
return false;
|
|
2126
2444
|
}
|
|
2127
2445
|
function useGrabMode() {
|
|
2128
|
-
const [mode, setMode] =
|
|
2129
|
-
const [hoveredElement, setHoveredElement] =
|
|
2446
|
+
const [mode, setMode] = useState10("idle");
|
|
2447
|
+
const [hoveredElement, setHoveredElement] = useState10(null);
|
|
2130
2448
|
const { getElementInfo } = useElementInfo();
|
|
2131
2449
|
const startGrabbing = useCallback6(() => {
|
|
2132
2450
|
setMode("grabbing");
|
|
@@ -2144,7 +2462,7 @@ function useGrabMode() {
|
|
|
2144
2462
|
if (!hoveredElement) return null;
|
|
2145
2463
|
return hoveredElement.info;
|
|
2146
2464
|
}, [hoveredElement]);
|
|
2147
|
-
|
|
2465
|
+
useEffect6(() => {
|
|
2148
2466
|
if (mode !== "grabbing") return;
|
|
2149
2467
|
const handleMouseMove = (e) => {
|
|
2150
2468
|
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
@@ -2168,7 +2486,7 @@ function useGrabMode() {
|
|
|
2168
2486
|
document.addEventListener("mousemove", handleMouseMove, { passive: true });
|
|
2169
2487
|
return () => document.removeEventListener("mousemove", handleMouseMove);
|
|
2170
2488
|
}, [mode, getElementInfo]);
|
|
2171
|
-
|
|
2489
|
+
useEffect6(() => {
|
|
2172
2490
|
const handleKeyDown = (e) => {
|
|
2173
2491
|
if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "g") {
|
|
2174
2492
|
e.preventDefault();
|
|
@@ -2195,7 +2513,7 @@ function useGrabMode() {
|
|
|
2195
2513
|
}
|
|
2196
2514
|
|
|
2197
2515
|
// src/devtools/hooks/useStepStore.ts
|
|
2198
|
-
import { useCallback as useCallback7, useEffect as
|
|
2516
|
+
import { useCallback as useCallback7, useEffect as useEffect7, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2199
2517
|
|
|
2200
2518
|
// src/devtools/utils/storage.ts
|
|
2201
2519
|
var STORAGE_KEY = "flowsterix-devtools-steps";
|
|
@@ -2258,14 +2576,14 @@ function generateId() {
|
|
|
2258
2576
|
}
|
|
2259
2577
|
function useStepStore() {
|
|
2260
2578
|
const steps = useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot);
|
|
2261
|
-
|
|
2579
|
+
useEffect7(() => {
|
|
2262
2580
|
const saved = loadSteps();
|
|
2263
2581
|
if (saved.length > 0) {
|
|
2264
2582
|
store.steps = saved;
|
|
2265
2583
|
notifyListeners();
|
|
2266
2584
|
}
|
|
2267
2585
|
}, []);
|
|
2268
|
-
|
|
2586
|
+
useEffect7(() => {
|
|
2269
2587
|
saveSteps(steps);
|
|
2270
2588
|
}, [steps]);
|
|
2271
2589
|
const addStep = useCallback7((params) => {
|
|
@@ -2452,10 +2770,10 @@ var styles9 = {
|
|
|
2452
2770
|
};
|
|
2453
2771
|
function DevToolsProvider(props) {
|
|
2454
2772
|
const { children, enabled = true, defaultTab = "steps" } = props;
|
|
2455
|
-
const [mounted, setMounted] =
|
|
2456
|
-
const [shadowRoot, setShadowRoot] =
|
|
2457
|
-
const [activeTab, setActiveTab] =
|
|
2458
|
-
|
|
2773
|
+
const [mounted, setMounted] = useState11(false);
|
|
2774
|
+
const [shadowRoot, setShadowRoot] = useState11(null);
|
|
2775
|
+
const [activeTab, setActiveTab] = useState11(defaultTab);
|
|
2776
|
+
useEffect8(() => {
|
|
2459
2777
|
setMounted(true);
|
|
2460
2778
|
const host = document.createElement("div");
|
|
2461
2779
|
host.setAttribute("data-devtools-host", "");
|
|
@@ -2486,10 +2804,10 @@ function DevToolsProvider(props) {
|
|
|
2486
2804
|
exportSteps
|
|
2487
2805
|
} = useStepStore();
|
|
2488
2806
|
const { flows } = useFlowsData();
|
|
2489
|
-
const [collapsed, setCollapsed] =
|
|
2490
|
-
const [position, setPosition] =
|
|
2491
|
-
const [isPanelDragging, setIsPanelDragging] =
|
|
2492
|
-
const dragStartRef =
|
|
2807
|
+
const [collapsed, setCollapsed] = useState11(false);
|
|
2808
|
+
const [position, setPosition] = useState11({ x: 16, y: 16 });
|
|
2809
|
+
const [isPanelDragging, setIsPanelDragging] = useState11(false);
|
|
2810
|
+
const dragStartRef = useRef2(null);
|
|
2493
2811
|
const handleClick = useCallback8(
|
|
2494
2812
|
(e) => {
|
|
2495
2813
|
if (mode !== "grabbing") return;
|
|
@@ -2510,12 +2828,12 @@ function DevToolsProvider(props) {
|
|
|
2510
2828
|
},
|
|
2511
2829
|
[mode, selectCurrent, addStep]
|
|
2512
2830
|
);
|
|
2513
|
-
|
|
2831
|
+
useEffect8(() => {
|
|
2514
2832
|
if (mode !== "grabbing") return;
|
|
2515
2833
|
document.addEventListener("click", handleClick, { capture: true });
|
|
2516
2834
|
return () => document.removeEventListener("click", handleClick, { capture: true });
|
|
2517
2835
|
}, [mode, handleClick]);
|
|
2518
|
-
|
|
2836
|
+
useEffect8(() => {
|
|
2519
2837
|
if (mode !== "grabbing") return;
|
|
2520
2838
|
const preventDefault = (e) => {
|
|
2521
2839
|
const target = e.target;
|
|
@@ -2527,7 +2845,7 @@ function DevToolsProvider(props) {
|
|
|
2527
2845
|
document.removeEventListener("submit", preventDefault, { capture: true });
|
|
2528
2846
|
};
|
|
2529
2847
|
}, [mode]);
|
|
2530
|
-
|
|
2848
|
+
useEffect8(() => {
|
|
2531
2849
|
const handleKeyDown = (e) => {
|
|
2532
2850
|
if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "m") {
|
|
2533
2851
|
e.preventDefault();
|
|
@@ -2580,7 +2898,8 @@ function DevToolsProvider(props) {
|
|
|
2580
2898
|
};
|
|
2581
2899
|
const headerStyle = {
|
|
2582
2900
|
...styles9.header,
|
|
2583
|
-
...isPanelDragging && styles9.headerDragging
|
|
2901
|
+
...isPanelDragging && styles9.headerDragging,
|
|
2902
|
+
...collapsed && { borderBottom: "none" }
|
|
2584
2903
|
};
|
|
2585
2904
|
const portalContainer = shadowContainer ?? document.body;
|
|
2586
2905
|
return /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
@@ -2595,9 +2914,11 @@ function DevToolsProvider(props) {
|
|
|
2595
2914
|
),
|
|
2596
2915
|
createPortal3(
|
|
2597
2916
|
/* @__PURE__ */ jsxs9(
|
|
2598
|
-
|
|
2917
|
+
motion9.div,
|
|
2599
2918
|
{
|
|
2600
2919
|
style: panelStyle,
|
|
2920
|
+
layoutRoot: true,
|
|
2921
|
+
layout: "size",
|
|
2601
2922
|
initial: { opacity: 0, x: 20, scale: 0.95 },
|
|
2602
2923
|
animate: { opacity: 1, x: 0, scale: 1 },
|
|
2603
2924
|
transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
|
|
@@ -2645,15 +2966,22 @@ function DevToolsProvider(props) {
|
|
|
2645
2966
|
]
|
|
2646
2967
|
}
|
|
2647
2968
|
),
|
|
2648
|
-
/* @__PURE__ */ jsx9(
|
|
2649
|
-
|
|
2969
|
+
/* @__PURE__ */ jsx9(
|
|
2970
|
+
motion9.div,
|
|
2650
2971
|
{
|
|
2651
|
-
style:
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2972
|
+
style: {
|
|
2973
|
+
...styles9.body,
|
|
2974
|
+
overflow: "hidden",
|
|
2975
|
+
flex: collapsed ? "0 0 auto" : "1 1 auto"
|
|
2976
|
+
},
|
|
2977
|
+
initial: false,
|
|
2978
|
+
animate: { height: collapsed ? 0 : "auto", opacity: collapsed ? 0 : 1 },
|
|
2979
|
+
transition: {
|
|
2980
|
+
height: springs.smooth,
|
|
2981
|
+
opacity: { duration: 0.12 }
|
|
2982
|
+
},
|
|
2983
|
+
"aria-hidden": collapsed,
|
|
2984
|
+
children: /* @__PURE__ */ jsxs9("div", { style: { pointerEvents: collapsed ? "none" : "auto" }, children: [
|
|
2657
2985
|
/* @__PURE__ */ jsx9(
|
|
2658
2986
|
TabNav,
|
|
2659
2987
|
{
|
|
@@ -2675,9 +3003,9 @@ function DevToolsProvider(props) {
|
|
|
2675
3003
|
onExport: exportSteps
|
|
2676
3004
|
}
|
|
2677
3005
|
) : /* @__PURE__ */ jsx9(FlowsTab, { container: shadowContainer })
|
|
2678
|
-
]
|
|
3006
|
+
] })
|
|
2679
3007
|
}
|
|
2680
|
-
)
|
|
3008
|
+
)
|
|
2681
3009
|
]
|
|
2682
3010
|
}
|
|
2683
3011
|
),
|