@zoneflow/editor-dom 0.0.10 → 0.0.12-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,17 @@
1
- import { type PathId, type Point, type UniverseLayoutModel, type UniverseModel, type ZoneId } from "@zoneflow/core";
1
+ import { type Path, type PathId, type Point, type UniverseLayoutModel, type UniverseModel, type Zone, type ZoneId } from "@zoneflow/core";
2
2
  import { type CameraState, type Rect, type RendererFrame } from "@zoneflow/renderer-dom";
3
3
  import type { GridSnapOptions } from "./zoneMoveEditor";
4
+ export type CanConnectPathParams = {
5
+ mode: "create" | "retarget";
6
+ sourceZoneId: ZoneId;
7
+ targetZoneId: ZoneId;
8
+ sourceZone: Zone;
9
+ targetZone: Zone;
10
+ model: UniverseModel;
11
+ pathId?: PathId;
12
+ path?: Path;
13
+ };
14
+ export type CanConnectPath = (params: CanConnectPathParams) => boolean;
4
15
  export declare function screenPointToWorldPoint(point: Point, camera: CameraState): Point;
5
16
  export declare function resolveZoneAnchorScreenRect(params: {
6
17
  frame: RendererFrame;
@@ -14,6 +25,7 @@ export declare function resolveInputAnchorTargetZoneId(params: {
14
25
  camera: CameraState;
15
26
  point: Point;
16
27
  excludeZoneIds?: ZoneId[];
28
+ canConnect?: (targetZoneId: ZoneId) => boolean;
17
29
  }): ZoneId | null;
18
30
  export declare function resolvePathOutputAnchorScreenRect(params: {
19
31
  frame: RendererFrame;
@@ -30,6 +42,7 @@ export declare function retargetPathFromOutputAnchorDrag(params: {
30
42
  sourceZoneId: ZoneId;
31
43
  pathId: PathId;
32
44
  targetZoneId?: ZoneId | null;
45
+ canConnect?: CanConnectPath;
33
46
  }): UniverseModel | undefined;
34
47
  export declare function createPathFromOutputAnchorDrag(params: {
35
48
  model: UniverseModel;
@@ -39,4 +52,5 @@ export declare function createPathFromOutputAnchorDrag(params: {
39
52
  dropWorldPoint: Point;
40
53
  targetZoneId?: ZoneId | null;
41
54
  gridSnap?: GridSnapOptions;
55
+ canConnect?: CanConnectPath;
42
56
  }): CreatePathFromAnchorDragResult | undefined;
@@ -98,7 +98,7 @@ export function resolveZoneAnchorScreenRect(params) {
98
98
  return projectWorldRectToScreenRect(anchorRect, camera);
99
99
  }
100
100
  export function resolveInputAnchorTargetZoneId(params) {
101
- const { model, frame, camera, point, excludeZoneIds } = params;
101
+ const { model, frame, camera, point, excludeZoneIds, canConnect } = params;
102
102
  const excluded = new Set(excludeZoneIds ?? []);
103
103
  let bestZoneId = null;
104
104
  let bestArea = Number.POSITIVE_INFINITY;
@@ -120,6 +120,8 @@ export function resolveInputAnchorTargetZoneId(params) {
120
120
  });
121
121
  if (!rect || !containsPoint(rect, point))
122
122
  continue;
123
+ if (canConnect && !canConnect(zoneVisual.zoneId))
124
+ continue;
123
125
  const area = getRectArea(rect);
124
126
  if (area < bestArea) {
125
127
  bestZoneId = zoneVisual.zoneId;
@@ -152,34 +154,67 @@ export function resolvePathOutputAnchorScreenRect(params) {
152
154
  }, camera);
153
155
  }
154
156
  export function retargetPathFromOutputAnchorDrag(params) {
155
- const { model, sourceZoneId, pathId, targetZoneId, } = params;
157
+ const { model, sourceZoneId, pathId, targetZoneId, canConnect, } = params;
156
158
  const sourceZone = model.zonesById[sourceZoneId];
157
- if (!sourceZone?.pathsById[pathId])
158
- return undefined;
159
- if (targetZoneId && !isZoneInputEnabled(model.zonesById[targetZoneId])) {
159
+ const path = sourceZone?.pathsById[pathId];
160
+ if (!sourceZone || !path)
160
161
  return undefined;
162
+ let resolvedTargetZoneId = targetZoneId ?? null;
163
+ if (resolvedTargetZoneId) {
164
+ const targetZone = model.zonesById[resolvedTargetZoneId];
165
+ if (!targetZone || !isZoneInputEnabled(targetZone)) {
166
+ return undefined;
167
+ }
168
+ if (canConnect &&
169
+ !canConnect({
170
+ mode: "retarget",
171
+ sourceZoneId,
172
+ targetZoneId: resolvedTargetZoneId,
173
+ sourceZone,
174
+ targetZone,
175
+ model,
176
+ pathId,
177
+ path,
178
+ })) {
179
+ resolvedTargetZoneId = null;
180
+ }
161
181
  }
162
- return setPathTarget(model, sourceZoneId, pathId, targetZoneId
182
+ return setPathTarget(model, sourceZoneId, pathId, resolvedTargetZoneId
163
183
  ? {
164
184
  universeId: model.universeId,
165
- zoneId: targetZoneId,
185
+ zoneId: resolvedTargetZoneId,
166
186
  }
167
187
  : null);
168
188
  }
169
189
  export function createPathFromOutputAnchorDrag(params) {
170
- const { model, layoutModel, frame, sourceZoneId, dropWorldPoint, targetZoneId, gridSnap, } = params;
190
+ const { model, layoutModel, frame, sourceZoneId, dropWorldPoint, targetZoneId, gridSnap, canConnect, } = params;
171
191
  const sourceZone = model.zonesById[sourceZoneId];
172
192
  const sourceVisual = frame.pipeline.graphLayout.zonesById[sourceZoneId];
173
- const targetVisual = targetZoneId
174
- ? frame.pipeline.graphLayout.zonesById[targetZoneId]
175
- : undefined;
176
193
  if (!sourceZone || !sourceVisual)
177
194
  return undefined;
178
195
  if (!isZoneOutputEnabled(sourceZone))
179
196
  return undefined;
180
- if (targetZoneId && !isZoneInputEnabled(model.zonesById[targetZoneId])) {
181
- return undefined;
197
+ let resolvedTargetZoneId = targetZoneId ?? null;
198
+ if (resolvedTargetZoneId) {
199
+ const targetZone = model.zonesById[resolvedTargetZoneId];
200
+ if (!targetZone || !isZoneInputEnabled(targetZone)) {
201
+ return undefined;
202
+ }
203
+ if (canConnect &&
204
+ !canConnect({
205
+ mode: "create",
206
+ sourceZoneId,
207
+ targetZoneId: resolvedTargetZoneId,
208
+ sourceZone,
209
+ targetZone,
210
+ model,
211
+ })) {
212
+ resolvedTargetZoneId = null;
213
+ }
182
214
  }
215
+ const targetVisual = resolvedTargetZoneId
216
+ ? frame.pipeline.graphLayout.zonesById[resolvedTargetZoneId]
217
+ : undefined;
183
218
  const pathId = createPathId();
184
219
  const nextPathIndex = sourceZone.pathIds.length;
185
220
  const sourceOutlet = sourceVisual.anchors.outlet.point;
@@ -201,10 +236,10 @@ export function createPathFromOutputAnchorDrag(params) {
201
236
  id: pathId,
202
237
  key: `condition_${ordinal}`,
203
238
  name: "Empty",
204
- target: targetZoneId
239
+ target: resolvedTargetZoneId
205
240
  ? {
206
241
  universeId: model.universeId,
207
- zoneId: targetZoneId,
242
+ zoneId: resolvedTargetZoneId,
208
243
  }
209
244
  : null,
210
245
  rule: null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zoneflow/editor-dom",
3
- "version": "0.0.10",
3
+ "version": "0.0.12-rc.0",
4
4
  "license": "MIT",
5
5
  "description": "Low-level editor geometry and interaction helpers for Zoneflow.",
6
6
  "type": "module",
@@ -19,8 +19,8 @@
19
19
  "dist"
20
20
  ],
21
21
  "dependencies": {
22
- "@zoneflow/core": "0.0.10",
23
- "@zoneflow/renderer-dom": "0.0.10"
22
+ "@zoneflow/core": "0.0.12-rc.0",
23
+ "@zoneflow/renderer-dom": "0.0.12-rc.0"
24
24
  },
25
25
  "scripts": {
26
26
  "build": "tsc -p tsconfig.json",