@green-on-grey/ui-kit 1.11.1 → 1.14.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.
- package/dist/components/Graph.d.ts +112 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +382 -33
- package/dist/index.js.map +1 -1
- package/dist/locales/index.d.ts +25 -0
- package/dist/locales.js +25 -0
- package/dist/locales.js.map +1 -1
- package/dist/manifest.json +31 -1
- package/dist/styles.css +192 -0
- package/package.json +3 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/** A node: `group` picks the colour (g-c1…g-c6), `size` the radius. */
|
|
2
|
+
export type GraphNode = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
group?: number;
|
|
7
|
+
size?: number;
|
|
8
|
+
/** Not in the data of the product, only referred to: a dashed outline. */
|
|
9
|
+
dashed?: boolean;
|
|
10
|
+
/** Context around the shown set: drawn faded. */
|
|
11
|
+
muted?: boolean;
|
|
12
|
+
/** The label shows only on hover, focus or highlight. */
|
|
13
|
+
hideLabel?: boolean;
|
|
14
|
+
/** With `rows` on the graph: the id of the row of the node and its place in it, ascending left to right. */
|
|
15
|
+
row?: string;
|
|
16
|
+
order?: number;
|
|
17
|
+
};
|
|
18
|
+
export type GraphEdge = {
|
|
19
|
+
source: string;
|
|
20
|
+
target: string;
|
|
21
|
+
weight?: number;
|
|
22
|
+
directed?: boolean;
|
|
23
|
+
dashed?: boolean;
|
|
24
|
+
title?: string;
|
|
25
|
+
};
|
|
26
|
+
export type GraphSelection = {
|
|
27
|
+
kind: "node";
|
|
28
|
+
id: string;
|
|
29
|
+
} | {
|
|
30
|
+
kind: "edge";
|
|
31
|
+
source: string;
|
|
32
|
+
target: string;
|
|
33
|
+
} | null;
|
|
34
|
+
/** A row of the row layout, top to bottom in the order given; the label is drawn at its left. */
|
|
35
|
+
export type GraphRow = {
|
|
36
|
+
id: string;
|
|
37
|
+
label: string;
|
|
38
|
+
};
|
|
39
|
+
/** A node with its place; the fields of d3-force are spelled out, so the types of the kit need no d3 types. */
|
|
40
|
+
type Placed = GraphNode & {
|
|
41
|
+
r: number;
|
|
42
|
+
index?: number;
|
|
43
|
+
x?: number;
|
|
44
|
+
y?: number;
|
|
45
|
+
vx?: number;
|
|
46
|
+
vy?: number;
|
|
47
|
+
fx?: number | null;
|
|
48
|
+
fy?: number | null;
|
|
49
|
+
};
|
|
50
|
+
type Field = {
|
|
51
|
+
w: number;
|
|
52
|
+
h: number;
|
|
53
|
+
};
|
|
54
|
+
/** The places of the nodes, the size of the field and, in the row layout, the rows with their middle line. */
|
|
55
|
+
type Placement = {
|
|
56
|
+
placed: Placed[];
|
|
57
|
+
field: Field;
|
|
58
|
+
rows?: {
|
|
59
|
+
id: string;
|
|
60
|
+
label: string;
|
|
61
|
+
y: number;
|
|
62
|
+
x: number;
|
|
63
|
+
x2: number;
|
|
64
|
+
}[];
|
|
65
|
+
};
|
|
66
|
+
/** Ids within `depth` steps of `from`, edges taken both ways. */
|
|
67
|
+
export declare function neighbours(edges: GraphEdge[], from: string, depth: number): Set<string>;
|
|
68
|
+
/** Positions of the nodes (exported for the tests): a force layout computed once per data. The start of
|
|
69
|
+
* d3-force is deterministic, so the same data gives the same picture. */
|
|
70
|
+
export declare function layout(nodes: GraphNode[], edges: GraphEdge[]): Placed[];
|
|
71
|
+
/** The row layout (FTR.HMR.DEV-0002 R15, exported for the tests): a row per `rows` entry that has nodes, top to
|
|
72
|
+
* bottom in the given order; in a row the nodes by `order`, then id, left to right. A node whose row is not
|
|
73
|
+
* among `rows` goes to a last row without a label. The block is centred in a field at least as big as that of
|
|
74
|
+
* the force layout. */
|
|
75
|
+
export declare function rowLayout(nodes: GraphNode[], rows: GraphRow[]): Placement;
|
|
76
|
+
/** The line of an edge: straight, or in the row layout an arc between two nodes of one row — above when it goes
|
|
77
|
+
* right, below when it goes left, so links both ways do not cover each other. A directed line ends at the
|
|
78
|
+
* circle of the target. */
|
|
79
|
+
export declare function edgeLine(a: Placed, b: Placed, directed: boolean, arcs: boolean): {
|
|
80
|
+
d?: string;
|
|
81
|
+
hit?: string;
|
|
82
|
+
x1: number;
|
|
83
|
+
y1: number;
|
|
84
|
+
x2: number;
|
|
85
|
+
y2: number;
|
|
86
|
+
};
|
|
87
|
+
/** A graph of nodes and links (FTR.NAB.CMN-0003 R19, FTR.HMR.DEV-0002 R15, R16).
|
|
88
|
+
* Hovering highlights the neighbours, a click pins the selection; the wheel zooms,
|
|
89
|
+
* dragging the field moves it. `focus` highlights a node and its neighbours within `depth`
|
|
90
|
+
* steps; `onOpen` is called on a double click or Enter on a node. With `rows` the nodes stand in
|
|
91
|
+
* rows (`GraphNode.row`, `order`) instead of the force layout; with `draggable` a node can be moved
|
|
92
|
+
* and a button puts the moved nodes back. The kit knows nothing of what the nodes are: labels,
|
|
93
|
+
* rows and the legend come from the product.
|
|
94
|
+
* The layout runs when `nodes`, `edges` or `rows` change identity: keep them stable (useMemo). */
|
|
95
|
+
export declare function Graph({ nodes, edges, ariaLabel, selected, onSelect, focus, depth, onOpen, legend, nodeLabel, rows, draggable }: {
|
|
96
|
+
nodes: GraphNode[];
|
|
97
|
+
edges: GraphEdge[];
|
|
98
|
+
ariaLabel: string;
|
|
99
|
+
selected: GraphSelection;
|
|
100
|
+
onSelect: (s: GraphSelection) => void;
|
|
101
|
+
focus?: string;
|
|
102
|
+
depth?: 1 | 2;
|
|
103
|
+
onOpen?: (id: string) => void;
|
|
104
|
+
legend?: {
|
|
105
|
+
group: number;
|
|
106
|
+
label: string;
|
|
107
|
+
}[];
|
|
108
|
+
nodeLabel?: (n: GraphNode) => string;
|
|
109
|
+
rows?: GraphRow[];
|
|
110
|
+
draggable?: boolean;
|
|
111
|
+
}): import("react").JSX.Element;
|
|
112
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export { Button, IconButton } from "./components/Button";
|
|
|
4
4
|
export { Tabs } from "./components/Tabs";
|
|
5
5
|
export { Menu } from "./components/Menu";
|
|
6
6
|
export { TopBar, type LinkComponent, type TopBarSection } from "./components/TopBar";
|
|
7
|
+
export { Graph, neighbours, type GraphNode, type GraphEdge, type GraphSelection, type GraphRow } from "./components/Graph";
|
|
7
8
|
export { Modal, ToastProvider, useToast, Avatar, Switch, Empty, Loading, useOutside, type ToastSpec } from "./components/ui";
|
|
8
9
|
export { UIKIT_NS } from "./i18n";
|
package/dist/index.js
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, r as c, s as l, t as u, u as d } from "./ui-BrAaLui6.js";
|
|
2
2
|
import { n as f, t as p } from "./i18n-BJ8rsBp6.js";
|
|
3
|
-
import {
|
|
4
|
-
import { useCallback as
|
|
3
|
+
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
4
|
+
import { useCallback as _, useEffect as v, useId as y, useMemo as b, useRef as x, useState as S } from "react";
|
|
5
|
+
import { forceCenter as C, forceCollide as w, forceLink as T, forceManyBody as E, forceSimulation as D } from "d3-force";
|
|
5
6
|
//#region src/components/Button.tsx
|
|
6
|
-
function
|
|
7
|
+
function O({ variant: e, size: t, className: n, type: r = "button", ...i }) {
|
|
7
8
|
let a = [
|
|
8
9
|
"btn",
|
|
9
10
|
e,
|
|
10
11
|
t,
|
|
11
12
|
n
|
|
12
13
|
].filter(Boolean).join(" ");
|
|
13
|
-
return /* @__PURE__ */
|
|
14
|
+
return /* @__PURE__ */ h("button", {
|
|
14
15
|
type: r,
|
|
15
16
|
className: a,
|
|
16
17
|
...i
|
|
17
18
|
});
|
|
18
19
|
}
|
|
19
|
-
function
|
|
20
|
+
function k({ label: e, fill: t, on: n, className: r, type: i = "button", ...a }) {
|
|
20
21
|
let o = [
|
|
21
22
|
"iconbtn",
|
|
22
23
|
t && "fill",
|
|
23
24
|
n && "on",
|
|
24
25
|
r
|
|
25
26
|
].filter(Boolean).join(" ");
|
|
26
|
-
return /* @__PURE__ */
|
|
27
|
+
return /* @__PURE__ */ h("button", {
|
|
27
28
|
type: i,
|
|
28
29
|
className: o,
|
|
29
30
|
"aria-label": e,
|
|
@@ -32,12 +33,12 @@ function b({ label: e, fill: t, on: n, className: r, type: i = "button", ...a })
|
|
|
32
33
|
}
|
|
33
34
|
//#endregion
|
|
34
35
|
//#region src/components/Menu.tsx
|
|
35
|
-
function
|
|
36
|
+
function A({ onClose: e, label: t, className: n, children: r }) {
|
|
36
37
|
let i = l(!0, e);
|
|
37
|
-
return
|
|
38
|
+
return v(() => {
|
|
38
39
|
let e = document.activeElement;
|
|
39
40
|
return () => e?.focus?.();
|
|
40
|
-
}, []), /* @__PURE__ */
|
|
41
|
+
}, []), /* @__PURE__ */ h("div", {
|
|
41
42
|
className: `menu${n ? ` ${n}` : ""}`,
|
|
42
43
|
role: "dialog",
|
|
43
44
|
"aria-label": t,
|
|
@@ -47,65 +48,65 @@ function x({ onClose: e, label: t, className: n, children: r }) {
|
|
|
47
48
|
}
|
|
48
49
|
//#endregion
|
|
49
50
|
//#region src/components/TopBar.tsx
|
|
50
|
-
function
|
|
51
|
-
let p = f(), [
|
|
51
|
+
function j({ logo: e, name: t, home: n = "/", sections: i, Link: a, center: o, actions: s, avatar: c, profileMenu: u, menu: d }) {
|
|
52
|
+
let p = f(), [m, v] = S(!1), [y, b] = S(!1), x = _(() => b(!1), []), C = _(() => v(!1), []), w = l(y, x), T = i.map((e) => /* @__PURE__ */ h(a, {
|
|
52
53
|
href: e.href,
|
|
53
54
|
className: e.active ? "on" : void 0,
|
|
54
55
|
"aria-current": e.active ? "page" : void 0,
|
|
55
|
-
onClick:
|
|
56
|
+
onClick: x,
|
|
56
57
|
children: e.label
|
|
57
58
|
}, e.key));
|
|
58
|
-
return /* @__PURE__ */
|
|
59
|
+
return /* @__PURE__ */ g("div", {
|
|
59
60
|
className: "topbar",
|
|
60
61
|
children: [
|
|
61
|
-
/* @__PURE__ */
|
|
62
|
+
/* @__PURE__ */ g(a, {
|
|
62
63
|
href: n,
|
|
63
64
|
className: "brand",
|
|
64
|
-
children: [/* @__PURE__ */
|
|
65
|
+
children: [/* @__PURE__ */ h("img", {
|
|
65
66
|
src: e,
|
|
66
67
|
alt: ""
|
|
67
|
-
}), /* @__PURE__ */
|
|
68
|
+
}), /* @__PURE__ */ h("span", {
|
|
68
69
|
className: "hide-m",
|
|
69
70
|
children: t
|
|
70
71
|
})]
|
|
71
72
|
}),
|
|
72
|
-
/* @__PURE__ */
|
|
73
|
+
/* @__PURE__ */ h("nav", {
|
|
73
74
|
className: "nav hide-m",
|
|
74
75
|
"aria-label": p("topbar.sections"),
|
|
75
76
|
children: T
|
|
76
77
|
}),
|
|
77
78
|
o,
|
|
78
|
-
/* @__PURE__ */
|
|
79
|
+
/* @__PURE__ */ g("div", {
|
|
79
80
|
className: "top-actions",
|
|
80
81
|
children: [
|
|
81
82
|
s,
|
|
82
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ h("button", {
|
|
83
84
|
className: "avatar",
|
|
84
|
-
style:
|
|
85
|
+
style: m ? { boxShadow: "0 0 0 2px var(--violet)" } : void 0,
|
|
85
86
|
onClick: () => {
|
|
86
|
-
|
|
87
|
+
b(!1), v((e) => !e);
|
|
87
88
|
},
|
|
88
89
|
"aria-label": p("topbar.profile"),
|
|
89
|
-
"aria-expanded":
|
|
90
|
+
"aria-expanded": m,
|
|
90
91
|
children: c
|
|
91
92
|
}),
|
|
92
|
-
/* @__PURE__ */
|
|
93
|
+
/* @__PURE__ */ g("div", {
|
|
93
94
|
className: "burger",
|
|
94
95
|
ref: w,
|
|
95
|
-
children: [/* @__PURE__ */
|
|
96
|
-
className: `iconbtn${
|
|
96
|
+
children: [/* @__PURE__ */ h("button", {
|
|
97
|
+
className: `iconbtn${y ? " on" : ""}`,
|
|
97
98
|
onClick: () => {
|
|
98
|
-
|
|
99
|
+
v(!1), b((e) => !e);
|
|
99
100
|
},
|
|
100
101
|
"aria-label": d?.label ?? p("topbar.sections"),
|
|
101
|
-
"aria-expanded":
|
|
102
|
+
"aria-expanded": y,
|
|
102
103
|
"aria-controls": "nav-sections",
|
|
103
|
-
children: /* @__PURE__ */
|
|
104
|
-
}),
|
|
104
|
+
children: /* @__PURE__ */ h(r, { name: y ? "x" : "menu" })
|
|
105
|
+
}), y && (d ? /* @__PURE__ */ h("div", {
|
|
105
106
|
id: "nav-sections",
|
|
106
107
|
className: "navmenu",
|
|
107
|
-
children: d.render(
|
|
108
|
-
}) : /* @__PURE__ */
|
|
108
|
+
children: d.render(x)
|
|
109
|
+
}) : /* @__PURE__ */ h("nav", {
|
|
109
110
|
id: "nav-sections",
|
|
110
111
|
className: "navmenu",
|
|
111
112
|
"aria-label": p("topbar.sections"),
|
|
@@ -114,11 +115,359 @@ function S({ logo: e, name: t, home: n = "/", sections: i, Link: a, center: o, a
|
|
|
114
115
|
})
|
|
115
116
|
]
|
|
116
117
|
}),
|
|
117
|
-
|
|
118
|
+
m && u(C)
|
|
118
119
|
]
|
|
119
120
|
});
|
|
120
121
|
}
|
|
121
122
|
//#endregion
|
|
122
|
-
|
|
123
|
+
//#region src/components/Graph.tsx
|
|
124
|
+
var M = 760, N = 500, P = (e = 1) => 7 + Math.sqrt(e) * 3.2, F = (e, t, n) => {
|
|
125
|
+
let r = Math.max(.5, Math.min(4, e.k * t));
|
|
126
|
+
return {
|
|
127
|
+
k: r,
|
|
128
|
+
x: n.w / 2 - (n.w / 2 - e.x) / e.k * r,
|
|
129
|
+
y: n.h / 2 - (n.h / 2 - e.y) / e.k * r
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
function I(e, t, n) {
|
|
133
|
+
let r = /* @__PURE__ */ new Set([t]), i = [t];
|
|
134
|
+
for (let t = 0; t < n; t++) {
|
|
135
|
+
let t = [];
|
|
136
|
+
for (let n of i) for (let i of e) {
|
|
137
|
+
let e = i.source === n ? i.target : i.target === n ? i.source : null;
|
|
138
|
+
e && !r.has(e) && (r.add(e), t.push(e));
|
|
139
|
+
}
|
|
140
|
+
i = t;
|
|
141
|
+
}
|
|
142
|
+
return r;
|
|
143
|
+
}
|
|
144
|
+
function L(e, t) {
|
|
145
|
+
let n = e.map((e) => ({
|
|
146
|
+
...e,
|
|
147
|
+
r: P(e.size)
|
|
148
|
+
})), r = new Set(n.map((e) => e.id)), i = t.filter((e) => r.has(e.source) && r.has(e.target)).map((e) => ({
|
|
149
|
+
source: e.source,
|
|
150
|
+
target: e.target,
|
|
151
|
+
weight: e.weight ?? 1
|
|
152
|
+
})), a = D(n).force("link", T(i).id((e) => e.id).distance(90).strength((e) => Math.min(1, .2 + e.weight * .08))).force("charge", E().strength(-260)).force("center", C(M / 2, N / 2)).force("collide", w().radius((e) => e.r + 14)).stop();
|
|
153
|
+
for (let e = 0; e < 260; e++) a.tick();
|
|
154
|
+
for (let e of n) e.x = Math.max(e.r + 30, Math.min(M - e.r - 30, e.x ?? M / 2)), e.y = Math.max(e.r + 10, Math.min(N - e.r - 24, e.y ?? N / 2));
|
|
155
|
+
return n;
|
|
156
|
+
}
|
|
157
|
+
var R = 130, z = 104, B = 76;
|
|
158
|
+
function V(e, t) {
|
|
159
|
+
let n = new Map(t.map((e, t) => [e.id, t])), r = /* @__PURE__ */ new Map(), i = e.map((e) => ({
|
|
160
|
+
...e,
|
|
161
|
+
r: P(e.size)
|
|
162
|
+
}));
|
|
163
|
+
for (let e of i) {
|
|
164
|
+
let i = n.get(e.row ?? "") ?? t.length;
|
|
165
|
+
r.set(i, [...r.get(i) ?? [], e]);
|
|
166
|
+
}
|
|
167
|
+
let a = [...r.keys()].toSorted((e, t) => e - t), o = R + Math.max(1, ...a.map((e) => r.get(e).length)) * z, s = a.length * B, c = {
|
|
168
|
+
w: Math.max(M, o + 40),
|
|
169
|
+
h: Math.max(N, s + 40)
|
|
170
|
+
}, l = (c.w - o) / 2, u = (c.h - s) / 2;
|
|
171
|
+
return {
|
|
172
|
+
placed: i,
|
|
173
|
+
field: c,
|
|
174
|
+
rows: a.map((e, n) => {
|
|
175
|
+
let i = u + B * (n + .5) - 8;
|
|
176
|
+
return r.get(e).toSorted((e, t) => (e.order ?? Infinity) - (t.order ?? Infinity) || (e.id < t.id ? -1 : +(e.id > t.id))).forEach((e, t) => {
|
|
177
|
+
e.x = l + R + z * (t + .5), e.y = i;
|
|
178
|
+
}), {
|
|
179
|
+
id: t[e]?.id ?? "",
|
|
180
|
+
label: t[e]?.label ?? "",
|
|
181
|
+
y: i,
|
|
182
|
+
x: l + 8,
|
|
183
|
+
x2: l + o
|
|
184
|
+
};
|
|
185
|
+
})
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function H(e, t, n, r) {
|
|
189
|
+
let i = e.x ?? 0, a = e.y ?? 0, o = t.x ?? 0, s = t.y ?? 0, c = o, l = s, u = r && Math.abs(l - a) < 1 && i !== c, d = (i + c) / 2, f = a - Math.sign(c - i) * Math.min(B * .8, 14 + Math.abs(c - i) * .25);
|
|
190
|
+
if (n) {
|
|
191
|
+
let e = u ? d : i, n = u ? f : a, r = c - e, o = l - n, s = Math.hypot(r, o) || 1;
|
|
192
|
+
c -= r / s * (t.r + 2), l -= o / s * (t.r + 2);
|
|
193
|
+
}
|
|
194
|
+
return u ? {
|
|
195
|
+
d: `M${i},${a} Q${d},${f} ${c},${l}`,
|
|
196
|
+
hit: `M${i},${a} Q${d},${f} ${o},${s}`,
|
|
197
|
+
x1: i,
|
|
198
|
+
y1: a,
|
|
199
|
+
x2: c,
|
|
200
|
+
y2: l
|
|
201
|
+
} : {
|
|
202
|
+
x1: i,
|
|
203
|
+
y1: a,
|
|
204
|
+
x2: c,
|
|
205
|
+
y2: l
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function U({ nodes: e, edges: t, ariaLabel: n, selected: i, onSelect: a, focus: o, depth: s = 1, onOpen: c, legend: l, nodeLabel: u, rows: d, draggable: p }) {
|
|
209
|
+
let _ = f(), C = `g-arrow-${y().replace(/:/g, "")}`, [w, T] = S(null), [E, D] = S({
|
|
210
|
+
k: 1,
|
|
211
|
+
x: 0,
|
|
212
|
+
y: 0
|
|
213
|
+
}), O = x(null), k = x(null), A = x(-Infinity), j = x(null), P = d ? void 0 : t, R = b(() => d ? V(e, d) : {
|
|
214
|
+
placed: L(e, P ?? []),
|
|
215
|
+
field: {
|
|
216
|
+
w: M,
|
|
217
|
+
h: N
|
|
218
|
+
}
|
|
219
|
+
}, [
|
|
220
|
+
e,
|
|
221
|
+
P,
|
|
222
|
+
d
|
|
223
|
+
]), { field: z } = R, [U, W] = S(null), G = U?.of === R ? U.at : void 0, { placed: K, byId: q } = b(() => {
|
|
224
|
+
let e = G ? R.placed.map((e) => G.has(e.id) ? {
|
|
225
|
+
...e,
|
|
226
|
+
...G.get(e.id)
|
|
227
|
+
} : e) : R.placed;
|
|
228
|
+
return {
|
|
229
|
+
placed: e,
|
|
230
|
+
byId: new Map(e.map((e) => [e.id, e]))
|
|
231
|
+
};
|
|
232
|
+
}, [R, G]), J = o !== void 0 && q.has(o) ? o : void 0, Y = w ?? (i?.kind === "node" ? i.id : null), X = b(() => i?.kind === "edge" && !w ? /* @__PURE__ */ new Set([i.source, i.target]) : Y ? I(t, Y, 1) : J ? I(t, J, s) : /* @__PURE__ */ new Set(), [
|
|
233
|
+
Y,
|
|
234
|
+
i,
|
|
235
|
+
w,
|
|
236
|
+
J,
|
|
237
|
+
s,
|
|
238
|
+
t
|
|
239
|
+
]), ee = X.size > 0, te = (e) => i?.kind === "edge" && !w ? i.source === e.source && i.target === e.target : Y ? e.source === Y || e.target === Y : J !== void 0 && X.has(e.source) && X.has(e.target), Z = (e) => D((t) => F(t, e, z)), Q = (e, t) => a(t ? null : {
|
|
240
|
+
kind: "node",
|
|
241
|
+
id: e
|
|
242
|
+
}), $ = (e) => {
|
|
243
|
+
let t = e.getBoundingClientRect();
|
|
244
|
+
return 1 / (Math.min(t.width / z.w, t.height / z.h) || 1);
|
|
245
|
+
};
|
|
246
|
+
return v(() => {
|
|
247
|
+
let e = j.current;
|
|
248
|
+
if (!e) return;
|
|
249
|
+
let t = (e) => {
|
|
250
|
+
e.preventDefault(), D((t) => F(t, e.deltaY < 0 ? 1.15 : 1 / 1.15, z));
|
|
251
|
+
};
|
|
252
|
+
return e.addEventListener("wheel", t, { passive: !1 }), () => e.removeEventListener("wheel", t);
|
|
253
|
+
}, [z]), /* @__PURE__ */ g("div", {
|
|
254
|
+
className: "gwrap",
|
|
255
|
+
children: [
|
|
256
|
+
/* @__PURE__ */ g("svg", {
|
|
257
|
+
ref: j,
|
|
258
|
+
viewBox: `0 0 ${z.w} ${z.h}`,
|
|
259
|
+
role: "group",
|
|
260
|
+
"aria-label": n,
|
|
261
|
+
className: ee ? "dimmed" : void 0,
|
|
262
|
+
onPointerDown: (e) => {
|
|
263
|
+
e.target === e.currentTarget && (O.current = {
|
|
264
|
+
x: e.clientX,
|
|
265
|
+
y: e.clientY,
|
|
266
|
+
moved: !1
|
|
267
|
+
}, e.currentTarget.setPointerCapture(e.pointerId));
|
|
268
|
+
},
|
|
269
|
+
onPointerMove: (e) => {
|
|
270
|
+
if (!O.current) return;
|
|
271
|
+
let t = $(e.currentTarget), n = (e.clientX - O.current.x) * t, r = (e.clientY - O.current.y) * t;
|
|
272
|
+
O.current = {
|
|
273
|
+
x: e.clientX,
|
|
274
|
+
y: e.clientY,
|
|
275
|
+
moved: O.current.moved || n !== 0 || r !== 0
|
|
276
|
+
}, D((e) => ({
|
|
277
|
+
...e,
|
|
278
|
+
x: e.x + n,
|
|
279
|
+
y: e.y + r
|
|
280
|
+
}));
|
|
281
|
+
},
|
|
282
|
+
onPointerUp: () => {
|
|
283
|
+
O.current?.moved || (O.current = null);
|
|
284
|
+
},
|
|
285
|
+
onClick: (e) => {
|
|
286
|
+
let t = O.current?.moved;
|
|
287
|
+
O.current = null, !t && e.target === e.currentTarget && a(null);
|
|
288
|
+
},
|
|
289
|
+
children: [t.some((e) => e.directed) && /* @__PURE__ */ h("defs", { children: /* @__PURE__ */ h("marker", {
|
|
290
|
+
id: C,
|
|
291
|
+
viewBox: "0 0 10 10",
|
|
292
|
+
refX: "10",
|
|
293
|
+
refY: "5",
|
|
294
|
+
markerWidth: "7",
|
|
295
|
+
markerHeight: "7",
|
|
296
|
+
orient: "auto-start-reverse",
|
|
297
|
+
children: /* @__PURE__ */ h("path", { d: "M0,0 L10,5 L0,10 z" })
|
|
298
|
+
}) }), /* @__PURE__ */ g("g", {
|
|
299
|
+
transform: `translate(${E.x} ${E.y}) scale(${E.k})`,
|
|
300
|
+
children: [
|
|
301
|
+
R.rows?.map((e, t) => /* @__PURE__ */ g("g", {
|
|
302
|
+
className: "g-row",
|
|
303
|
+
children: [t > 0 && /* @__PURE__ */ h("line", {
|
|
304
|
+
x1: e.x,
|
|
305
|
+
x2: e.x2,
|
|
306
|
+
y1: e.y - B / 2 + 8,
|
|
307
|
+
y2: e.y - B / 2 + 8
|
|
308
|
+
}), /* @__PURE__ */ h("text", {
|
|
309
|
+
x: e.x,
|
|
310
|
+
y: e.y,
|
|
311
|
+
children: e.label
|
|
312
|
+
})]
|
|
313
|
+
}, `${e.id}\u0000${t}`)),
|
|
314
|
+
t.map((e, t) => {
|
|
315
|
+
let n = q.get(e.source), r = q.get(e.target);
|
|
316
|
+
if (!n || !r) return null;
|
|
317
|
+
let i = H(n, r, !!e.directed, !!d), o = e.directed ? `url(#${C})` : void 0;
|
|
318
|
+
return /* @__PURE__ */ g("g", {
|
|
319
|
+
className: `g-e${e.dashed ? " dashed" : ""}${te(e) ? " hl" : ""}`,
|
|
320
|
+
onClick: () => a({
|
|
321
|
+
kind: "edge",
|
|
322
|
+
source: e.source,
|
|
323
|
+
target: e.target
|
|
324
|
+
}),
|
|
325
|
+
children: [i.d ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("path", {
|
|
326
|
+
d: i.d,
|
|
327
|
+
strokeWidth: 1 + (e.weight ?? 1) * .5,
|
|
328
|
+
markerEnd: o
|
|
329
|
+
}), /* @__PURE__ */ h("path", {
|
|
330
|
+
className: "hit",
|
|
331
|
+
d: i.hit
|
|
332
|
+
})] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("line", {
|
|
333
|
+
x1: i.x1,
|
|
334
|
+
y1: i.y1,
|
|
335
|
+
x2: i.x2,
|
|
336
|
+
y2: i.y2,
|
|
337
|
+
strokeWidth: 1 + (e.weight ?? 1) * .5,
|
|
338
|
+
markerEnd: o
|
|
339
|
+
}), /* @__PURE__ */ h("line", {
|
|
340
|
+
className: "hit",
|
|
341
|
+
x1: n.x,
|
|
342
|
+
y1: n.y,
|
|
343
|
+
x2: r.x,
|
|
344
|
+
y2: r.y
|
|
345
|
+
})] }), e.title && /* @__PURE__ */ h("title", { children: e.title })]
|
|
346
|
+
}, `${e.source}\u0000${e.target}\u0000${t}`);
|
|
347
|
+
}),
|
|
348
|
+
K.map((e) => {
|
|
349
|
+
let t = i?.kind === "node" && i.id === e.id, n = [
|
|
350
|
+
"g-n",
|
|
351
|
+
`g-c${e.group ?? 1}`,
|
|
352
|
+
e.hideLabel && "small",
|
|
353
|
+
e.dashed && "dashed",
|
|
354
|
+
e.muted && "muted",
|
|
355
|
+
X.has(e.id) && "hl",
|
|
356
|
+
t && "pin",
|
|
357
|
+
J === e.id && "focus"
|
|
358
|
+
].filter(Boolean).join(" ");
|
|
359
|
+
return /* @__PURE__ */ g("g", {
|
|
360
|
+
className: n,
|
|
361
|
+
tabIndex: 0,
|
|
362
|
+
role: "button",
|
|
363
|
+
"aria-pressed": t,
|
|
364
|
+
"aria-label": u ? u(e) : e.label,
|
|
365
|
+
onMouseEnter: () => T(e.id),
|
|
366
|
+
onMouseLeave: () => T(null),
|
|
367
|
+
onFocus: () => T(e.id),
|
|
368
|
+
onBlur: () => T(null),
|
|
369
|
+
onPointerDown: p ? (t) => {
|
|
370
|
+
t.button === 0 && (k.current = {
|
|
371
|
+
id: e.id,
|
|
372
|
+
x: t.clientX,
|
|
373
|
+
y: t.clientY,
|
|
374
|
+
moved: !1
|
|
375
|
+
}, t.currentTarget.setPointerCapture(t.pointerId));
|
|
376
|
+
} : void 0,
|
|
377
|
+
onPointerMove: p ? (t) => {
|
|
378
|
+
let n = k.current;
|
|
379
|
+
if (!n || n.id !== e.id || !n.moved && Math.hypot(t.clientX - n.x, t.clientY - n.y) < 4) return;
|
|
380
|
+
let r = j.current ? $(j.current) / E.k : 1, i = (t.clientX - n.x) * r, a = (t.clientY - n.y) * r;
|
|
381
|
+
k.current = {
|
|
382
|
+
id: e.id,
|
|
383
|
+
x: t.clientX,
|
|
384
|
+
y: t.clientY,
|
|
385
|
+
moved: !0
|
|
386
|
+
}, W((t) => {
|
|
387
|
+
let n = new Map(t?.of === R ? t.at : []), r = n.get(e.id) ?? {
|
|
388
|
+
x: e.x ?? 0,
|
|
389
|
+
y: e.y ?? 0
|
|
390
|
+
};
|
|
391
|
+
return n.set(e.id, {
|
|
392
|
+
x: r.x + i,
|
|
393
|
+
y: r.y + a
|
|
394
|
+
}), {
|
|
395
|
+
of: R,
|
|
396
|
+
at: n
|
|
397
|
+
};
|
|
398
|
+
});
|
|
399
|
+
} : void 0,
|
|
400
|
+
onPointerUp: p ? (e) => {
|
|
401
|
+
k.current?.moved && (A.current = e.timeStamp, setTimeout(() => {
|
|
402
|
+
k.current = null;
|
|
403
|
+
}, 0));
|
|
404
|
+
} : void 0,
|
|
405
|
+
onPointerCancel: p ? () => {
|
|
406
|
+
k.current = null;
|
|
407
|
+
} : void 0,
|
|
408
|
+
onClick: () => {
|
|
409
|
+
let n = k.current?.moved;
|
|
410
|
+
k.current = null, n || Q(e.id, t);
|
|
411
|
+
},
|
|
412
|
+
onDoubleClick: (t) => {
|
|
413
|
+
t.timeStamp - A.current > 600 && c?.(e.id);
|
|
414
|
+
},
|
|
415
|
+
onKeyDown: (n) => {
|
|
416
|
+
n.key === "Enter" && c ? (n.preventDefault(), c(e.id)) : (n.key === "Enter" || n.key === " ") && (n.preventDefault(), Q(e.id, t));
|
|
417
|
+
},
|
|
418
|
+
children: [
|
|
419
|
+
/* @__PURE__ */ h("circle", {
|
|
420
|
+
cx: e.x,
|
|
421
|
+
cy: e.y,
|
|
422
|
+
r: e.r
|
|
423
|
+
}),
|
|
424
|
+
/* @__PURE__ */ h("text", {
|
|
425
|
+
x: e.x,
|
|
426
|
+
y: (e.y ?? 0) + e.r + 14,
|
|
427
|
+
children: e.label
|
|
428
|
+
}),
|
|
429
|
+
e.title && /* @__PURE__ */ h("title", { children: e.title })
|
|
430
|
+
]
|
|
431
|
+
}, e.id);
|
|
432
|
+
})
|
|
433
|
+
]
|
|
434
|
+
})]
|
|
435
|
+
}),
|
|
436
|
+
l && l.length > 0 && /* @__PURE__ */ h("div", {
|
|
437
|
+
className: "gleg",
|
|
438
|
+
children: l.map((e) => /* @__PURE__ */ g("span", { children: [/* @__PURE__ */ h("i", { className: `g-c${e.group}` }), e.label] }, e.group))
|
|
439
|
+
}),
|
|
440
|
+
/* @__PURE__ */ g("div", {
|
|
441
|
+
className: "gzoom",
|
|
442
|
+
children: [
|
|
443
|
+
/* @__PURE__ */ h("button", {
|
|
444
|
+
type: "button",
|
|
445
|
+
onClick: () => Z(1.3),
|
|
446
|
+
"aria-label": _("graph.zoomIn"),
|
|
447
|
+
children: "+"
|
|
448
|
+
}),
|
|
449
|
+
/* @__PURE__ */ h("button", {
|
|
450
|
+
type: "button",
|
|
451
|
+
onClick: () => Z(1 / 1.3),
|
|
452
|
+
"aria-label": _("graph.zoomOut"),
|
|
453
|
+
children: "−"
|
|
454
|
+
}),
|
|
455
|
+
G && G.size > 0 && /* @__PURE__ */ h("button", {
|
|
456
|
+
type: "button",
|
|
457
|
+
onClick: () => W(null),
|
|
458
|
+
"aria-label": _("graph.resetLayout"),
|
|
459
|
+
title: _("graph.resetLayout"),
|
|
460
|
+
children: /* @__PURE__ */ h(r, {
|
|
461
|
+
name: "reset",
|
|
462
|
+
size: 14
|
|
463
|
+
})
|
|
464
|
+
})
|
|
465
|
+
]
|
|
466
|
+
})
|
|
467
|
+
]
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
//#endregion
|
|
471
|
+
export { u as Avatar, O as Button, o as Empty, n as GitHubIcon, U as Graph, r as Icon, k as IconButton, c as Loading, d as Markdown, A as Menu, i as Modal, e as Switch, a as Tabs, s as ToastProvider, j as TopBar, p as UIKIT_NS, I as neighbours, l as useOutside, t as useToast };
|
|
123
472
|
|
|
124
473
|
//# sourceMappingURL=index.js.map
|