sysml-diagram 0.20.1 → 0.20.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/out/main.js +415 -264
- package/out/main.js.map +3 -3
- package/package.json +1 -1
- package/resources/sysml.dimension-table.json +1 -1
package/out/main.js
CHANGED
|
@@ -181834,6 +181834,13 @@ var DOCK_TANGENT = {
|
|
|
181834
181834
|
left: { x: 0, y: 1 },
|
|
181835
181835
|
right: { x: 0, y: 1 }
|
|
181836
181836
|
};
|
|
181837
|
+
var BODY_SNAP_POINT_HIT_SIZE = 12;
|
|
181838
|
+
function bodySnapPointOccludedByPort(point, portRects) {
|
|
181839
|
+
const half = BODY_SNAP_POINT_HIT_SIZE / 2;
|
|
181840
|
+
return portRects.some(
|
|
181841
|
+
(rect) => point.x + half >= rect.x && point.x - half <= rect.x + rect.width && point.y + half >= rect.y && point.y - half <= rect.y + rect.height
|
|
181842
|
+
);
|
|
181843
|
+
}
|
|
181837
181844
|
function portGlyphRect(g, w, h, topReserve = 0) {
|
|
181838
181845
|
const natural = endpointGlyphSize(g.port);
|
|
181839
181846
|
const along = g.along ?? natural;
|
|
@@ -183265,19 +183272,24 @@ function modelToFlow(model, opts) {
|
|
|
183265
183272
|
// could not be re-arranged. (Geometry nodes are the one exception —
|
|
183266
183273
|
// their positions are model attributes, see above.)
|
|
183267
183274
|
draggable: model.kind !== "gev",
|
|
183268
|
-
selectable: true
|
|
183269
|
-
// issue #
|
|
183270
|
-
//
|
|
183271
|
-
//
|
|
183272
|
-
//
|
|
183273
|
-
//
|
|
183274
|
-
//
|
|
183275
|
-
//
|
|
183276
|
-
//
|
|
183277
|
-
//
|
|
183278
|
-
//
|
|
183279
|
-
//
|
|
183280
|
-
|
|
183275
|
+
selectable: true
|
|
183276
|
+
// issue #226: NO `dragHandle` on a plain node, in any view.
|
|
183277
|
+
//
|
|
183278
|
+
// Issue #58 had scoped an Interconnection View part's drag to its title
|
|
183279
|
+
// strip for one reason: "as long as there is nothing to grab it should be
|
|
183280
|
+
// possible to pan the canvas". Issue #225 then made a left drag under the
|
|
183281
|
+
// select tool an editing gesture that NEVER pans (canvas-navigation.ts,
|
|
183282
|
+
// `panOnDrag: [1]`), and locks the nodes outright under the hand tool, where
|
|
183283
|
+
// a left drag pans over a part regardless. The restriction therefore bought
|
|
183284
|
+
// nothing any more and turned the whole body of every IV part into dead
|
|
183285
|
+
// area: press and drag there and the part did not move and the canvas did
|
|
183286
|
+
// not pan. That is the reported "sometimes I mousedown and drag and it does
|
|
183287
|
+
// not move". A part now moves from anywhere on its body, like every other
|
|
183288
|
+
// node in every other view; a click there still just selects it.
|
|
183289
|
+
//
|
|
183290
|
+
// Container FRAMES keep `.rf-frame-header` (set where they are built): their
|
|
183291
|
+
// interior is deliberately click-through so the connectors drawn underneath
|
|
183292
|
+
// stay selectable, so there is nothing there to grab in the first place.
|
|
183281
183293
|
});
|
|
183282
183294
|
}
|
|
183283
183295
|
if (model.kind === "sv") {
|
|
@@ -197210,7 +197222,7 @@ body {
|
|
|
197210
197222
|
* connect-target -> the whole port square lights up as the ready-to-land cue, with
|
|
197211
197223
|
* the dotted anchor point (.dport-anchor) naming the dock edge. */
|
|
197212
197224
|
.dnode-port.moving { stroke: var(--accent); stroke-width: 2.6; filter: drop-shadow(0 0 4px var(--accent)); }
|
|
197213
|
-
.dnode-port.connect-target { stroke: var(--cyan); stroke-width: 2.8; fill: var(--
|
|
197225
|
+
.dnode-port.connect-target { stroke: var(--cyan); stroke-width: 2.8; fill: var(--element-fill); fill-opacity: 1; filter: drop-shadow(0 0 5px var(--cyan)); }
|
|
197214
197226
|
/* The connect affordance shown in front of a SELECTED port (drag it to wire). */
|
|
197215
197227
|
.dport-plus { stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; pointer-events: none; }
|
|
197216
197228
|
/* The four dotted anchor points a connector docks onto, shown while a connection
|
|
@@ -197861,11 +197873,16 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197861
197873
|
.rf-frame .dframe-rect { pointer-events: none; }
|
|
197862
197874
|
.rf-frame-header { position: absolute; pointer-events: auto; cursor: move; }
|
|
197863
197875
|
/* issue #58 / user report 2026-08-11 \u2014 the matching title strip on an
|
|
197864
|
-
* Interconnection View PART node
|
|
197865
|
-
*
|
|
197866
|
-
*
|
|
197867
|
-
*
|
|
197876
|
+
* Interconnection View PART node, so a part reads identically whether it draws
|
|
197877
|
+
* its internals (a frame) or has them hidden (a node). Issue 226 removed the
|
|
197878
|
+
* dragHandle this strip used to select; it stays for the title tooltip and to
|
|
197879
|
+
* keep the title area's cursor the same as a frame's. */
|
|
197868
197880
|
.rf-node-header { position: absolute; pointer-events: auto; cursor: move; }
|
|
197881
|
+
/* issue 226. A node whose whole body moves says so over its whole body. React
|
|
197882
|
+
* Flow's grab hand used to sit next to the title strip's move cross even though
|
|
197883
|
+
* only the strip could be grabbed; both are the move cross now. The hand tool's
|
|
197884
|
+
* rules above outrank this one, and a locked node loses the class anyway. */
|
|
197885
|
+
.react-flow.rf-tool-select .rf-node-movable { cursor: move; }
|
|
197869
197886
|
/* REQ-379 \u2014 the frame's BORDER band is hover-sensitive (the interior stays
|
|
197870
197887
|
* click-through): hovering it reveals and mounts the frame's side connect points,
|
|
197871
197888
|
* which are drawn on that same border. Stroke-only hit testing, so nothing but the
|
|
@@ -197873,6 +197890,9 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197873
197890
|
.dframe-hover-band { stroke-width: 12; pointer-events: stroke; }
|
|
197874
197891
|
.rf-frame .dport-hit { pointer-events: auto; }
|
|
197875
197892
|
.rf-frame .react-flow__handle { pointer-events: auto; }
|
|
197893
|
+
/* REQ-370: a frame is click-through, but its stacked handles still obey React
|
|
197894
|
+
* Flow's active end choice. An inactive twin must not cover an eligible end. */
|
|
197895
|
+
.react-flow.sysml-connecting .rf-frame .react-flow__handle:not(.connectionindicator) { pointer-events: none; }
|
|
197876
197896
|
.rf-frame .react-flow__resize-control { pointer-events: auto; }
|
|
197877
197897
|
.rf-node .react-flow__resize-control.fork-join-resize {
|
|
197878
197898
|
width: 14px;
|
|
@@ -197930,7 +197950,11 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197930
197950
|
* strip. All connection dots share ONE visible 5px size so the affordance reads the same
|
|
197931
197951
|
* everywhere. */
|
|
197932
197952
|
.react-flow__handle.rf-handle-port { width: ${PORT_CONNECT_DOT_HIT}px; height: ${PORT_CONNECT_DOT_HIT}px; --rf-dot-size: 5px; z-index: 6; }
|
|
197933
|
-
.react-flow__handle.rf-handle-side { width:
|
|
197953
|
+
.react-flow__handle.rf-handle-side { width: ${BODY_SNAP_POINT_HIT_SIZE}px; height: ${BODY_SNAP_POINT_HIT_SIZE}px; --rf-dot-size: 5px; z-index: 2; }
|
|
197954
|
+
/* REQ-370: body snap points are hollow circles. Port and pin endpoints are
|
|
197955
|
+
* solid squares, so adjacent targets cannot be mistaken for each other. */
|
|
197956
|
+
.react-flow__handle.rf-handle-side::after { background: var(--bg-1); border: 1.5px solid var(--cyan); }
|
|
197957
|
+
.react-flow__handle.rf-handle-port::after { border-radius: 1px; }
|
|
197934
197958
|
/* The start/done centre stays available for normal node selection and dragging
|
|
197935
197959
|
* even though four 12px handle targets meet over these exact-size glyphs. The
|
|
197936
197960
|
* perimeter dots remain above the rest of the node and keep their full hit area. */
|
|
@@ -197944,25 +197968,32 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197944
197968
|
/* The whole-glyph DROP target on a port's inner dock side. It exists ALWAYS (so a
|
|
197945
197969
|
* delegation connector docking on the inner side resolves and isn't dropped by React
|
|
197946
197970
|
* Flow), but is click-through AT REST so it never steals the port's click-to-select or
|
|
197947
|
-
* the drag-to-move strip; while a connector is being dragged,
|
|
197948
|
-
* ".connectionindicator"
|
|
197949
|
-
* connectable end handle for a drop ANYWHERE on the glyph
|
|
197971
|
+
* the drag-to-move strip; while a connector is being dragged, React Flow's eligible
|
|
197972
|
+
* ".connectionindicator" twins become pointer-active, so elementFromPoint returns a
|
|
197973
|
+
* connectable end handle for a drop ANYWHERE on the glyph, inside or on an edge. It
|
|
197950
197974
|
* draws nothing (the drop cue is the port SQUARE highlight); its box is sized inline
|
|
197951
197975
|
* to PORT_GLYPH_SIZE by the renderer. */
|
|
197952
197976
|
.react-flow__handle.rf-handle-portdrop { --rf-dot-size: 0px; z-index: 5; border-radius: 3px; }
|
|
197953
197977
|
.react-flow__handle.rf-handle-portdrop::after { display: none; }
|
|
197954
197978
|
/* Both rules are (0,4,0), higher than React Flow's own .react-flow__handle.connectionindicator
|
|
197955
|
-
* (0,2,0) which otherwise forces pointer-events
|
|
197956
|
-
* we still restrict pointer events to ".connectionindicator"
|
|
197957
|
-
* target
|
|
197958
|
-
*
|
|
197979
|
+
* (0,2,0) which otherwise forces pointer-events on every connectable handle. During a drag
|
|
197980
|
+
* we still restrict pointer events to ".connectionindicator". Each DualHandle renders a stacked
|
|
197981
|
+
* target and source. Loose-mode reconnect can end on either twin, while semantic validation
|
|
197982
|
+
* still rejects an incompatible model endpoint. */
|
|
197959
197983
|
.react-flow:not(.sysml-connecting) .react-flow__handle.rf-handle-portdrop { pointer-events: none; }
|
|
197960
197984
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-portdrop.connectionindicator { pointer-events: auto; }
|
|
197961
197985
|
/* REQ-006 \u2014 graph nodes advertise their default drag relationship with modest
|
|
197962
197986
|
* cyan side dots; all valid targets light up while a drag is in progress. */
|
|
197963
197987
|
.rf-node-graph:hover .react-flow__handle.rf-handle-side { opacity: 0.85; }
|
|
197964
197988
|
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectionindicator,
|
|
197965
|
-
.react-flow.sysml-connecting .react-flow__handle.rf-handle-lifeline.connectionindicator { opacity: 0.
|
|
197989
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-lifeline.connectionindicator { opacity: 0.42; }
|
|
197990
|
+
/* The nearest semantically valid body target is stronger than the candidate
|
|
197991
|
+
* points. Port and pin targets use the highlighted endpoint glyph instead. */
|
|
197992
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectingto.valid { opacity: 1; }
|
|
197993
|
+
.react-flow.sysml-connecting .react-flow__handle.rf-handle-side.connectingto.valid::after {
|
|
197994
|
+
background: var(--cyan); box-shadow: 0 0 0 3px rgba(108,209,217,0.4);
|
|
197995
|
+
transform: translate(-50%, -50%) scale(1.35);
|
|
197996
|
+
}
|
|
197966
197997
|
/* issues.md (#2) \u2014 the offset "+" bubble lights up (accent, ringed) while a
|
|
197967
197998
|
* connector is being CREATED from this port. React Flow flags the start handle
|
|
197968
197999
|
* with the connectingfrom class; the SQUARE port (not the bubble) lights up as
|
|
@@ -197972,10 +198003,14 @@ svg.react-flow__connectionline { z-index: 1; }
|
|
|
197972
198003
|
.react-flow__handle.rf-handle:hover { opacity: 1; box-shadow: none; }
|
|
197973
198004
|
.react-flow__handle.rf-handle:hover::after { box-shadow: 0 0 0 3px rgba(108,209,217,0.4); }
|
|
197974
198005
|
.react-flow__handle.rf-handle.connectionindicator { cursor: crosshair; }
|
|
198006
|
+
/* REQ-370: an opaque port or action pin owns its whole footprint. Keep an
|
|
198007
|
+
* overlapping body handle mounted so an existing edge keeps its handle ID, but
|
|
198008
|
+
* never paint or hit-test it in idle, hover, connect, or reconnect states. */
|
|
198009
|
+
.react-flow__handle.rf-handle-side.rf-handle-occluded { visibility: hidden; pointer-events: none; }
|
|
197975
198010
|
/* REQ-006 \u2014 port move overlay: a transparent hit-target ON the port glyph; drag
|
|
197976
198011
|
* to slide the port along its owner's edge, click to select. Kept interactive even
|
|
197977
198012
|
* inside a click-through container frame. */
|
|
197978
|
-
.port-drag-hit { pointer-events: auto; cursor: grab; }
|
|
198013
|
+
.port-drag-hit { pointer-events: auto; cursor: grab; z-index: 4; }
|
|
197979
198014
|
.port-drag-hit:active { cursor: grabbing; }
|
|
197980
198015
|
.rf-frame .port-drag-hit { pointer-events: auto; }
|
|
197981
198016
|
/* REQ-386 \u2014 a nested-port host's expansion control, on the port's INNER side
|
|
@@ -199345,6 +199380,99 @@ function GeoShapeNode({ id: id2, data, selected: selected2 }) {
|
|
|
199345
199380
|
);
|
|
199346
199381
|
}
|
|
199347
199382
|
|
|
199383
|
+
// ../extension/src/webview/diagram/flow/connection-gesture.ts
|
|
199384
|
+
function validPortDropTarget(connection, isKnownPort) {
|
|
199385
|
+
if (!connection?.inProgress || connection.isValid !== true) return void 0;
|
|
199386
|
+
const handleId = connection.toHandle?.id;
|
|
199387
|
+
const nodeId = connection.toHandle?.nodeId;
|
|
199388
|
+
if (!handleId || !nodeId) return void 0;
|
|
199389
|
+
const portId = parsePortAnchorHandleId(handleId)?.portId ?? handleId;
|
|
199390
|
+
return isKnownPort(portId) ? { nodeId, handleId, portId } : void 0;
|
|
199391
|
+
}
|
|
199392
|
+
|
|
199393
|
+
// ../extension/src/webview/diagram/flow/pointer-gesture.ts
|
|
199394
|
+
var POINTER_DRAG_THRESHOLD_PX = 4;
|
|
199395
|
+
function beginPointerGesture(host, spec) {
|
|
199396
|
+
const threshold = spec.threshold ?? POINTER_DRAG_THRESHOLD_PX;
|
|
199397
|
+
let moved = false;
|
|
199398
|
+
let active = true;
|
|
199399
|
+
let captureHeld = false;
|
|
199400
|
+
let lastDelivered;
|
|
199401
|
+
function isOurs(event) {
|
|
199402
|
+
return event?.pointerId === spec.pointerId;
|
|
199403
|
+
}
|
|
199404
|
+
function releaseCapture() {
|
|
199405
|
+
if (!captureHeld) return;
|
|
199406
|
+
captureHeld = false;
|
|
199407
|
+
try {
|
|
199408
|
+
spec.captureTarget?.releasePointerCapture(spec.pointerId);
|
|
199409
|
+
} catch {
|
|
199410
|
+
}
|
|
199411
|
+
}
|
|
199412
|
+
function finish(reason, event) {
|
|
199413
|
+
if (!active) return;
|
|
199414
|
+
active = false;
|
|
199415
|
+
host.unbind("pointermove", onMove);
|
|
199416
|
+
host.unbind("pointerup", onUp);
|
|
199417
|
+
host.unbind("pointercancel", onCancel);
|
|
199418
|
+
host.unbind("blur", onInterrupt);
|
|
199419
|
+
releaseCapture();
|
|
199420
|
+
spec.onEnd({ reason, moved, event });
|
|
199421
|
+
}
|
|
199422
|
+
function deliverMove(event) {
|
|
199423
|
+
if (!moved && Math.hypot(event.clientX - spec.startX, event.clientY - spec.startY) < threshold) return;
|
|
199424
|
+
moved = true;
|
|
199425
|
+
if (lastDelivered?.x === event.clientX && lastDelivered.y === event.clientY) return;
|
|
199426
|
+
lastDelivered = { x: event.clientX, y: event.clientY };
|
|
199427
|
+
spec.onMove(event);
|
|
199428
|
+
}
|
|
199429
|
+
function onMove(event) {
|
|
199430
|
+
if (!active || !isOurs(event)) return;
|
|
199431
|
+
if (event.buttons === 0) {
|
|
199432
|
+
finish("cancel");
|
|
199433
|
+
return;
|
|
199434
|
+
}
|
|
199435
|
+
deliverMove(event);
|
|
199436
|
+
}
|
|
199437
|
+
function onUp(event) {
|
|
199438
|
+
if (!isOurs(event)) return;
|
|
199439
|
+
deliverMove(event);
|
|
199440
|
+
finish("up", event);
|
|
199441
|
+
}
|
|
199442
|
+
function onCancel(event) {
|
|
199443
|
+
if (isOurs(event)) finish("cancel");
|
|
199444
|
+
}
|
|
199445
|
+
function onInterrupt() {
|
|
199446
|
+
finish("cancel");
|
|
199447
|
+
}
|
|
199448
|
+
host.bind("pointermove", onMove);
|
|
199449
|
+
host.bind("pointerup", onUp);
|
|
199450
|
+
host.bind("pointercancel", onCancel);
|
|
199451
|
+
host.bind("blur", onInterrupt);
|
|
199452
|
+
try {
|
|
199453
|
+
if (spec.captureTarget) {
|
|
199454
|
+
spec.captureTarget.setPointerCapture(spec.pointerId);
|
|
199455
|
+
captureHeld = true;
|
|
199456
|
+
}
|
|
199457
|
+
} catch {
|
|
199458
|
+
}
|
|
199459
|
+
return {
|
|
199460
|
+
get moved() {
|
|
199461
|
+
return moved;
|
|
199462
|
+
},
|
|
199463
|
+
get active() {
|
|
199464
|
+
return active;
|
|
199465
|
+
},
|
|
199466
|
+
abort: () => finish("abort")
|
|
199467
|
+
};
|
|
199468
|
+
}
|
|
199469
|
+
function windowPointerHost() {
|
|
199470
|
+
return {
|
|
199471
|
+
bind: (type, listener) => window.addEventListener(type, listener),
|
|
199472
|
+
unbind: (type, listener) => window.removeEventListener(type, listener)
|
|
199473
|
+
};
|
|
199474
|
+
}
|
|
199475
|
+
|
|
199348
199476
|
// ../extension/src/webview/diagram/flow/nodes.tsx
|
|
199349
199477
|
var import_jsx_runtime4 = __toESM(require_jsx_runtime());
|
|
199350
199478
|
var SIDES = [...PORT_DOCK_SIDES];
|
|
@@ -199395,7 +199523,9 @@ var SIDE_NORMAL = {
|
|
|
199395
199523
|
var clampOffset = (v) => Math.max(0.06, Math.min(0.94, v));
|
|
199396
199524
|
function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview, onSelect) {
|
|
199397
199525
|
const [dragId, setDragId] = (0, import_react8.useState)(void 0);
|
|
199398
|
-
const
|
|
199526
|
+
const gestureRef = (0, import_react8.useRef)(void 0);
|
|
199527
|
+
(0, import_react8.useEffect)(() => () => gestureRef.current?.abort(), []);
|
|
199528
|
+
const onPortPointerDown = (portId, e, origin, draggable = true) => {
|
|
199399
199529
|
if (e.button !== 0) return;
|
|
199400
199530
|
e.stopPropagation();
|
|
199401
199531
|
const el2 = containerRef.current;
|
|
@@ -199403,40 +199533,47 @@ function usePortDrag(containerRef, w, h, topReserve, onPortMove, onPortPreview,
|
|
|
199403
199533
|
onSelect?.(portId);
|
|
199404
199534
|
return;
|
|
199405
199535
|
}
|
|
199406
|
-
|
|
199536
|
+
gestureRef.current?.abort();
|
|
199407
199537
|
const rect = el2.getBoundingClientRect();
|
|
199408
|
-
const sx = e.clientX, sy = e.clientY;
|
|
199409
|
-
let moved = false;
|
|
199410
199538
|
const placement = (cx, cy) => {
|
|
199411
199539
|
const lx = rect.width ? (cx - rect.left) / rect.width * w : 0;
|
|
199412
199540
|
const ly = rect.height ? (cy - rect.top) / rect.height * h : 0;
|
|
199413
199541
|
const nearest = nearestPortOwnerPlacement(lx, ly, w, h, topReserve);
|
|
199414
199542
|
return { side: nearest.side, offset: clampOffset(nearest.offset) };
|
|
199415
199543
|
};
|
|
199416
|
-
|
|
199417
|
-
|
|
199418
|
-
|
|
199419
|
-
|
|
199420
|
-
|
|
199421
|
-
|
|
199422
|
-
};
|
|
199423
|
-
const up = (ev) => {
|
|
199424
|
-
window.removeEventListener("pointermove", move);
|
|
199425
|
-
window.removeEventListener("pointerup", up);
|
|
199426
|
-
if (moved) {
|
|
199544
|
+
gestureRef.current = beginPointerGesture(windowPointerHost(), {
|
|
199545
|
+
pointerId: e.pointerId,
|
|
199546
|
+
startX: e.clientX,
|
|
199547
|
+
startY: e.clientY,
|
|
199548
|
+
captureTarget: e.currentTarget,
|
|
199549
|
+
onMove: (ev) => {
|
|
199427
199550
|
const p = placement(ev.clientX, ev.clientY);
|
|
199428
|
-
|
|
199429
|
-
|
|
199430
|
-
|
|
199431
|
-
|
|
199432
|
-
|
|
199433
|
-
|
|
199551
|
+
setDragId(portId);
|
|
199552
|
+
onPortPreview?.(portId, p.side, p.offset);
|
|
199553
|
+
},
|
|
199554
|
+
onEnd: ({ reason, moved, event }) => {
|
|
199555
|
+
gestureRef.current = void 0;
|
|
199556
|
+
setDragId(void 0);
|
|
199557
|
+
if (!moved) {
|
|
199558
|
+
if (reason === "up") onSelect?.(portId);
|
|
199559
|
+
return;
|
|
199560
|
+
}
|
|
199561
|
+
if (reason === "up" && event) {
|
|
199562
|
+
const p = placement(event.clientX, event.clientY);
|
|
199563
|
+
onPortMove(portId, p.side, p.offset);
|
|
199564
|
+
return;
|
|
199565
|
+
}
|
|
199566
|
+
onPortPreview?.(portId, origin.side, origin.offset);
|
|
199567
|
+
}
|
|
199568
|
+
});
|
|
199434
199569
|
};
|
|
199435
199570
|
return { dragId, onPortPointerDown };
|
|
199436
199571
|
}
|
|
199437
|
-
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size }) {
|
|
199438
|
-
const
|
|
199439
|
-
const
|
|
199572
|
+
function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, startable = false, size, occluded = false }) {
|
|
199573
|
+
const dimensions = typeof size === "number" ? { width: size, height: size } : size;
|
|
199574
|
+
const style2 = dimensions ? { left: x, top: y, ...dimensions, transform: "translate(-50%,-50%)" } : { left: x, top: y, transform: "translate(-50%,-50%)" };
|
|
199575
|
+
const enabled = connectable && !occluded;
|
|
199576
|
+
const cls = `rf-handle rf-handle-${kind}${active ? " active" : ""}${occluded ? " rf-handle-occluded" : ""}`;
|
|
199440
199577
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
199441
199578
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
199442
199579
|
Handle,
|
|
@@ -199446,9 +199583,9 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
199446
199583
|
position: POS[side],
|
|
199447
199584
|
style: style2,
|
|
199448
199585
|
className: cls,
|
|
199449
|
-
isConnectable:
|
|
199586
|
+
isConnectable: enabled,
|
|
199450
199587
|
isConnectableStart: false,
|
|
199451
|
-
isConnectableEnd:
|
|
199588
|
+
isConnectableEnd: enabled
|
|
199452
199589
|
}
|
|
199453
199590
|
),
|
|
199454
199591
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -199459,9 +199596,9 @@ function DualHandle({ id: id2, side, x, y, kind, active, connectable = true, sta
|
|
|
199459
199596
|
position: POS[side],
|
|
199460
199597
|
style: style2,
|
|
199461
199598
|
className: cls,
|
|
199462
|
-
isConnectable:
|
|
199463
|
-
isConnectableStart:
|
|
199464
|
-
isConnectableEnd:
|
|
199599
|
+
isConnectable: enabled,
|
|
199600
|
+
isConnectableStart: enabled && startable,
|
|
199601
|
+
isConnectableEnd: enabled
|
|
199465
199602
|
}
|
|
199466
199603
|
)
|
|
199467
199604
|
] });
|
|
@@ -200188,14 +200325,12 @@ function NodeBody({ node, data, selectedPortId, hoveredPortId, movingPortId, con
|
|
|
200188
200325
|
))
|
|
200189
200326
|
] });
|
|
200190
200327
|
}
|
|
200191
|
-
function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
200328
|
+
function SysmlNode({ id: id2, data, draggable, selected: selected2, width, height }) {
|
|
200192
200329
|
const ctx = useDiagram();
|
|
200193
200330
|
const node = data.node;
|
|
200194
200331
|
const myPortIds = node.ports?.map((p) => p.id) ?? [];
|
|
200195
200332
|
const connectTargetPortId = useConnection((c) => {
|
|
200196
|
-
|
|
200197
|
-
const portId = parsePortAnchorHandleId(t)?.portId ?? t;
|
|
200198
|
-
return portId && myPortIds.includes(portId) ? portId : void 0;
|
|
200333
|
+
return validPortDropTarget(c, (portId) => myPortIds.includes(portId))?.portId;
|
|
200199
200334
|
});
|
|
200200
200335
|
const w = width ?? data.w;
|
|
200201
200336
|
const h = height ?? data.h;
|
|
@@ -200247,207 +200382,219 @@ function SysmlNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200247
200382
|
sideConnectable,
|
|
200248
200383
|
(selected2 || sidePointsHovered || perimeterControl) && !isPackageNode
|
|
200249
200384
|
));
|
|
200385
|
+
const visiblePortRects = ports.map((port) => portGlyphRect(port, w, h, featureCompartmentHeight));
|
|
200250
200386
|
useMountedHandleRegistration(id2, sideOffsets);
|
|
200251
|
-
return
|
|
200252
|
-
|
|
200253
|
-
|
|
200254
|
-
|
|
200255
|
-
|
|
200256
|
-
|
|
200257
|
-
|
|
200258
|
-
|
|
200259
|
-
|
|
200260
|
-
|
|
200261
|
-
|
|
200262
|
-
|
|
200263
|
-
|
|
200264
|
-
|
|
200265
|
-
|
|
200266
|
-
|
|
200267
|
-
|
|
200268
|
-
|
|
200269
|
-
|
|
200270
|
-
|
|
200271
|
-
|
|
200272
|
-
|
|
200273
|
-
|
|
200274
|
-
|
|
200275
|
-
|
|
200276
|
-
|
|
200277
|
-
|
|
200278
|
-
|
|
200279
|
-
|
|
200280
|
-
|
|
200281
|
-
|
|
200282
|
-
|
|
200283
|
-
|
|
200284
|
-
|
|
200285
|
-
|
|
200286
|
-
|
|
200287
|
-
|
|
200288
|
-
|
|
200289
|
-
|
|
200290
|
-
|
|
200291
|
-
|
|
200292
|
-
|
|
200293
|
-
|
|
200294
|
-
|
|
200295
|
-
|
|
200296
|
-
const maxWidth = data.kind === "gv" && node.shape !== "package" ? GV_NODE_MAX_WIDTH : void 0;
|
|
200297
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200298
|
-
NodeResizer,
|
|
200299
|
-
{
|
|
200300
|
-
minWidth,
|
|
200301
|
-
minHeight,
|
|
200302
|
-
maxWidth,
|
|
200303
|
-
maxHeight: min2.maxHeight,
|
|
200304
|
-
isVisible: true,
|
|
200305
|
-
color: "var(--accent)"
|
|
200306
|
-
}
|
|
200307
|
-
);
|
|
200308
|
-
})() : null,
|
|
200309
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200310
|
-
NodeBody,
|
|
200311
|
-
{
|
|
200312
|
-
node,
|
|
200313
|
-
data: liveData,
|
|
200314
|
-
selectedPortId,
|
|
200315
|
-
hoveredPortId,
|
|
200316
|
-
movingPortId: dragId,
|
|
200317
|
-
connectTargetPortId,
|
|
200318
|
-
showPortConnectStart: data.kind === "iv" || data.kind === "afv",
|
|
200319
|
-
onPortSelect: !ctx.onPortMove && data.ports.length ? portSource : void 0,
|
|
200320
|
-
onPortContext: ctx.onContextNode
|
|
200321
|
-
}
|
|
200322
|
-
),
|
|
200323
|
-
data.kind === "iv" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200324
|
-
"div",
|
|
200325
|
-
{
|
|
200326
|
-
className: "rf-node-header",
|
|
200327
|
-
title: node.name,
|
|
200328
|
-
style: {
|
|
200329
|
-
left: 0,
|
|
200330
|
-
top: 0,
|
|
200331
|
-
height: NODE_COMPARTMENT_TOP,
|
|
200332
|
-
width: containerTitleArea(w, nodeShowsControls(node)).width
|
|
200387
|
+
return (
|
|
200388
|
+
// issue #226. A movable body advertises the move cursor over its whole
|
|
200389
|
+
// surface, not only over the title strip. The two used to disagree because
|
|
200390
|
+
// only the strip could actually be grabbed (see model-to-flow, dragHandle).
|
|
200391
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
200392
|
+
"div",
|
|
200393
|
+
{
|
|
200394
|
+
ref: containerRef,
|
|
200395
|
+
className: `rf-node${selected2 ? " selected" : ""}${nodeSideStartable ? " rf-node-graph" : ""}${dropClass}${draggable === false ? "" : " rf-node-movable"}`,
|
|
200396
|
+
style: { width: w, height: h, opacity: dim ? 0.18 : 1 },
|
|
200397
|
+
onMouseEnter: () => setSidePointsHovered(true),
|
|
200398
|
+
onMouseLeave: () => setSidePointsHovered(false),
|
|
200399
|
+
onContextMenu: (e) => {
|
|
200400
|
+
e.preventDefault();
|
|
200401
|
+
e.stopPropagation();
|
|
200402
|
+
ctx.onContextNode(id2, e.clientX, e.clientY);
|
|
200403
|
+
},
|
|
200404
|
+
children: [
|
|
200405
|
+
resizable ? (() => {
|
|
200406
|
+
if (isForkJoinShape(node.shape)) {
|
|
200407
|
+
const horizontal = forkJoinOrientation({ w, h }) === "horizontal";
|
|
200408
|
+
const limits = horizontal ? { minWidth: FORK_JOIN_MIN_LENGTH, minHeight: FORK_JOIN_THICKNESS, maxHeight: FORK_JOIN_THICKNESS } : { minWidth: FORK_JOIN_THICKNESS, maxWidth: FORK_JOIN_THICKNESS, minHeight: FORK_JOIN_MIN_LENGTH };
|
|
200409
|
+
const direction = horizontal ? "horizontal" : "vertical";
|
|
200410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
200411
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200412
|
+
NodeResizeControl,
|
|
200413
|
+
{
|
|
200414
|
+
className: "fork-join-resize",
|
|
200415
|
+
color: "var(--accent)",
|
|
200416
|
+
position: horizontal ? "left" : "top",
|
|
200417
|
+
resizeDirection: direction,
|
|
200418
|
+
...limits
|
|
200419
|
+
}
|
|
200420
|
+
),
|
|
200421
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200422
|
+
NodeResizeControl,
|
|
200423
|
+
{
|
|
200424
|
+
className: "fork-join-resize",
|
|
200425
|
+
color: "var(--accent)",
|
|
200426
|
+
position: horizontal ? "right" : "bottom",
|
|
200427
|
+
resizeDirection: direction,
|
|
200428
|
+
...limits
|
|
200429
|
+
}
|
|
200430
|
+
)
|
|
200431
|
+
] });
|
|
200333
200432
|
}
|
|
200334
|
-
|
|
200335
|
-
|
|
200336
|
-
|
|
200337
|
-
|
|
200338
|
-
const out = nodeSideHandleOutset(node.shape);
|
|
200339
|
-
const offsets = sideOffsets[si];
|
|
200340
|
-
return offsets.map((offset2, i) => {
|
|
200341
|
-
const { x, y } = sideSurfacePoint(node.shape, side, offset2, w, h, featureCompartmentHeight);
|
|
200433
|
+
const min2 = resizeMinFor(node.shape, h);
|
|
200434
|
+
const minWidth = showsControls ? Math.max(min2.minWidth, COLLAPSED_CONTAINER_MIN_WIDTH) : min2.minWidth;
|
|
200435
|
+
const minHeight = Math.max(min2.minHeight, data.featureCompartmentMinHeight ?? 0);
|
|
200436
|
+
const maxWidth = data.kind === "gv" && node.shape !== "package" ? GV_NODE_MAX_WIDTH : void 0;
|
|
200342
200437
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200343
|
-
|
|
200438
|
+
NodeResizer,
|
|
200344
200439
|
{
|
|
200345
|
-
|
|
200346
|
-
|
|
200347
|
-
|
|
200348
|
-
|
|
200349
|
-
|
|
200350
|
-
|
|
200351
|
-
|
|
200352
|
-
size: perimeterControl ? 20 : void 0
|
|
200353
|
-
},
|
|
200354
|
-
`s-${side}-${i}`
|
|
200440
|
+
minWidth,
|
|
200441
|
+
minHeight,
|
|
200442
|
+
maxWidth,
|
|
200443
|
+
maxHeight: min2.maxHeight,
|
|
200444
|
+
isVisible: true,
|
|
200445
|
+
color: "var(--accent)"
|
|
200446
|
+
}
|
|
200355
200447
|
);
|
|
200356
|
-
})
|
|
200357
|
-
|
|
200358
|
-
|
|
200359
|
-
|
|
200360
|
-
|
|
200361
|
-
|
|
200362
|
-
|
|
200363
|
-
|
|
200364
|
-
|
|
200365
|
-
|
|
200366
|
-
|
|
200367
|
-
|
|
200368
|
-
|
|
200369
|
-
|
|
200370
|
-
|
|
200371
|
-
|
|
200372
|
-
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200373
|
-
return [
|
|
200374
|
-
// the DROP target stays centred over the glyph — it is a cover,
|
|
200375
|
-
// not a dock point (the edge geometry is `dockPoint`'s business)
|
|
200376
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: innerId, side: OPPOSITE_DOCK_SIDE[ph.side], x: c.x, y: c.y, kind: "portdrop", size: dropSize, startable: false }, `${ph.port.id}-drop`),
|
|
200377
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: outerId, side: ph.side, x: outer.x, y: outer.y, kind: "port", active, startable }, `${ph.port.id}-out`)
|
|
200378
|
-
];
|
|
200379
|
-
}),
|
|
200380
|
-
ctx.onPortMove ? ports.map((ph) => {
|
|
200381
|
-
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200382
|
-
const nestedChild = ph.port.parentPort !== void 0;
|
|
200383
|
-
const strip = portInteractionStrip(rect, ph.side);
|
|
200384
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200448
|
+
})() : null,
|
|
200449
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200450
|
+
NodeBody,
|
|
200451
|
+
{
|
|
200452
|
+
node,
|
|
200453
|
+
data: liveData,
|
|
200454
|
+
selectedPortId,
|
|
200455
|
+
hoveredPortId,
|
|
200456
|
+
movingPortId: dragId,
|
|
200457
|
+
connectTargetPortId,
|
|
200458
|
+
showPortConnectStart: data.kind === "iv" || data.kind === "afv",
|
|
200459
|
+
onPortSelect: !ctx.onPortMove && data.ports.length ? portSource : void 0,
|
|
200460
|
+
onPortContext: ctx.onContextNode
|
|
200461
|
+
}
|
|
200462
|
+
),
|
|
200463
|
+
data.kind === "iv" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200385
200464
|
"div",
|
|
200386
200465
|
{
|
|
200387
|
-
className: "
|
|
200388
|
-
|
|
200389
|
-
|
|
200390
|
-
|
|
200391
|
-
|
|
200392
|
-
|
|
200393
|
-
|
|
200394
|
-
|
|
200395
|
-
|
|
200396
|
-
|
|
200466
|
+
className: "rf-node-header",
|
|
200467
|
+
title: node.name,
|
|
200468
|
+
style: {
|
|
200469
|
+
left: 0,
|
|
200470
|
+
top: 0,
|
|
200471
|
+
height: NODE_COMPARTMENT_TOP,
|
|
200472
|
+
width: containerTitleArea(w, nodeShowsControls(node)).width
|
|
200473
|
+
}
|
|
200474
|
+
}
|
|
200475
|
+
) : null,
|
|
200476
|
+
SIDES.flatMap((side, si) => {
|
|
200477
|
+
const n2 = SIDE_NORMAL[side];
|
|
200478
|
+
const out = nodeSideHandleOutset(node.shape);
|
|
200479
|
+
const offsets = sideOffsets[si];
|
|
200480
|
+
return offsets.map((offset2, i) => {
|
|
200481
|
+
const { x, y } = sideSurfacePoint(node.shape, side, offset2, w, h, featureCompartmentHeight);
|
|
200482
|
+
const point = { x: x + n2.x * out, y: y + n2.y * out };
|
|
200483
|
+
const occluded = bodySnapPointOccludedByPort(point, visiblePortRects);
|
|
200484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200485
|
+
DualHandle,
|
|
200486
|
+
{
|
|
200487
|
+
id: sideAnchorHandleId(side, offset2),
|
|
200488
|
+
side,
|
|
200489
|
+
x: point.x,
|
|
200490
|
+
y: point.y,
|
|
200491
|
+
kind: "side",
|
|
200492
|
+
occluded,
|
|
200493
|
+
connectable: sideConnectable,
|
|
200494
|
+
startable: nodeSideStartable,
|
|
200495
|
+
size: perimeterControl ? 20 : void 0
|
|
200496
|
+
},
|
|
200497
|
+
`s-${side}-${i}`
|
|
200498
|
+
);
|
|
200499
|
+
});
|
|
200500
|
+
}),
|
|
200501
|
+
node.shape === "initial" || node.shape === "final" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "rf-circular-control-hit", "aria-hidden": "true" }) : null,
|
|
200502
|
+
ports.flatMap((ph) => {
|
|
200503
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200504
|
+
const c = { x: rect.cx, y: rect.cy };
|
|
200505
|
+
const startable = directRelationForHandle(data.kind, {
|
|
200506
|
+
id: ph.port.id,
|
|
200507
|
+
name: ph.port.name,
|
|
200508
|
+
keyword: ph.port.pin ? "pin" : "port",
|
|
200509
|
+
shape: ph.port.pin ? "pin" : "port",
|
|
200510
|
+
source: ph.port.source
|
|
200511
|
+
}) !== void 0;
|
|
200512
|
+
const active = startable && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId) || ph.port.id === connectTargetPortId;
|
|
200513
|
+
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
200514
|
+
const dropSize = {
|
|
200515
|
+
width: Math.max(rect.width, 16),
|
|
200516
|
+
height: Math.max(rect.height, 16)
|
|
200517
|
+
};
|
|
200518
|
+
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200519
|
+
return [
|
|
200520
|
+
// the DROP target stays centred over the glyph — it is a cover,
|
|
200521
|
+
// not a dock point (the edge geometry is `dockPoint`'s business)
|
|
200522
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: innerId, side: OPPOSITE_DOCK_SIDE[ph.side], x: c.x, y: c.y, kind: "portdrop", size: dropSize, startable: false }, `${ph.port.id}-drop`),
|
|
200523
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: outerId, side: ph.side, x: outer.x, y: outer.y, kind: "port", active, startable }, `${ph.port.id}-out`)
|
|
200524
|
+
];
|
|
200525
|
+
}),
|
|
200526
|
+
ctx.onPortMove ? ports.map((ph) => {
|
|
200527
|
+
const rect = portGlyphRect(ph, w, h, featureCompartmentHeight);
|
|
200528
|
+
const nestedChild = ph.port.parentPort !== void 0;
|
|
200529
|
+
const strip = portInteractionStrip(rect, ph.side);
|
|
200530
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200531
|
+
"div",
|
|
200532
|
+
{
|
|
200533
|
+
className: "port-drag-hit nodrag",
|
|
200534
|
+
style: { position: "absolute", left: strip.cx, top: strip.cy, width: strip.w, height: strip.h, transform: "translate(-50%,-50%)" },
|
|
200535
|
+
title: nestedChild ? `${ph.port.name} - click to select; drag a dot to connect (moves with its parent port)` : `${ph.port.name} - drag the centre to move along the edge; drag a dot to connect; click to select`,
|
|
200536
|
+
onPointerEnter: () => setHoveredPortId(ph.port.id),
|
|
200537
|
+
onPointerLeave: () => setHoveredPortId((cur) => cur === ph.port.id ? void 0 : cur),
|
|
200538
|
+
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, { side: ph.side, offset: ph.offset }, !nestedChild),
|
|
200539
|
+
onContextMenu: (e) => {
|
|
200540
|
+
e.preventDefault();
|
|
200541
|
+
e.stopPropagation();
|
|
200542
|
+
ctx.onContextNode(ph.port.id, e.clientX, e.clientY);
|
|
200543
|
+
},
|
|
200544
|
+
onClick: (e) => e.stopPropagation()
|
|
200397
200545
|
},
|
|
200398
|
-
|
|
200399
|
-
|
|
200400
|
-
|
|
200401
|
-
)
|
|
200402
|
-
|
|
200403
|
-
|
|
200404
|
-
|
|
200405
|
-
|
|
200406
|
-
|
|
200407
|
-
|
|
200408
|
-
|
|
200409
|
-
|
|
200410
|
-
|
|
200411
|
-
|
|
200412
|
-
}
|
|
200413
|
-
|
|
200414
|
-
|
|
200415
|
-
|
|
200416
|
-
|
|
200417
|
-
|
|
200418
|
-
|
|
200419
|
-
|
|
200420
|
-
|
|
200421
|
-
|
|
200422
|
-
|
|
200423
|
-
|
|
200424
|
-
|
|
200425
|
-
|
|
200426
|
-
|
|
200427
|
-
|
|
200428
|
-
|
|
200429
|
-
|
|
200430
|
-
|
|
200431
|
-
|
|
200432
|
-
|
|
200433
|
-
|
|
200434
|
-
|
|
200435
|
-
|
|
200436
|
-
|
|
200437
|
-
|
|
200438
|
-
|
|
200439
|
-
|
|
200440
|
-
|
|
200441
|
-
|
|
200442
|
-
|
|
200443
|
-
|
|
200444
|
-
|
|
200445
|
-
|
|
200446
|
-
|
|
200447
|
-
|
|
200448
|
-
|
|
200449
|
-
|
|
200450
|
-
}
|
|
200546
|
+
`pd-${ph.port.id}`
|
|
200547
|
+
);
|
|
200548
|
+
}) : null,
|
|
200549
|
+
node.shape === "lifeline" ? (() => {
|
|
200550
|
+
const bottom = data.lineBottom ?? h;
|
|
200551
|
+
const handles = [];
|
|
200552
|
+
for (const mh of data.msgHandles ?? []) {
|
|
200553
|
+
handles.push(/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: mh.id, side: "right", x: w / 2, y: mh.y, kind: "lifeline", startable: directRelation !== void 0 }, mh.id));
|
|
200554
|
+
}
|
|
200555
|
+
for (const ih of data.insertHandles ?? []) {
|
|
200556
|
+
if (!directRelation || ih.y > bottom - 4) continue;
|
|
200557
|
+
handles.push(/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DualHandle, { id: ih.id, side: "right", x: w / 2, y: ih.y, kind: "lifeline", startable: true }, ih.id));
|
|
200558
|
+
}
|
|
200559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: handles });
|
|
200560
|
+
})() : null,
|
|
200561
|
+
ctx.onToggleNestedPort ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200562
|
+
NestedPortToggles,
|
|
200563
|
+
{
|
|
200564
|
+
ports,
|
|
200565
|
+
w,
|
|
200566
|
+
h,
|
|
200567
|
+
topReserve: featureCompartmentHeight,
|
|
200568
|
+
onToggle: ctx.onToggleNestedPort
|
|
200569
|
+
}
|
|
200570
|
+
) : null,
|
|
200571
|
+
showsControls ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200572
|
+
ContainerControls,
|
|
200573
|
+
{
|
|
200574
|
+
id: id2,
|
|
200575
|
+
label: node.name,
|
|
200576
|
+
internalNoun,
|
|
200577
|
+
internalsVisible: !hiddenContainer,
|
|
200578
|
+
featureCompartmentsVisible,
|
|
200579
|
+
cornerRadius: nodeCornerRadius(node.shape, node.isDef, h, (node.compartments?.length ?? 0) > 0),
|
|
200580
|
+
onToggleInternals: ctx.onToggleInternals,
|
|
200581
|
+
onToggleFeatureCompartments: ctx.onToggleFeatureCompartments
|
|
200582
|
+
}
|
|
200583
|
+
) : null,
|
|
200584
|
+
editingHere && ctx.onEditCommit && ctx.onEditCancel ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200585
|
+
InlineEditor,
|
|
200586
|
+
{
|
|
200587
|
+
initial: editing.initial,
|
|
200588
|
+
mode: editing.mode,
|
|
200589
|
+
elementKind: editing.elementKind,
|
|
200590
|
+
onCommit: ctx.onEditCommit,
|
|
200591
|
+
onCancel: ctx.onEditCancel,
|
|
200592
|
+
w
|
|
200593
|
+
}
|
|
200594
|
+
) : null
|
|
200595
|
+
]
|
|
200596
|
+
}
|
|
200597
|
+
)
|
|
200451
200598
|
);
|
|
200452
200599
|
}
|
|
200453
200600
|
function packageFrameTabWidth(w) {
|
|
@@ -200509,9 +200656,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200509
200656
|
const frameBottomHeight = loopUntil ? data.frameBottomHeight ?? LOOP_UNTIL_COMPARTMENT_HEIGHT : 0;
|
|
200510
200657
|
const myPortIds = isPartitionLane ? [] : frame2.ports?.map((p) => p.id) ?? [];
|
|
200511
200658
|
const connectTargetPortId = useConnection((c) => {
|
|
200512
|
-
|
|
200513
|
-
const portId = parsePortAnchorHandleId(t)?.portId ?? t;
|
|
200514
|
-
return portId && myPortIds.includes(portId) ? portId : void 0;
|
|
200659
|
+
return validPortDropTarget(c, (portId) => myPortIds.includes(portId))?.portId;
|
|
200515
200660
|
});
|
|
200516
200661
|
const w = width ?? data.w;
|
|
200517
200662
|
const h = height ?? data.h;
|
|
@@ -200582,6 +200727,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200582
200727
|
sideConnectable,
|
|
200583
200728
|
(selected2 || sidePointsHovered) && !isPackageFrame
|
|
200584
200729
|
));
|
|
200730
|
+
const visiblePortRects = showPorts ? ports.map((port) => portGlyphRect(port, w, h, featureCompartmentHeight)) : [];
|
|
200585
200731
|
useMountedHandleRegistration(id2, sideOffsets);
|
|
200586
200732
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
200587
200733
|
"div",
|
|
@@ -200796,17 +200942,19 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200796
200942
|
SIDES.flatMap((side, si) => {
|
|
200797
200943
|
const offsets = sideOffsets[si];
|
|
200798
200944
|
return offsets.map((offset2, i) => {
|
|
200799
|
-
const
|
|
200945
|
+
const point = sidePoint(side, offset2, w, h, featureCompartmentHeight);
|
|
200946
|
+
const occluded = bodySnapPointOccludedByPort(point, visiblePortRects);
|
|
200800
200947
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
200801
200948
|
DualHandle,
|
|
200802
200949
|
{
|
|
200803
200950
|
id: sideAnchorHandleId(side, offset2),
|
|
200804
200951
|
side,
|
|
200805
|
-
x,
|
|
200806
|
-
y,
|
|
200952
|
+
x: point.x,
|
|
200953
|
+
y: point.y,
|
|
200807
200954
|
kind: "side",
|
|
200808
200955
|
connectable: sideConnectable,
|
|
200809
|
-
startable: frameSideStartable
|
|
200956
|
+
startable: frameSideStartable,
|
|
200957
|
+
occluded
|
|
200810
200958
|
},
|
|
200811
200959
|
`s-${side}-${i}`
|
|
200812
200960
|
);
|
|
@@ -200824,7 +200972,10 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200824
200972
|
}) !== void 0;
|
|
200825
200973
|
const active = startable && (ph.port.id === hoveredPortId || ph.port.id === selectedPortId) || ph.port.id === connectTargetPortId;
|
|
200826
200974
|
const [outerId, innerId] = portConnectHandleIds(ph.port.id, ph.side);
|
|
200827
|
-
const dropSize =
|
|
200975
|
+
const dropSize = {
|
|
200976
|
+
width: Math.max(rect.width, 16),
|
|
200977
|
+
height: Math.max(rect.height, 16)
|
|
200978
|
+
};
|
|
200828
200979
|
const outer = portDockAt(rect, ph.side, ph.side);
|
|
200829
200980
|
return [
|
|
200830
200981
|
// the DROP target stays centred over the glyph — it is a cover,
|
|
@@ -200845,7 +200996,7 @@ function FrameNode({ id: id2, data, selected: selected2, width, height }) {
|
|
|
200845
200996
|
title: nestedChild ? `${ph.port.name} - click to select; drag a dot to connect (moves with its parent port)` : `${ph.port.name} - drag the centre to move along the edge; drag a dot to connect; click to select`,
|
|
200846
200997
|
onPointerEnter: () => setHoveredPortId(ph.port.id),
|
|
200847
200998
|
onPointerLeave: () => setHoveredPortId((cur) => cur === ph.port.id ? void 0 : cur),
|
|
200848
|
-
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, !nestedChild),
|
|
200999
|
+
onPointerDown: (e) => onPortPointerDown(ph.port.id, e, { side: ph.side, offset: ph.offset }, !nestedChild),
|
|
200849
201000
|
onContextMenu: (e) => {
|
|
200850
201001
|
e.preventDefault();
|
|
200851
201002
|
e.stopPropagation();
|
|
@@ -201220,7 +201371,7 @@ async function runExport(command) {
|
|
|
201220
201371
|
}
|
|
201221
201372
|
|
|
201222
201373
|
// src/main.ts
|
|
201223
|
-
var VERSION2 = true ? "0.20.
|
|
201374
|
+
var VERSION2 = true ? "0.20.2" : "dev";
|
|
201224
201375
|
function display(file) {
|
|
201225
201376
|
const rel2 = path9.relative(process.cwd(), file);
|
|
201226
201377
|
return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;
|