@flowsterix/react 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-D5LQLRSU.cjs +289 -0
- package/dist/chunk-FCOKCGV3.cjs +21 -0
- package/dist/chunk-HPVLOLCD.cjs +1 -0
- package/dist/components/TourPopoverPortal.d.ts +1 -1
- package/dist/components/TourPopoverPortal.d.ts.map +1 -1
- package/dist/context.d.ts +6 -0
- package/dist/context.d.ts.map +1 -1
- 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/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/globalBridge.d.ts +24 -0
- package/dist/devtools/globalBridge.d.ts.map +1 -0
- package/dist/devtools/hooks/useFlowsData.d.ts.map +1 -1
- package/dist/devtools/index.cjs +849 -577
- package/dist/devtools/index.mjs +605 -281
- package/dist/devtools/motion.d.ts +64 -0
- package/dist/devtools/motion.d.ts.map +1 -0
- package/dist/hooks/useHiddenTargetFallback.d.ts.map +1 -1
- package/dist/hooks/useTourOverlay.d.ts.map +1 -1
- package/dist/index.cjs +701 -927
- package/dist/index.mjs +116 -42
- package/dist/router/index.cjs +13 -202
- package/dist/router/nextAppRouterAdapter.cjs +11 -200
- package/dist/router/nextPagesRouterAdapter.cjs +10 -199
- package/dist/router/reactRouterAdapter.cjs +10 -199
- package/dist/router/tanstackRouterAdapter.cjs +22 -214
- 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 { AnimatePresence as
|
|
10
|
+
import { AnimatePresence as AnimatePresence7, 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 { useEffect as useEffect3, useRef } from "react";
|
|
1306
|
+
import { motion as motion5, AnimatePresence as AnimatePresence4 } from "motion/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,18 @@ 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: { scale: 1 },
|
|
1410
|
+
exit: { scale: 0.8, opacity: 0 },
|
|
1411
|
+
transition: reducedMotion ? { duration: 0 } : springs.bouncy,
|
|
1412
|
+
children: stepCount
|
|
1413
|
+
},
|
|
1414
|
+
`step-badge-${stepCount}`
|
|
1415
|
+
) })
|
|
1214
1416
|
]
|
|
1215
1417
|
}
|
|
1216
1418
|
),
|
|
@@ -1223,28 +1425,83 @@ function TabNav(props) {
|
|
|
1223
1425
|
children: [
|
|
1224
1426
|
/* @__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
1427
|
"Flows",
|
|
1226
|
-
|
|
1428
|
+
/* @__PURE__ */ jsx5(AnimatePresence4, { mode: "popLayout", children: flowCount > 0 && /* @__PURE__ */ jsx5(
|
|
1429
|
+
motion5.span,
|
|
1430
|
+
{
|
|
1431
|
+
style: flowsBadgeStyle,
|
|
1432
|
+
initial: flowCountChanged && !reducedMotion ? { scale: 1.3 } : { scale: 1 },
|
|
1433
|
+
animate: { scale: 1 },
|
|
1434
|
+
exit: { scale: 0.8, opacity: 0 },
|
|
1435
|
+
transition: reducedMotion ? { duration: 0 } : springs.bouncy,
|
|
1436
|
+
children: flowCount
|
|
1437
|
+
},
|
|
1438
|
+
`flow-badge-${flowCount}`
|
|
1439
|
+
) })
|
|
1227
1440
|
]
|
|
1228
1441
|
}
|
|
1442
|
+
),
|
|
1443
|
+
/* @__PURE__ */ jsx5(
|
|
1444
|
+
"div",
|
|
1445
|
+
{
|
|
1446
|
+
style: {
|
|
1447
|
+
...styles5.indicator,
|
|
1448
|
+
left: activeTab === "steps" ? 10 : "50%",
|
|
1449
|
+
width: "calc(50% - 11px)",
|
|
1450
|
+
transition: reducedMotion ? "none" : "left 0.2s cubic-bezier(0.16, 1, 0.3, 1)"
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1229
1453
|
)
|
|
1230
1454
|
] });
|
|
1231
1455
|
}
|
|
1232
1456
|
|
|
1233
1457
|
// src/devtools/components/FlowsTab.tsx
|
|
1234
|
-
import { useCallback as useCallback4, useState as
|
|
1235
|
-
import { motion as
|
|
1458
|
+
import { useCallback as useCallback4, useState as useState9 } from "react";
|
|
1459
|
+
import { motion as motion8 } from "motion/react";
|
|
1460
|
+
|
|
1461
|
+
// src/devtools/hooks/useFlowsData.ts
|
|
1462
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useState as useState6, useSyncExternalStore } from "react";
|
|
1463
|
+
|
|
1464
|
+
// src/devtools/globalBridge.ts
|
|
1465
|
+
var BRIDGE_KEY = "__FLOWSTERIX_DEVTOOLS_BRIDGE__";
|
|
1466
|
+
function getBridge() {
|
|
1467
|
+
if (typeof window === "undefined") {
|
|
1468
|
+
return { value: null, listeners: /* @__PURE__ */ new Set() };
|
|
1469
|
+
}
|
|
1470
|
+
const w = window;
|
|
1471
|
+
if (!w[BRIDGE_KEY]) {
|
|
1472
|
+
w[BRIDGE_KEY] = { value: null, listeners: /* @__PURE__ */ new Set() };
|
|
1473
|
+
}
|
|
1474
|
+
return w[BRIDGE_KEY];
|
|
1475
|
+
}
|
|
1476
|
+
function getDevToolsBridge() {
|
|
1477
|
+
return getBridge().value;
|
|
1478
|
+
}
|
|
1479
|
+
function subscribeDevToolsBridge(listener) {
|
|
1480
|
+
const bridge = getBridge();
|
|
1481
|
+
bridge.listeners.add(listener);
|
|
1482
|
+
return () => {
|
|
1483
|
+
bridge.listeners.delete(listener);
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1236
1486
|
|
|
1237
1487
|
// src/devtools/hooks/useFlowsData.ts
|
|
1238
|
-
|
|
1488
|
+
function useBridge() {
|
|
1489
|
+
return useSyncExternalStore(
|
|
1490
|
+
subscribeDevToolsBridge,
|
|
1491
|
+
getDevToolsBridge,
|
|
1492
|
+
() => null
|
|
1493
|
+
// Server snapshot
|
|
1494
|
+
);
|
|
1495
|
+
}
|
|
1239
1496
|
function useFlowsData() {
|
|
1240
|
-
const
|
|
1241
|
-
const [flowsData, setFlowsData] =
|
|
1497
|
+
const bridge = useBridge();
|
|
1498
|
+
const [flowsData, setFlowsData] = useState6([]);
|
|
1242
1499
|
const loadFlowStates = useCallback2(async () => {
|
|
1243
|
-
if (!
|
|
1500
|
+
if (!bridge) {
|
|
1244
1501
|
setFlowsData([]);
|
|
1245
1502
|
return;
|
|
1246
1503
|
}
|
|
1247
|
-
const { flows, activeFlowId, state: activeState, getFlowState } =
|
|
1504
|
+
const { flows, activeFlowId, state: activeState, getFlowState } = bridge;
|
|
1248
1505
|
const flowDataPromises = [];
|
|
1249
1506
|
for (const [flowId, definition] of flows) {
|
|
1250
1507
|
const isActive = flowId === activeFlowId;
|
|
@@ -1262,30 +1519,28 @@ function useFlowsData() {
|
|
|
1262
1519
|
}
|
|
1263
1520
|
const results = await Promise.all(flowDataPromises);
|
|
1264
1521
|
setFlowsData(results);
|
|
1265
|
-
}, [
|
|
1266
|
-
|
|
1522
|
+
}, [bridge]);
|
|
1523
|
+
useEffect4(() => {
|
|
1267
1524
|
void loadFlowStates();
|
|
1268
1525
|
}, [loadFlowStates]);
|
|
1269
|
-
useEffect(() => {
|
|
1270
|
-
if (!devtools?.activeFlowId || !devtools?.state) return;
|
|
1271
|
-
void loadFlowStates();
|
|
1272
|
-
}, [devtools?.activeFlowId, devtools?.state, loadFlowStates]);
|
|
1273
1526
|
const deleteFlow = useCallback2(
|
|
1274
1527
|
async (flowId) => {
|
|
1275
|
-
if (!
|
|
1276
|
-
|
|
1277
|
-
|
|
1528
|
+
if (!bridge) return;
|
|
1529
|
+
if (bridge.activeFlowId === flowId) {
|
|
1530
|
+
bridge.cancel();
|
|
1531
|
+
}
|
|
1532
|
+
await bridge.deleteFlowStorage(flowId);
|
|
1278
1533
|
await loadFlowStates();
|
|
1279
1534
|
},
|
|
1280
|
-
[
|
|
1535
|
+
[bridge, loadFlowStates]
|
|
1281
1536
|
);
|
|
1282
1537
|
const updateFlow = useCallback2(
|
|
1283
|
-
async (flowId,
|
|
1284
|
-
if (!
|
|
1285
|
-
await
|
|
1538
|
+
async (flowId, newState) => {
|
|
1539
|
+
if (!bridge) return;
|
|
1540
|
+
await bridge.updateFlowStorage(flowId, newState);
|
|
1286
1541
|
await loadFlowStates();
|
|
1287
1542
|
},
|
|
1288
|
-
[
|
|
1543
|
+
[bridge, loadFlowStates]
|
|
1289
1544
|
);
|
|
1290
1545
|
return {
|
|
1291
1546
|
flows: flowsData,
|
|
@@ -1296,8 +1551,8 @@ function useFlowsData() {
|
|
|
1296
1551
|
}
|
|
1297
1552
|
|
|
1298
1553
|
// src/devtools/components/FlowItem.tsx
|
|
1299
|
-
import { useState as
|
|
1300
|
-
import { motion as
|
|
1554
|
+
import { useState as useState7 } from "react";
|
|
1555
|
+
import { motion as motion6, AnimatePresence as AnimatePresence5 } from "motion/react";
|
|
1301
1556
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1302
1557
|
var styles6 = {
|
|
1303
1558
|
card: {
|
|
@@ -1309,7 +1564,12 @@ var styles6 = {
|
|
|
1309
1564
|
borderRadius: 8,
|
|
1310
1565
|
border: "1px solid hsl(215 20% 22%)",
|
|
1311
1566
|
fontSize: 12,
|
|
1312
|
-
fontFamily: "inherit"
|
|
1567
|
+
fontFamily: "inherit",
|
|
1568
|
+
transition: "border-color 0.15s ease, box-shadow 0.15s ease"
|
|
1569
|
+
},
|
|
1570
|
+
cardHover: {
|
|
1571
|
+
borderColor: "hsl(215 20% 28%)",
|
|
1572
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)"
|
|
1313
1573
|
},
|
|
1314
1574
|
cardActive: {
|
|
1315
1575
|
borderColor: "hsl(217 91% 55% / 0.5)",
|
|
@@ -1429,7 +1689,9 @@ var statusStyles = {
|
|
|
1429
1689
|
function FlowItem(props) {
|
|
1430
1690
|
const { flow, onEdit, onDelete } = props;
|
|
1431
1691
|
const { flowId, definition, state, isActive } = flow;
|
|
1432
|
-
const [confirmDelete, setConfirmDelete] =
|
|
1692
|
+
const [confirmDelete, setConfirmDelete] = useState7(false);
|
|
1693
|
+
const [isHovered, setIsHovered] = useState7(false);
|
|
1694
|
+
const reducedMotion = useReducedMotion();
|
|
1433
1695
|
const handleDelete = () => {
|
|
1434
1696
|
if (confirmDelete) {
|
|
1435
1697
|
onDelete();
|
|
@@ -1441,6 +1703,7 @@ function FlowItem(props) {
|
|
|
1441
1703
|
};
|
|
1442
1704
|
const cardStyle = {
|
|
1443
1705
|
...styles6.card,
|
|
1706
|
+
...isHovered && styles6.cardHover,
|
|
1444
1707
|
...isActive && styles6.cardActive
|
|
1445
1708
|
};
|
|
1446
1709
|
const statusBadgeStyle = {
|
|
@@ -1452,84 +1715,117 @@ function FlowItem(props) {
|
|
|
1452
1715
|
...confirmDelete && styles6.actionButtonDanger
|
|
1453
1716
|
};
|
|
1454
1717
|
const stepInfo = state ? `Step ${state.stepIndex + 1}/${definition.steps.length}` : null;
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
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
|
-
|
|
1718
|
+
const currentStatus = state?.status ?? "no state";
|
|
1719
|
+
return /* @__PURE__ */ jsxs6(
|
|
1720
|
+
"div",
|
|
1721
|
+
{
|
|
1722
|
+
style: cardStyle,
|
|
1723
|
+
onMouseEnter: () => setIsHovered(true),
|
|
1724
|
+
onMouseLeave: () => setIsHovered(false),
|
|
1725
|
+
children: [
|
|
1726
|
+
/* @__PURE__ */ jsxs6("div", { style: styles6.header, children: [
|
|
1727
|
+
/* @__PURE__ */ jsxs6("div", { style: styles6.titleGroup, children: [
|
|
1728
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.flowId, children: flowId }),
|
|
1729
|
+
/* @__PURE__ */ jsx6(AnimatePresence5, { mode: "wait", children: isActive && /* @__PURE__ */ jsx6(
|
|
1730
|
+
motion6.span,
|
|
1731
|
+
{
|
|
1732
|
+
style: { ...styles6.statusBadge, ...styles6.activeBadge },
|
|
1733
|
+
initial: reducedMotion ? {} : { scale: 0.8, opacity: 0 },
|
|
1734
|
+
animate: { scale: 1, opacity: 1 },
|
|
1735
|
+
exit: reducedMotion ? {} : { scale: 0.8, opacity: 0 },
|
|
1736
|
+
transition: reducedMotion ? { duration: 0 } : springs.bouncy,
|
|
1737
|
+
children: "Active"
|
|
1738
|
+
},
|
|
1739
|
+
"active-badge"
|
|
1740
|
+
) })
|
|
1741
|
+
] }),
|
|
1742
|
+
/* @__PURE__ */ jsx6(AnimatePresence5, { mode: "wait", children: /* @__PURE__ */ jsx6(
|
|
1743
|
+
motion6.span,
|
|
1744
|
+
{
|
|
1745
|
+
style: statusBadgeStyle,
|
|
1746
|
+
initial: reducedMotion ? {} : { scale: 0.9, opacity: 0 },
|
|
1747
|
+
animate: { scale: 1, opacity: 1 },
|
|
1748
|
+
exit: reducedMotion ? {} : { scale: 0.9, opacity: 0 },
|
|
1749
|
+
transition: reducedMotion ? { duration: 0 } : { duration: 0.15 },
|
|
1750
|
+
children: currentStatus
|
|
1751
|
+
},
|
|
1752
|
+
currentStatus
|
|
1753
|
+
) })
|
|
1754
|
+
] }),
|
|
1755
|
+
state ? /* @__PURE__ */ jsxs6("div", { style: styles6.infoRow, children: [
|
|
1756
|
+
stepInfo && /* @__PURE__ */ jsxs6("div", { style: styles6.infoItem, children: [
|
|
1757
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.label, children: "Step:" }),
|
|
1758
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.value, children: stepInfo })
|
|
1759
|
+
] }),
|
|
1760
|
+
/* @__PURE__ */ jsxs6("div", { style: styles6.infoItem, children: [
|
|
1761
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.label, children: "Version:" }),
|
|
1762
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.value, children: state.version })
|
|
1763
|
+
] }),
|
|
1764
|
+
state.stepId && /* @__PURE__ */ jsxs6("div", { style: styles6.infoItem, children: [
|
|
1765
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.label, children: "ID:" }),
|
|
1766
|
+
/* @__PURE__ */ jsx6("span", { style: styles6.value, children: state.stepId })
|
|
1767
|
+
] })
|
|
1768
|
+
] }) : /* @__PURE__ */ jsx6("div", { style: styles6.noState, children: "No stored state" }),
|
|
1769
|
+
/* @__PURE__ */ jsxs6("div", { style: styles6.actions, children: [
|
|
1770
|
+
/* @__PURE__ */ jsxs6(
|
|
1771
|
+
motion6.button,
|
|
1772
|
+
{
|
|
1773
|
+
type: "button",
|
|
1774
|
+
style: styles6.actionButton,
|
|
1775
|
+
onClick: onEdit,
|
|
1776
|
+
disabled: !state,
|
|
1777
|
+
whileHover: state && !reducedMotion ? { scale: 1.02 } : {},
|
|
1778
|
+
whileTap: state && !reducedMotion ? { scale: 0.98 } : {},
|
|
1779
|
+
title: state ? "Edit flow state" : "No state to edit",
|
|
1780
|
+
children: [
|
|
1781
|
+
/* @__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" }) }),
|
|
1782
|
+
"Edit"
|
|
1783
|
+
]
|
|
1784
|
+
}
|
|
1785
|
+
),
|
|
1786
|
+
/* @__PURE__ */ jsxs6(
|
|
1787
|
+
motion6.button,
|
|
1788
|
+
{
|
|
1789
|
+
type: "button",
|
|
1790
|
+
style: deleteButtonStyle,
|
|
1791
|
+
onClick: handleDelete,
|
|
1792
|
+
disabled: !state,
|
|
1793
|
+
whileHover: state && !reducedMotion ? { scale: 1.02 } : {},
|
|
1794
|
+
whileTap: state && !reducedMotion ? { scale: 0.98 } : {},
|
|
1795
|
+
title: confirmDelete ? "Click again to confirm deletion" : state ? "Delete flow state" : "No state to delete",
|
|
1796
|
+
children: [
|
|
1797
|
+
/* @__PURE__ */ jsxs6("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "currentColor", children: [
|
|
1798
|
+
/* @__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" }),
|
|
1799
|
+
/* @__PURE__ */ jsx6(
|
|
1800
|
+
"path",
|
|
1801
|
+
{
|
|
1802
|
+
fillRule: "evenodd",
|
|
1803
|
+
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"
|
|
1804
|
+
}
|
|
1805
|
+
)
|
|
1806
|
+
] }),
|
|
1807
|
+
confirmDelete ? "Confirm?" : "Delete"
|
|
1808
|
+
]
|
|
1809
|
+
}
|
|
1810
|
+
)
|
|
1811
|
+
] })
|
|
1812
|
+
]
|
|
1813
|
+
}
|
|
1814
|
+
);
|
|
1521
1815
|
}
|
|
1522
1816
|
|
|
1523
1817
|
// src/devtools/components/FlowEditModal.tsx
|
|
1524
|
-
import { useCallback as useCallback3, useEffect as
|
|
1818
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useState as useState8 } from "react";
|
|
1525
1819
|
import { createPortal as createPortal2 } from "react-dom";
|
|
1526
|
-
import { AnimatePresence as
|
|
1820
|
+
import { AnimatePresence as AnimatePresence6, motion as motion7 } from "motion/react";
|
|
1527
1821
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1528
1822
|
var styles7 = {
|
|
1529
1823
|
overlay: {
|
|
1530
1824
|
position: "fixed",
|
|
1531
1825
|
inset: 0,
|
|
1532
1826
|
backgroundColor: "rgba(0, 0, 0, 0.6)",
|
|
1827
|
+
backdropFilter: "blur(4px)",
|
|
1828
|
+
WebkitBackdropFilter: "blur(4px)",
|
|
1533
1829
|
display: "flex",
|
|
1534
1830
|
alignItems: "center",
|
|
1535
1831
|
justifyContent: "center",
|
|
@@ -1592,7 +1888,8 @@ var styles7 = {
|
|
|
1592
1888
|
fontFamily: "ui-monospace, monospace",
|
|
1593
1889
|
resize: "vertical",
|
|
1594
1890
|
outline: "none",
|
|
1595
|
-
lineHeight: 1.5
|
|
1891
|
+
lineHeight: 1.5,
|
|
1892
|
+
transition: "border-color 0.15s ease"
|
|
1596
1893
|
},
|
|
1597
1894
|
textareaError: {
|
|
1598
1895
|
borderColor: "hsl(0 70% 50%)"
|
|
@@ -1644,14 +1941,21 @@ var styles7 = {
|
|
|
1644
1941
|
};
|
|
1645
1942
|
function FlowEditModal(props) {
|
|
1646
1943
|
const { isOpen, flowId, initialState, onClose, onSave, container } = props;
|
|
1647
|
-
const [jsonValue, setJsonValue] =
|
|
1648
|
-
const [error, setError] =
|
|
1649
|
-
|
|
1944
|
+
const [jsonValue, setJsonValue] = useState8("");
|
|
1945
|
+
const [error, setError] = useState8(null);
|
|
1946
|
+
const [shake, setShake] = useState8(false);
|
|
1947
|
+
const reducedMotion = useReducedMotion();
|
|
1948
|
+
useEffect5(() => {
|
|
1650
1949
|
if (isOpen && initialState) {
|
|
1651
1950
|
setJsonValue(JSON.stringify(initialState, null, 2));
|
|
1652
1951
|
setError(null);
|
|
1653
1952
|
}
|
|
1654
1953
|
}, [isOpen, initialState]);
|
|
1954
|
+
const triggerShake = useCallback3(() => {
|
|
1955
|
+
if (reducedMotion) return;
|
|
1956
|
+
setShake(true);
|
|
1957
|
+
setTimeout(() => setShake(false), 400);
|
|
1958
|
+
}, [reducedMotion]);
|
|
1655
1959
|
const handleSave = useCallback3(() => {
|
|
1656
1960
|
try {
|
|
1657
1961
|
const parsed = JSON.parse(jsonValue);
|
|
@@ -1668,8 +1972,9 @@ function FlowEditModal(props) {
|
|
|
1668
1972
|
onClose();
|
|
1669
1973
|
} catch (err) {
|
|
1670
1974
|
setError(err instanceof Error ? err.message : "Invalid JSON");
|
|
1975
|
+
triggerShake();
|
|
1671
1976
|
}
|
|
1672
|
-
}, [jsonValue, onSave, onClose]);
|
|
1977
|
+
}, [jsonValue, onSave, onClose, triggerShake]);
|
|
1673
1978
|
const handleKeyDown = useCallback3(
|
|
1674
1979
|
(e) => {
|
|
1675
1980
|
if (e.key === "Escape") {
|
|
@@ -1694,26 +1999,31 @@ function FlowEditModal(props) {
|
|
|
1694
1999
|
...error && styles7.buttonDisabled
|
|
1695
2000
|
};
|
|
1696
2001
|
return createPortal2(
|
|
1697
|
-
/* @__PURE__ */ jsx7(
|
|
1698
|
-
|
|
2002
|
+
/* @__PURE__ */ jsx7(AnimatePresence6, { children: isOpen && /* @__PURE__ */ jsx7(
|
|
2003
|
+
motion7.div,
|
|
1699
2004
|
{
|
|
1700
2005
|
style: styles7.overlay,
|
|
1701
|
-
initial: { opacity: 0 },
|
|
2006
|
+
initial: reducedMotion ? {} : { opacity: 0 },
|
|
1702
2007
|
animate: { opacity: 1 },
|
|
1703
|
-
exit: { opacity: 0 },
|
|
1704
|
-
transition: { duration: 0.15 },
|
|
2008
|
+
exit: reducedMotion ? {} : { opacity: 0 },
|
|
2009
|
+
transition: reducedMotion ? { duration: 0 } : { duration: 0.15 },
|
|
1705
2010
|
onClick: (e) => {
|
|
1706
2011
|
if (e.target === e.currentTarget) onClose();
|
|
1707
2012
|
},
|
|
1708
2013
|
onKeyDown: handleKeyDown,
|
|
1709
2014
|
children: /* @__PURE__ */ jsxs7(
|
|
1710
|
-
|
|
2015
|
+
motion7.div,
|
|
1711
2016
|
{
|
|
1712
2017
|
style: styles7.modal,
|
|
1713
|
-
initial: { opacity: 0, scale: 0.95, y: 10 },
|
|
1714
|
-
animate: {
|
|
1715
|
-
|
|
1716
|
-
|
|
2018
|
+
initial: reducedMotion ? {} : { opacity: 0, scale: 0.95, y: 10 },
|
|
2019
|
+
animate: {
|
|
2020
|
+
opacity: 1,
|
|
2021
|
+
scale: 1,
|
|
2022
|
+
y: 0,
|
|
2023
|
+
x: shake ? [0, -8, 8, -6, 6, -4, 4, 0] : 0
|
|
2024
|
+
},
|
|
2025
|
+
exit: reducedMotion ? {} : { opacity: 0, scale: 0.95, y: 10 },
|
|
2026
|
+
transition: reducedMotion ? { duration: 0 } : springs.smooth,
|
|
1717
2027
|
onClick: (e) => e.stopPropagation(),
|
|
1718
2028
|
children: [
|
|
1719
2029
|
/* @__PURE__ */ jsxs7("div", { style: styles7.header, children: [
|
|
@@ -1722,12 +2032,14 @@ function FlowEditModal(props) {
|
|
|
1722
2032
|
flowId
|
|
1723
2033
|
] }),
|
|
1724
2034
|
/* @__PURE__ */ jsx7(
|
|
1725
|
-
|
|
2035
|
+
motion7.button,
|
|
1726
2036
|
{
|
|
1727
2037
|
type: "button",
|
|
1728
2038
|
style: styles7.closeButton,
|
|
1729
2039
|
onClick: onClose,
|
|
1730
2040
|
title: "Close",
|
|
2041
|
+
whileHover: reducedMotion ? {} : { scale: 1.1 },
|
|
2042
|
+
whileTap: reducedMotion ? {} : { scale: 0.9 },
|
|
1731
2043
|
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" }) })
|
|
1732
2044
|
}
|
|
1733
2045
|
)
|
|
@@ -1746,27 +2058,39 @@ function FlowEditModal(props) {
|
|
|
1746
2058
|
autoFocus: true
|
|
1747
2059
|
}
|
|
1748
2060
|
),
|
|
1749
|
-
|
|
2061
|
+
/* @__PURE__ */ jsx7(AnimatePresence6, { children: error && /* @__PURE__ */ jsx7(
|
|
2062
|
+
motion7.div,
|
|
2063
|
+
{
|
|
2064
|
+
style: styles7.error,
|
|
2065
|
+
initial: reducedMotion ? {} : { opacity: 0, y: -4 },
|
|
2066
|
+
animate: { opacity: 1, y: 0 },
|
|
2067
|
+
exit: reducedMotion ? {} : { opacity: 0, y: -4 },
|
|
2068
|
+
transition: { duration: 0.15 },
|
|
2069
|
+
children: error
|
|
2070
|
+
}
|
|
2071
|
+
) })
|
|
1750
2072
|
] }),
|
|
1751
2073
|
/* @__PURE__ */ jsxs7("div", { style: styles7.footer, children: [
|
|
1752
2074
|
/* @__PURE__ */ jsx7(
|
|
1753
|
-
|
|
2075
|
+
motion7.button,
|
|
1754
2076
|
{
|
|
1755
2077
|
type: "button",
|
|
1756
2078
|
style: styles7.button,
|
|
1757
2079
|
onClick: onClose,
|
|
2080
|
+
whileHover: reducedMotion ? {} : { scale: 1.02 },
|
|
2081
|
+
whileTap: reducedMotion ? {} : { scale: 0.98 },
|
|
1758
2082
|
children: "Cancel"
|
|
1759
2083
|
}
|
|
1760
2084
|
),
|
|
1761
2085
|
/* @__PURE__ */ jsx7(
|
|
1762
|
-
|
|
2086
|
+
motion7.button,
|
|
1763
2087
|
{
|
|
1764
2088
|
type: "button",
|
|
1765
2089
|
style: saveButtonStyle,
|
|
1766
2090
|
onClick: handleSave,
|
|
1767
2091
|
disabled: !!error,
|
|
1768
|
-
whileHover: !error ? { scale: 1.02 } : {},
|
|
1769
|
-
whileTap: !error ? { scale: 0.98 } : {},
|
|
2092
|
+
whileHover: !error && !reducedMotion ? { scale: 1.02 } : {},
|
|
2093
|
+
whileTap: !error && !reducedMotion ? { scale: 0.98 } : {},
|
|
1770
2094
|
children: "Save"
|
|
1771
2095
|
}
|
|
1772
2096
|
)
|
|
@@ -1854,7 +2178,7 @@ var styles8 = {
|
|
|
1854
2178
|
function FlowsTab(props) {
|
|
1855
2179
|
const { container } = props;
|
|
1856
2180
|
const { flows, refreshFlows, deleteFlow, updateFlow } = useFlowsData();
|
|
1857
|
-
const [editModal, setEditModal] =
|
|
2181
|
+
const [editModal, setEditModal] = useState9({
|
|
1858
2182
|
isOpen: false,
|
|
1859
2183
|
flowId: "",
|
|
1860
2184
|
state: null
|
|
@@ -1909,7 +2233,7 @@ function FlowsTab(props) {
|
|
|
1909
2233
|
" registered"
|
|
1910
2234
|
] }),
|
|
1911
2235
|
/* @__PURE__ */ jsxs8(
|
|
1912
|
-
|
|
2236
|
+
motion8.button,
|
|
1913
2237
|
{
|
|
1914
2238
|
type: "button",
|
|
1915
2239
|
style: styles8.refreshButton,
|
|
@@ -1957,7 +2281,7 @@ function FlowsTab(props) {
|
|
|
1957
2281
|
}
|
|
1958
2282
|
|
|
1959
2283
|
// src/devtools/hooks/useGrabMode.ts
|
|
1960
|
-
import { useCallback as useCallback6, useEffect as
|
|
2284
|
+
import { useCallback as useCallback6, useEffect as useEffect6, useState as useState10 } from "react";
|
|
1961
2285
|
|
|
1962
2286
|
// src/devtools/hooks/useElementInfo.ts
|
|
1963
2287
|
import { useCallback as useCallback5 } from "react";
|
|
@@ -2094,8 +2418,8 @@ function isDevToolsElement(element) {
|
|
|
2094
2418
|
return false;
|
|
2095
2419
|
}
|
|
2096
2420
|
function useGrabMode() {
|
|
2097
|
-
const [mode, setMode] =
|
|
2098
|
-
const [hoveredElement, setHoveredElement] =
|
|
2421
|
+
const [mode, setMode] = useState10("idle");
|
|
2422
|
+
const [hoveredElement, setHoveredElement] = useState10(null);
|
|
2099
2423
|
const { getElementInfo } = useElementInfo();
|
|
2100
2424
|
const startGrabbing = useCallback6(() => {
|
|
2101
2425
|
setMode("grabbing");
|
|
@@ -2113,7 +2437,7 @@ function useGrabMode() {
|
|
|
2113
2437
|
if (!hoveredElement) return null;
|
|
2114
2438
|
return hoveredElement.info;
|
|
2115
2439
|
}, [hoveredElement]);
|
|
2116
|
-
|
|
2440
|
+
useEffect6(() => {
|
|
2117
2441
|
if (mode !== "grabbing") return;
|
|
2118
2442
|
const handleMouseMove = (e) => {
|
|
2119
2443
|
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
@@ -2137,7 +2461,7 @@ function useGrabMode() {
|
|
|
2137
2461
|
document.addEventListener("mousemove", handleMouseMove, { passive: true });
|
|
2138
2462
|
return () => document.removeEventListener("mousemove", handleMouseMove);
|
|
2139
2463
|
}, [mode, getElementInfo]);
|
|
2140
|
-
|
|
2464
|
+
useEffect6(() => {
|
|
2141
2465
|
const handleKeyDown = (e) => {
|
|
2142
2466
|
if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "g") {
|
|
2143
2467
|
e.preventDefault();
|
|
@@ -2164,7 +2488,7 @@ function useGrabMode() {
|
|
|
2164
2488
|
}
|
|
2165
2489
|
|
|
2166
2490
|
// src/devtools/hooks/useStepStore.ts
|
|
2167
|
-
import { useCallback as useCallback7, useEffect as
|
|
2491
|
+
import { useCallback as useCallback7, useEffect as useEffect7, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2168
2492
|
|
|
2169
2493
|
// src/devtools/utils/storage.ts
|
|
2170
2494
|
var STORAGE_KEY = "flowsterix-devtools-steps";
|
|
@@ -2226,15 +2550,15 @@ function generateId() {
|
|
|
2226
2550
|
return `step-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
2227
2551
|
}
|
|
2228
2552
|
function useStepStore() {
|
|
2229
|
-
const steps =
|
|
2230
|
-
|
|
2553
|
+
const steps = useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot);
|
|
2554
|
+
useEffect7(() => {
|
|
2231
2555
|
const saved = loadSteps();
|
|
2232
2556
|
if (saved.length > 0) {
|
|
2233
2557
|
store.steps = saved;
|
|
2234
2558
|
notifyListeners();
|
|
2235
2559
|
}
|
|
2236
2560
|
}, []);
|
|
2237
|
-
|
|
2561
|
+
useEffect7(() => {
|
|
2238
2562
|
saveSteps(steps);
|
|
2239
2563
|
}, [steps]);
|
|
2240
2564
|
const addStep = useCallback7((params) => {
|
|
@@ -2421,10 +2745,10 @@ var styles9 = {
|
|
|
2421
2745
|
};
|
|
2422
2746
|
function DevToolsProvider(props) {
|
|
2423
2747
|
const { children, enabled = true, defaultTab = "steps" } = props;
|
|
2424
|
-
const [mounted, setMounted] =
|
|
2425
|
-
const [shadowRoot, setShadowRoot] =
|
|
2426
|
-
const [activeTab, setActiveTab] =
|
|
2427
|
-
|
|
2748
|
+
const [mounted, setMounted] = useState11(false);
|
|
2749
|
+
const [shadowRoot, setShadowRoot] = useState11(null);
|
|
2750
|
+
const [activeTab, setActiveTab] = useState11(defaultTab);
|
|
2751
|
+
useEffect8(() => {
|
|
2428
2752
|
setMounted(true);
|
|
2429
2753
|
const host = document.createElement("div");
|
|
2430
2754
|
host.setAttribute("data-devtools-host", "");
|
|
@@ -2455,10 +2779,10 @@ function DevToolsProvider(props) {
|
|
|
2455
2779
|
exportSteps
|
|
2456
2780
|
} = useStepStore();
|
|
2457
2781
|
const { flows } = useFlowsData();
|
|
2458
|
-
const [collapsed, setCollapsed] =
|
|
2459
|
-
const [position, setPosition] =
|
|
2460
|
-
const [isPanelDragging, setIsPanelDragging] =
|
|
2461
|
-
const dragStartRef =
|
|
2782
|
+
const [collapsed, setCollapsed] = useState11(false);
|
|
2783
|
+
const [position, setPosition] = useState11({ x: 16, y: 16 });
|
|
2784
|
+
const [isPanelDragging, setIsPanelDragging] = useState11(false);
|
|
2785
|
+
const dragStartRef = useRef2(null);
|
|
2462
2786
|
const handleClick = useCallback8(
|
|
2463
2787
|
(e) => {
|
|
2464
2788
|
if (mode !== "grabbing") return;
|
|
@@ -2479,12 +2803,12 @@ function DevToolsProvider(props) {
|
|
|
2479
2803
|
},
|
|
2480
2804
|
[mode, selectCurrent, addStep]
|
|
2481
2805
|
);
|
|
2482
|
-
|
|
2806
|
+
useEffect8(() => {
|
|
2483
2807
|
if (mode !== "grabbing") return;
|
|
2484
2808
|
document.addEventListener("click", handleClick, { capture: true });
|
|
2485
2809
|
return () => document.removeEventListener("click", handleClick, { capture: true });
|
|
2486
2810
|
}, [mode, handleClick]);
|
|
2487
|
-
|
|
2811
|
+
useEffect8(() => {
|
|
2488
2812
|
if (mode !== "grabbing") return;
|
|
2489
2813
|
const preventDefault = (e) => {
|
|
2490
2814
|
const target = e.target;
|
|
@@ -2496,7 +2820,7 @@ function DevToolsProvider(props) {
|
|
|
2496
2820
|
document.removeEventListener("submit", preventDefault, { capture: true });
|
|
2497
2821
|
};
|
|
2498
2822
|
}, [mode]);
|
|
2499
|
-
|
|
2823
|
+
useEffect8(() => {
|
|
2500
2824
|
const handleKeyDown = (e) => {
|
|
2501
2825
|
if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "m") {
|
|
2502
2826
|
e.preventDefault();
|
|
@@ -2564,7 +2888,7 @@ function DevToolsProvider(props) {
|
|
|
2564
2888
|
),
|
|
2565
2889
|
createPortal3(
|
|
2566
2890
|
/* @__PURE__ */ jsxs9(
|
|
2567
|
-
|
|
2891
|
+
motion9.div,
|
|
2568
2892
|
{
|
|
2569
2893
|
style: panelStyle,
|
|
2570
2894
|
initial: { opacity: 0, x: 20, scale: 0.95 },
|
|
@@ -2614,14 +2938,14 @@ function DevToolsProvider(props) {
|
|
|
2614
2938
|
]
|
|
2615
2939
|
}
|
|
2616
2940
|
),
|
|
2617
|
-
/* @__PURE__ */ jsx9(
|
|
2618
|
-
|
|
2941
|
+
/* @__PURE__ */ jsx9(AnimatePresence7, { initial: false, children: !collapsed && /* @__PURE__ */ jsxs9(
|
|
2942
|
+
motion9.div,
|
|
2619
2943
|
{
|
|
2620
|
-
style: styles9.body,
|
|
2944
|
+
style: { ...styles9.body, overflow: "hidden" },
|
|
2621
2945
|
initial: { height: 0, opacity: 0 },
|
|
2622
2946
|
animate: { height: "auto", opacity: 1 },
|
|
2623
2947
|
exit: { height: 0, opacity: 0 },
|
|
2624
|
-
transition:
|
|
2948
|
+
transition: springs.smooth,
|
|
2625
2949
|
children: [
|
|
2626
2950
|
/* @__PURE__ */ jsx9(
|
|
2627
2951
|
TabNav,
|