@eventcatalog/visualiser 5.2.1 → 5.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/studio.css +9 -5
- package/dist/studio.d.mts +18 -3
- package/dist/studio.mjs +682 -254
- package/dist/studio.mjs.map +1 -1
- package/dist/styles-core.css +89 -32
- package/dist/styles.css +89 -32
- package/package.json +1 -1
package/dist/studio.mjs
CHANGED
|
@@ -834,17 +834,7 @@ var deleteNodes = (doc, ids) => doc.transact(() => {
|
|
|
834
834
|
thread.delete("offset");
|
|
835
835
|
});
|
|
836
836
|
hotspots.forEach((hotspot, id) => {
|
|
837
|
-
|
|
838
|
-
if (!node) return;
|
|
839
|
-
const position = getAbsolutePosition(node, lookup);
|
|
840
|
-
const { nodeId: _, ...rest } = hotspot;
|
|
841
|
-
hotspots.set(id, {
|
|
842
|
-
...rest,
|
|
843
|
-
position: {
|
|
844
|
-
x: position.x + (node.measured?.width ?? node.width ?? 0),
|
|
845
|
-
y: position.y
|
|
846
|
-
}
|
|
847
|
-
});
|
|
837
|
+
if (hotspot.nodeId && removed.has(hotspot.nodeId)) hotspots.delete(id);
|
|
848
838
|
});
|
|
849
839
|
removed.forEach((id) => {
|
|
850
840
|
nodes.delete(id);
|
|
@@ -3181,6 +3171,21 @@ var EditingContext = createContext(
|
|
|
3181
3171
|
);
|
|
3182
3172
|
var DropTargetContext = createContext(null);
|
|
3183
3173
|
var StartWritingContext = createContext(null);
|
|
3174
|
+
var START_WRITING_EVENT = "studio:start-writing";
|
|
3175
|
+
var startWriting = (id) => window.dispatchEvent(
|
|
3176
|
+
new CustomEvent(START_WRITING_EVENT, { detail: id })
|
|
3177
|
+
);
|
|
3178
|
+
function useStartWriting(id, start) {
|
|
3179
|
+
const latest = useRef3(start);
|
|
3180
|
+
latest.current = start;
|
|
3181
|
+
useEffect4(() => {
|
|
3182
|
+
const listener = (event) => {
|
|
3183
|
+
if (event.detail === id) latest.current();
|
|
3184
|
+
};
|
|
3185
|
+
window.addEventListener(START_WRITING_EVENT, listener);
|
|
3186
|
+
return () => window.removeEventListener(START_WRITING_EVENT, listener);
|
|
3187
|
+
}, [id]);
|
|
3188
|
+
}
|
|
3184
3189
|
var LockedContext = createContext(false);
|
|
3185
3190
|
var SystemGroupComponent = SystemGroupNode_default;
|
|
3186
3191
|
function WidthHandles() {
|
|
@@ -3289,6 +3294,7 @@ var StickyNote = memo3(function StickyNote2({ id, data, selected }) {
|
|
|
3289
3294
|
useContext(StartWritingContext) === id
|
|
3290
3295
|
);
|
|
3291
3296
|
const locked = useContext(LockedContext);
|
|
3297
|
+
useStartWriting(id, () => !locked && setEditing(true));
|
|
3292
3298
|
const colorName = typeof data.color === "string" && NOTE_COLORS[data.color] ? data.color : "yellow";
|
|
3293
3299
|
const color = NOTE_COLORS[colorName];
|
|
3294
3300
|
return /* @__PURE__ */ jsxs3(
|
|
@@ -3444,6 +3450,7 @@ var TextNode = memo3(function TextNode2({ id, data, selected }) {
|
|
|
3444
3450
|
if (!text.trim()) void deleteElements({ nodes: [{ id }] });
|
|
3445
3451
|
};
|
|
3446
3452
|
const locked = useContext(LockedContext);
|
|
3453
|
+
useStartWriting(id, () => !locked && setEditing(true));
|
|
3447
3454
|
const framed = (selected || scaling !== null || turning !== null) && !editing && !locked;
|
|
3448
3455
|
return /* @__PURE__ */ jsxs3(
|
|
3449
3456
|
"div",
|
|
@@ -4461,7 +4468,9 @@ function CommentList({
|
|
|
4461
4468
|
|
|
4462
4469
|
// src/studio/components/ContextMenu.tsx
|
|
4463
4470
|
import {
|
|
4471
|
+
Fragment as Fragment5,
|
|
4464
4472
|
memo as memo5,
|
|
4473
|
+
useContext as useContext3,
|
|
4465
4474
|
useEffect as useEffect6,
|
|
4466
4475
|
useLayoutEffect as useLayoutEffect2,
|
|
4467
4476
|
useRef as useRef5,
|
|
@@ -4473,18 +4482,75 @@ import {
|
|
|
4473
4482
|
CopyPlus,
|
|
4474
4483
|
MessageCircle,
|
|
4475
4484
|
MessageCircleQuestion,
|
|
4485
|
+
Palette,
|
|
4476
4486
|
Pencil,
|
|
4487
|
+
Scissors,
|
|
4477
4488
|
SendToBack,
|
|
4478
4489
|
StickyNote as StickyNote3,
|
|
4479
4490
|
Trash2 as Trash22,
|
|
4480
4491
|
TriangleAlert
|
|
4481
4492
|
} from "lucide-react";
|
|
4482
|
-
import {
|
|
4493
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4483
4494
|
var EDGE = 8;
|
|
4495
|
+
var itemClass = "flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-left text-[13px] leading-5 transition-colors hover:bg-[rgb(var(--ec-page-border)/0.5)]";
|
|
4496
|
+
var iconClass = "flex-none text-[rgb(var(--ec-icon-color))]";
|
|
4497
|
+
function Item({
|
|
4498
|
+
icon,
|
|
4499
|
+
label,
|
|
4500
|
+
onClick,
|
|
4501
|
+
shortcut,
|
|
4502
|
+
danger
|
|
4503
|
+
}) {
|
|
4504
|
+
return /* @__PURE__ */ jsxs5(
|
|
4505
|
+
"button",
|
|
4506
|
+
{
|
|
4507
|
+
type: "button",
|
|
4508
|
+
role: "menuitem",
|
|
4509
|
+
className: `${itemClass} ${danger ? `${STATUS.danger.text} ${STATUS.danger.hover}` : ""}`,
|
|
4510
|
+
onClick,
|
|
4511
|
+
children: [
|
|
4512
|
+
/* @__PURE__ */ jsx7("span", { className: danger ? "flex-none" : iconClass, children: icon }),
|
|
4513
|
+
/* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate", children: label }),
|
|
4514
|
+
shortcut && /* @__PURE__ */ jsx7("kbd", { className: "ml-4 flex-none font-sans text-[11px] text-[rgb(var(--ec-page-text-muted))]", children: shortcut })
|
|
4515
|
+
]
|
|
4516
|
+
}
|
|
4517
|
+
);
|
|
4518
|
+
}
|
|
4519
|
+
function NoteColours({ node, onPicked }) {
|
|
4520
|
+
const updateNodeData2 = useContext3(UpdateNodeDataContext);
|
|
4521
|
+
const current = typeof node.data.color === "string" && NOTE_COLORS[node.data.color] ? node.data.color : "yellow";
|
|
4522
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2.5 px-2 py-1.5 text-[13px] leading-5", children: [
|
|
4523
|
+
/* @__PURE__ */ jsx7(Palette, { size: 14, className: iconClass }),
|
|
4524
|
+
/* @__PURE__ */ jsx7("span", { className: "flex-1", children: "Colour" }),
|
|
4525
|
+
/* @__PURE__ */ jsx7("span", { role: "radiogroup", "aria-label": "Note colour", className: "flex gap-1", children: Object.entries(NOTE_COLORS).map(([name, { fill, border }]) => /* @__PURE__ */ jsx7(
|
|
4526
|
+
"button",
|
|
4527
|
+
{
|
|
4528
|
+
type: "button",
|
|
4529
|
+
role: "radio",
|
|
4530
|
+
"aria-checked": name === current,
|
|
4531
|
+
title: name.charAt(0).toUpperCase() + name.slice(1),
|
|
4532
|
+
onClick: () => {
|
|
4533
|
+
updateNodeData2(node.id, (data) => ({ ...data, color: name }));
|
|
4534
|
+
onPicked();
|
|
4535
|
+
},
|
|
4536
|
+
className: "h-4 w-4 rounded-full border transition-transform hover:scale-110",
|
|
4537
|
+
style: {
|
|
4538
|
+
background: fill,
|
|
4539
|
+
borderColor: border,
|
|
4540
|
+
...name === current && {
|
|
4541
|
+
boxShadow: "0 0 0 1.5px rgb(var(--ec-card-bg)), 0 0 0 3px rgb(var(--ec-page-text))"
|
|
4542
|
+
}
|
|
4543
|
+
}
|
|
4544
|
+
},
|
|
4545
|
+
name
|
|
4546
|
+
)) })
|
|
4547
|
+
] });
|
|
4548
|
+
}
|
|
4484
4549
|
var ContextMenu = memo5(function ContextMenu2({
|
|
4485
4550
|
menu,
|
|
4486
4551
|
questions,
|
|
4487
4552
|
onCopy,
|
|
4553
|
+
onCut,
|
|
4488
4554
|
onDuplicate,
|
|
4489
4555
|
onPaste,
|
|
4490
4556
|
onAddNote,
|
|
@@ -4495,6 +4561,7 @@ var ContextMenu = memo5(function ContextMenu2({
|
|
|
4495
4561
|
onDeleteNode,
|
|
4496
4562
|
onClose
|
|
4497
4563
|
}) {
|
|
4564
|
+
const locked = useContext3(LockedContext);
|
|
4498
4565
|
useEffect6(() => {
|
|
4499
4566
|
if (!menu) return;
|
|
4500
4567
|
const close = (event) => {
|
|
@@ -4525,70 +4592,211 @@ var ContextMenu = memo5(function ContextMenu2({
|
|
|
4525
4592
|
});
|
|
4526
4593
|
}, [menu]);
|
|
4527
4594
|
if (!menu) return null;
|
|
4528
|
-
const
|
|
4529
|
-
const
|
|
4530
|
-
const
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4595
|
+
const node = menu.node;
|
|
4596
|
+
const written = !!node && isWrittenOnCanvas(node.type);
|
|
4597
|
+
const editable = !locked;
|
|
4598
|
+
const clipboard = [
|
|
4599
|
+
editable && onCut && /* @__PURE__ */ jsx7(
|
|
4600
|
+
Item,
|
|
4601
|
+
{
|
|
4602
|
+
icon: /* @__PURE__ */ jsx7(Scissors, { size: 14 }),
|
|
4603
|
+
label: "Cut",
|
|
4604
|
+
onClick: onCut,
|
|
4605
|
+
shortcut: "\u2318X"
|
|
4606
|
+
},
|
|
4607
|
+
"cut"
|
|
4608
|
+
),
|
|
4609
|
+
/* @__PURE__ */ jsx7(
|
|
4610
|
+
Item,
|
|
4611
|
+
{
|
|
4612
|
+
icon: /* @__PURE__ */ jsx7(Copy, { size: 14 }),
|
|
4613
|
+
label: "Copy",
|
|
4614
|
+
onClick: onCopy,
|
|
4615
|
+
shortcut: "\u2318C"
|
|
4616
|
+
},
|
|
4617
|
+
"copy"
|
|
4618
|
+
),
|
|
4619
|
+
editable && onPaste && /* @__PURE__ */ jsx7(
|
|
4620
|
+
Item,
|
|
4621
|
+
{
|
|
4622
|
+
icon: /* @__PURE__ */ jsx7(ClipboardPaste, { size: 14 }),
|
|
4623
|
+
label: "Paste",
|
|
4624
|
+
onClick: onPaste,
|
|
4625
|
+
shortcut: "\u2318V"
|
|
4626
|
+
},
|
|
4627
|
+
"paste"
|
|
4628
|
+
),
|
|
4629
|
+
editable && /* @__PURE__ */ jsx7(
|
|
4630
|
+
Item,
|
|
4631
|
+
{
|
|
4632
|
+
icon: /* @__PURE__ */ jsx7(CopyPlus, { size: 14 }),
|
|
4633
|
+
label: "Duplicate",
|
|
4634
|
+
onClick: onDuplicate,
|
|
4635
|
+
shortcut: "\u2318D"
|
|
4636
|
+
},
|
|
4637
|
+
"duplicate"
|
|
4638
|
+
)
|
|
4639
|
+
];
|
|
4640
|
+
const comment = onAddComment && /* @__PURE__ */ jsx7(
|
|
4641
|
+
Item,
|
|
4642
|
+
{
|
|
4643
|
+
icon: /* @__PURE__ */ jsx7(MessageCircle, { size: 14 }),
|
|
4644
|
+
label: "Add comment",
|
|
4645
|
+
onClick: onAddComment,
|
|
4646
|
+
shortcut: "C"
|
|
4647
|
+
},
|
|
4648
|
+
"comment"
|
|
4649
|
+
);
|
|
4650
|
+
const remove = editable && /* @__PURE__ */ jsx7(
|
|
4651
|
+
Item,
|
|
4652
|
+
{
|
|
4653
|
+
icon: /* @__PURE__ */ jsx7(Trash22, { size: 14 }),
|
|
4654
|
+
label: "Delete",
|
|
4655
|
+
onClick: onDeleteNode,
|
|
4656
|
+
shortcut: "\u232B",
|
|
4657
|
+
danger: true
|
|
4658
|
+
},
|
|
4659
|
+
"delete"
|
|
4660
|
+
);
|
|
4661
|
+
const groups = node ? written ? [
|
|
4662
|
+
[
|
|
4663
|
+
editable && /* @__PURE__ */ jsx7(
|
|
4664
|
+
Item,
|
|
4665
|
+
{
|
|
4666
|
+
icon: /* @__PURE__ */ jsx7(Pencil, { size: 14 }),
|
|
4667
|
+
label: "Edit text",
|
|
4668
|
+
onClick: () => {
|
|
4669
|
+
startWriting(node.id);
|
|
4670
|
+
onClose();
|
|
4671
|
+
}
|
|
4672
|
+
},
|
|
4673
|
+
"edit"
|
|
4674
|
+
)
|
|
4675
|
+
],
|
|
4676
|
+
clipboard,
|
|
4677
|
+
[
|
|
4678
|
+
editable && node.type === "note" && /* @__PURE__ */ jsx7(NoteColours, { node, onPicked: onClose }, "colour")
|
|
4679
|
+
],
|
|
4680
|
+
[comment],
|
|
4681
|
+
[remove]
|
|
4682
|
+
] : [
|
|
4683
|
+
(questions ?? []).map((question) => /* @__PURE__ */ jsx7(
|
|
4684
|
+
Item,
|
|
4685
|
+
{
|
|
4686
|
+
icon: /* @__PURE__ */ jsx7(MessageCircleQuestion, { size: 14 }),
|
|
4687
|
+
label: question.label,
|
|
4688
|
+
onClick: question.onSelect
|
|
4689
|
+
},
|
|
4690
|
+
question.label
|
|
4691
|
+
)),
|
|
4692
|
+
[
|
|
4693
|
+
onEditDetails && /* @__PURE__ */ jsx7(
|
|
4694
|
+
Item,
|
|
4695
|
+
{
|
|
4696
|
+
icon: /* @__PURE__ */ jsx7(Pencil, { size: 14 }),
|
|
4697
|
+
label: "Edit details",
|
|
4698
|
+
onClick: onEditDetails
|
|
4699
|
+
},
|
|
4700
|
+
"details"
|
|
4701
|
+
)
|
|
4702
|
+
],
|
|
4703
|
+
clipboard,
|
|
4704
|
+
[
|
|
4705
|
+
comment,
|
|
4706
|
+
onAddHotspot && /* @__PURE__ */ jsx7(
|
|
4707
|
+
Item,
|
|
4708
|
+
{
|
|
4709
|
+
icon: /* @__PURE__ */ jsx7(TriangleAlert, { size: 14 }),
|
|
4710
|
+
label: "Add hotspot",
|
|
4711
|
+
onClick: onAddHotspot,
|
|
4712
|
+
shortcut: "A"
|
|
4713
|
+
},
|
|
4714
|
+
"hotspot"
|
|
4715
|
+
),
|
|
4716
|
+
editable && /* @__PURE__ */ jsx7(
|
|
4717
|
+
Item,
|
|
4718
|
+
{
|
|
4719
|
+
icon: /* @__PURE__ */ jsx7(StickyNote3, { size: 14 }),
|
|
4720
|
+
label: "Add note",
|
|
4721
|
+
onClick: onAddNote
|
|
4722
|
+
},
|
|
4723
|
+
"note"
|
|
4724
|
+
)
|
|
4725
|
+
],
|
|
4726
|
+
[remove]
|
|
4727
|
+
] : [
|
|
4728
|
+
[
|
|
4729
|
+
editable && onPaste && /* @__PURE__ */ jsx7(
|
|
4730
|
+
Item,
|
|
4731
|
+
{
|
|
4732
|
+
icon: /* @__PURE__ */ jsx7(ClipboardPaste, { size: 14 }),
|
|
4733
|
+
label: "Paste here",
|
|
4734
|
+
onClick: onPaste,
|
|
4735
|
+
shortcut: "\u2318V"
|
|
4736
|
+
},
|
|
4737
|
+
"paste"
|
|
4738
|
+
)
|
|
4739
|
+
],
|
|
4740
|
+
[
|
|
4741
|
+
editable && /* @__PURE__ */ jsx7(
|
|
4742
|
+
Item,
|
|
4743
|
+
{
|
|
4744
|
+
icon: /* @__PURE__ */ jsx7(StickyNote3, { size: 14 }),
|
|
4745
|
+
label: "Add sticky note",
|
|
4746
|
+
onClick: onAddNote,
|
|
4747
|
+
shortcut: "N"
|
|
4748
|
+
},
|
|
4749
|
+
"note"
|
|
4750
|
+
),
|
|
4751
|
+
comment,
|
|
4752
|
+
onAddHotspot && /* @__PURE__ */ jsx7(
|
|
4753
|
+
Item,
|
|
4754
|
+
{
|
|
4755
|
+
icon: /* @__PURE__ */ jsx7(TriangleAlert, { size: 14 }),
|
|
4756
|
+
label: "Add hotspot",
|
|
4757
|
+
onClick: onAddHotspot,
|
|
4758
|
+
shortcut: "A"
|
|
4759
|
+
},
|
|
4760
|
+
"hotspot"
|
|
4761
|
+
)
|
|
4762
|
+
],
|
|
4763
|
+
[
|
|
4764
|
+
onReorder && /* @__PURE__ */ jsx7(
|
|
4765
|
+
Item,
|
|
4766
|
+
{
|
|
4767
|
+
icon: /* @__PURE__ */ jsx7(SendToBack, { size: 14 }),
|
|
4768
|
+
label: "Reorder diagram",
|
|
4769
|
+
onClick: onReorder
|
|
4770
|
+
},
|
|
4771
|
+
"reorder"
|
|
4772
|
+
)
|
|
4773
|
+
]
|
|
4774
|
+
];
|
|
4775
|
+
const sections = groups.map((group) => group.filter(Boolean)).filter((group) => group.length > 0);
|
|
4776
|
+
return /* @__PURE__ */ jsx7(
|
|
4537
4777
|
"div",
|
|
4538
4778
|
{
|
|
4779
|
+
role: "menu",
|
|
4539
4780
|
onPointerDown: (event) => event.stopPropagation(),
|
|
4540
4781
|
onContextMenu: (event) => event.preventDefault(),
|
|
4541
4782
|
ref: menuRef,
|
|
4542
|
-
className: "fixed z-50 w-
|
|
4783
|
+
className: "fixed z-50 w-60 overflow-y-auto rounded-xl border p-1.5 shadow-xl bg-[rgb(var(--ec-card-bg))] border-[rgb(var(--ec-page-border))] text-[rgb(var(--ec-page-text))]",
|
|
4543
4784
|
style: {
|
|
4544
4785
|
left: placed?.left ?? menu.x,
|
|
4545
4786
|
top: placed?.top ?? menu.y,
|
|
4546
4787
|
maxHeight: `calc(100vh - ${EDGE * 2}px)`,
|
|
4547
4788
|
visibility: placed ? "visible" : "hidden"
|
|
4548
4789
|
},
|
|
4549
|
-
children: [
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
]
|
|
4560
|
-
},
|
|
4561
|
-
question.label
|
|
4562
|
-
)),
|
|
4563
|
-
separator
|
|
4564
|
-
] }) : null,
|
|
4565
|
-
menu.node && /* @__PURE__ */ jsxs5(Fragment5, { children: [
|
|
4566
|
-
onAddComment && item(/* @__PURE__ */ jsx7(MessageCircle, { size: 14 }), "Add comment", onAddComment, "C"),
|
|
4567
|
-
onAddHotspot && !isWrittenOnCanvas(menu.node.type) && item(/* @__PURE__ */ jsx7(TriangleAlert, { size: 14 }), "Add hotspot", onAddHotspot, "A"),
|
|
4568
|
-
!isWrittenOnCanvas(menu.node.type) && item(/* @__PURE__ */ jsx7(StickyNote3, { size: 14 }), "Add a note", onAddNote),
|
|
4569
|
-
onEditDetails && !isWrittenOnCanvas(menu.node.type) && item(/* @__PURE__ */ jsx7(Pencil, { size: 14 }), "Edit details", onEditDetails),
|
|
4570
|
-
item(/* @__PURE__ */ jsx7(Copy, { size: 14 }), "Copy", onCopy, "\u2318C"),
|
|
4571
|
-
item(/* @__PURE__ */ jsx7(CopyPlus, { size: 14 }), "Duplicate", onDuplicate, "\u2318D"),
|
|
4572
|
-
separator,
|
|
4573
|
-
item(
|
|
4574
|
-
/* @__PURE__ */ jsx7(Trash22, { size: 14 }),
|
|
4575
|
-
"Delete",
|
|
4576
|
-
onDeleteNode,
|
|
4577
|
-
"\u232B",
|
|
4578
|
-
STATUS.danger.text
|
|
4579
|
-
)
|
|
4580
|
-
] }),
|
|
4581
|
-
!menu.node && /* @__PURE__ */ jsxs5(Fragment5, { children: [
|
|
4582
|
-
onAddComment && item(/* @__PURE__ */ jsx7(MessageCircle, { size: 14 }), "Add comment", onAddComment, "C"),
|
|
4583
|
-
onAddHotspot && item(/* @__PURE__ */ jsx7(TriangleAlert, { size: 14 }), "Add hotspot", onAddHotspot, "A"),
|
|
4584
|
-
item(/* @__PURE__ */ jsx7(StickyNote3, { size: 14 }), "Add a sticky note", onAddNote, "N"),
|
|
4585
|
-
onPaste && item(/* @__PURE__ */ jsx7(ClipboardPaste, { size: 14 }), "Paste here", onPaste, "\u2318V"),
|
|
4586
|
-
onReorder && /* @__PURE__ */ jsxs5(Fragment5, { children: [
|
|
4587
|
-
separator,
|
|
4588
|
-
item(/* @__PURE__ */ jsx7(SendToBack, { size: 14 }), "Reorder diagram", onReorder)
|
|
4589
|
-
] })
|
|
4590
|
-
] })
|
|
4591
|
-
]
|
|
4790
|
+
children: sections.map((section, index) => /* @__PURE__ */ jsxs5(Fragment5, { children: [
|
|
4791
|
+
index > 0 && /* @__PURE__ */ jsx7(
|
|
4792
|
+
"div",
|
|
4793
|
+
{
|
|
4794
|
+
role: "separator",
|
|
4795
|
+
className: "-mx-1.5 my-1.5 h-px bg-[rgb(var(--ec-page-border))]"
|
|
4796
|
+
}
|
|
4797
|
+
),
|
|
4798
|
+
section
|
|
4799
|
+
] }, index))
|
|
4592
4800
|
}
|
|
4593
4801
|
);
|
|
4594
4802
|
});
|
|
@@ -4704,6 +4912,7 @@ function DragGhost({ ghost, onEnd }) {
|
|
|
4704
4912
|
// src/studio/components/Hotspots.tsx
|
|
4705
4913
|
import {
|
|
4706
4914
|
memo as memo6,
|
|
4915
|
+
useEffect as useEffect8,
|
|
4707
4916
|
useLayoutEffect as useLayoutEffect3,
|
|
4708
4917
|
useRef as useRef7,
|
|
4709
4918
|
useState as useState9
|
|
@@ -4715,6 +4924,7 @@ import {
|
|
|
4715
4924
|
} from "@xyflow/react";
|
|
4716
4925
|
import {
|
|
4717
4926
|
Info,
|
|
4927
|
+
LocateFixed,
|
|
4718
4928
|
OctagonAlert,
|
|
4719
4929
|
Pencil as Pencil2,
|
|
4720
4930
|
Trash2 as Trash23,
|
|
@@ -4738,7 +4948,6 @@ var topSeverity = (hotspots) => [...hotspots].sort(bySeverity)[0]?.severity;
|
|
|
4738
4948
|
var MARKER_SCALE = "--studio-hotspot-scale";
|
|
4739
4949
|
var PANEL_SCALE = "--studio-hotspot-panel-scale";
|
|
4740
4950
|
var MIN_SCREEN_SCALE = 0.5;
|
|
4741
|
-
var ICONS_ONLY_BELOW_ZOOM = 0.6;
|
|
4742
4951
|
function useMarkerScale(ref) {
|
|
4743
4952
|
const store = useStoreApi4();
|
|
4744
4953
|
useLayoutEffect3(() => {
|
|
@@ -4748,7 +4957,6 @@ function useMarkerScale(ref) {
|
|
|
4748
4957
|
const scale = zoom >= 1 ? 1 / zoom : Math.max(1, MIN_SCREEN_SCALE / zoom);
|
|
4749
4958
|
element.style.setProperty(MARKER_SCALE, String(scale));
|
|
4750
4959
|
element.style.setProperty(PANEL_SCALE, String(1 / zoom / scale));
|
|
4751
|
-
element.classList.toggle("is-icons-only", zoom < ICONS_ONLY_BELOW_ZOOM);
|
|
4752
4960
|
};
|
|
4753
4961
|
apply(store.getState().transform[2]);
|
|
4754
4962
|
return store.subscribe((state, previous) => {
|
|
@@ -4795,6 +5003,48 @@ function SeverityIcon({
|
|
|
4795
5003
|
}
|
|
4796
5004
|
var DRAG_THRESHOLD_PX2 = 4;
|
|
4797
5005
|
var ICON_CENTRE_PX = 14;
|
|
5006
|
+
function useMarkerDrag(onClick, onDrag) {
|
|
5007
|
+
const drag = useRef7(null);
|
|
5008
|
+
const pointOf = (event, grab) => ({ x: event.clientX - grab.x, y: event.clientY - grab.y });
|
|
5009
|
+
return {
|
|
5010
|
+
onKeyDown: (event) => (event.key === "Enter" || event.key === " ") && onClick(),
|
|
5011
|
+
onPointerDown: (event) => {
|
|
5012
|
+
if (event.button !== 0) return;
|
|
5013
|
+
try {
|
|
5014
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
5015
|
+
} catch {
|
|
5016
|
+
}
|
|
5017
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
5018
|
+
drag.current = {
|
|
5019
|
+
start: { x: event.clientX, y: event.clientY },
|
|
5020
|
+
grab: {
|
|
5021
|
+
x: event.clientX - rect.left - ICON_CENTRE_PX * (rect.height / 28),
|
|
5022
|
+
y: event.clientY - rect.top - rect.height / 2
|
|
5023
|
+
},
|
|
5024
|
+
moved: false
|
|
5025
|
+
};
|
|
5026
|
+
},
|
|
5027
|
+
onPointerMove: (event) => {
|
|
5028
|
+
const current = drag.current;
|
|
5029
|
+
if (!current || !onDrag) return;
|
|
5030
|
+
if (!current.moved && Math.hypot(
|
|
5031
|
+
event.clientX - current.start.x,
|
|
5032
|
+
event.clientY - current.start.y
|
|
5033
|
+
) < DRAG_THRESHOLD_PX2)
|
|
5034
|
+
return;
|
|
5035
|
+
current.moved = true;
|
|
5036
|
+
onDrag(pointOf(event, current.grab), "move");
|
|
5037
|
+
},
|
|
5038
|
+
onPointerUp: (event) => {
|
|
5039
|
+
const current = drag.current;
|
|
5040
|
+
drag.current = null;
|
|
5041
|
+
if (!current) return;
|
|
5042
|
+
if (current.moved) onDrag?.(pointOf(event, current.grab), "end");
|
|
5043
|
+
else onClick();
|
|
5044
|
+
},
|
|
5045
|
+
onPointerCancel: () => drag.current = null
|
|
5046
|
+
};
|
|
5047
|
+
}
|
|
4798
5048
|
function Marker({
|
|
4799
5049
|
spot,
|
|
4800
5050
|
open,
|
|
@@ -4802,67 +5052,22 @@ function Marker({
|
|
|
4802
5052
|
onClick,
|
|
4803
5053
|
onDrag
|
|
4804
5054
|
}) {
|
|
4805
|
-
const
|
|
4806
|
-
const pointOf = (event) => ({
|
|
4807
|
-
x: event.clientX - drag.current.grab.x,
|
|
4808
|
-
y: event.clientY - drag.current.grab.y
|
|
4809
|
-
});
|
|
5055
|
+
const handlers = useMarkerDrag(onClick, onDrag);
|
|
4810
5056
|
const sorted = [...spot.hotspots].sort(bySeverity);
|
|
4811
5057
|
const severity = sorted[0].severity;
|
|
4812
5058
|
const count = sorted.length;
|
|
4813
|
-
const label = spot.inside ? `${count} hotspot${count === 1 ? "" : "s"}` :
|
|
5059
|
+
const label = count > 1 || spot.inside ? `${count} hotspot${count === 1 ? "" : "s"}` : sorted[0].title;
|
|
4814
5060
|
return /* @__PURE__ */ jsxs6(
|
|
4815
5061
|
"button",
|
|
4816
5062
|
{
|
|
4817
5063
|
type: "button",
|
|
4818
5064
|
"aria-expanded": open,
|
|
5065
|
+
"aria-label": label,
|
|
4819
5066
|
title: sorted.map(
|
|
4820
5067
|
(hotspot) => `${SEVERITIES[hotspot.severity].label}: ${hotspot.title}`
|
|
4821
5068
|
).join("\n"),
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
if (event.button !== 0) return;
|
|
4825
|
-
try {
|
|
4826
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
4827
|
-
} catch {
|
|
4828
|
-
}
|
|
4829
|
-
const rect = event.currentTarget.getBoundingClientRect();
|
|
4830
|
-
drag.current = {
|
|
4831
|
-
start: { x: event.clientX, y: event.clientY },
|
|
4832
|
-
grab: {
|
|
4833
|
-
x: event.clientX - rect.left - ICON_CENTRE_PX * (rect.height / 28),
|
|
4834
|
-
y: event.clientY - rect.top - rect.height / 2
|
|
4835
|
-
},
|
|
4836
|
-
moved: false
|
|
4837
|
-
};
|
|
4838
|
-
},
|
|
4839
|
-
onPointerMove: (event) => {
|
|
4840
|
-
const current = drag.current;
|
|
4841
|
-
if (!current || !onDrag) return;
|
|
4842
|
-
if (!current.moved && Math.hypot(
|
|
4843
|
-
event.clientX - current.start.x,
|
|
4844
|
-
event.clientY - current.start.y
|
|
4845
|
-
) < DRAG_THRESHOLD_PX2)
|
|
4846
|
-
return;
|
|
4847
|
-
current.moved = true;
|
|
4848
|
-
onDrag(pointOf(event), "move");
|
|
4849
|
-
},
|
|
4850
|
-
onPointerUp: (event) => {
|
|
4851
|
-
const current = drag.current;
|
|
4852
|
-
drag.current = null;
|
|
4853
|
-
if (!current) return;
|
|
4854
|
-
if (current.moved)
|
|
4855
|
-
onDrag?.(
|
|
4856
|
-
{
|
|
4857
|
-
x: event.clientX - current.grab.x,
|
|
4858
|
-
y: event.clientY - current.grab.y
|
|
4859
|
-
},
|
|
4860
|
-
"end"
|
|
4861
|
-
);
|
|
4862
|
-
else onClick();
|
|
4863
|
-
},
|
|
4864
|
-
onPointerCancel: () => drag.current = null,
|
|
4865
|
-
className: `studio-hotspot-marker flex h-7 max-w-[240px] items-center gap-1.5 rounded-full pl-1 pr-2.5 text-[11px] font-semibold text-white ${onDrag ? "cursor-grab active:cursor-grabbing" : ""}`,
|
|
5069
|
+
...handlers,
|
|
5070
|
+
className: `studio-hotspot-marker relative flex h-7 w-7 items-center justify-center rounded-full text-white ${onDrag ? "cursor-grab active:cursor-grabbing" : ""}`,
|
|
4866
5071
|
style: {
|
|
4867
5072
|
background: SEVERITIES[severity].color,
|
|
4868
5073
|
touchAction: "none",
|
|
@@ -4872,18 +5077,37 @@ function Marker({
|
|
|
4872
5077
|
},
|
|
4873
5078
|
children: [
|
|
4874
5079
|
/* @__PURE__ */ jsx9("span", { className: "flex h-5 w-5 flex-none items-center justify-center rounded-full bg-white/20", children: /* @__PURE__ */ jsx9(SeverityIcon, { severity }) }),
|
|
4875
|
-
/* @__PURE__ */ jsx9(
|
|
5080
|
+
count > 1 && /* @__PURE__ */ jsx9(
|
|
5081
|
+
"span",
|
|
5082
|
+
{
|
|
5083
|
+
"aria-hidden": true,
|
|
5084
|
+
className: "absolute -right-1.5 -top-1.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-[rgb(var(--ec-card-bg))] px-1 text-[10px] font-bold leading-none shadow-sm",
|
|
5085
|
+
style: { color: SEVERITIES[severity].color },
|
|
5086
|
+
children: count
|
|
5087
|
+
}
|
|
5088
|
+
)
|
|
4876
5089
|
]
|
|
4877
5090
|
}
|
|
4878
5091
|
);
|
|
4879
5092
|
}
|
|
4880
|
-
var panelClass2 = "studio-hotspot-panel absolute left-
|
|
5093
|
+
var panelClass2 = "studio-hotspot-panel absolute left-[40px] top-[-8px] w-80 rounded-xl border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] text-[rgb(var(--ec-page-text))] shadow-xl";
|
|
5094
|
+
var PanelArrow = ({ tint }) => /* @__PURE__ */ jsx9(
|
|
5095
|
+
"span",
|
|
5096
|
+
{
|
|
5097
|
+
"aria-hidden": true,
|
|
5098
|
+
className: "absolute left-[-6.5px] top-[16px] h-3 w-3 rotate-45 rounded-bl-[2px] border-b border-l border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))]",
|
|
5099
|
+
style: tint ? {
|
|
5100
|
+
background: `linear-gradient(${tint}14, ${tint}14), rgb(var(--ec-card-bg))`
|
|
5101
|
+
} : void 0
|
|
5102
|
+
}
|
|
5103
|
+
);
|
|
4881
5104
|
var inputClass = "block w-full rounded-md border border-[rgb(var(--ec-input-border))] bg-[rgb(var(--ec-input-bg))] px-2.5 py-1.5 text-sm text-[rgb(var(--ec-input-text))] outline-none focus:border-[rgb(var(--ec-accent))]";
|
|
4882
5105
|
function HotspotForm({
|
|
4883
5106
|
initial,
|
|
4884
5107
|
submitLabel,
|
|
4885
5108
|
onSubmit,
|
|
4886
|
-
onCancel
|
|
5109
|
+
onCancel,
|
|
5110
|
+
onSeverityChange
|
|
4887
5111
|
}) {
|
|
4888
5112
|
const [severity, setSeverity] = useState9(
|
|
4889
5113
|
initial?.severity ?? "warning"
|
|
@@ -4919,7 +5143,10 @@ function HotspotForm({
|
|
|
4919
5143
|
type: "button",
|
|
4920
5144
|
role: "radio",
|
|
4921
5145
|
"aria-checked": picked,
|
|
4922
|
-
onClick: () =>
|
|
5146
|
+
onClick: () => {
|
|
5147
|
+
setSeverity(value);
|
|
5148
|
+
onSeverityChange?.(value);
|
|
5149
|
+
},
|
|
4923
5150
|
className: "flex flex-1 items-center justify-center gap-1 rounded-md border px-2 py-1.5 text-xs font-semibold transition-colors",
|
|
4924
5151
|
style: picked ? {
|
|
4925
5152
|
background: SEVERITIES[value].color,
|
|
@@ -4953,14 +5180,14 @@ function HotspotForm({
|
|
|
4953
5180
|
{
|
|
4954
5181
|
value: description,
|
|
4955
5182
|
maxLength: 1e3,
|
|
4956
|
-
rows:
|
|
5183
|
+
rows: 5,
|
|
4957
5184
|
onChange: (event) => setDescription(event.target.value),
|
|
4958
5185
|
onKeyDown: (event) => {
|
|
4959
5186
|
if (event.key === "Enter" && (event.metaKey || event.ctrlKey))
|
|
4960
5187
|
submit();
|
|
4961
5188
|
},
|
|
4962
5189
|
placeholder: "Why it matters, and what to do about it (optional)",
|
|
4963
|
-
className: `${inputClass} resize-
|
|
5190
|
+
className: `${inputClass} min-h-20 max-h-[60vh] resize-y`
|
|
4964
5191
|
}
|
|
4965
5192
|
),
|
|
4966
5193
|
/* @__PURE__ */ jsxs6("div", { className: "flex justify-end gap-2", children: [
|
|
@@ -4978,7 +5205,7 @@ function HotspotForm({
|
|
|
4978
5205
|
{
|
|
4979
5206
|
type: "submit",
|
|
4980
5207
|
disabled: !title.trim(),
|
|
4981
|
-
className: "rounded-md bg-[rgb(var(--ec-
|
|
5208
|
+
className: "rounded-md bg-[rgb(var(--ec-button-bg))] px-3 py-1.5 text-xs font-semibold text-[rgb(var(--ec-button-text))] disabled:opacity-40",
|
|
4982
5209
|
children: submitLabel
|
|
4983
5210
|
}
|
|
4984
5211
|
)
|
|
@@ -4987,41 +5214,28 @@ function HotspotForm({
|
|
|
4987
5214
|
}
|
|
4988
5215
|
);
|
|
4989
5216
|
}
|
|
4990
|
-
function
|
|
4991
|
-
return /* @__PURE__ */ jsxs6(
|
|
4992
|
-
"
|
|
4993
|
-
{
|
|
4994
|
-
|
|
4995
|
-
style: { background: SEVERITIES[severity].color },
|
|
4996
|
-
children: [
|
|
4997
|
-
/* @__PURE__ */ jsx9(SeverityIcon, { severity, size: 10 }),
|
|
4998
|
-
SEVERITIES[severity].label
|
|
4999
|
-
]
|
|
5000
|
-
}
|
|
5001
|
-
);
|
|
5217
|
+
function HotspotItem({ hotspot }) {
|
|
5218
|
+
return /* @__PURE__ */ jsxs6("div", { children: [
|
|
5219
|
+
/* @__PURE__ */ jsx9("p", { className: "text-[15px] font-semibold leading-snug text-[rgb(var(--ec-page-text))]", children: hotspot.title }),
|
|
5220
|
+
hotspot.description && /* @__PURE__ */ jsx9("p", { className: "mt-1.5 whitespace-pre-wrap text-[13px] leading-relaxed text-[rgb(var(--ec-page-text-muted))]", children: hotspot.description })
|
|
5221
|
+
] });
|
|
5002
5222
|
}
|
|
5003
|
-
function
|
|
5223
|
+
function Flagged({
|
|
5004
5224
|
hotspot,
|
|
5005
|
-
|
|
5225
|
+
className = ""
|
|
5006
5226
|
}) {
|
|
5007
5227
|
return /* @__PURE__ */ jsxs6(
|
|
5008
5228
|
"div",
|
|
5009
5229
|
{
|
|
5010
|
-
className:
|
|
5011
|
-
style: { borderColor: SEVERITIES[hotspot.severity].color },
|
|
5230
|
+
className: `flex items-center gap-1.5 text-[11px] text-[rgb(var(--ec-page-text-muted))] ${className}`,
|
|
5012
5231
|
children: [
|
|
5013
|
-
/* @__PURE__ */
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
] }),
|
|
5021
|
-
actions && /* @__PURE__ */ jsx9("span", { className: "ml-auto flex flex-none items-center gap-0.5", children: actions })
|
|
5022
|
-
] }),
|
|
5023
|
-
/* @__PURE__ */ jsx9("p", { className: "mt-1.5 text-sm font-semibold leading-snug", children: hotspot.title }),
|
|
5024
|
-
hotspot.description && /* @__PURE__ */ jsx9("p", { className: "mt-1 whitespace-pre-wrap text-xs leading-relaxed text-[rgb(var(--ec-page-text-muted))]", children: hotspot.description })
|
|
5232
|
+
hotspot.author.agent && /* @__PURE__ */ jsx9(AgentMark, { name: hotspot.author.name, size: 12 }),
|
|
5233
|
+
/* @__PURE__ */ jsxs6("span", { className: "min-w-0 truncate", children: [
|
|
5234
|
+
"Flagged by ",
|
|
5235
|
+
hotspot.author.name,
|
|
5236
|
+
" \xB7 ",
|
|
5237
|
+
timeAgo(hotspot.createdAt)
|
|
5238
|
+
] })
|
|
5025
5239
|
]
|
|
5026
5240
|
}
|
|
5027
5241
|
);
|
|
@@ -5043,6 +5257,32 @@ function IconButton2({
|
|
|
5043
5257
|
}
|
|
5044
5258
|
);
|
|
5045
5259
|
}
|
|
5260
|
+
function SeverityHeader({
|
|
5261
|
+
severity,
|
|
5262
|
+
actions,
|
|
5263
|
+
className = ""
|
|
5264
|
+
}) {
|
|
5265
|
+
const { label, color } = SEVERITIES[severity];
|
|
5266
|
+
return /* @__PURE__ */ jsxs6(
|
|
5267
|
+
"div",
|
|
5268
|
+
{
|
|
5269
|
+
className: `flex items-center gap-2 border-b px-3 py-2.5 ${className}`,
|
|
5270
|
+
style: { background: `${color}14`, borderColor: `${color}33` },
|
|
5271
|
+
children: [
|
|
5272
|
+
/* @__PURE__ */ jsx9(
|
|
5273
|
+
"span",
|
|
5274
|
+
{
|
|
5275
|
+
className: "flex h-6 w-6 flex-none items-center justify-center rounded-full text-white",
|
|
5276
|
+
style: { background: color },
|
|
5277
|
+
children: /* @__PURE__ */ jsx9(SeverityIcon, { severity, size: 13 })
|
|
5278
|
+
}
|
|
5279
|
+
),
|
|
5280
|
+
/* @__PURE__ */ jsx9("span", { className: "text-xs font-semibold", style: { color }, children: label }),
|
|
5281
|
+
actions && /* @__PURE__ */ jsx9("span", { className: "ml-auto flex items-center gap-0.5", children: actions })
|
|
5282
|
+
]
|
|
5283
|
+
}
|
|
5284
|
+
);
|
|
5285
|
+
}
|
|
5046
5286
|
function SpotPanel({
|
|
5047
5287
|
spot,
|
|
5048
5288
|
locked,
|
|
@@ -5051,64 +5291,108 @@ function SpotPanel({
|
|
|
5051
5291
|
onDelete,
|
|
5052
5292
|
onGo
|
|
5053
5293
|
}) {
|
|
5054
|
-
const [editing,
|
|
5294
|
+
const [editing, setEditingId] = useState9(null);
|
|
5295
|
+
const [picked, setPicked] = useState9(null);
|
|
5296
|
+
const setEditing = (id) => {
|
|
5297
|
+
setEditingId(id);
|
|
5298
|
+
setPicked(null);
|
|
5299
|
+
};
|
|
5055
5300
|
const sorted = [...spot.hotspots].sort(bySeverity);
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
/* @__PURE__ */
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
{
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5301
|
+
const single = sorted.length === 1 && !spot.inside;
|
|
5302
|
+
const close = /* @__PURE__ */ jsx9(IconButton2, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx9(X3, { size: 14 }) });
|
|
5303
|
+
const severityOf = (hotspot) => editing === hotspot.id && picked || hotspot.severity;
|
|
5304
|
+
const section = (hotspot, first) => {
|
|
5305
|
+
const changing = editing === hotspot.id;
|
|
5306
|
+
const actions = /* @__PURE__ */ jsxs6(Fragment6, { children: [
|
|
5307
|
+
!locked && !spot.inside && !changing && /* @__PURE__ */ jsxs6(Fragment6, { children: [
|
|
5308
|
+
/* @__PURE__ */ jsx9(IconButton2, { label: "Edit", onClick: () => setEditing(hotspot.id), children: /* @__PURE__ */ jsx9(Pencil2, { size: 13 }) }),
|
|
5309
|
+
/* @__PURE__ */ jsx9(IconButton2, { label: "Remove", onClick: () => onDelete(hotspot.id), children: /* @__PURE__ */ jsx9(Trash23, { size: 13 }) })
|
|
5310
|
+
] }),
|
|
5311
|
+
single && close
|
|
5312
|
+
] });
|
|
5313
|
+
const body = changing ? /* @__PURE__ */ jsx9(
|
|
5314
|
+
HotspotForm,
|
|
5315
|
+
{
|
|
5316
|
+
initial: hotspot,
|
|
5317
|
+
submitLabel: "Save",
|
|
5318
|
+
onSeverityChange: setPicked,
|
|
5319
|
+
onCancel: () => setEditing(null),
|
|
5320
|
+
onSubmit: (fields) => {
|
|
5321
|
+
onUpdate(hotspot.id, fields);
|
|
5322
|
+
setEditing(null);
|
|
5072
5323
|
}
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
type: "button",
|
|
5079
|
-
onClick: () => onGo(hotspot),
|
|
5080
|
-
className: "block w-full rounded-md text-left hover:bg-[rgb(var(--ec-content-hover))]!",
|
|
5081
|
-
children: /* @__PURE__ */ jsx9(HotspotItem, { hotspot })
|
|
5082
|
-
},
|
|
5083
|
-
hotspot.id
|
|
5084
|
-
)
|
|
5085
|
-
) : /* @__PURE__ */ jsx9(
|
|
5086
|
-
HotspotItem,
|
|
5324
|
+
}
|
|
5325
|
+
) : /* @__PURE__ */ jsxs6(Fragment6, { children: [
|
|
5326
|
+
/* @__PURE__ */ jsx9("div", { className: "px-4 pb-3.5 pt-3", children: /* @__PURE__ */ jsx9(HotspotItem, { hotspot }) }),
|
|
5327
|
+
/* @__PURE__ */ jsx9(
|
|
5328
|
+
Flagged,
|
|
5087
5329
|
{
|
|
5088
5330
|
hotspot,
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
IconButton2,
|
|
5092
|
-
{
|
|
5093
|
-
label: "Edit",
|
|
5094
|
-
onClick: () => setEditing(hotspot.id),
|
|
5095
|
-
children: /* @__PURE__ */ jsx9(Pencil2, { size: 13 })
|
|
5096
|
-
}
|
|
5097
|
-
),
|
|
5098
|
-
/* @__PURE__ */ jsx9(
|
|
5099
|
-
IconButton2,
|
|
5100
|
-
{
|
|
5101
|
-
label: "Remove",
|
|
5102
|
-
onClick: () => onDelete(hotspot.id),
|
|
5103
|
-
children: /* @__PURE__ */ jsx9(Trash23, { size: 13 })
|
|
5104
|
-
}
|
|
5105
|
-
)
|
|
5106
|
-
] })
|
|
5107
|
-
},
|
|
5108
|
-
hotspot.id
|
|
5331
|
+
className: "border-t border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-text)/0.02)] px-4 py-2.5"
|
|
5332
|
+
}
|
|
5109
5333
|
)
|
|
5110
|
-
|
|
5111
|
-
|
|
5334
|
+
] });
|
|
5335
|
+
return /* @__PURE__ */ jsx9(
|
|
5336
|
+
HotspotSection,
|
|
5337
|
+
{
|
|
5338
|
+
header: /* @__PURE__ */ jsx9(
|
|
5339
|
+
SeverityHeader,
|
|
5340
|
+
{
|
|
5341
|
+
severity: severityOf(hotspot),
|
|
5342
|
+
actions,
|
|
5343
|
+
className: single && first ? "rounded-t-[11px]" : ""
|
|
5344
|
+
}
|
|
5345
|
+
),
|
|
5346
|
+
onGo: spot.inside ? () => onGo(hotspot) : void 0,
|
|
5347
|
+
children: body
|
|
5348
|
+
},
|
|
5349
|
+
hotspot.id
|
|
5350
|
+
);
|
|
5351
|
+
};
|
|
5352
|
+
return /* @__PURE__ */ jsxs6("div", { className: panelClass2, children: [
|
|
5353
|
+
/* @__PURE__ */ jsx9(
|
|
5354
|
+
PanelArrow,
|
|
5355
|
+
{
|
|
5356
|
+
tint: single ? SEVERITIES[severityOf(sorted[0])].color : void 0
|
|
5357
|
+
}
|
|
5358
|
+
),
|
|
5359
|
+
!single && /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between border-b border-[rgb(var(--ec-page-border))] px-3 py-2.5", children: [
|
|
5360
|
+
/* @__PURE__ */ jsxs6("span", { className: "text-xs font-semibold", children: [
|
|
5361
|
+
sorted.length,
|
|
5362
|
+
" hotspot",
|
|
5363
|
+
sorted.length === 1 ? "" : "s"
|
|
5364
|
+
] }),
|
|
5365
|
+
close
|
|
5366
|
+
] }),
|
|
5367
|
+
/* @__PURE__ */ jsx9(
|
|
5368
|
+
"div",
|
|
5369
|
+
{
|
|
5370
|
+
className: `max-h-[min(70vh,640px)] divide-y divide-[rgb(var(--ec-page-border))] overflow-y-auto ${spot.inside ? "" : "rounded-b-[11px]"} ${single ? "rounded-t-[11px]" : ""}`,
|
|
5371
|
+
children: sorted.map((hotspot, index) => section(hotspot, index === 0))
|
|
5372
|
+
}
|
|
5373
|
+
),
|
|
5374
|
+
spot.inside && /* @__PURE__ */ jsx9("p", { className: "rounded-b-[11px] border-t border-[rgb(var(--ec-page-border))] px-4 py-2 text-[11px] text-[rgb(var(--ec-page-text-muted))]", children: "Inside this: click one to go to it." })
|
|
5375
|
+
] });
|
|
5376
|
+
}
|
|
5377
|
+
function HotspotSection({
|
|
5378
|
+
header,
|
|
5379
|
+
onGo,
|
|
5380
|
+
children
|
|
5381
|
+
}) {
|
|
5382
|
+
return onGo ? /* @__PURE__ */ jsxs6(
|
|
5383
|
+
"button",
|
|
5384
|
+
{
|
|
5385
|
+
type: "button",
|
|
5386
|
+
onClick: onGo,
|
|
5387
|
+
className: "block w-full text-left transition-colors hover:bg-[rgb(var(--ec-accent)/0.06)]",
|
|
5388
|
+
children: [
|
|
5389
|
+
header,
|
|
5390
|
+
children
|
|
5391
|
+
]
|
|
5392
|
+
}
|
|
5393
|
+
) : /* @__PURE__ */ jsxs6("div", { children: [
|
|
5394
|
+
header,
|
|
5395
|
+
children
|
|
5112
5396
|
] });
|
|
5113
5397
|
}
|
|
5114
5398
|
var HotspotLayer = memo6(function HotspotLayer2({
|
|
@@ -5126,11 +5410,13 @@ var HotspotLayer = memo6(function HotspotLayer2({
|
|
|
5126
5410
|
onUpdate,
|
|
5127
5411
|
onDelete,
|
|
5128
5412
|
onGo,
|
|
5413
|
+
onMoveDraft,
|
|
5129
5414
|
live
|
|
5130
5415
|
}) {
|
|
5131
5416
|
const layer = useRef7(null);
|
|
5132
5417
|
useMarkerScale(layer);
|
|
5133
5418
|
const { screenToFlowPosition } = useReactFlow4();
|
|
5419
|
+
const store = useStoreApi4();
|
|
5134
5420
|
const [moving, setMoving] = useState9(null);
|
|
5135
5421
|
const remote = useRemoteMoves(live, "hotspot");
|
|
5136
5422
|
const remoteAt = (spot) => {
|
|
@@ -5162,6 +5448,50 @@ var HotspotLayer = memo6(function HotspotLayer2({
|
|
|
5162
5448
|
);
|
|
5163
5449
|
sendMove(live, "hotspot", spot.hotspots[0].id, null);
|
|
5164
5450
|
} : void 0;
|
|
5451
|
+
const [draftSeverity, setDraftSeverity] = useState9("warning");
|
|
5452
|
+
useEffect8(() => {
|
|
5453
|
+
if (!draft) setDraftSeverity("warning");
|
|
5454
|
+
}, [draft]);
|
|
5455
|
+
const [draftMoving, setDraftMoving] = useState9(null);
|
|
5456
|
+
const draftDrag = onMoveDraft && !locked ? (point, phase) => {
|
|
5457
|
+
const position = screenToFlowPosition(point);
|
|
5458
|
+
const over = nodeUnder(point);
|
|
5459
|
+
if (phase === "move") {
|
|
5460
|
+
if (over !== draftMoving?.over)
|
|
5461
|
+
onDropTarget(
|
|
5462
|
+
over ? { nodeId: over, severity: draftSeverity } : null
|
|
5463
|
+
);
|
|
5464
|
+
return setDraftMoving({ position, over });
|
|
5465
|
+
}
|
|
5466
|
+
setDraftMoving(null);
|
|
5467
|
+
onDropTarget(null);
|
|
5468
|
+
onMoveDraft(over ? { nodeId: over, position } : { position });
|
|
5469
|
+
} : void 0;
|
|
5470
|
+
const openSpot = useRef7(void 0);
|
|
5471
|
+
openSpot.current = spots.find((spot) => spot.key === openKey);
|
|
5472
|
+
const deleteOpen = useRef7(onDelete);
|
|
5473
|
+
deleteOpen.current = onDelete;
|
|
5474
|
+
const closeOpen = useRef7(onOpen);
|
|
5475
|
+
closeOpen.current = onOpen;
|
|
5476
|
+
useEffect8(() => {
|
|
5477
|
+
if (!openKey || locked) return;
|
|
5478
|
+
const onKey = (event) => {
|
|
5479
|
+
if (event.key !== "Delete" && event.key !== "Backspace") return;
|
|
5480
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
5481
|
+
if (target?.closest("input, textarea, select, [contenteditable]")) return;
|
|
5482
|
+
const spot = openSpot.current;
|
|
5483
|
+
if (!spot || spot.inside) return;
|
|
5484
|
+
const { nodes, edges } = store.getState();
|
|
5485
|
+
if (nodes.some((node) => node.selected) || edges.some((edge) => edge.selected))
|
|
5486
|
+
return;
|
|
5487
|
+
event.preventDefault();
|
|
5488
|
+
event.stopPropagation();
|
|
5489
|
+
spot.hotspots.forEach((hotspot) => deleteOpen.current(hotspot.id));
|
|
5490
|
+
closeOpen.current(null);
|
|
5491
|
+
};
|
|
5492
|
+
window.addEventListener("keydown", onKey, true);
|
|
5493
|
+
return () => window.removeEventListener("keydown", onKey, true);
|
|
5494
|
+
}, [openKey, locked, store]);
|
|
5165
5495
|
return /* @__PURE__ */ jsx9(CanvasPortal, { children: /* @__PURE__ */ jsxs6(
|
|
5166
5496
|
"div",
|
|
5167
5497
|
{
|
|
@@ -5186,11 +5516,14 @@ var HotspotLayer = memo6(function HotspotLayer2({
|
|
|
5186
5516
|
spot,
|
|
5187
5517
|
open,
|
|
5188
5518
|
selected: !!selectedIds && spot.hotspots.some((hotspot) => selectedIds.has(hotspot.id)),
|
|
5189
|
-
onClick: () =>
|
|
5519
|
+
onClick: () => {
|
|
5520
|
+
if (!open) store.getState().unselectNodesAndEdges();
|
|
5521
|
+
onOpen(open ? null : spot.key);
|
|
5522
|
+
},
|
|
5190
5523
|
onDrag: dragHandler(spot)
|
|
5191
5524
|
}
|
|
5192
5525
|
),
|
|
5193
|
-
open && !dragged && /* @__PURE__ */ jsx9(
|
|
5526
|
+
open && (!dragged || moving?.key === spot.key) && /* @__PURE__ */ jsx9(
|
|
5194
5527
|
SpotPanel,
|
|
5195
5528
|
{
|
|
5196
5529
|
spot,
|
|
@@ -5209,26 +5542,23 @@ var HotspotLayer = memo6(function HotspotLayer2({
|
|
|
5209
5542
|
draft && /* @__PURE__ */ jsxs6(
|
|
5210
5543
|
SpotAt,
|
|
5211
5544
|
{
|
|
5212
|
-
nodeId: draft.nodeId,
|
|
5213
|
-
position: draft.nodeId ? void 0 : draft.position,
|
|
5545
|
+
nodeId: draftMoving ? void 0 : draft.nodeId,
|
|
5546
|
+
position: draftMoving ? draftMoving.position : draft.nodeId ? void 0 : draft.position,
|
|
5214
5547
|
zIndex: 4,
|
|
5215
5548
|
children: [
|
|
5216
|
-
/* @__PURE__ */ jsx9(
|
|
5217
|
-
|
|
5218
|
-
{
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
onCancel: onCancelDraft
|
|
5230
|
-
}
|
|
5231
|
-
) })
|
|
5549
|
+
/* @__PURE__ */ jsx9(DraftMarker, { severity: draftSeverity, onDrag: draftDrag }),
|
|
5550
|
+
/* @__PURE__ */ jsxs6("div", { className: panelClass2, children: [
|
|
5551
|
+
/* @__PURE__ */ jsx9(PanelArrow, {}),
|
|
5552
|
+
/* @__PURE__ */ jsx9(
|
|
5553
|
+
HotspotForm,
|
|
5554
|
+
{
|
|
5555
|
+
onSeverityChange: setDraftSeverity,
|
|
5556
|
+
submitLabel: "Add hotspot",
|
|
5557
|
+
onSubmit: onCreate,
|
|
5558
|
+
onCancel: onCancelDraft
|
|
5559
|
+
}
|
|
5560
|
+
)
|
|
5561
|
+
] })
|
|
5232
5562
|
]
|
|
5233
5563
|
}
|
|
5234
5564
|
)
|
|
@@ -5236,33 +5566,101 @@ var HotspotLayer = memo6(function HotspotLayer2({
|
|
|
5236
5566
|
}
|
|
5237
5567
|
) });
|
|
5238
5568
|
});
|
|
5569
|
+
function DraftMarker({
|
|
5570
|
+
severity,
|
|
5571
|
+
onDrag
|
|
5572
|
+
}) {
|
|
5573
|
+
const handlers = useMarkerDrag(() => {
|
|
5574
|
+
}, onDrag);
|
|
5575
|
+
return /* @__PURE__ */ jsx9(
|
|
5576
|
+
"span",
|
|
5577
|
+
{
|
|
5578
|
+
...handlers,
|
|
5579
|
+
title: onDrag ? "Drag to move it" : void 0,
|
|
5580
|
+
className: `studio-hotspot-marker flex h-7 w-7 items-center justify-center rounded-full text-white ${onDrag ? "cursor-grab active:cursor-grabbing" : ""}`,
|
|
5581
|
+
style: { background: SEVERITIES[severity].color, touchAction: "none" },
|
|
5582
|
+
children: /* @__PURE__ */ jsx9(SeverityIcon, { severity })
|
|
5583
|
+
}
|
|
5584
|
+
);
|
|
5585
|
+
}
|
|
5239
5586
|
function HotspotList({
|
|
5240
5587
|
hotspots,
|
|
5241
5588
|
nameOf,
|
|
5242
|
-
onOpen
|
|
5589
|
+
onOpen,
|
|
5590
|
+
goOnHover = true
|
|
5243
5591
|
}) {
|
|
5244
5592
|
const sorted = [...hotspots].sort(bySeverity);
|
|
5245
5593
|
if (!sorted.length)
|
|
5246
5594
|
return /* @__PURE__ */ jsx9("p", { className: "px-4 py-6 text-center text-xs leading-relaxed text-[rgb(var(--ec-page-text-muted))]", children: "No hotspots yet. Press A, or right-click a node, to flag what people should know: a risk, a problem, or the key part." });
|
|
5247
|
-
return /* @__PURE__ */ jsx9("
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5595
|
+
return /* @__PURE__ */ jsx9("ul", { className: "divide-y divide-[rgb(var(--ec-page-border))]", children: sorted.map((hotspot) => /* @__PURE__ */ jsx9(
|
|
5596
|
+
HotspotRow,
|
|
5597
|
+
{
|
|
5598
|
+
hotspot,
|
|
5599
|
+
on: hotspot.nodeId && nameOf(hotspot.nodeId),
|
|
5600
|
+
onOpen,
|
|
5601
|
+
goOnHover
|
|
5602
|
+
},
|
|
5603
|
+
hotspot.id
|
|
5604
|
+
)) });
|
|
5605
|
+
}
|
|
5606
|
+
var GO_ON_HOVER_MS = 250;
|
|
5607
|
+
function HotspotRow({
|
|
5608
|
+
hotspot,
|
|
5609
|
+
on,
|
|
5610
|
+
onOpen,
|
|
5611
|
+
goOnHover
|
|
5612
|
+
}) {
|
|
5613
|
+
const hover = useRef7(null);
|
|
5614
|
+
const cancel = () => {
|
|
5615
|
+
if (hover.current !== null) clearTimeout(hover.current);
|
|
5616
|
+
hover.current = null;
|
|
5617
|
+
};
|
|
5618
|
+
useEffect8(() => cancel, []);
|
|
5619
|
+
const { label, color, icon: Icon } = SEVERITIES[hotspot.severity];
|
|
5620
|
+
return /* @__PURE__ */ jsx9("li", { children: /* @__PURE__ */ jsxs6(
|
|
5621
|
+
"button",
|
|
5622
|
+
{
|
|
5623
|
+
type: "button",
|
|
5624
|
+
onClick: () => {
|
|
5625
|
+
cancel();
|
|
5626
|
+
onOpen(hotspot);
|
|
5627
|
+
},
|
|
5628
|
+
onMouseEnter: () => {
|
|
5629
|
+
cancel();
|
|
5630
|
+
if (goOnHover)
|
|
5631
|
+
hover.current = setTimeout(() => onOpen(hotspot), GO_ON_HOVER_MS);
|
|
5632
|
+
},
|
|
5633
|
+
onMouseLeave: cancel,
|
|
5634
|
+
title: "Show me on the canvas",
|
|
5635
|
+
className: "flex w-full cursor-pointer items-center gap-2.5 px-3 py-2 text-left text-xs text-[rgb(var(--ec-page-text))] transition-colors hover:bg-[rgb(var(--ec-accent)/0.06)]",
|
|
5636
|
+
children: [
|
|
5637
|
+
/* @__PURE__ */ jsx9(
|
|
5638
|
+
Icon,
|
|
5639
|
+
{
|
|
5640
|
+
size: 14,
|
|
5641
|
+
className: "flex-none",
|
|
5642
|
+
style: { color },
|
|
5643
|
+
"aria-label": label
|
|
5644
|
+
}
|
|
5645
|
+
),
|
|
5646
|
+
/* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1", children: [
|
|
5647
|
+
/* @__PURE__ */ jsx9("span", { className: "block", children: hotspot.title }),
|
|
5648
|
+
on && /* @__PURE__ */ jsxs6("span", { className: "mt-0.5 block truncate text-[11px] text-[rgb(var(--ec-page-text-muted))]", children: [
|
|
5258
5649
|
"On ",
|
|
5259
5650
|
on
|
|
5260
5651
|
] })
|
|
5261
|
-
]
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5652
|
+
] }),
|
|
5653
|
+
/* @__PURE__ */ jsx9(
|
|
5654
|
+
LocateFixed,
|
|
5655
|
+
{
|
|
5656
|
+
size: 12,
|
|
5657
|
+
className: "flex-none text-[rgb(var(--ec-icon-color))]",
|
|
5658
|
+
"aria-hidden": true
|
|
5659
|
+
}
|
|
5660
|
+
)
|
|
5661
|
+
]
|
|
5662
|
+
}
|
|
5663
|
+
) });
|
|
5266
5664
|
}
|
|
5267
5665
|
|
|
5268
5666
|
// src/studio/components/CanvasControls.tsx
|
|
@@ -5572,7 +5970,7 @@ var ViewControls = memo7(function ViewControls2({
|
|
|
5572
5970
|
});
|
|
5573
5971
|
|
|
5574
5972
|
// src/studio/components/ContainerChooser.tsx
|
|
5575
|
-
import { useEffect as
|
|
5973
|
+
import { useEffect as useEffect9, useState as useState10 } from "react";
|
|
5576
5974
|
import { X as X4 } from "lucide-react";
|
|
5577
5975
|
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5578
5976
|
var plural = (count, noun) => `${count} ${noun}${count === 1 ? "" : "s"}`;
|
|
@@ -5728,7 +6126,7 @@ function ContainerChooser({
|
|
|
5728
6126
|
contents.systems > 0 && plural(contents.systems, "system"),
|
|
5729
6127
|
contents.services > 0 && plural(contents.services, "service")
|
|
5730
6128
|
].filter(Boolean).join(" and ") : "";
|
|
5731
|
-
|
|
6129
|
+
useEffect9(() => {
|
|
5732
6130
|
const onKeyDown = (event) => event.key === "Escape" && onCancel();
|
|
5733
6131
|
window.addEventListener("keydown", onKeyDown);
|
|
5734
6132
|
return () => window.removeEventListener("keydown", onKeyDown);
|
|
@@ -5853,9 +6251,11 @@ var EditButton_default = memo8(function EditButton({
|
|
|
5853
6251
|
import {
|
|
5854
6252
|
memo as memo9,
|
|
5855
6253
|
useCallback as useCallback5,
|
|
5856
|
-
useEffect as
|
|
6254
|
+
useEffect as useEffect10,
|
|
6255
|
+
useLayoutEffect as useLayoutEffect4,
|
|
5857
6256
|
useRef as useRef8,
|
|
5858
|
-
useState as useState11
|
|
6257
|
+
useState as useState11,
|
|
6258
|
+
useSyncExternalStore
|
|
5859
6259
|
} from "react";
|
|
5860
6260
|
import { ChevronDown, GripVertical as GripVertical2 } from "lucide-react";
|
|
5861
6261
|
import { Fragment as Fragment9, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
@@ -5891,6 +6291,21 @@ var readCollapsed = () => {
|
|
|
5891
6291
|
return false;
|
|
5892
6292
|
}
|
|
5893
6293
|
};
|
|
6294
|
+
var shownCollapsed = false;
|
|
6295
|
+
var collapsedListeners = /* @__PURE__ */ new Set();
|
|
6296
|
+
var showCollapsed = (collapsed) => {
|
|
6297
|
+
if (collapsed === shownCollapsed) return;
|
|
6298
|
+
shownCollapsed = collapsed;
|
|
6299
|
+
collapsedListeners.forEach((listener) => listener());
|
|
6300
|
+
};
|
|
6301
|
+
var usePaletteCollapsed = () => useSyncExternalStore(
|
|
6302
|
+
(listener) => {
|
|
6303
|
+
collapsedListeners.add(listener);
|
|
6304
|
+
return () => collapsedListeners.delete(listener);
|
|
6305
|
+
},
|
|
6306
|
+
() => shownCollapsed,
|
|
6307
|
+
() => false
|
|
6308
|
+
);
|
|
5894
6309
|
function PaletteItem({
|
|
5895
6310
|
icon: Icon,
|
|
5896
6311
|
iconClassName,
|
|
@@ -5949,7 +6364,7 @@ function PaletteSection({
|
|
|
5949
6364
|
);
|
|
5950
6365
|
}
|
|
5951
6366
|
var COMPONENTS_TAB = "components";
|
|
5952
|
-
var
|
|
6367
|
+
var Palette2 = memo9(function Palette3({
|
|
5953
6368
|
level,
|
|
5954
6369
|
onAddComponent,
|
|
5955
6370
|
footer,
|
|
@@ -5969,6 +6384,8 @@ var Palette = memo9(function Palette2({
|
|
|
5969
6384
|
} catch {
|
|
5970
6385
|
}
|
|
5971
6386
|
};
|
|
6387
|
+
useLayoutEffect4(() => showCollapsed(collapsed), [collapsed]);
|
|
6388
|
+
useLayoutEffect4(() => () => showCollapsed(false), []);
|
|
5972
6389
|
const toggle = useCallback5(() => {
|
|
5973
6390
|
setCollapsed((current) => {
|
|
5974
6391
|
remember(!current);
|
|
@@ -5986,7 +6403,7 @@ var Palette = memo9(function Palette2({
|
|
|
5986
6403
|
}
|
|
5987
6404
|
};
|
|
5988
6405
|
const chosen = useRef8(tab);
|
|
5989
|
-
|
|
6406
|
+
useEffect10(() => {
|
|
5990
6407
|
if (tab === chosen.current) return;
|
|
5991
6408
|
chosen.current = tab;
|
|
5992
6409
|
if (tab === void 0 || !collapsed) return;
|
|
@@ -6187,7 +6604,7 @@ function ShortcutsList({ omit = [] }) {
|
|
|
6187
6604
|
}
|
|
6188
6605
|
|
|
6189
6606
|
// src/studio/components/EmptyCanvas.tsx
|
|
6190
|
-
import { useEffect as
|
|
6607
|
+
import { useEffect as useEffect11, useState as useState12 } from "react";
|
|
6191
6608
|
import { CircleHelp, FolderOpen, Plug } from "lucide-react";
|
|
6192
6609
|
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
6193
6610
|
var hintText = "font-[Excalifont,Inter,sans-serif] text-[14px] leading-snug text-[color-mix(in_srgb,rgb(var(--ec-page-text))_22%,transparent)]";
|
|
@@ -6199,8 +6616,16 @@ var arrow = {
|
|
|
6199
6616
|
strokeLinejoin: "round"
|
|
6200
6617
|
};
|
|
6201
6618
|
function Hints({ palette, live }) {
|
|
6619
|
+
const paletteCollapsed = usePaletteCollapsed();
|
|
6202
6620
|
return /* @__PURE__ */ jsxs12("div", { "aria-hidden": true, className: `hidden md:block! ${hintText}`, children: [
|
|
6203
|
-
palette && /* @__PURE__ */ jsxs12("div", { className: "absolute
|
|
6621
|
+
palette && paletteCollapsed && /* @__PURE__ */ jsxs12("div", { className: "absolute left-[284px] top-[75px] flex items-start gap-1", children: [
|
|
6622
|
+
/* @__PURE__ */ jsxs12("svg", { width: "56", height: "32", viewBox: "0 0 70 40", ...arrow, children: [
|
|
6623
|
+
/* @__PURE__ */ jsx15("path", { d: "M66 30 C 45 34, 22 28, 6 12" }),
|
|
6624
|
+
/* @__PURE__ */ jsx15("path", { d: "M6 12 L15.7 14.6 M6 12 L8.6 21.7" })
|
|
6625
|
+
] }),
|
|
6626
|
+
/* @__PURE__ */ jsx15("p", { className: "mt-4 max-w-[160px]", children: "Drag resources onto the canvas, then connect them" })
|
|
6627
|
+
] }),
|
|
6628
|
+
palette && !paletteCollapsed && /* @__PURE__ */ jsxs12("div", { className: "absolute bottom-[120px] left-[290px] flex items-start gap-1", children: [
|
|
6204
6629
|
/* @__PURE__ */ jsxs12("svg", { width: "56", height: "32", viewBox: "0 0 70 40", ...arrow, children: [
|
|
6205
6630
|
/* @__PURE__ */ jsx15("path", { d: "M66 8 C 45 4, 22 10, 6 26" }),
|
|
6206
6631
|
/* @__PURE__ */ jsx15("path", { d: "M6 26 L15.7 23.4 M6 26 L8.6 16.3" })
|
|
@@ -6245,7 +6670,7 @@ function EmptyCanvas({
|
|
|
6245
6670
|
}) {
|
|
6246
6671
|
const [dragging, setDragging] = useState12(false);
|
|
6247
6672
|
const [dropped, setDropped] = useState12(false);
|
|
6248
|
-
|
|
6673
|
+
useEffect11(() => {
|
|
6249
6674
|
const start = () => setDragging(true);
|
|
6250
6675
|
const end = () => setDragging(false);
|
|
6251
6676
|
const drop = () => {
|
|
@@ -6306,7 +6731,7 @@ function EmptyCanvas({
|
|
|
6306
6731
|
}
|
|
6307
6732
|
|
|
6308
6733
|
// src/studio/components/RemeasureHandles.tsx
|
|
6309
|
-
import { memo as memo10, useEffect as
|
|
6734
|
+
import { memo as memo10, useEffect as useEffect12 } from "react";
|
|
6310
6735
|
import {
|
|
6311
6736
|
useStore as useStore2,
|
|
6312
6737
|
useUpdateNodeInternals as useUpdateNodeInternals2
|
|
@@ -6315,7 +6740,7 @@ var selectDomNode = (state) => state.domNode;
|
|
|
6315
6740
|
var RemeasureHandles = memo10(function RemeasureHandles2() {
|
|
6316
6741
|
const domNode = useStore2(selectDomNode);
|
|
6317
6742
|
const updateNodeInternals = useUpdateNodeInternals2();
|
|
6318
|
-
|
|
6743
|
+
useEffect12(() => {
|
|
6319
6744
|
if (!domNode) return;
|
|
6320
6745
|
const pending = /* @__PURE__ */ new Set();
|
|
6321
6746
|
let frame = 0;
|
|
@@ -6398,9 +6823,10 @@ export {
|
|
|
6398
6823
|
MESSAGE_COLLECTIONS,
|
|
6399
6824
|
NODE_CATEGORIES,
|
|
6400
6825
|
NODE_ICONS,
|
|
6826
|
+
NOTE_COLORS,
|
|
6401
6827
|
NodeCard,
|
|
6402
6828
|
OpenAILogo,
|
|
6403
|
-
Palette,
|
|
6829
|
+
Palette2 as Palette,
|
|
6404
6830
|
PaletteItem,
|
|
6405
6831
|
PaletteSection,
|
|
6406
6832
|
Picture,
|
|
@@ -6534,6 +6960,7 @@ export {
|
|
|
6534
6960
|
shortId,
|
|
6535
6961
|
sizeOf,
|
|
6536
6962
|
sortByHierarchy,
|
|
6963
|
+
startWriting,
|
|
6537
6964
|
timeAgo,
|
|
6538
6965
|
toDiagramFile,
|
|
6539
6966
|
toRelativePosition,
|
|
@@ -6546,6 +6973,7 @@ export {
|
|
|
6546
6973
|
useCounterScale,
|
|
6547
6974
|
useDragGhost,
|
|
6548
6975
|
useNodeAnchor,
|
|
6976
|
+
usePaletteCollapsed,
|
|
6549
6977
|
useRemoteMoves,
|
|
6550
6978
|
useSavedFlash,
|
|
6551
6979
|
withDescendants,
|