@floegence/floe-webapp-core 0.86.20 → 0.86.22
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/assets/layout-worker-CLVTDA3E.js +1922 -0
- package/dist/components/graph/GraphCanvas.js +166 -141
- package/dist/components/graph/engine.js +1 -1
- package/dist/components/graph/group-layout.d.ts +6 -0
- package/dist/components/graph/types.d.ts +8 -0
- package/dist/graph.css +3 -2
- package/package.json +1 -1
- package/dist/assets/layout-worker-BK6m515B.js +0 -1875
|
@@ -1,111 +1,111 @@
|
|
|
1
|
-
import { insert as
|
|
2
|
-
import { createUniqueId as
|
|
3
|
-
import { InfiniteCanvas as
|
|
4
|
-
import { resolveSurfaceInteractionTargetRole as
|
|
5
|
-
import { graphRelatedEdges as
|
|
6
|
-
import { GraphMinimap as
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
-
const
|
|
10
|
-
let
|
|
11
|
-
const [
|
|
1
|
+
import { insert as S, createComponent as w, setAttribute as c, effect as z, setStyleProperty as L, className as U, template as B, memo as it, use as ot, delegateEvents as lt } from "solid-js/web";
|
|
2
|
+
import { createUniqueId as dt, createSignal as J, createMemo as x, onMount as ct, For as Y, Show as _, onCleanup as ut } from "solid-js";
|
|
3
|
+
import { InfiniteCanvas as st } from "../ui/InfiniteCanvas.js";
|
|
4
|
+
import { resolveSurfaceInteractionTargetRole as ht } from "../ui/localInteractionSurface.js";
|
|
5
|
+
import { graphRelatedEdges as Q, graphEdgeLabelPosition as gt, graphSectionPath as vt } from "./geometry.js";
|
|
6
|
+
import { GraphMinimap as ft } from "./GraphMinimap.js";
|
|
7
|
+
var mt = /* @__PURE__ */ B("<div data-floe-canvas-pan-surface=true role=group tabindex=0>"), bt = /* @__PURE__ */ B("<div role=region tabindex=0>"), xt = /* @__PURE__ */ B('<svg class=floe-graph__edges><defs><marker viewBox="0 0 8 8"refX=7 refY=4 markerWidth=7 markerHeight=7 orient=auto-start-reverse><path d="M1 1 L7 4 L1 7"fill=none stroke=context-stroke stroke-width=1.2>'), yt = /* @__PURE__ */ B("<svg><g><path class=floe-graph__edge></path><path class=floe-graph__edge-target tabindex=0 role=button data-floe-canvas-pan-surface=true></svg>", !1, !0, !1), kt = /* @__PURE__ */ B("<svg><text class=floe-graph__edge-label aria-hidden=true></svg>", !1, !0, !1);
|
|
8
|
+
function Lt(i) {
|
|
9
|
+
const N = `graph-arrow-${dt()}`;
|
|
10
|
+
let v;
|
|
11
|
+
const [Z, p] = J(null), [V, tt] = J({
|
|
12
12
|
width: 0,
|
|
13
13
|
height: 0
|
|
14
|
-
}),
|
|
15
|
-
const
|
|
16
|
-
return
|
|
17
|
-
}),
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
20
|
-
const
|
|
21
|
-
return
|
|
22
|
-
}),
|
|
14
|
+
}), F = () => i.highlight === void 0 ? Z() : i.highlight, et = x(() => new Map(i.layout.nodes.map((t) => [t.id, t]))), nt = x(() => {
|
|
15
|
+
const t = F();
|
|
16
|
+
return t?.kind === "node" ? Q(i.layout, t.id) : new Set(t ? [t.id] : []);
|
|
17
|
+
}), W = x(() => {
|
|
18
|
+
const t = F();
|
|
19
|
+
if (t?.kind !== "node") return null;
|
|
20
|
+
const e = et().get(t.id), r = e?.kind === "group" ? e.id : e?.parentId;
|
|
21
|
+
return r ? Q(i.layout, r) : null;
|
|
22
|
+
}), j = (t) => i.selected?.kind === t.kind && i.selected.id === t.id, D = (t) => {
|
|
23
23
|
const {
|
|
24
|
-
width:
|
|
25
|
-
height:
|
|
24
|
+
width: e,
|
|
25
|
+
height: r
|
|
26
26
|
} = V();
|
|
27
|
-
if (!
|
|
28
|
-
const
|
|
27
|
+
if (!e || !r) return;
|
|
28
|
+
const n = -t.x / t.scale - 240, a = -t.y / t.scale - 240, y = n + e / t.scale + 480, s = a + r / t.scale + 480;
|
|
29
29
|
return {
|
|
30
|
-
left:
|
|
30
|
+
left: n,
|
|
31
31
|
top: a,
|
|
32
|
-
right:
|
|
33
|
-
bottom:
|
|
32
|
+
right: y,
|
|
33
|
+
bottom: s
|
|
34
34
|
};
|
|
35
|
-
},
|
|
36
|
-
const
|
|
37
|
-
if (!
|
|
35
|
+
}, rt = (t) => {
|
|
36
|
+
const e = D(t);
|
|
37
|
+
if (!e) return i.layout.nodes;
|
|
38
38
|
const {
|
|
39
|
-
left:
|
|
40
|
-
top:
|
|
39
|
+
left: r,
|
|
40
|
+
top: n,
|
|
41
41
|
right: a,
|
|
42
|
-
bottom:
|
|
43
|
-
} =
|
|
44
|
-
return i.layout.nodes.filter((
|
|
45
|
-
},
|
|
46
|
-
edge:
|
|
47
|
-
path:
|
|
48
|
-
label:
|
|
49
|
-
segments:
|
|
50
|
-
left: Math.min(
|
|
51
|
-
right: Math.max(
|
|
52
|
-
top: Math.min(
|
|
53
|
-
bottom: Math.max(
|
|
42
|
+
bottom: y
|
|
43
|
+
} = e;
|
|
44
|
+
return i.layout.nodes.filter((s) => s.id === i.selected?.id || s.x + s.width >= r && s.x <= a && s.y + s.height >= n && s.y <= y);
|
|
45
|
+
}, q = x(() => i.layout.edges.map((t) => ({
|
|
46
|
+
edge: t,
|
|
47
|
+
path: t.sections.map(vt).join(" "),
|
|
48
|
+
label: gt(t.sections),
|
|
49
|
+
segments: t.sections.flatMap((e) => e.slice(1).map((r, n) => ({
|
|
50
|
+
left: Math.min(r.x, e[n].x),
|
|
51
|
+
right: Math.max(r.x, e[n].x),
|
|
52
|
+
top: Math.min(r.y, e[n].y),
|
|
53
|
+
bottom: Math.max(r.y, e[n].y)
|
|
54
54
|
})))
|
|
55
|
-
}))),
|
|
56
|
-
const
|
|
57
|
-
return
|
|
58
|
-
edge:
|
|
59
|
-
segments:
|
|
60
|
-
}) =>
|
|
61
|
-
}, f = (
|
|
62
|
-
|
|
63
|
-
},
|
|
64
|
-
const
|
|
55
|
+
}))), at = (t) => {
|
|
56
|
+
const e = D(t);
|
|
57
|
+
return e ? q().filter(({
|
|
58
|
+
edge: r,
|
|
59
|
+
segments: n
|
|
60
|
+
}) => r.id === i.selected?.id || n.some((a) => a.left <= e.right && a.right >= e.left && a.top <= e.bottom && a.bottom >= e.top)) : q();
|
|
61
|
+
}, f = (t) => {
|
|
62
|
+
p(t), i.onHover?.(t);
|
|
63
|
+
}, $ = (t, e, r) => {
|
|
64
|
+
const n = e.getBoundingClientRect();
|
|
65
65
|
return {
|
|
66
|
-
object:
|
|
67
|
-
owner:
|
|
68
|
-
position:
|
|
69
|
-
x:
|
|
70
|
-
y:
|
|
66
|
+
object: t,
|
|
67
|
+
owner: e,
|
|
68
|
+
position: r && (r.clientX !== 0 || r.clientY !== 0) ? {
|
|
69
|
+
x: r.clientX,
|
|
70
|
+
y: r.clientY
|
|
71
71
|
} : {
|
|
72
|
-
x:
|
|
73
|
-
y:
|
|
72
|
+
x: n.left + n.width / 2,
|
|
73
|
+
y: n.top + Math.min(32, n.height / 2)
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
|
-
},
|
|
77
|
-
i.onContextMenu && (
|
|
78
|
-
},
|
|
79
|
-
|
|
76
|
+
}, H = (t, e) => {
|
|
77
|
+
i.onContextMenu && (e.preventDefault(), e.stopPropagation(), i.onContextMenu($(t, e.currentTarget, e)));
|
|
78
|
+
}, X = (t, e) => {
|
|
79
|
+
e.target === e.currentTarget && (e.key === "ContextMenu" || e.shiftKey && e.key === "F10" ? (e.preventDefault(), e.stopPropagation(), i.onContextMenu?.($(t, e.currentTarget))) : e.key === "Enter" ? (e.preventDefault(), e.stopPropagation(), i.onActivate?.($(t, e.currentTarget))) : e.key === "Escape" && (f(null), i.onActivate?.($(null, v))));
|
|
80
80
|
};
|
|
81
|
-
|
|
82
|
-
if (!
|
|
83
|
-
const
|
|
84
|
-
width:
|
|
85
|
-
height:
|
|
81
|
+
ct(() => {
|
|
82
|
+
if (!v) return;
|
|
83
|
+
const t = () => tt({
|
|
84
|
+
width: v.clientWidth,
|
|
85
|
+
height: v.clientHeight
|
|
86
86
|
});
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
87
|
+
t();
|
|
88
|
+
const e = new ResizeObserver(t);
|
|
89
|
+
e.observe(v), ut(() => e.disconnect());
|
|
90
90
|
});
|
|
91
|
-
const
|
|
92
|
-
const
|
|
91
|
+
const K = (t) => {
|
|
92
|
+
const e = {
|
|
93
93
|
kind: "node",
|
|
94
|
-
id:
|
|
95
|
-
},
|
|
96
|
-
selected: () =>
|
|
97
|
-
openMenu: (
|
|
94
|
+
id: t.id
|
|
95
|
+
}, r = {
|
|
96
|
+
selected: () => j(e),
|
|
97
|
+
openMenu: (n) => H(e, n)
|
|
98
98
|
};
|
|
99
99
|
return (() => {
|
|
100
|
-
var
|
|
101
|
-
return
|
|
102
|
-
a.target.closest("button, a, input, select, textarea, [data-floe-canvas-interactive]") || (a.stopPropagation(), i.onActivate?.(
|
|
103
|
-
},
|
|
104
|
-
var a =
|
|
105
|
-
return () => a() ? i.renderGroup(
|
|
106
|
-
})()),
|
|
107
|
-
var
|
|
108
|
-
return
|
|
100
|
+
var n = mt();
|
|
101
|
+
return n.$$keydown = (a) => X(e, a), n.$$contextmenu = (a) => H(e, a), n.$$click = (a) => {
|
|
102
|
+
a.target.closest("button, a, input, select, textarea, [data-floe-canvas-interactive]") || (a.stopPropagation(), i.onActivate?.($(e, a.currentTarget, a)));
|
|
103
|
+
}, n.$$focusout = () => f(null), n.$$focusin = () => f(e), n.addEventListener("pointerleave", () => f(null)), n.addEventListener("pointerenter", () => f(e)), S(n, (() => {
|
|
104
|
+
var a = it(() => !!(t.kind === "group" && i.renderGroup));
|
|
105
|
+
return () => a() ? i.renderGroup(t, r) : i.renderNode(t, r);
|
|
106
|
+
})()), z((a) => {
|
|
107
|
+
var y = t.kind === "group" ? "floe-graph__group" : "floe-graph__node", s = t.id, G = j(e), d = `${t.x}px`, C = `${t.y}px`, M = `${t.width}px`, l = `${t.height}px`, u = t.label;
|
|
108
|
+
return y !== a.e && U(n, a.e = y), s !== a.t && c(n, "data-graph-object", a.t = s), G !== a.a && c(n, "data-selected", a.a = G), d !== a.o && L(n, "left", a.o = d), C !== a.i && L(n, "top", a.i = C), M !== a.n && L(n, "width", a.n = M), l !== a.s && L(n, "height", a.s = l), u !== a.h && c(n, "aria-label", a.h = u), a;
|
|
109
109
|
}, {
|
|
110
110
|
e: void 0,
|
|
111
111
|
t: void 0,
|
|
@@ -115,14 +115,14 @@ function Ee(i) {
|
|
|
115
115
|
n: void 0,
|
|
116
116
|
s: void 0,
|
|
117
117
|
h: void 0
|
|
118
|
-
}),
|
|
118
|
+
}), n;
|
|
119
119
|
})();
|
|
120
120
|
};
|
|
121
121
|
return (() => {
|
|
122
|
-
var
|
|
123
|
-
|
|
124
|
-
var
|
|
125
|
-
return typeof
|
|
122
|
+
var t = bt();
|
|
123
|
+
t.$$keydown = (r) => X(null, r);
|
|
124
|
+
var e = v;
|
|
125
|
+
return typeof e == "function" ? ot(e, t) : v = t, S(t, w(st, {
|
|
126
126
|
get viewport() {
|
|
127
127
|
return i.viewport;
|
|
128
128
|
},
|
|
@@ -135,64 +135,79 @@ function Ee(i) {
|
|
|
135
135
|
return i.onViewportChange;
|
|
136
136
|
},
|
|
137
137
|
onViewportInteractionStart: () => i.onInteractionStart?.(),
|
|
138
|
-
resolveTargetRole: (
|
|
139
|
-
onCanvasPointerDown: (
|
|
140
|
-
!(
|
|
138
|
+
resolveTargetRole: (r) => (r.target instanceof Element ? r.target : null)?.closest('button, a, input, select, textarea, [data-floe-canvas-interactive="true"]') ? "local_surface" : ht(r),
|
|
139
|
+
onCanvasPointerDown: (r) => {
|
|
140
|
+
!(r.target instanceof Element) || r.target.closest("[data-graph-object]") || i.onActivate?.($(null, v, r));
|
|
141
141
|
},
|
|
142
|
-
onCanvasContextMenu: (
|
|
142
|
+
onCanvasContextMenu: (r) => i.onContextMenu?.({
|
|
143
143
|
object: null,
|
|
144
|
-
owner:
|
|
144
|
+
owner: v,
|
|
145
145
|
position: {
|
|
146
|
-
x:
|
|
147
|
-
y:
|
|
146
|
+
x: r.clientX,
|
|
147
|
+
y: r.clientY
|
|
148
148
|
}
|
|
149
149
|
}),
|
|
150
|
-
children: (
|
|
151
|
-
const
|
|
152
|
-
|
|
150
|
+
children: (r) => {
|
|
151
|
+
const n = x(() => {
|
|
152
|
+
const d = D(r());
|
|
153
|
+
if (d) return d;
|
|
154
|
+
const {
|
|
155
|
+
x: C,
|
|
156
|
+
y: M,
|
|
157
|
+
width: l,
|
|
158
|
+
height: u
|
|
159
|
+
} = i.layout.bounds;
|
|
160
|
+
return {
|
|
161
|
+
left: C - 240,
|
|
162
|
+
top: M - 240,
|
|
163
|
+
right: C + l + 240,
|
|
164
|
+
bottom: M + u + 240
|
|
165
|
+
};
|
|
166
|
+
}), a = x(() => rt(r())), y = x(() => a().filter((d) => d.kind === "group")), s = x(() => a().filter((d) => d.kind !== "group")), G = x(() => at(r()));
|
|
167
|
+
return [w(Y, {
|
|
153
168
|
get each() {
|
|
154
|
-
return
|
|
169
|
+
return y();
|
|
155
170
|
},
|
|
156
|
-
children:
|
|
171
|
+
children: K
|
|
157
172
|
}), (() => {
|
|
158
|
-
var d =
|
|
159
|
-
return
|
|
173
|
+
var d = xt(), C = d.firstChild, M = C.firstChild;
|
|
174
|
+
return c(M, "id", N), S(d, w(Y, {
|
|
160
175
|
get each() {
|
|
161
|
-
return
|
|
176
|
+
return G();
|
|
162
177
|
},
|
|
163
|
-
children: (
|
|
178
|
+
children: (l) => {
|
|
164
179
|
const {
|
|
165
180
|
edge: u
|
|
166
|
-
} =
|
|
181
|
+
} = l, m = {
|
|
167
182
|
kind: "edge",
|
|
168
183
|
id: u.id
|
|
169
|
-
},
|
|
170
|
-
return
|
|
184
|
+
}, I = () => l.path, R = () => l.label;
|
|
185
|
+
return w(_, {
|
|
171
186
|
get when() {
|
|
172
|
-
return !
|
|
187
|
+
return !W() || W().has(u.id);
|
|
173
188
|
},
|
|
174
189
|
get children() {
|
|
175
|
-
var
|
|
176
|
-
return
|
|
190
|
+
var b = yt(), E = b.firstChild, h = E.nextSibling;
|
|
191
|
+
return c(E, "marker-end", `url(#${N})`), S(b, w(_, {
|
|
177
192
|
get when() {
|
|
178
|
-
return
|
|
193
|
+
return R();
|
|
179
194
|
},
|
|
180
195
|
children: (o) => (() => {
|
|
181
|
-
var
|
|
182
|
-
return
|
|
183
|
-
var
|
|
184
|
-
return
|
|
196
|
+
var k = kt();
|
|
197
|
+
return S(k, () => u.label), z((g) => {
|
|
198
|
+
var P = /^\d+$/.test(u.label), T = o().x, A = o().y - 6;
|
|
199
|
+
return P !== g.e && c(k, "data-count", g.e = P), T !== g.t && c(k, "x", g.t = T), A !== g.a && c(k, "y", g.a = A), g;
|
|
185
200
|
}, {
|
|
186
201
|
e: void 0,
|
|
187
202
|
t: void 0,
|
|
188
203
|
a: void 0
|
|
189
|
-
}),
|
|
204
|
+
}), k;
|
|
190
205
|
})()
|
|
191
|
-
}),
|
|
192
|
-
o.stopPropagation(), i.onActivate?.(
|
|
193
|
-
},
|
|
194
|
-
var
|
|
195
|
-
return
|
|
206
|
+
}), h), h.$$keydown = (o) => X(m, o), h.$$contextmenu = (o) => H(m, o), h.$$click = (o) => {
|
|
207
|
+
o.stopPropagation(), i.onActivate?.($(m, o.currentTarget, o));
|
|
208
|
+
}, h.addEventListener("blur", () => f(null)), h.addEventListener("focus", () => f(m)), h.addEventListener("pointerleave", () => f(null)), h.addEventListener("pointerenter", () => f(m)), z((o) => {
|
|
209
|
+
var k = u.id, g = nt().has(u.id), P = j(m), T = I(), A = I(), O = u.label;
|
|
210
|
+
return k !== o.e && c(b, "data-graph-object", o.e = k), g !== o.t && c(b, "data-emphasized", o.t = g), P !== o.a && c(b, "data-selected", o.a = P), T !== o.o && c(E, "d", o.o = T), A !== o.i && c(h, "d", o.i = A), O !== o.n && c(h, "aria-label", o.n = O), o;
|
|
196
211
|
}, {
|
|
197
212
|
e: void 0,
|
|
198
213
|
t: void 0,
|
|
@@ -200,23 +215,33 @@ function Ee(i) {
|
|
|
200
215
|
o: void 0,
|
|
201
216
|
i: void 0,
|
|
202
217
|
n: void 0
|
|
203
|
-
}),
|
|
218
|
+
}), b;
|
|
204
219
|
}
|
|
205
220
|
});
|
|
206
221
|
}
|
|
207
|
-
}), null),
|
|
208
|
-
|
|
222
|
+
}), null), z((l) => {
|
|
223
|
+
var u = n().right - n().left, m = n().bottom - n().top, I = `${n().left} ${n().top} ${n().right - n().left} ${n().bottom - n().top}`, R = `${n().left}px`, b = `${n().top}px`, E = i.ariaLabel;
|
|
224
|
+
return u !== l.e && c(d, "width", l.e = u), m !== l.t && c(d, "height", l.t = m), I !== l.a && c(d, "viewBox", l.a = I), R !== l.o && L(d, "left", l.o = R), b !== l.i && L(d, "top", l.i = b), E !== l.n && c(d, "aria-label", l.n = E), l;
|
|
225
|
+
}, {
|
|
226
|
+
e: void 0,
|
|
227
|
+
t: void 0,
|
|
228
|
+
a: void 0,
|
|
229
|
+
o: void 0,
|
|
230
|
+
i: void 0,
|
|
231
|
+
n: void 0
|
|
232
|
+
}), d;
|
|
233
|
+
})(), w(Y, {
|
|
209
234
|
get each() {
|
|
210
|
-
return
|
|
235
|
+
return s();
|
|
211
236
|
},
|
|
212
|
-
children:
|
|
237
|
+
children: K
|
|
213
238
|
})];
|
|
214
239
|
}
|
|
215
|
-
}), null),
|
|
240
|
+
}), null), S(t, w(_, {
|
|
216
241
|
get when() {
|
|
217
242
|
return i.minimap;
|
|
218
243
|
},
|
|
219
|
-
children: (
|
|
244
|
+
children: (r) => w(ft, {
|
|
220
245
|
get layout() {
|
|
221
246
|
return i.layout;
|
|
222
247
|
},
|
|
@@ -233,22 +258,22 @@ function Ee(i) {
|
|
|
233
258
|
return i.onInteractionStart;
|
|
234
259
|
},
|
|
235
260
|
get ariaLabel() {
|
|
236
|
-
return
|
|
261
|
+
return r().ariaLabel;
|
|
237
262
|
},
|
|
238
263
|
get nodeStyle() {
|
|
239
|
-
return
|
|
264
|
+
return r().nodeStyle;
|
|
240
265
|
}
|
|
241
266
|
})
|
|
242
|
-
}), null),
|
|
243
|
-
var
|
|
244
|
-
return
|
|
267
|
+
}), null), S(t, () => i.overlay, null), z((r) => {
|
|
268
|
+
var n = `floe-graph ${i.class ?? ""}`, a = i.ariaLabel;
|
|
269
|
+
return n !== r.e && U(t, r.e = n), a !== r.t && c(t, "aria-label", r.t = a), r;
|
|
245
270
|
}, {
|
|
246
271
|
e: void 0,
|
|
247
272
|
t: void 0
|
|
248
|
-
}),
|
|
273
|
+
}), t;
|
|
249
274
|
})();
|
|
250
275
|
}
|
|
251
|
-
|
|
276
|
+
lt(["focusin", "focusout", "click", "contextmenu", "keydown"]);
|
|
252
277
|
export {
|
|
253
|
-
|
|
278
|
+
Lt as GraphCanvas
|
|
254
279
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function w() {
|
|
2
|
-
const t = new Worker(new URL("../../assets/layout-worker-
|
|
2
|
+
const t = new Worker(new URL("../../assets/layout-worker-CLVTDA3E.js", import.meta.url), { type: "module" });
|
|
3
3
|
let s, u = 0;
|
|
4
4
|
const o = /* @__PURE__ */ new Map(), n = (e) => {
|
|
5
5
|
s = e, t.terminate();
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { GraphGroupLayout, GraphLayoutNode, GraphLayoutOptions, GraphPoint } from './types';
|
|
2
|
+
/** Pack complete child subtrees in submitted order, without using edges as ranks. */
|
|
3
|
+
export declare function arrangeGroupMembers(members: readonly GraphLayoutNode[], rule: GraphGroupLayout, padding: NonNullable<GraphLayoutOptions['groupPadding']>, spacing: number, translate: (node: GraphLayoutNode, dx: number, dy: number) => void, origin?: GraphPoint): {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
};
|
|
@@ -46,6 +46,8 @@ export interface GraphLayout {
|
|
|
46
46
|
bounds: GraphBounds;
|
|
47
47
|
}
|
|
48
48
|
export interface GraphLayoutOptions {
|
|
49
|
+
/** Explicit packing of a group's direct children; independent of global direction and edges. */
|
|
50
|
+
groupLayouts?: Readonly<Record<string, GraphGroupLayout>>;
|
|
49
51
|
/** Clearance around routing obstacles in world units. Defaults to 4; never changes node geometry. */
|
|
50
52
|
edgeClearance?: number;
|
|
51
53
|
/** Desired width/height when packing disconnected objects, including group members. */
|
|
@@ -72,6 +74,12 @@ export interface GraphLayoutOptions {
|
|
|
72
74
|
position: GraphPoint;
|
|
73
75
|
};
|
|
74
76
|
}
|
|
77
|
+
export interface GraphGroupLayout {
|
|
78
|
+
/** Row fills left to right; column fills top to bottom. Omitted rules retain automatic layout. */
|
|
79
|
+
flow: 'row' | 'column';
|
|
80
|
+
/** Positive integer maximum per row/column. Omit for a single row/column. */
|
|
81
|
+
maxPerLine?: number;
|
|
82
|
+
}
|
|
75
83
|
export type GraphObjectRef = {
|
|
76
84
|
kind: 'node' | 'edge';
|
|
77
85
|
id: string;
|
package/dist/graph.css
CHANGED
|
@@ -37,8 +37,9 @@
|
|
|
37
37
|
}
|
|
38
38
|
.floe-graph__edges {
|
|
39
39
|
position: absolute;
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
/* A visible route may have endpoints far outside the viewport. Clip painting,
|
|
41
|
+
* not geometry, so its full world bounds do not expand the composited layer. */
|
|
42
|
+
overflow: hidden;
|
|
42
43
|
z-index: 1;
|
|
43
44
|
pointer-events: none;
|
|
44
45
|
}
|