@floegence/floe-webapp-core 0.82.0 → 0.83.1
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/_virtual/_commonjs-dynamic-modules.js +6 -0
- package/dist/_virtual/_commonjsHelpers.js +6 -0
- package/dist/_virtual/elk-api.js +7 -0
- package/dist/_virtual/elk-api2.js +4 -0
- package/dist/assets/elk-worker-CrDP6jPz.js +47082 -0
- package/dist/components/chat/blocks/MarkdownMedia.d.ts +1 -0
- package/dist/components/chat/blocks/MarkdownMedia.js +104 -106
- package/dist/components/graph/GraphCanvas.d.ts +27 -0
- package/dist/components/graph/GraphCanvas.js +178 -0
- package/dist/components/graph/engine.d.ts +7 -0
- package/dist/components/graph/engine.js +35 -0
- package/dist/components/graph/geometry.d.ts +8 -0
- package/dist/components/graph/geometry.js +35 -0
- package/dist/components/graph/layout.d.ts +5 -0
- package/dist/components/graph/layout.js +121 -0
- package/dist/components/graph/types.d.ts +72 -0
- package/dist/components/ui/InfiniteCanvas.d.ts +1 -1
- package/dist/components/ui/InfiniteCanvas.js +58 -55
- package/dist/graph.css +93 -0
- package/dist/graph.d.ts +4 -0
- package/dist/graph.js +10 -0
- package/dist/licenses/elkjs.txt +263 -0
- package/dist/licenses/graph-notice.txt +5 -0
- package/dist/node_modules/.pnpm/elkjs@0.12.0/node_modules/elkjs/lib/elk-api.js +186 -0
- package/package.json +8 -2
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
function c(t) {
|
|
2
|
+
return t.map((h, a) => `${a ? "L" : "M"}${h.x},${h.y}`).join(" ");
|
|
3
|
+
}
|
|
4
|
+
function o(t, h, a = 48) {
|
|
5
|
+
const i = Math.max(
|
|
6
|
+
0.1,
|
|
7
|
+
Math.min(
|
|
8
|
+
1,
|
|
9
|
+
(h.width - a * 2) / Math.max(1, t.width),
|
|
10
|
+
(h.height - a * 2) / Math.max(1, t.height)
|
|
11
|
+
)
|
|
12
|
+
);
|
|
13
|
+
return {
|
|
14
|
+
x: (h.width - t.width * i) / 2 - t.x * i,
|
|
15
|
+
y: (h.height - t.height * i) / 2 - t.y * i,
|
|
16
|
+
scale: i
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function f(t, h) {
|
|
20
|
+
const a = /* @__PURE__ */ new Set([h]), i = /* @__PURE__ */ new Map();
|
|
21
|
+
for (const e of t.nodes)
|
|
22
|
+
e.parentId && i.set(e.parentId, [...i.get(e.parentId) ?? [], e.id]);
|
|
23
|
+
const n = (e) => {
|
|
24
|
+
for (const r of i.get(e) ?? [])
|
|
25
|
+
a.has(r) || (a.add(r), n(r));
|
|
26
|
+
};
|
|
27
|
+
return n(h), new Set(
|
|
28
|
+
t.edges.filter((e) => a.has(e.source) || a.has(e.target)).map((e) => e.id)
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
o as fitGraphViewport,
|
|
33
|
+
f as graphRelatedEdges,
|
|
34
|
+
c as graphSectionPath
|
|
35
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ELK } from 'elkjs/lib/elk-api';
|
|
2
|
+
import type { GraphInput, GraphLayout, GraphLayoutOptions } from './types';
|
|
3
|
+
export declare function validateGraphInput(input: GraphInput): void;
|
|
4
|
+
/** Normalizes geometry around the supplied ELK engine; browser layout runs in its worker. */
|
|
5
|
+
export declare function computeGraphLayout(input: GraphInput, options: GraphLayoutOptions, engine: Pick<ELK, 'layout'>): Promise<GraphLayout>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
function k(n) {
|
|
2
|
+
const i = /* @__PURE__ */ new Set(), p = (e) => {
|
|
3
|
+
if (!e || i.has(e)) throw new Error(`Duplicate or empty graph ID: ${e}`);
|
|
4
|
+
i.add(e);
|
|
5
|
+
}, s = new Map(n.nodes.map((e) => [e.id, e]));
|
|
6
|
+
for (const e of n.nodes) {
|
|
7
|
+
if (p(e.id), ![e.width, e.height].every((r) => Number.isFinite(r) && r > 0))
|
|
8
|
+
throw new Error(`Invalid dimensions for graph node: ${e.id}`);
|
|
9
|
+
for (const r of e.ports ?? []) p(r.id);
|
|
10
|
+
const a = /* @__PURE__ */ new Set([e.id]);
|
|
11
|
+
let d = e.parentId;
|
|
12
|
+
for (; d !== void 0; ) {
|
|
13
|
+
const r = s.get(d);
|
|
14
|
+
if (!r || r.kind !== "group")
|
|
15
|
+
throw new Error(`Invalid parent for graph node: ${e.id}`);
|
|
16
|
+
if (a.has(d)) throw new Error(`Cyclic graph containment: ${e.id}`);
|
|
17
|
+
a.add(d), d = r.parentId;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
for (const e of n.edges) {
|
|
21
|
+
p(e.id);
|
|
22
|
+
for (const [a, d] of [
|
|
23
|
+
[e.source, e.sourcePort],
|
|
24
|
+
[e.target, e.targetPort]
|
|
25
|
+
]) {
|
|
26
|
+
const r = s.get(a);
|
|
27
|
+
if (!r || d !== void 0 && !r.ports?.some((c) => c.id === d))
|
|
28
|
+
throw new Error(`Invalid endpoint for graph edge: ${e.id}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function N(n, i, p) {
|
|
33
|
+
k(n);
|
|
34
|
+
const s = i.groupPadding ?? { top: 64, right: 28, bottom: 28, left: 28 };
|
|
35
|
+
if (![...Object.values(s), i.spacing ?? 64].every((t) => Number.isFinite(t) && t >= 0))
|
|
36
|
+
throw new Error("Graph layout spacing must be finite and nonnegative");
|
|
37
|
+
const e = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const t of n.nodes)
|
|
39
|
+
e.set(t.id, {
|
|
40
|
+
id: t.id,
|
|
41
|
+
width: t.width,
|
|
42
|
+
height: t.height,
|
|
43
|
+
...t.kind === "group" ? { children: [] } : {},
|
|
44
|
+
ports: t.ports?.map((o) => ({
|
|
45
|
+
id: o.id,
|
|
46
|
+
width: 1,
|
|
47
|
+
height: 1,
|
|
48
|
+
layoutOptions: { "elk.port.side": o.side }
|
|
49
|
+
})),
|
|
50
|
+
layoutOptions: {
|
|
51
|
+
"elk.portConstraints": "FIXED_ORDER",
|
|
52
|
+
"elk.padding": `[top=${s.top},left=${s.left},bottom=${s.bottom},right=${s.right}]`
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const a = [];
|
|
56
|
+
for (const t of n.nodes)
|
|
57
|
+
(t.parentId ? e.get(t.parentId).children : a).push(e.get(t.id));
|
|
58
|
+
const d = /* @__PURE__ */ new Set([
|
|
59
|
+
...n.nodes.flatMap((t) => [t.id, ...(t.ports ?? []).map((o) => o.id)]),
|
|
60
|
+
...n.edges.map((t) => t.id)
|
|
61
|
+
]);
|
|
62
|
+
let r = "$graph";
|
|
63
|
+
for (; d.has(r); ) r += "$";
|
|
64
|
+
const c = await p.layout({
|
|
65
|
+
id: r,
|
|
66
|
+
children: a,
|
|
67
|
+
edges: n.edges.map((t) => ({
|
|
68
|
+
id: t.id,
|
|
69
|
+
sources: [t.sourcePort ?? t.source],
|
|
70
|
+
targets: [t.targetPort ?? t.target]
|
|
71
|
+
})),
|
|
72
|
+
layoutOptions: {
|
|
73
|
+
"elk.algorithm": "layered",
|
|
74
|
+
"elk.direction": i.direction ?? "RIGHT",
|
|
75
|
+
"elk.edgeRouting": "ORTHOGONAL",
|
|
76
|
+
"elk.hierarchyHandling": "INCLUDE_CHILDREN",
|
|
77
|
+
"elk.spacing.nodeNode": String(i.spacing ?? 64),
|
|
78
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": String(i.spacing ?? 64),
|
|
79
|
+
"elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES",
|
|
80
|
+
"elk.randomSeed": "1"
|
|
81
|
+
}
|
|
82
|
+
}), f = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), I = (t) => {
|
|
83
|
+
for (const o of t.edges ?? []) {
|
|
84
|
+
const h = o.container ?? t.id, l = f.get(h) ?? { x: 0, y: 0 };
|
|
85
|
+
x.set(
|
|
86
|
+
o.id,
|
|
87
|
+
(o.sections ?? []).map(
|
|
88
|
+
(g) => [g.startPoint, ...g.bendPoints ?? [], g.endPoint].map((w) => ({
|
|
89
|
+
x: w.x + l.x,
|
|
90
|
+
y: w.y + l.y
|
|
91
|
+
}))
|
|
92
|
+
)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
for (const o of t.children ?? []) I(o);
|
|
96
|
+
}, E = (t, o, h) => {
|
|
97
|
+
const l = o + (t.x ?? 0), g = h + (t.y ?? 0);
|
|
98
|
+
f.set(t.id, { x: l, y: g, width: t.width ?? 0, height: t.height ?? 0 });
|
|
99
|
+
for (const w of t.children ?? []) E(w, l, g);
|
|
100
|
+
};
|
|
101
|
+
for (const t of c.children ?? []) E(t, 0, 0);
|
|
102
|
+
I(c);
|
|
103
|
+
const y = i.anchor && f.get(i.anchor.nodeId), u = y ? i.anchor.position.x - y.x : 0, m = y ? i.anchor.position.y - y.y : 0;
|
|
104
|
+
return {
|
|
105
|
+
nodes: n.nodes.map((t) => {
|
|
106
|
+
const o = f.get(t.id);
|
|
107
|
+
return { ...t, ...o, x: o.x + u, y: o.y + m };
|
|
108
|
+
}),
|
|
109
|
+
edges: n.edges.map((t) => ({
|
|
110
|
+
...t,
|
|
111
|
+
sections: (x.get(t.id) ?? []).map(
|
|
112
|
+
(o) => o.map((h) => ({ x: h.x + u, y: h.y + m }))
|
|
113
|
+
)
|
|
114
|
+
})),
|
|
115
|
+
bounds: { x: u, y: m, width: c.width ?? 0, height: c.height ?? 0 }
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export {
|
|
119
|
+
N as computeGraphLayout,
|
|
120
|
+
k as validateGraphInput
|
|
121
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { InfiniteCanvasPoint } from '../ui/InfiniteCanvas';
|
|
2
|
+
export interface GraphPoint {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
}
|
|
6
|
+
export interface GraphBounds extends GraphPoint {
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
}
|
|
10
|
+
export type GraphViewport = InfiniteCanvasPoint;
|
|
11
|
+
/** Port IDs, node IDs, and edge IDs share one namespace. */
|
|
12
|
+
export interface GraphPort {
|
|
13
|
+
id: string;
|
|
14
|
+
side: 'NORTH' | 'EAST' | 'SOUTH' | 'WEST';
|
|
15
|
+
}
|
|
16
|
+
export interface GraphNode {
|
|
17
|
+
id: string;
|
|
18
|
+
label: string;
|
|
19
|
+
kind?: 'node' | 'group';
|
|
20
|
+
parentId?: string;
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
ports?: readonly GraphPort[];
|
|
24
|
+
}
|
|
25
|
+
export interface GraphEdge {
|
|
26
|
+
id: string;
|
|
27
|
+
label: string;
|
|
28
|
+
source: string;
|
|
29
|
+
target: string;
|
|
30
|
+
sourcePort?: string;
|
|
31
|
+
targetPort?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface GraphInput {
|
|
34
|
+
nodes: readonly GraphNode[];
|
|
35
|
+
edges: readonly GraphEdge[];
|
|
36
|
+
}
|
|
37
|
+
export interface GraphLayoutNode extends GraphNode, GraphBounds {
|
|
38
|
+
}
|
|
39
|
+
export interface GraphLayoutEdge extends GraphEdge {
|
|
40
|
+
/** Separate sections preserve branches and self loops without inventing joins. */
|
|
41
|
+
sections: readonly (readonly GraphPoint[])[];
|
|
42
|
+
}
|
|
43
|
+
export interface GraphLayout {
|
|
44
|
+
nodes: readonly GraphLayoutNode[];
|
|
45
|
+
edges: readonly GraphLayoutEdge[];
|
|
46
|
+
bounds: GraphBounds;
|
|
47
|
+
}
|
|
48
|
+
export interface GraphLayoutOptions {
|
|
49
|
+
direction?: 'RIGHT' | 'DOWN' | 'LEFT' | 'UP';
|
|
50
|
+
spacing?: number;
|
|
51
|
+
groupPadding?: {
|
|
52
|
+
top: number;
|
|
53
|
+
right: number;
|
|
54
|
+
bottom: number;
|
|
55
|
+
left: number;
|
|
56
|
+
};
|
|
57
|
+
/** Keep the object under inspection at its previous world position after layout. */
|
|
58
|
+
anchor?: {
|
|
59
|
+
nodeId: string;
|
|
60
|
+
position: GraphPoint;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export type GraphObjectRef = {
|
|
64
|
+
kind: 'node' | 'edge';
|
|
65
|
+
id: string;
|
|
66
|
+
};
|
|
67
|
+
/** Client coordinates go directly to SurfaceFloatingLayer; never rescale them. */
|
|
68
|
+
export interface GraphObjectEvent {
|
|
69
|
+
object: GraphObjectRef | null;
|
|
70
|
+
position: GraphPoint;
|
|
71
|
+
owner: Element;
|
|
72
|
+
}
|
|
@@ -14,7 +14,7 @@ export interface InfiniteCanvasContextMenuEvent {
|
|
|
14
14
|
worldY: number;
|
|
15
15
|
}
|
|
16
16
|
export interface InfiniteCanvasProps {
|
|
17
|
-
children: JSX.Element;
|
|
17
|
+
children: JSX.Element | ((viewport: Accessor<InfiniteCanvasPoint>) => JSX.Element);
|
|
18
18
|
overlay?: (viewport: Accessor<InfiniteCanvasPoint>) => JSX.Element;
|
|
19
19
|
viewport: InfiniteCanvasPoint;
|
|
20
20
|
onViewportChange?: (viewport: InfiniteCanvasPoint) => void;
|
|
@@ -1,38 +1,41 @@
|
|
|
1
|
-
import { spread as
|
|
2
|
-
import { createSignal as b, untrack as x, createEffect as A, onCleanup as D } from "solid-js";
|
|
3
|
-
import { cn as
|
|
4
|
-
import { startHotInteraction as
|
|
5
|
-
import { resolveSurfaceInteractionTargetRole as
|
|
6
|
-
import { startPointerSession as
|
|
7
|
-
import { clientToCanvasLocal as R, localToCanvasWorld as
|
|
8
|
-
import { SURFACE_PORTAL_LAYER_ATTR as
|
|
9
|
-
var
|
|
10
|
-
const
|
|
11
|
-
function
|
|
12
|
-
return Math.max(s, Math.min(
|
|
1
|
+
import { spread as j, mergeProps as q, insert as T, effect as G, className as J, setStyleProperty as K, template as Q, use as ee } from "solid-js/web";
|
|
2
|
+
import { createSignal as b, untrack as x, createMemo as te, createEffect as A, onCleanup as D } from "solid-js";
|
|
3
|
+
import { cn as y } from "../../utils/cn.js";
|
|
4
|
+
import { startHotInteraction as I } from "../../utils/hotInteraction.js";
|
|
5
|
+
import { resolveSurfaceInteractionTargetRole as ne, resolveSurfaceWheelRouting as re, DEFAULT_CANVAS_WHEEL_INTERACTIVE_SELECTOR as oe } from "./localInteractionSurface.js";
|
|
6
|
+
import { startPointerSession as ae } from "./pointerSession.js";
|
|
7
|
+
import { clientToCanvasLocal as R, localToCanvasWorld as ie, createViewportFromZoomAnchor as ce } from "./canvasGeometry.js";
|
|
8
|
+
import { SURFACE_PORTAL_LAYER_ATTR as le } from "./dialogSurfaceScope.js";
|
|
9
|
+
var se = /* @__PURE__ */ Q('<div><div style="transform-origin:0 0">');
|
|
10
|
+
const ue = 1, de = 0.45, fe = 2.2, me = 14e-4, we = '[data-floe-canvas-pan-surface="true"]', Y = 3;
|
|
11
|
+
function Se(t, s, i) {
|
|
12
|
+
return Math.max(s, Math.min(i, t));
|
|
13
13
|
}
|
|
14
14
|
function k(t) {
|
|
15
15
|
return {
|
|
16
16
|
x: Number.isFinite(t.x) ? t.x : 0,
|
|
17
17
|
y: Number.isFinite(t.y) ? t.y : 0,
|
|
18
|
-
scale: Number.isFinite(t.scale) && t.scale > 0 ? t.scale :
|
|
18
|
+
scale: Number.isFinite(t.scale) && t.scale > 0 ? t.scale : ue
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function ve(t, s) {
|
|
22
22
|
return t.deltaMode === 1 ? t.deltaY * 16 : t.deltaMode === 2 ? t.deltaY * (s?.clientHeight ?? window.innerHeight) : t.deltaY;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function Te(t) {
|
|
25
25
|
let s = !1;
|
|
26
|
-
const [
|
|
26
|
+
const [i, S] = b(x(() => k(t.viewport))), [w, v] = b(null), M = te(() => {
|
|
27
|
+
const e = t.children;
|
|
28
|
+
return typeof e == "function" ? e(i) : e;
|
|
29
|
+
});
|
|
27
30
|
let l, d, f, m = !1, u;
|
|
28
|
-
const
|
|
31
|
+
const X = () => t.interactiveSelector ?? '[data-floe-canvas-interactive="true"]', F = () => t.panSurfaceSelector ?? we, V = () => t.wheelInteractiveSelector ?? oe, N = () => t.minScale ?? de, H = () => t.maxScale ?? fe, U = () => t.wheelZoomSpeed ?? me, W = () => {
|
|
29
32
|
const e = w();
|
|
30
33
|
return e ? e.startedFromPanSurface ? e.moved : !0 : !1;
|
|
31
34
|
}, p = () => {
|
|
32
35
|
f !== void 0 && (window.clearTimeout(f), f = void 0);
|
|
33
36
|
}, g = () => {
|
|
34
37
|
m = !1, u !== void 0 && (window.clearTimeout(u), u = void 0);
|
|
35
|
-
},
|
|
38
|
+
}, Z = () => {
|
|
36
39
|
if (typeof window > "u") {
|
|
37
40
|
m = !1;
|
|
38
41
|
return;
|
|
@@ -42,7 +45,7 @@ function Le(t) {
|
|
|
42
45
|
}, 0);
|
|
43
46
|
}, E = (e) => {
|
|
44
47
|
x(() => t.onViewportChange?.(e));
|
|
45
|
-
},
|
|
48
|
+
}, O = (e) => {
|
|
46
49
|
if (typeof window > "u") {
|
|
47
50
|
E(e);
|
|
48
51
|
return;
|
|
@@ -50,16 +53,16 @@ function Le(t) {
|
|
|
50
53
|
p(), f = window.setTimeout(() => {
|
|
51
54
|
f = void 0, E(e);
|
|
52
55
|
}, 90);
|
|
53
|
-
}, C = (e) => (t.resolveTargetRole ??
|
|
56
|
+
}, C = (e) => (t.resolveTargetRole ?? ne)({
|
|
54
57
|
target: e,
|
|
55
|
-
interactiveSelector:
|
|
56
|
-
panSurfaceSelector:
|
|
57
|
-
}),
|
|
58
|
+
interactiveSelector: X(),
|
|
59
|
+
panSurfaceSelector: F()
|
|
60
|
+
}), $ = () => {
|
|
58
61
|
const e = w();
|
|
59
62
|
if (!e) return;
|
|
60
63
|
e.stopInteraction?.();
|
|
61
|
-
const n =
|
|
62
|
-
v(null), d = void 0, e.startedFromPanSurface && e.moved && (m = !0,
|
|
64
|
+
const n = i();
|
|
65
|
+
v(null), d = void 0, e.startedFromPanSurface && e.moved && (m = !0, Z()), E(n);
|
|
63
66
|
};
|
|
64
67
|
A(() => {
|
|
65
68
|
w() || S(k(t.viewport));
|
|
@@ -74,13 +77,13 @@ function Le(t) {
|
|
|
74
77
|
s = !1;
|
|
75
78
|
};
|
|
76
79
|
document.addEventListener("keydown", a), document.addEventListener("keyup", r), window.addEventListener("blur", r);
|
|
77
|
-
const
|
|
80
|
+
const c = (o) => {
|
|
78
81
|
(o.button === 1 || o.button === 0 && s) && h(o);
|
|
79
82
|
};
|
|
80
|
-
e.addEventListener("pointerdown",
|
|
83
|
+
e.addEventListener("pointerdown", c, !0), e.addEventListener("click", n, !0), e.addEventListener("wheel", P, {
|
|
81
84
|
passive: !1
|
|
82
85
|
}), D(() => {
|
|
83
|
-
document.removeEventListener("keydown", a), document.removeEventListener("keyup", r), window.removeEventListener("blur", r), e.removeEventListener("pointerdown",
|
|
86
|
+
document.removeEventListener("keydown", a), document.removeEventListener("keyup", r), window.removeEventListener("blur", r), e.removeEventListener("pointerdown", c, !0), e.removeEventListener("click", n, !0), e.removeEventListener("wheel", P);
|
|
84
87
|
});
|
|
85
88
|
}), D(() => {
|
|
86
89
|
p(), d?.stop({
|
|
@@ -102,23 +105,23 @@ function Le(t) {
|
|
|
102
105
|
pointerId: e.pointerId,
|
|
103
106
|
startClientX: e.clientX,
|
|
104
107
|
startClientY: e.clientY,
|
|
105
|
-
startViewport:
|
|
108
|
+
startViewport: i(),
|
|
106
109
|
moved: !1,
|
|
107
110
|
startedFromPanSurface: r,
|
|
108
|
-
stopInteraction: r ? void 0 :
|
|
111
|
+
stopInteraction: r ? void 0 : I({
|
|
109
112
|
kind: "drag",
|
|
110
113
|
cursor: "grabbing"
|
|
111
114
|
})
|
|
112
|
-
}), d =
|
|
115
|
+
}), d = ae({
|
|
113
116
|
pointerEvent: e,
|
|
114
117
|
captureEl: l ?? null,
|
|
115
118
|
capturePointer: !r,
|
|
116
|
-
onMove:
|
|
119
|
+
onMove: z,
|
|
117
120
|
onEnd: () => {
|
|
118
|
-
|
|
121
|
+
$();
|
|
119
122
|
}
|
|
120
123
|
}));
|
|
121
|
-
},
|
|
124
|
+
}, z = (e) => {
|
|
122
125
|
const n = w();
|
|
123
126
|
if (!n || n.pointerId !== e.pointerId) return;
|
|
124
127
|
const a = e.clientX - n.startClientX, r = e.clientY - n.startClientY;
|
|
@@ -132,31 +135,31 @@ function Le(t) {
|
|
|
132
135
|
n.moved || v({
|
|
133
136
|
...n,
|
|
134
137
|
moved: !0,
|
|
135
|
-
stopInteraction: n.stopInteraction ??
|
|
138
|
+
stopInteraction: n.stopInteraction ?? I({
|
|
136
139
|
kind: "drag",
|
|
137
140
|
cursor: "grabbing"
|
|
138
141
|
})
|
|
139
142
|
}), S(o);
|
|
140
143
|
}, P = (e) => {
|
|
141
144
|
const n = l?.getBoundingClientRect();
|
|
142
|
-
if (!n || (t.resolveWheelRouting ??
|
|
145
|
+
if (!n || (t.resolveWheelRouting ?? re)({
|
|
143
146
|
target: e.target,
|
|
144
147
|
disablePanZoom: !!t.disablePanZoom,
|
|
145
|
-
wheelInteractiveSelector:
|
|
148
|
+
wheelInteractiveSelector: V()
|
|
146
149
|
}).kind !== "canvas_zoom") return;
|
|
147
150
|
e.preventDefault(), t.onViewportInteractionStart?.("wheel");
|
|
148
|
-
const r =
|
|
151
|
+
const r = i(), c = R(n, {
|
|
149
152
|
clientX: e.clientX,
|
|
150
153
|
clientY: e.clientY
|
|
151
|
-
}), o =
|
|
154
|
+
}), o = ve(e, l), L = Se(r.scale * Math.exp(-o * U()), N(), H());
|
|
152
155
|
if (Math.abs(L - r.scale) < 1e-4) return;
|
|
153
|
-
const _ =
|
|
156
|
+
const _ = ce({
|
|
154
157
|
viewport: r,
|
|
155
|
-
localPoint:
|
|
158
|
+
localPoint: c,
|
|
156
159
|
nextScale: L
|
|
157
160
|
});
|
|
158
|
-
S(_),
|
|
159
|
-
},
|
|
161
|
+
S(_), O(_);
|
|
162
|
+
}, B = (e) => {
|
|
160
163
|
if (C(e.target) !== "canvas") return;
|
|
161
164
|
const n = l?.getBoundingClientRect();
|
|
162
165
|
if (!n) return;
|
|
@@ -164,33 +167,33 @@ function Le(t) {
|
|
|
164
167
|
const a = R(n, {
|
|
165
168
|
clientX: e.clientX,
|
|
166
169
|
clientY: e.clientY
|
|
167
|
-
}), r =
|
|
170
|
+
}), r = i(), c = ie(r, a);
|
|
168
171
|
t.onCanvasContextMenu?.({
|
|
169
172
|
clientX: e.clientX,
|
|
170
173
|
clientY: e.clientY,
|
|
171
174
|
localX: a.localX,
|
|
172
175
|
localY: a.localY,
|
|
173
|
-
worldX:
|
|
174
|
-
worldY:
|
|
176
|
+
worldX: c.worldX,
|
|
177
|
+
worldY: c.worldY
|
|
175
178
|
});
|
|
176
179
|
};
|
|
177
180
|
return (() => {
|
|
178
|
-
var e =
|
|
179
|
-
return typeof a == "function" ?
|
|
181
|
+
var e = se(), n = e.firstChild, a = l;
|
|
182
|
+
return typeof a == "function" ? ee(a, e) : l = e, j(e, q({
|
|
180
183
|
get class() {
|
|
181
|
-
return
|
|
184
|
+
return y("floe-infinite-canvas", W() && "is-panning", t.disablePanZoom && "is-locked", t.class);
|
|
182
185
|
}
|
|
183
186
|
}, {
|
|
184
|
-
[
|
|
187
|
+
[le]: "true"
|
|
185
188
|
}, {
|
|
186
189
|
onPointerDown: h,
|
|
187
|
-
onContextMenu:
|
|
190
|
+
onContextMenu: B,
|
|
188
191
|
get "aria-label"() {
|
|
189
192
|
return t.ariaLabel ?? "Infinite canvas";
|
|
190
193
|
}
|
|
191
|
-
}), !1, !0), T(n,
|
|
192
|
-
var
|
|
193
|
-
return
|
|
194
|
+
}), !1, !0), T(n, M), T(e, () => t.overlay?.(i), null), G((r) => {
|
|
195
|
+
var c = y("floe-infinite-canvas__viewport", t.contentClass), o = `translate(${i().x}px, ${i().y}px) scale(${i().scale})`;
|
|
196
|
+
return c !== r.e && J(n, r.e = c), o !== r.t && K(n, "transform", r.t = o), r;
|
|
194
197
|
}, {
|
|
195
198
|
e: void 0,
|
|
196
199
|
t: void 0
|
|
@@ -198,5 +201,5 @@ function Le(t) {
|
|
|
198
201
|
})();
|
|
199
202
|
}
|
|
200
203
|
export {
|
|
201
|
-
|
|
204
|
+
Te as InfiniteCanvas
|
|
202
205
|
};
|
package/dist/graph.css
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* Domain colors and card content belong to the consumer. These tokens are theme-neutral. */
|
|
2
|
+
.floe-graph {
|
|
3
|
+
position: relative;
|
|
4
|
+
isolation: isolate;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
min-height: 0;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
background-color: var(--graph-background, var(--background));
|
|
10
|
+
background-image: radial-gradient(
|
|
11
|
+
circle,
|
|
12
|
+
var(--graph-dot, color-mix(in srgb, var(--foreground) 12%, transparent)) 0.65px,
|
|
13
|
+
transparent 0.8px
|
|
14
|
+
);
|
|
15
|
+
background-size: 22px 22px;
|
|
16
|
+
color: var(--foreground);
|
|
17
|
+
}
|
|
18
|
+
.floe-graph .floe-infinite-canvas {
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
}
|
|
22
|
+
.floe-graph__node,
|
|
23
|
+
.floe-graph__group {
|
|
24
|
+
position: absolute;
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
user-select: none;
|
|
27
|
+
}
|
|
28
|
+
.floe-graph__node {
|
|
29
|
+
z-index: 2;
|
|
30
|
+
}
|
|
31
|
+
.floe-graph__group {
|
|
32
|
+
z-index: 0;
|
|
33
|
+
}
|
|
34
|
+
.floe-graph__node > *,
|
|
35
|
+
.floe-graph__group > * {
|
|
36
|
+
box-sizing: border-box;
|
|
37
|
+
}
|
|
38
|
+
.floe-graph__edges {
|
|
39
|
+
position: absolute;
|
|
40
|
+
inset: 0;
|
|
41
|
+
overflow: visible;
|
|
42
|
+
z-index: 1;
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
}
|
|
45
|
+
.floe-graph__edge {
|
|
46
|
+
fill: none;
|
|
47
|
+
stroke: var(--graph-edge, var(--muted-foreground));
|
|
48
|
+
stroke-width: 1.3px;
|
|
49
|
+
opacity: 0.32;
|
|
50
|
+
vector-effect: non-scaling-stroke;
|
|
51
|
+
stroke-linejoin: round;
|
|
52
|
+
}
|
|
53
|
+
.floe-graph__edge-target {
|
|
54
|
+
fill: none;
|
|
55
|
+
stroke: transparent;
|
|
56
|
+
stroke-width: 14px;
|
|
57
|
+
vector-effect: non-scaling-stroke;
|
|
58
|
+
pointer-events: stroke;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
}
|
|
61
|
+
.floe-graph__edges [data-emphasized='true'] .floe-graph__edge,
|
|
62
|
+
.floe-graph__edges [data-selected='true'] .floe-graph__edge {
|
|
63
|
+
stroke: var(--graph-edge-active, var(--foreground));
|
|
64
|
+
stroke-width: 2px;
|
|
65
|
+
opacity: 0.95;
|
|
66
|
+
}
|
|
67
|
+
.floe-graph__edge-target:focus-visible {
|
|
68
|
+
outline: none;
|
|
69
|
+
stroke: var(--graph-edge-active, var(--foreground));
|
|
70
|
+
stroke-width: 3px;
|
|
71
|
+
}
|
|
72
|
+
.floe-graph__node:focus-visible,
|
|
73
|
+
.floe-graph__group:focus-visible {
|
|
74
|
+
outline: 2px solid var(--ring);
|
|
75
|
+
outline-offset: 4px;
|
|
76
|
+
border-radius: 8px;
|
|
77
|
+
}
|
|
78
|
+
@media (forced-colors: active) {
|
|
79
|
+
.floe-graph {
|
|
80
|
+
background: Canvas;
|
|
81
|
+
}
|
|
82
|
+
.floe-graph__edge {
|
|
83
|
+
stroke: CanvasText;
|
|
84
|
+
opacity: 1;
|
|
85
|
+
}
|
|
86
|
+
.floe-graph__edges [data-emphasized='true'] .floe-graph__edge {
|
|
87
|
+
stroke: Highlight;
|
|
88
|
+
}
|
|
89
|
+
.floe-graph__node:focus-visible,
|
|
90
|
+
.floe-graph__group:focus-visible {
|
|
91
|
+
outline-color: Highlight;
|
|
92
|
+
}
|
|
93
|
+
}
|
package/dist/graph.d.ts
ADDED
package/dist/graph.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { fitGraphViewport as e, graphRelatedEdges as t, graphSectionPath as o } from "./components/graph/geometry.js";
|
|
2
|
+
import { createGraphLayoutEngine as h } from "./components/graph/engine.js";
|
|
3
|
+
import { GraphCanvas as g } from "./components/graph/GraphCanvas.js";
|
|
4
|
+
export {
|
|
5
|
+
g as GraphCanvas,
|
|
6
|
+
h as createGraphLayoutEngine,
|
|
7
|
+
e as fitGraphViewport,
|
|
8
|
+
t as graphRelatedEdges,
|
|
9
|
+
o as graphSectionPath
|
|
10
|
+
};
|