@weasel-js/diagram 1.10.1 → 1.11.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/README.md +1160 -26
- package/dist/chunk-43LDZ6L4.js +2053 -0
- package/dist/chunk-43LDZ6L4.js.map +1 -0
- package/dist/chunk-CI3I3I6T.js +3600 -0
- package/dist/chunk-CI3I3I6T.js.map +1 -0
- package/dist/chunk-IM6DHWZO.js +3220 -0
- package/dist/chunk-IM6DHWZO.js.map +1 -0
- package/dist/chunk-QKSWZEJH.js +312 -0
- package/dist/chunk-QKSWZEJH.js.map +1 -0
- package/dist/chunk-T6DQT553.js +1431 -0
- package/dist/chunk-T6DQT553.js.map +1 -0
- package/dist/chunk-WDIE35AK.js +3 -0
- package/dist/chunk-WDIE35AK.js.map +1 -0
- package/dist/dataTypes-B-iEwKZp.d.ts +553 -0
- package/dist/effect-audio.d.ts +138 -0
- package/dist/effect-audio.js +527 -0
- package/dist/effect-audio.js.map +1 -0
- package/dist/effect.d.ts +782 -0
- package/dist/effect.js +2542 -0
- package/dist/effect.js.map +1 -0
- package/dist/icons.table.d.ts +6 -0
- package/dist/icons.table.js +32 -0
- package/dist/icons.table.js.map +1 -0
- package/dist/icons.table.json +24 -0
- package/dist/index.d.ts +2270 -355
- package/dist/index.js +953 -1331
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +3 -2
- package/dist/layout.entry-CH9gc0CY.d.ts +512 -0
- package/dist/layout.js +3 -1
- package/dist/stageTypes-DvnR8cKQ.d.ts +189 -0
- package/dist/{layout.entry-BUkiRKuX.d.ts → types-BbHunLXm.d.ts} +382 -261
- package/package.json +32 -7
- package/dist/chunk-JZ4CVLAB.js +0 -1247
- package/dist/chunk-JZ4CVLAB.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,57 +1,144 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { g as Port, h as DiagramNodeLike, i as DiagramNodeReader, O as Outline, a as Row, M as MeasureRowText, C as ContainerRole, j as DiagramContainer, k as ContainerHeader, c as DiagramLabel, l as LabelSpot, E as EdgeHop, R as RowTextStyle, m as Bounds$2, e as LayoutOptions, n as LayoutResult, G as Graph, d as LayoutFn, o as GraphSource, p as LayoutPlanner, q as LayoutDirection, L as LayoutPorts, r as LayoutPlan, s as GraphNodeLike, S as StyleField, F as FontField } from './types-BbHunLXm.js';
|
|
2
|
+
export { t as BodyFloor, u as BodyNodeSpec, B as BodySpec, v as BuildBodyOptions, w as BuildGraphOptions, x as DEFAULT_GROUP_INSET, y as DEFAULT_HOP_SIZE, z as DEFAULT_NODE_GAP, A as DEFAULT_RANK_GAP, H as DIAGRAM_TRAIT_KEY, D as DiagramGroup, f as DiagramNode, I as DiagramNodeEntry, J as EdgeLabelRoom, K as GraphEdge, N as GraphGroup, Q as GraphNode, T as GroupInset, U as HOPS_DOC_KEY, V as HopsDocValue, W as LABEL_PLACEMENT, X as LayoutAxes, Y as PORT_LABEL_GAP, Z as PerimeterPortLabelBox, P as PortAnchor, _ as PortLabelPlacement, $ as PortSite, b as PortSpec, a0 as RowBox, a1 as RowNodeData, a2 as RowPort, a3 as RowPortBox, a4 as Slot, a5 as anchorOffset, a6 as axesFor, a7 as bodyBox, a8 as bodyOutline, a9 as bodyTrait, aa as boxForContent, ab as buildBody, ac as buildGraph, ad as canvasMeasure, ae as contentBox, af as createDiagramNodes, ag as dataKeyReader, ah as diagramContainerOf, ai as diagramLabelOf, aj as diagramNodeOf, ak as expandGroupEdges, al as graphOrder, am as headerBox, an as insetOf, ao as isPinned, ap as layoutBody, aq as layoutRowPorts, ar as marginOf, as as measureBody, at as outlinePath, au as packAcross, av as packClusters, aw as pinnedSet, ax as planOf, ay as plannerPlan, az as portLabelBox, aA as portLabelsOf, aB as rankGaps, aC as seededOrder, aD as settle, aE as sizeToBody, aF as titleIdOf, aG as translated, aH as untilSettled } from './types-BbHunLXm.js';
|
|
3
|
+
import { P as PortsOptions, A as AvoidInput, a as AvoidRouter, b as AvoidOptions, c as AvoidRoutes, d as PlaceLabelsOptions, F as ForceOptions } from './layout.entry-CH9gc0CY.js';
|
|
4
|
+
export { e as AVOID_DEFAULTS, f as AvoidEdge, g as AvoidEnd, h as AvoidLabel, i as AvoidObstacle, j as AvoidPort, k as AvoidUpdateOptions, C as COMPASS, D as DEFAULT_PORTS, l as ForceBody, m as ForceRelaxation, n as Forest, L as LabelPlacements, o as LayeredPlan, p as PlaceLabel, q as PlaceLabelsInput, r as PlaceRoute, s as backEdges, t as chain, u as createAvoidRouter, v as edgeHops, w as footprintNode, x as force, y as forceRelaxation, z as forestOf, B as labelCenter, E as layered, G as layeredPlan, H as outlinePolyline, I as placeLabels, J as portOf, K as portSitesOf, M as portsOf, N as portsOnOutline, O as ranksByLength, Q as ranksOf, R as rayHit, S as routeHolds, T as tree } from './layout.entry-CH9gc0CY.js';
|
|
5
|
+
import { Vec2, ActionDeps, Action, InvocationCtx, TargetPredicate, GestureBinding, Contribution, DerivedDep, Path, SceneRegistry, paintsLayer, PoseDescriptor, ChromeState, CommandFill, CommandStroke, CursorSpec, Affordance, Stroke, Tool, Op, AddNodeSpec, RectPose, NodeId, Scene, LayoutStrategy, ContainerBounds, RenderLayer, TransformFollower, PlacedPage, Bounds as Bounds$3, GatedLayer, Fill, NodeShapeEntry, Paint, View, SelectionApi } from '@weasel-js/core';
|
|
6
|
+
import { Vec2 as Vec2$1, Path as Path$2 } from '@weasel-js/core/math';
|
|
7
|
+
import { c as DataEdge, a as DiagramData, b as DiagramSceneOptions, f as DiagramSpec, g as EdgeEnd, N as NodeStyle, h as DiagramSceneData, i as DiagramEdge, O as OffPageSplit, D as DiagramTheme, j as DataContainer, E as EdgeStyle, d as DataNode } from './dataTypes-B-iEwKZp.js';
|
|
8
|
+
export { A as ANCHOR_DERIVE_POSE, k as DEFAULT_LANE_SIZE, l as DEFAULT_POOL_ACROSS, m as DIAGRAM_ANCHOR, n as DIAGRAM_GROUP, o as DIAGRAM_ROLES, p as DIAGRAM_THEME_KEY, q as DataGroup, r as DataLane, s as DataMark, t as DiagramAnchor, u as DiagramDerivePose, v as DiagramFont, w as DiagramMark, x as DiagramRole, e as DiagramRouter, y as DiagramTextStyle, z as EDGE_STROKE_WIDTH, G as GROUP_DERIVE_POSE, B as GroupPoseOptions, L as LANE_STROKE_WIDTH, C as NODE_STROKE_WIDTH, F as OffPageTag, H as anchorDerivePose, I as boxAround, J as diagramAnchorOf, K as diagramEdgeOf, M as diagramGroupOf, P as diagramMarkOf, Q as groupDerivePose, R as layoutOwnsPort, S as layoutOwnsRoute, T as layoutWritesRoute, U as markShape, V as offPageTagId, W as offPageTagOf, X as registerMarkShape, Y as rowTextStyle } from './dataTypes-B-iEwKZp.js';
|
|
9
|
+
import { IconRef } from '@weasel-js/icons';
|
|
10
|
+
import { Path as Path$1, Placement } from '@weasel-js/geom';
|
|
5
11
|
import { EasingFn } from '@weasel-js/animator';
|
|
6
12
|
import * as react from 'react';
|
|
7
|
-
import '
|
|
13
|
+
import { ReactNode } from 'react';
|
|
8
14
|
import '@weasel-js/simulation';
|
|
9
15
|
|
|
16
|
+
/** The scene node id `diagramScene` gives an edge: its `id` when set, else one
|
|
17
|
+
* built from its ends, ports, and label. Two edges differing in any of those
|
|
18
|
+
* get different ids, an empty port or label included: a `.`, `>`, `:`, `/` or
|
|
19
|
+
* `\` in one of them is escaped with a backslash. */
|
|
20
|
+
declare const edgeIdOf: (e: DataEdge) => string;
|
|
21
|
+
|
|
22
|
+
/** Every spec carries an id — a node's own, `<id>/<k>` for its text,
|
|
23
|
+
* `<id>/mark:<i>` for its marks, `<edge id>/label`, a group's own and
|
|
24
|
+
* `<group id>/label`, a region's own and `<region id>/title` — so a later call's
|
|
25
|
+
* specs can be reconciled against this one's. Throws on a repeated id among
|
|
26
|
+
* nodes, groups, containers and lanes, which names two things as one. An edge whose
|
|
27
|
+
* end is not a node is dropped, and so is a repeat of an earlier edge with
|
|
28
|
+
* the same ends, ports and label: it would draw exactly on top of the first. */
|
|
29
|
+
declare function diagramScene<TLayer extends string>(data: DiagramData, opts: DiagramSceneOptions<TLayer> & {
|
|
30
|
+
layer: TLayer;
|
|
31
|
+
}): DiagramSpec<TLayer>[];
|
|
32
|
+
declare function diagramScene(data: DiagramData, opts?: DiagramSceneOptions): DiagramSpec[];
|
|
33
|
+
|
|
10
34
|
/**
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* `derivePath` that runs a **router**. Being a scene node rather than a
|
|
15
|
-
* plugin-owned render layer buys selection, hit-testing, hover, styling,
|
|
16
|
-
* z-order, SVG export, undo, and copy/paste. The cost is that an edge costs
|
|
17
|
-
* what a node costs — right for tens to hundreds of edges, wrong for a
|
|
18
|
-
* 10k-edge force graph.
|
|
19
|
-
*
|
|
20
|
-
* **Author-dragged waypoints are data on the edge and the router routes
|
|
21
|
-
* through them**, so a moved endpoint still re-routes.
|
|
22
|
-
*
|
|
23
|
-
* Arrowheads are not here. They are stroke markers, the same
|
|
24
|
-
* `markerStart` / `markerEnd` any other stroke carries.
|
|
35
|
+
* The `'slide'` look of a reorder: the carried item under the pointer and the
|
|
36
|
+
* others in the places they would take, published as pose overrides so
|
|
37
|
+
* everything that derives its pose from them follows.
|
|
25
38
|
*/
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
type Box$3 = {
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Reorder: dragging one item of a drawn sequence — boxes in a row, rows in a
|
|
49
|
+
* column, the members of a group — to another place in it. The item follows
|
|
50
|
+
* the pointer along the sequence's axis and lands in the gap nearest its
|
|
51
|
+
* middle. A `'bar'` drag marks that gap with an insertion bar; a `'slide'`
|
|
52
|
+
* drag slides the other items into the places they would take. Either way
|
|
53
|
+
* the release hands the move to a commit, and nothing is written to the scene.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/** The action that drags an item of a sequence to another place in it. */
|
|
57
|
+
declare const REORDER_ACTION_ID = "diagram.reorder";
|
|
58
|
+
/** One item of a sequence, in world units. */
|
|
59
|
+
interface ReorderItem {
|
|
60
|
+
/** The scene node drawn for it. */
|
|
61
|
+
id: string;
|
|
62
|
+
bounds: Box$3;
|
|
63
|
+
/** Where a press picks it up. Default `bounds`; `null` never picks it up, though it keeps its gaps. */
|
|
64
|
+
grip?: Box$3 | null;
|
|
65
|
+
/** The scene nodes that move with it, in either `show` mode. Default `[id]`. */
|
|
66
|
+
carries?: readonly string[];
|
|
33
67
|
}
|
|
34
|
-
/**
|
|
35
|
-
interface
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
68
|
+
/** A place an item can land: before `items[index]`, or after the last at `items.length`. */
|
|
69
|
+
interface ReorderGap {
|
|
70
|
+
index: number;
|
|
71
|
+
/** The insertion bar's two ends. */
|
|
72
|
+
a: Vec2;
|
|
73
|
+
b: Vec2;
|
|
74
|
+
}
|
|
75
|
+
/** A drawn sequence: its items in order along `axis`, and the gaps between them. */
|
|
76
|
+
interface ReorderSlots {
|
|
77
|
+
axis: 'x' | 'y';
|
|
78
|
+
items: readonly ReorderItem[];
|
|
79
|
+
gaps: readonly ReorderGap[];
|
|
80
|
+
}
|
|
81
|
+
/** The item at index `from` dropped in gap `to`, and every item's id in the order that leaves. */
|
|
82
|
+
interface ReorderMove {
|
|
83
|
+
id: string;
|
|
84
|
+
from: number;
|
|
85
|
+
to: number;
|
|
86
|
+
order: readonly string[];
|
|
44
87
|
}
|
|
45
|
-
/**
|
|
46
|
-
|
|
88
|
+
/** Options for {@link createReorderAction}. */
|
|
89
|
+
interface ReorderOptions {
|
|
90
|
+
/** Default {@link REORDER_ACTION_ID}. */
|
|
91
|
+
id?: string;
|
|
92
|
+
/** Default 'Reorder'. */
|
|
93
|
+
label?: string;
|
|
94
|
+
/** The sequence a press at `at` picks from, as drawn now, or `null` when there is none. */
|
|
95
|
+
slots: (deps: ActionDeps, at: Vec2) => ReorderSlots | null;
|
|
96
|
+
/** Deps `slots` reads beyond `scene`. */
|
|
97
|
+
requires?: Action['requires'];
|
|
98
|
+
/**
|
|
99
|
+
* `'bar'` (default) carries the item and draws an insertion bar at its
|
|
100
|
+
* gap. `'slide'` carries everything each item `carries` as pose overrides,
|
|
101
|
+
* so what derives from them follows, and slides the others into place; the
|
|
102
|
+
* overrides stay after a commit until the scene next changes.
|
|
103
|
+
*/
|
|
104
|
+
show?: 'bar' | 'slide';
|
|
105
|
+
/** Whether a drop may land. The bar draws refused, or nothing slides, where not. Default: every drop. */
|
|
106
|
+
canDrop?: (move: ReorderMove) => boolean;
|
|
107
|
+
/** Called once, on release over a gap that is not the item's own and that `canDrop` allows. */
|
|
108
|
+
commit: (move: ReorderMove, ctx: InvocationCtx) => void;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The slots of items laid out in order along `axis`: a gap halfway between
|
|
112
|
+
* each pair, its bar spanning both across the axis, and one beyond each end,
|
|
113
|
+
* as far out as the nearest interior gap's half, or `END_GAP / 2` with none.
|
|
114
|
+
*/
|
|
115
|
+
declare function sequenceSlots(axis: 'x' | 'y', items: readonly ReorderItem[]): ReorderSlots;
|
|
116
|
+
/** The `diagram.reorder` action: an ongoing drag carrying one item of a sequence. */
|
|
117
|
+
declare function createReorderAction(opts: ReorderOptions): Action;
|
|
118
|
+
/** The binding that starts a reorder: a drag pressed on `on`, by default anywhere; the action declines off an item's grip. */
|
|
119
|
+
declare function reorderBinding(actionId?: string, on?: TargetPredicate): GestureBinding;
|
|
120
|
+
/** The reorder action and its binding, to pass as `ambient`. */
|
|
121
|
+
declare function reorderContribution(opts: ReorderOptions & {
|
|
122
|
+
on?: TargetPredicate;
|
|
123
|
+
}): Contribution;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* The routers an edge is drawn with: functions from two resolved ends and the
|
|
127
|
+
* waypoints between them to the points the edge runs through. `edge` resolves
|
|
128
|
+
* the ends and calls one by the key the edge names.
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/** What a router is given: the two resolved ends, the author's waypoints
|
|
132
|
+
* between them, and the route stored on the edge, when it holds one. */
|
|
47
133
|
interface RouteRequest {
|
|
48
134
|
from: Port;
|
|
49
135
|
to: Port;
|
|
50
|
-
waypoints: readonly Vec2[];
|
|
136
|
+
waypoints: readonly Vec2$1[];
|
|
137
|
+
route?: readonly Vec2$1[] | undefined;
|
|
51
138
|
}
|
|
52
139
|
/** A router returns the points the edge runs through, `from.point` first and
|
|
53
140
|
* `to.point` last. */
|
|
54
|
-
type Router = (req: RouteRequest) => readonly Vec2[];
|
|
141
|
+
type Router = (req: RouteRequest) => readonly Vec2$1[];
|
|
55
142
|
/** The straight run between the two ends, through any waypoints. */
|
|
56
143
|
declare const straight: Router;
|
|
57
144
|
/**
|
|
@@ -73,15 +160,36 @@ declare const orthogonal: Router;
|
|
|
73
160
|
* same thing.
|
|
74
161
|
*/
|
|
75
162
|
declare const bezier: Router;
|
|
163
|
+
/**
|
|
164
|
+
* The route the obstacle-avoiding router stored on the edge, while it still
|
|
165
|
+
* fits the ends and passes every waypoint; else `orthogonal` through the stops,
|
|
166
|
+
* so an end moved by something that did not reroute still draws sensibly.
|
|
167
|
+
* The route itself is computed at edit time (`useAvoidRouting`).
|
|
168
|
+
*/
|
|
169
|
+
declare const avoid: Router;
|
|
76
170
|
/** The routers this package ships. A consumer's own go in the same shape. */
|
|
77
171
|
declare const ROUTERS: Readonly<Record<string, Router>>;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* `DiagramEdge` — a connection between two participants.
|
|
175
|
+
*
|
|
176
|
+
* An edge is an ordinary leaf scene node with `dependsOn: [from, to]` and a
|
|
177
|
+
* `derivePath` that runs a **router**. Being a scene node rather than a
|
|
178
|
+
* plugin-owned render layer buys selection, hit-testing, hover, styling,
|
|
179
|
+
* z-order, SVG export, undo, and copy/paste. The cost is that an edge costs
|
|
180
|
+
* what a node costs — right for tens to hundreds of edges, wrong for a
|
|
181
|
+
* 10k-edge force graph.
|
|
182
|
+
*
|
|
183
|
+
* **Author-dragged waypoints are data on the edge and the router routes
|
|
184
|
+
* through them**, so a moved endpoint still re-routes.
|
|
185
|
+
*
|
|
186
|
+
* Arrowheads are not here. They are stroke markers, the same
|
|
187
|
+
* `markerStart` / `markerEnd` any other stroke carries.
|
|
188
|
+
*/
|
|
189
|
+
|
|
82
190
|
/**
|
|
83
|
-
* The port an end resolves to: the one it named,
|
|
84
|
-
*
|
|
191
|
+
* The port an end resolves to: the one it named, at whichever of its places
|
|
192
|
+
* faces `toward` most directly, else the port facing `toward` most directly.
|
|
85
193
|
*
|
|
86
194
|
* "Facing" rather than "nearest": a port on the far side of a wide node can be
|
|
87
195
|
* closer in a straight line than the one pointing at the target.
|
|
@@ -102,12 +210,36 @@ interface EdgeRouteOptions<TPose> extends PortsOptions<TPose> {
|
|
|
102
210
|
* sides {@link selfLoop} picks, and where the author set no waypoints the
|
|
103
211
|
* router is handed that rule's point outside the node as one.
|
|
104
212
|
*
|
|
213
|
+
* An edge carrying `hops` bows over each one that still lies on its route.
|
|
214
|
+
*
|
|
105
215
|
* Returns `null` — nothing to draw — when the node is not an edge, when either
|
|
106
216
|
* dependency is gone, or when an endpoint offers no ports at all.
|
|
107
217
|
*/
|
|
108
218
|
declare function edgeDerivePath<TPose>(opts?: EdgeRouteOptions<TPose>): (node: {
|
|
109
219
|
data: unknown;
|
|
110
220
|
}, deps: readonly (DerivedDep<TPose> | undefined)[]) => Path | null;
|
|
221
|
+
/** An edge's route as {@link edgeDerivePath} draws it, before it becomes a path. */
|
|
222
|
+
interface ResolvedRoute {
|
|
223
|
+
/** The two ends, resolved. */
|
|
224
|
+
from: Port;
|
|
225
|
+
to: Port;
|
|
226
|
+
/** What the router was handed between them: the author's waypoints, or a
|
|
227
|
+
* self-loop's turning point. */
|
|
228
|
+
waypoints: readonly Vec2[];
|
|
229
|
+
/** The router's answer, `from.point` first and `to.point` last. */
|
|
230
|
+
points: readonly Vec2[];
|
|
231
|
+
/** Set while the edge is split across pages (`DiagramEdge.offPage`): the
|
|
232
|
+
* two runs drawn in place of `points`, one out of `from` to its tag's
|
|
233
|
+
* side and one from the other tag's side into `to`. */
|
|
234
|
+
stubs?: readonly [readonly Vec2[], readonly Vec2[]];
|
|
235
|
+
}
|
|
236
|
+
/** How far a split edge's stub runs out of its shape, in world units. */
|
|
237
|
+
declare const OFF_PAGE_STUB = 24;
|
|
238
|
+
/** Routes an edge between its two dependencies the way {@link edgeDerivePath}
|
|
239
|
+
* does, answering the route itself; null where that draws nothing. */
|
|
240
|
+
declare function edgeRouter<TPose>(opts?: EdgeRouteOptions<TPose>): (node: {
|
|
241
|
+
data: unknown;
|
|
242
|
+
}, deps: readonly (DerivedDep<TPose> | undefined)[]) => ResolvedRoute | null;
|
|
111
243
|
/** Registry key for {@link EDGE_DERIVE_PATH}. */
|
|
112
244
|
declare const DIAGRAM_EDGE = "diagram:edge";
|
|
113
245
|
/** The default edge router, as one stable function reference so `toJSON` can
|
|
@@ -153,7 +285,23 @@ declare const PORT_AFFORDANCE_KIND: "layer:diagram-ports";
|
|
|
153
285
|
interface ParticipantPose<TPose> {
|
|
154
286
|
node: DiagramNodeLike;
|
|
155
287
|
pose: TPose;
|
|
288
|
+
/** Not drawn: on a hidden layer, or hidden on its own or by an ancestor.
|
|
289
|
+
* `sceneParticipants` answers it from the scene's `nodeGates`. */
|
|
290
|
+
hidden?: boolean;
|
|
291
|
+
/** Out of reach: locked, or on a locked layer. */
|
|
292
|
+
locked?: boolean;
|
|
293
|
+
/** The scene layer the node is painted on, which the asking view may not
|
|
294
|
+
* paint (`ChromeState.layerIsPainted`, `ViewApi.layerIsPainted`). */
|
|
295
|
+
layer?: string;
|
|
156
296
|
}
|
|
297
|
+
/** Whether a participant's ports are drawn, grabbed and landed on. A hidden
|
|
298
|
+
* or locked node gets none, as it gets no selection or hover chrome either,
|
|
299
|
+
* and nor does one on a layer the asking view does not paint. */
|
|
300
|
+
declare function offersPorts(p: {
|
|
301
|
+
hidden?: boolean;
|
|
302
|
+
locked?: boolean;
|
|
303
|
+
layer?: string;
|
|
304
|
+
}, view?: Parameters<typeof paintsLayer>[0]): boolean;
|
|
157
305
|
/** Where the affordance gets its participants. A thunk rather than a scene so
|
|
158
306
|
* the geometry is testable without one, and so a consumer whose participants
|
|
159
307
|
* come from somewhere else needs no adapter. */
|
|
@@ -178,13 +326,21 @@ interface PortAffordanceOptions<TPose> {
|
|
|
178
326
|
/** Which participants show their ports. Default: all of them. Gate on
|
|
179
327
|
* selection or hover by reading `state`. */
|
|
180
328
|
shows?: (node: DiagramNodeLike, state: ChromeState) => boolean;
|
|
329
|
+
/** Which of a participant's ports show. Default: all of them. A port
|
|
330
|
+
* this turns away is not painted or grabbable, and passed with the connect
|
|
331
|
+
* options (as `diagramPorts` and `DiagramView` do), no connect lands on it. */
|
|
332
|
+
showsPort?: (port: Port) => boolean;
|
|
181
333
|
/** Screen-pixel hit radius. Default 8, the kit's `HANDLE_BASE_PX`. */
|
|
182
334
|
hitRadiusPx?: number;
|
|
183
|
-
/** Screen-pixel
|
|
184
|
-
* by passing 0 — a port the
|
|
335
|
+
/** Screen-pixel size of the painted mark: a square's side, or a circle's
|
|
336
|
+
* diameter. Default 7. Omit `paint` entirely by passing 0 — a port the
|
|
337
|
+
* consumer draws itself is still hittable. */
|
|
185
338
|
sizePx?: number;
|
|
186
|
-
fill
|
|
339
|
+
/** One fill for every port, or a function of the port — its `type`, say. */
|
|
340
|
+
fill?: CommandFill | ((port: Port) => CommandFill);
|
|
187
341
|
stroke?: CommandStroke;
|
|
342
|
+
/** Default `'square'`. */
|
|
343
|
+
shape?: 'square' | 'circle';
|
|
188
344
|
cursor?: CursorSpec;
|
|
189
345
|
/** Default `'exclusive'` on pointer gestures: a drag from a port is a
|
|
190
346
|
* connect, never a move of the node underneath it. */
|
|
@@ -201,6 +357,36 @@ declare function portScratchOf(hit: {
|
|
|
201
357
|
*/
|
|
202
358
|
declare function createPortAffordance<TPose>(participants: ParticipantSource<TPose>, opts?: PortAffordanceOptions<TPose>): Affordance;
|
|
203
359
|
|
|
360
|
+
/** An end on a participant's body rather than on one of its ports. `point` is
|
|
361
|
+
* where the pointer was, in world coordinates. */
|
|
362
|
+
interface BodyEnd {
|
|
363
|
+
kind: 'body';
|
|
364
|
+
nodeId: string;
|
|
365
|
+
point: Vec2$1;
|
|
366
|
+
}
|
|
367
|
+
/** Either end of a connect. */
|
|
368
|
+
type ConnectEnd = Port | BodyEnd;
|
|
369
|
+
/** Whether a connect end lands on a node's body rather than a port. */
|
|
370
|
+
declare function isBodyEnd(end: ConnectEnd): end is BodyEnd;
|
|
371
|
+
/** A body under the pointer, and the participant it belongs to. */
|
|
372
|
+
interface BodyHit<TPose> {
|
|
373
|
+
end: BodyEnd;
|
|
374
|
+
participant: ParticipantPose<TPose>;
|
|
375
|
+
}
|
|
376
|
+
/** The view a connect started in, which decides what layers it may reach. */
|
|
377
|
+
type ConnectView = Parameters<typeof offersPorts>[1];
|
|
378
|
+
/**
|
|
379
|
+
* The topmost participant whose body contains `at`, or `null`.
|
|
380
|
+
*
|
|
381
|
+
* Its outline when it declares one, else its bounds, both taken in the pose's
|
|
382
|
+
* unrotated frame. Edges, edge labels and group boxes are not bodies, and nor
|
|
383
|
+
* is anything the reader does not take as a participant or that `offersPorts`
|
|
384
|
+
* turns away.
|
|
385
|
+
*/
|
|
386
|
+
declare function bodyAt<TPose>(participants: ParticipantSource<TPose>, at: Vec2$1, opts?: PortsOptions<TPose> & {
|
|
387
|
+
view?: ConnectView;
|
|
388
|
+
}): BodyHit<TPose> | null;
|
|
389
|
+
|
|
204
390
|
/**
|
|
205
391
|
* The connect gesture — dragging one port onto another to author an edge.
|
|
206
392
|
*
|
|
@@ -217,17 +403,26 @@ declare function createPortAffordance<TPose>(participants: ParticipantSource<TPo
|
|
|
217
403
|
*
|
|
218
404
|
* One resolver answers both the live preview and the commit, so the preview
|
|
219
405
|
* cannot lie about what releasing will do.
|
|
406
|
+
*
|
|
407
|
+
* With `bodies`, a release over a participant's body away from any port lands
|
|
408
|
+
* on the body (`connectTargets`); with `startFrom: 'body'`, so can the press.
|
|
220
409
|
*/
|
|
221
410
|
|
|
222
411
|
/** The default action id, and what {@link connectBinding} points at. */
|
|
223
412
|
declare const CONNECT_ACTION_ID = "diagram.connect";
|
|
224
|
-
/**
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
413
|
+
/** The edge end a reconnect is carrying: the scene id of the edge, and which end. */
|
|
414
|
+
interface MovingEnd {
|
|
415
|
+
edge: string;
|
|
416
|
+
end: 'from' | 'to';
|
|
417
|
+
}
|
|
418
|
+
/** Whether an edge may run from `from` to `to`. `moving` is the end being
|
|
419
|
+
* dragged when the edge already exists, and absent for a new connect. */
|
|
420
|
+
type CanConnect = (from: ConnectEnd, to: ConnectEnd, moving?: MovingEnd) => boolean;
|
|
421
|
+
/** The edge a finished connect describes. Each end is a resolved port, or a
|
|
422
|
+
* body whose port the edge picks each time it is routed. */
|
|
228
423
|
interface PendingEdge {
|
|
229
|
-
from:
|
|
230
|
-
to:
|
|
424
|
+
from: ConnectEnd;
|
|
425
|
+
to: ConnectEnd;
|
|
231
426
|
/** Registry key for the router the new edge should name. */
|
|
232
427
|
router: string;
|
|
233
428
|
}
|
|
@@ -236,7 +431,8 @@ interface PendingEdge {
|
|
|
236
431
|
* declare a `type` must declare the same one.
|
|
237
432
|
*
|
|
238
433
|
* A port with no type joins anything. Two different ports on the *same node*
|
|
239
|
-
* may be joined: a self-edge is meaningful in a state machine.
|
|
434
|
+
* may be joined: a self-edge is meaningful in a state machine. A body is
|
|
435
|
+
* untyped, and never joins its own node.
|
|
240
436
|
*/
|
|
241
437
|
declare const defaultCanConnect: CanConnect;
|
|
242
438
|
/** Options for {@link createConnectAction}. Only `participants` is required. */
|
|
@@ -250,6 +446,10 @@ interface ConnectActionOptions<TPose> {
|
|
|
250
446
|
geometry?: PoseDescriptor<TPose>;
|
|
251
447
|
/** Default {@link defaultCanConnect}. */
|
|
252
448
|
canConnect?: CanConnect;
|
|
449
|
+
/** Which ports a connect may land on: a port this turns away is never a
|
|
450
|
+
* target. The port affordance's option of the same name, so a port that is
|
|
451
|
+
* not shown cannot be dropped onto. Default: all of them. */
|
|
452
|
+
showsPort?: (port: Port) => boolean;
|
|
253
453
|
/** How near the pointer must come to a port, in world units, before the
|
|
254
454
|
* edge snaps to it. Default 16. */
|
|
255
455
|
snapRadius?: number;
|
|
@@ -257,13 +457,22 @@ interface ConnectActionOptions<TPose> {
|
|
|
257
457
|
* Default `'straight'`. */
|
|
258
458
|
router?: string;
|
|
259
459
|
routers?: Readonly<Record<string, Router>>;
|
|
460
|
+
/** A release over a participant's body, with no port in reach, lands on the
|
|
461
|
+
* body. Default false. */
|
|
462
|
+
bodies?: boolean;
|
|
463
|
+
/** `'body'`: a press that is not on a port starts from the participant
|
|
464
|
+
* under it. Default `'port'`, where such a press falls through. */
|
|
465
|
+
startFrom?: 'port' | 'body';
|
|
260
466
|
/**
|
|
261
|
-
* Mints and commits the edge. Called once, on release over a valid
|
|
467
|
+
* Mints and commits the edge. Called once, on release over a valid target.
|
|
262
468
|
*
|
|
263
469
|
* Defaults to {@link commitEdgeToScene} against `deps.scene`. Override it to
|
|
264
470
|
* choose the edge node's data, its layer, or its stroke.
|
|
265
471
|
*/
|
|
266
472
|
commit?: (edge: PendingEdge, ctx: InvocationCtx) => void;
|
|
473
|
+
/** What the default commit draws the edge with. Default {@link DEFAULT_EDGE_STROKE}.
|
|
474
|
+
* Ignored when `commit` is given. */
|
|
475
|
+
edgeStroke?: Stroke;
|
|
267
476
|
}
|
|
268
477
|
/** What a connect-authored edge is drawn with, when the consumer overrides
|
|
269
478
|
* nothing. */
|
|
@@ -289,21 +498,722 @@ declare const GRAB_PORT_ACTION_ID = "diagram.grabPort";
|
|
|
289
498
|
* happens.
|
|
290
499
|
*/
|
|
291
500
|
declare function grabPortAction(id?: string): Action;
|
|
292
|
-
/** The two bindings that keep a port's claim from dropping the press.
|
|
293
|
-
|
|
501
|
+
/** The two bindings that keep a port's claim from dropping the press. `kind`
|
|
502
|
+
* names another affordance that claims the press protocol the same way. */
|
|
503
|
+
declare function grabPortBindings(actionId?: string, kind?: string): GestureBinding[];
|
|
294
504
|
/**
|
|
295
505
|
* The default commit: one leaf node carrying the edge trait, added to
|
|
296
506
|
* `deps.scene`. One `add` is one history entry, so the edge undoes in one.
|
|
297
507
|
*
|
|
298
508
|
* The edge lands on the **source node's** layer rather than the bottom one.
|
|
299
509
|
*/
|
|
300
|
-
declare function commitEdgeToScene(edge: PendingEdge, ctx: InvocationCtx
|
|
510
|
+
declare function commitEdgeToScene(edge: PendingEdge, ctx: InvocationCtx, opts?: {
|
|
511
|
+
stroke?: Stroke;
|
|
512
|
+
}): void;
|
|
301
513
|
/**
|
|
302
514
|
* The `diagram.connect` action: an ongoing drag whose preview is an ephemeral
|
|
303
515
|
* edge and whose commit is one op batch.
|
|
304
516
|
*/
|
|
305
517
|
declare function createConnectAction<TPose>(opts: ConnectActionOptions<TPose>): Action;
|
|
306
518
|
|
|
519
|
+
/** The connector tool's id. */
|
|
520
|
+
declare const CONNECTOR_TOOL_ID = "diagram.connector";
|
|
521
|
+
/** The action the connector tool binds a drag to. */
|
|
522
|
+
declare const CONNECTOR_ACTION_ID = "diagram.connectorDraw";
|
|
523
|
+
/** The connector tool's definition, outside React. `id`, `startFrom` and
|
|
524
|
+
* `bodies` are the tool's own. */
|
|
525
|
+
declare function connectorTool<TPose>(opts: ConnectActionOptions<TPose>): Tool;
|
|
526
|
+
/** {@link connectorTool}, rebuilt when one of its options changes rather than
|
|
527
|
+
* when the bag holding them does. */
|
|
528
|
+
declare function useConnectorTool<TPose>(opts: ConnectActionOptions<TPose>): Tool;
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Stencils: the shapes a palette offers, as data, and what one becomes when it
|
|
532
|
+
* is drawn — a `buildBody` body whose rows are ordinary text nodes.
|
|
533
|
+
*/
|
|
534
|
+
|
|
535
|
+
/** One shape a palette offers. `size` is what a click places; `rows` default
|
|
536
|
+
* to one empty label, so the body has a text node to type into. `icon` is its
|
|
537
|
+
* tool's glyph in a palette. */
|
|
538
|
+
interface DiagramStencil {
|
|
539
|
+
id: string;
|
|
540
|
+
label: string;
|
|
541
|
+
outline: Outline;
|
|
542
|
+
size: {
|
|
543
|
+
width: number;
|
|
544
|
+
height: number;
|
|
545
|
+
};
|
|
546
|
+
rows?: readonly Row[];
|
|
547
|
+
icon?: IconRef;
|
|
548
|
+
}
|
|
549
|
+
/** The basic flowchart symbols. */
|
|
550
|
+
declare const FLOWCHART_STENCILS: readonly DiagramStencil[];
|
|
551
|
+
/** The insert kind a stencil's tool passes to the `insert` dep. */
|
|
552
|
+
declare const stencilKind: (id: string) => string;
|
|
553
|
+
/** The stencil id an insert kind names, or `null` for a kind that is no stencil's. */
|
|
554
|
+
declare function stencilIdOf(kind: string): string | null;
|
|
555
|
+
type Bounds$1 = {
|
|
556
|
+
x: number;
|
|
557
|
+
y: number;
|
|
558
|
+
width: number;
|
|
559
|
+
height: number;
|
|
560
|
+
};
|
|
561
|
+
/**
|
|
562
|
+
* The ops that insert `stencil` at `bounds`: its container first, then one
|
|
563
|
+
* text node per text row. Applied as one batch, they are one undo entry.
|
|
564
|
+
* `style` colors the body and its text; default `diagramScene`'s node style.
|
|
565
|
+
* `font` is the face its text rows fall back on; default 12px sans-serif.
|
|
566
|
+
* `parent` is the container the body goes in; default the top level.
|
|
567
|
+
*/
|
|
568
|
+
declare function stencilBuild<TLayer extends string>(stencil: DiagramStencil, bounds: Bounds$1, opts: {
|
|
569
|
+
layer: TLayer;
|
|
570
|
+
newId: () => string;
|
|
571
|
+
measure?: MeasureRowText;
|
|
572
|
+
style?: NodeStyle;
|
|
573
|
+
font?: {
|
|
574
|
+
fontFamily: string;
|
|
575
|
+
fontSize: number;
|
|
576
|
+
};
|
|
577
|
+
parent?: string | null;
|
|
578
|
+
}): {
|
|
579
|
+
id: string;
|
|
580
|
+
ops: Op[];
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* The node specs of a region — a container, a pool, or a lane — and its title,
|
|
585
|
+
* which a stencil drawn on the canvas and a `DiagramData` container both build
|
|
586
|
+
* from.
|
|
587
|
+
*/
|
|
588
|
+
|
|
589
|
+
/** A region's node spec, always with an id. */
|
|
590
|
+
type RegionSpec<TLayer extends string> = AddNodeSpec<DiagramSceneData, TLayer, RectPose> & {
|
|
591
|
+
id: NodeId;
|
|
592
|
+
};
|
|
593
|
+
/** Options for `containerBuild`. */
|
|
594
|
+
interface ContainerBuildOptions<TLayer extends string> {
|
|
595
|
+
layer: TLayer;
|
|
596
|
+
newId: () => string;
|
|
597
|
+
/** The box's fill, stroke and title colors. Default `diagramScene`'s node style. */
|
|
598
|
+
style?: NodeStyle;
|
|
599
|
+
/** The container the new one goes in. Default the top level. */
|
|
600
|
+
parent?: string | null;
|
|
601
|
+
/** A pool's header colors and its lanes' bodies in turn. Default `style` for both. */
|
|
602
|
+
laneStyles?: {
|
|
603
|
+
header: NodeStyle;
|
|
604
|
+
bodies: readonly NodeStyle[];
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
/** Options for {@link regionSpecs}. */
|
|
608
|
+
interface RegionOptions<TLayer extends string> {
|
|
609
|
+
id: string;
|
|
610
|
+
layer: TLayer;
|
|
611
|
+
/** Default the top level. */
|
|
612
|
+
parent?: string | null;
|
|
613
|
+
/** Default `diagramScene`'s node style. */
|
|
614
|
+
style?: NodeStyle;
|
|
615
|
+
/** Marks a region whose box is fitted to its members each time it is built from data. */
|
|
616
|
+
fitted?: boolean;
|
|
617
|
+
/** The title's family. Default sans-serif. */
|
|
618
|
+
fontFamily?: string;
|
|
619
|
+
}
|
|
620
|
+
/** The node specs of one region, and its title unless `title` is null. */
|
|
621
|
+
declare function regionSpecs<TLayer extends string>(role: ContainerRole, axis: 'x' | 'y', pose: RectPose, title: string | null, opts: RegionOptions<TLayer>): RegionSpec<TLayer>[];
|
|
622
|
+
/** The lane specs a new pool at `at` starts with. */
|
|
623
|
+
declare function firstLanes<TLayer extends string>(poolId: string, axis: 'x' | 'y', at: RectPose, opts: ContainerBuildOptions<TLayer>): RegionSpec<TLayer>[];
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* The container stencils a palette offers, what one becomes when it is drawn,
|
|
627
|
+
* and the edits on one: adding a lane to a pool, and releasing a container's
|
|
628
|
+
* members.
|
|
629
|
+
*/
|
|
630
|
+
|
|
631
|
+
/** One container a palette offers. A pool stacks its lanes along `axis`. */
|
|
632
|
+
interface ContainerStencil {
|
|
633
|
+
id: string;
|
|
634
|
+
label: string;
|
|
635
|
+
role: 'container' | 'pool';
|
|
636
|
+
axis?: 'x' | 'y';
|
|
637
|
+
size: {
|
|
638
|
+
width: number;
|
|
639
|
+
height: number;
|
|
640
|
+
};
|
|
641
|
+
/** The glyph a palette draws on its button. */
|
|
642
|
+
icon?: IconRef;
|
|
643
|
+
}
|
|
644
|
+
/** A titled box, and pools of rows and of columns. */
|
|
645
|
+
declare const CONTAINER_STENCILS: readonly ContainerStencil[];
|
|
646
|
+
type Bounds = {
|
|
647
|
+
x: number;
|
|
648
|
+
y: number;
|
|
649
|
+
width: number;
|
|
650
|
+
height: number;
|
|
651
|
+
};
|
|
652
|
+
type AnyScene$3 = Scene<unknown, string, unknown>;
|
|
653
|
+
/** The ops that insert `stencil` at `bounds`: the region and its title, and a
|
|
654
|
+
* pool's first lanes. Applied as one batch, they are one undo entry. */
|
|
655
|
+
declare function containerBuild<TLayer extends string>(stencil: ContainerStencil, bounds: Bounds, opts: ContainerBuildOptions<TLayer>): {
|
|
656
|
+
id: string;
|
|
657
|
+
ops: Op[];
|
|
658
|
+
};
|
|
659
|
+
/** The axis a pool stacks its lanes along, read off its header. */
|
|
660
|
+
declare const poolAxisOf: (pool: DiagramContainer) => "x" | "y";
|
|
661
|
+
/** The lanes of `poolId`, in the order they stack. */
|
|
662
|
+
declare function lanesOf(scene: AnyScene$3, poolId: string): NodeId[];
|
|
663
|
+
/**
|
|
664
|
+
* Add a lane to `poolId` before the lane at `index`, or at the end of the
|
|
665
|
+
* stack, as one history entry. The pool grows to hold it. Returns the new
|
|
666
|
+
* lane's id, or null when `poolId` is not a pool.
|
|
667
|
+
*/
|
|
668
|
+
declare function addLane(scene: AnyScene$3, poolId: string, index?: number, style?: NodeStyle): string | null;
|
|
669
|
+
/**
|
|
670
|
+
* Remove container `id` and keep its members, which take its place in its
|
|
671
|
+
* parent, as one history entry. A pool's members are its lanes' members, and
|
|
672
|
+
* a lane's go past its pool. Connectors on what is removed go with it.
|
|
673
|
+
*/
|
|
674
|
+
declare function releaseMembers(scene: AnyScene$3, id: string): void;
|
|
675
|
+
|
|
676
|
+
/** The tool that draws `stencil`, a shape's or a container's: its id is the stencil's insert kind. */
|
|
677
|
+
declare function stencilTool(stencil: Pick<DiagramStencil, 'id' | 'label' | 'icon'>): Tool;
|
|
678
|
+
/** {@link stencilTool}, rebuilt only when the stencil changes. */
|
|
679
|
+
declare function useStencilTool(stencil: Pick<DiagramStencil, 'id' | 'label' | 'icon'>): Tool;
|
|
680
|
+
/** Options for {@link useStencilInsert}. */
|
|
681
|
+
interface StencilInsertOptions {
|
|
682
|
+
/** The layer bodies are inserted on. Default: the scene's first layer. */
|
|
683
|
+
layer?: string;
|
|
684
|
+
measure?: MeasureRowText;
|
|
685
|
+
/** The body's fill, stroke and text colors. Default `diagramScene`'s node style. */
|
|
686
|
+
style?: NodeStyle;
|
|
687
|
+
/** The face the body's text rows fall back on. Default 12px sans-serif. */
|
|
688
|
+
font?: {
|
|
689
|
+
fontFamily: string;
|
|
690
|
+
fontSize: number;
|
|
691
|
+
};
|
|
692
|
+
/** Container stencils to draw beside the shapes (`CONTAINER_STENCILS`). */
|
|
693
|
+
containers?: readonly ContainerStencil[];
|
|
694
|
+
/** Container stencils' box and title colors. Default `style`. */
|
|
695
|
+
containerStyle?: NodeStyle;
|
|
696
|
+
/** A new pool's header colors and its lanes' bodies in turn. Default `containerStyle`. */
|
|
697
|
+
laneStyles?: {
|
|
698
|
+
header: NodeStyle;
|
|
699
|
+
bodies: readonly NodeStyle[];
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Registers the `insert` dep for stencil kinds. Any other kind goes to the
|
|
704
|
+
* `insert` dep this one displaced, so core's rect, ellipse and text tools
|
|
705
|
+
* keep working beside the stencils. A stencil drawn inside a container or a
|
|
706
|
+
* lane becomes its member (`diagramDropParentAt`).
|
|
707
|
+
*/
|
|
708
|
+
declare function useStencilInsert(stencils: readonly DiagramStencil[], opts?: StencilInsertOptions): void;
|
|
709
|
+
|
|
710
|
+
type Box$2 = {
|
|
711
|
+
x: number;
|
|
712
|
+
y: number;
|
|
713
|
+
width: number;
|
|
714
|
+
height: number;
|
|
715
|
+
};
|
|
716
|
+
/** Where a container's title sits: its header strip, turned a quarter to run
|
|
717
|
+
* up a left header. */
|
|
718
|
+
declare function titlePose(bounds: Box$2, header: ContainerHeader | undefined): RectPose;
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* `diagramContainerLayout` — free placement under a header. A member stays
|
|
722
|
+
* wherever it is dropped or the container is resized to; only the title is
|
|
723
|
+
* placed, in the header.
|
|
724
|
+
*
|
|
725
|
+
* A strategy sees ids and poses, never data, so it cannot tell a lane from a
|
|
726
|
+
* shape. Which nodes a container admits is `diagramCanDropInto`'s call.
|
|
727
|
+
*/
|
|
728
|
+
|
|
729
|
+
/** Options for {@link diagramContainerLayout}. */
|
|
730
|
+
interface ContainerLayoutOptions {
|
|
731
|
+
/** Where the title sits; matches the container trait's own `header`. */
|
|
732
|
+
header?: ContainerHeader;
|
|
733
|
+
}
|
|
734
|
+
/** A free-placement layout whose drops land in the body below or beside `header`. */
|
|
735
|
+
declare function diagramContainerLayout(opts?: ContainerLayoutOptions): LayoutStrategy<RectPose>;
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* `laneStackLayout` — a pool's lanes, stacked along one axis in the order they
|
|
739
|
+
* sit and stretched across the body past the header. The pool's size along
|
|
740
|
+
* the stack is the sum of its lanes; its size across is the author's.
|
|
741
|
+
*
|
|
742
|
+
* Like every strategy it sees ids and poses only: the title is told apart by
|
|
743
|
+
* its name, and which nodes a pool admits (lanes) is `diagramCanDropInto`'s call.
|
|
744
|
+
*/
|
|
745
|
+
|
|
746
|
+
/** Options for {@link laneStackLayout}. */
|
|
747
|
+
interface LaneStackOptions {
|
|
748
|
+
/** The axis lanes stack along: `'y'` for a pool of rows, `'x'` for columns. */
|
|
749
|
+
axis: 'x' | 'y';
|
|
750
|
+
/** The header's depth, across the stack. Default {@link POOL_HEADER_SIZE}. */
|
|
751
|
+
headerSize?: number;
|
|
752
|
+
}
|
|
753
|
+
/** A pool header's default depth. */
|
|
754
|
+
declare const POOL_HEADER_SIZE = 32;
|
|
755
|
+
/** The least a lane is along the stack. */
|
|
756
|
+
declare const MIN_LANE_SIZE = 40;
|
|
757
|
+
/** The header a pool stacking along `axis` has: across the stack, at its start. */
|
|
758
|
+
declare const poolHeader: (axis: "x" | "y", size?: number) => ContainerHeader;
|
|
759
|
+
/** Where lanes of the given sizes sit, in order, in a pool at `bounds`. */
|
|
760
|
+
declare function stackedLanes(axis: 'x' | 'y', bounds: ContainerBounds, header: ContainerHeader, lanes: readonly {
|
|
761
|
+
id: string;
|
|
762
|
+
size: number;
|
|
763
|
+
}[]): Map<string, RectPose>;
|
|
764
|
+
/** A pool stacking its lanes along `axis`. */
|
|
765
|
+
declare function laneStackLayout(opts: LaneStackOptions): LayoutStrategy<RectPose>;
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* The container layouts by registry key, as stable references so a saved
|
|
769
|
+
* scene finds them again (`withDiagramRegistry`).
|
|
770
|
+
*/
|
|
771
|
+
|
|
772
|
+
/** A plain container's header. */
|
|
773
|
+
declare const CONTAINER_HEADER: ContainerHeader;
|
|
774
|
+
/** A lane's header depth, across its pool's stack. */
|
|
775
|
+
declare const LANE_HEADER_SIZE = 28;
|
|
776
|
+
/** The header a lane of a pool stacking along `axis` has. */
|
|
777
|
+
declare const laneHeader: (axis: "x" | "y") => ContainerHeader;
|
|
778
|
+
/** A titled container's layout key: free placement in the body below its header. */
|
|
779
|
+
declare const DIAGRAM_CONTAINER_LAYOUT = "diagram:container";
|
|
780
|
+
/** A pool's layout key when its lanes stack as rows, top to bottom. */
|
|
781
|
+
declare const DIAGRAM_POOL_ROWS_LAYOUT = "diagram:pool-rows";
|
|
782
|
+
/** A pool's layout key when its lanes stack as columns, left to right. */
|
|
783
|
+
declare const DIAGRAM_POOL_COLUMNS_LAYOUT = "diagram:pool-columns";
|
|
784
|
+
/** The layout key of a lane in a pool of rows: free placement beside its left header. */
|
|
785
|
+
declare const DIAGRAM_LANE_ROWS_LAYOUT = "diagram:lane-rows";
|
|
786
|
+
/** The layout key of a lane in a pool of columns: free placement below its top header. */
|
|
787
|
+
declare const DIAGRAM_LANE_COLUMNS_LAYOUT = "diagram:lane-columns";
|
|
788
|
+
/** Every container layout this package registers, by key. */
|
|
789
|
+
declare const CONTAINER_LAYOUTS: Readonly<Record<string, LayoutStrategy<RectPose>>>;
|
|
790
|
+
/** The layout key and header for a container of `role`; a pool or lane's
|
|
791
|
+
* follow the axis its pool stacks along. */
|
|
792
|
+
declare function containerShape(role: ContainerRole, axis?: 'x' | 'y'): {
|
|
793
|
+
layout: string;
|
|
794
|
+
header: ContainerHeader;
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
type SceneLike = {
|
|
798
|
+
get(id: never): {
|
|
799
|
+
id: string;
|
|
800
|
+
kind: 'leaf' | 'container';
|
|
801
|
+
data: unknown;
|
|
802
|
+
} | undefined;
|
|
803
|
+
};
|
|
804
|
+
/**
|
|
805
|
+
* The `canDropInto` dep for a diagram scene. A container or a lane takes
|
|
806
|
+
* shapes and other containers, a pool takes only lanes, and a lane goes
|
|
807
|
+
* nowhere but a pool. A stencil body, an edge, or a label takes nothing, and
|
|
808
|
+
* edges and labels are never dropped in: they stay where they are, drawn from
|
|
809
|
+
* what they are attached to. Any other container — a plain group — takes
|
|
810
|
+
* anything but a lane.
|
|
811
|
+
*/
|
|
812
|
+
declare function diagramCanDropInto(scene: SceneLike): (parent: string, ids: readonly string[]) => boolean;
|
|
813
|
+
/** What {@link diagramDropParentAt} walks. */
|
|
814
|
+
interface DropParentScene {
|
|
815
|
+
readonly roots: readonly string[];
|
|
816
|
+
childrenOf(id: never): readonly string[];
|
|
817
|
+
get(id: never): {
|
|
818
|
+
id: string;
|
|
819
|
+
kind: 'leaf' | 'container';
|
|
820
|
+
data: unknown;
|
|
821
|
+
pose: unknown;
|
|
822
|
+
} | undefined;
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* The innermost container or lane whose body holds `point`, that would admit
|
|
826
|
+
* a new node of `role` (`null` for a shape): where an insert at `point` goes.
|
|
827
|
+
* Null for the top level — always so for a pool.
|
|
828
|
+
*/
|
|
829
|
+
declare function diagramDropParentAt(scene: DropParentScene, point: {
|
|
830
|
+
x: number;
|
|
831
|
+
y: number;
|
|
832
|
+
}, role: ContainerRole | null): string | null;
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* The lane affordances on every pool: the boundary after each lane, which a
|
|
836
|
+
* drag moves to resize that lane, and the add-lane button past the end of the
|
|
837
|
+
* stack. Built the way the edge-end handles are: regions with a `null`
|
|
838
|
+
* `targetId`, composed into a layer whose id is the kind a press reports.
|
|
839
|
+
*/
|
|
840
|
+
|
|
841
|
+
/** The layer id the lane affordances are composed into. */
|
|
842
|
+
declare const LANE_LAYER_ID = "diagram-lanes";
|
|
843
|
+
/** The affordance kind a press on a lane affordance reports. */
|
|
844
|
+
declare const LANE_AFFORDANCE_KIND: "layer:diagram-lanes";
|
|
845
|
+
/** What a press on a lane affordance hands the action: the boundary after
|
|
846
|
+
* `laneId`, or, with no lane, the add-lane button. */
|
|
847
|
+
interface LaneScratch {
|
|
848
|
+
targetId: string;
|
|
849
|
+
poolId: string;
|
|
850
|
+
laneId?: string;
|
|
851
|
+
}
|
|
852
|
+
/** Read a lane press's scratch back off the hit an action was handed. */
|
|
853
|
+
declare function laneScratchOf(hit: {
|
|
854
|
+
payload?: unknown;
|
|
855
|
+
} | null | undefined): LaneScratch | null;
|
|
856
|
+
type AnyScene$2 = Scene<unknown, string, unknown>;
|
|
857
|
+
/** A pool as the affordances see it: its box, the axis it stacks along, and its lanes in order. */
|
|
858
|
+
interface PoolLanes {
|
|
859
|
+
id: string;
|
|
860
|
+
axis: 'x' | 'y';
|
|
861
|
+
pose: RectPose;
|
|
862
|
+
lanes: {
|
|
863
|
+
id: string;
|
|
864
|
+
pose: RectPose;
|
|
865
|
+
}[];
|
|
866
|
+
}
|
|
867
|
+
/** Every pool in `scene` that is drawn and not locked. */
|
|
868
|
+
declare function poolsOf(scene: AnyScene$2): PoolLanes[];
|
|
869
|
+
/** Options for {@link laneLayer}. */
|
|
870
|
+
interface LaneLayerOptions {
|
|
871
|
+
/** Screen-pixel reach of a boundary either side of it. Default 4. */
|
|
872
|
+
hitRadiusPx?: number;
|
|
873
|
+
/** Screen-pixel diameter of the add-lane button. Default 14; 0 hides it. */
|
|
874
|
+
addSizePx?: number;
|
|
875
|
+
fill?: CommandFill;
|
|
876
|
+
stroke?: CommandStroke;
|
|
877
|
+
}
|
|
878
|
+
/** The affordance: a boundary region after each lane of each pool, and an add-lane button per pool. */
|
|
879
|
+
declare function createLaneAffordance(scene: AnyScene$2, opts?: LaneLayerOptions): Affordance;
|
|
880
|
+
/** The composed layer, for `CanvasExtensionApi.registerLayer`. */
|
|
881
|
+
declare function laneLayer(scene: AnyScene$2, opts?: LaneLayerOptions): RenderLayer<unknown>;
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* The container actions: dragging the boundary after a lane resizes it, the
|
|
885
|
+
* add-lane button adds one at the end of the stack, and Release members
|
|
886
|
+
* removes a container and keeps what it holds. The two lane gestures take a
|
|
887
|
+
* swappable commit; the default writes the scene.
|
|
888
|
+
*/
|
|
889
|
+
|
|
890
|
+
/** The action that drags a lane's boundary. */
|
|
891
|
+
declare const LANE_RESIZE_ACTION_ID = "diagram.resizeLane";
|
|
892
|
+
/** The action the add-lane button runs. */
|
|
893
|
+
declare const ADD_LANE_ACTION_ID = "diagram.addLane";
|
|
894
|
+
/** The command that removes the selected containers and keeps their members. */
|
|
895
|
+
declare const RELEASE_MEMBERS_ACTION_ID = "diagram.releaseMembers";
|
|
896
|
+
type AnyScene$1 = Scene<unknown, string, unknown>;
|
|
897
|
+
/** A lane resized: its new size along its pool's stack. */
|
|
898
|
+
interface LaneResize {
|
|
899
|
+
poolId: string;
|
|
900
|
+
laneId: string;
|
|
901
|
+
size: number;
|
|
902
|
+
}
|
|
903
|
+
/** The default commit: the lane's and the pool's new size, as one history
|
|
904
|
+
* entry labeled "Resize lane". The pool's layout restacks the lanes after it. */
|
|
905
|
+
declare function commitLaneResizeToScene(resize: LaneResize, ctx: InvocationCtx): void;
|
|
906
|
+
/** Where everything stands with the lane at `index` of `pool` resized to `size`: the
|
|
907
|
+
* lane, its title, the pool and its title, and every later lane with what it holds. */
|
|
908
|
+
declare function laneResizeFrame(scene: AnyScene$1, pool: PoolLanes, index: number, size: number): Map<string, RectPose>;
|
|
909
|
+
/** Options for the container actions. */
|
|
910
|
+
interface LaneActionOptions extends LaneLayerOptions {
|
|
911
|
+
scene: AnyScene$1;
|
|
912
|
+
/** The selected ids, which Release members reads. */
|
|
913
|
+
selected?: () => readonly string[];
|
|
914
|
+
/** Defaults to {@link commitLaneResizeToScene}. */
|
|
915
|
+
commitResize?: (resize: LaneResize, ctx: InvocationCtx) => void;
|
|
916
|
+
/** Defaults to `addLane` on `deps.scene`, at the end of the stack. */
|
|
917
|
+
commitAddLane?: (poolId: string, ctx: InvocationCtx) => void;
|
|
918
|
+
/** Runs for each selected region in place of `releaseMembers`. */
|
|
919
|
+
commitRelease?: (id: string) => void;
|
|
920
|
+
}
|
|
921
|
+
/** The `diagram.resizeLane` action: an ongoing drag moving one lane's far boundary. */
|
|
922
|
+
declare function createLaneResizeAction(opts: LaneActionOptions): Action;
|
|
923
|
+
/** The `diagram.addLane` action: the add-lane button's click. */
|
|
924
|
+
declare function createAddLaneAction(opts: LaneActionOptions): Action;
|
|
925
|
+
/** The `diagram.releaseMembers` command: removes each selected container and
|
|
926
|
+
* keeps what it holds, in one history entry. */
|
|
927
|
+
declare function createReleaseMembersAction(opts: LaneActionOptions): Action;
|
|
928
|
+
/**
|
|
929
|
+
* Both halves of container editing: the lane layer to `registerLayer`, and
|
|
930
|
+
* the contribution to pass as `ambient`, which carries the lane boundary
|
|
931
|
+
* drag, the add-lane click, and the `diagram.releaseMembers` command. Like
|
|
932
|
+
* `diagramPorts`, one without the other fails quietly.
|
|
933
|
+
*/
|
|
934
|
+
declare function diagramContainers(opts: LaneActionOptions): {
|
|
935
|
+
layer: RenderLayer<unknown>;
|
|
936
|
+
contribution: Contribution;
|
|
937
|
+
};
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* A double-click on a region's header: the action that reports which region's
|
|
941
|
+
* title to edit, and its binding.
|
|
942
|
+
*/
|
|
943
|
+
|
|
944
|
+
/** The action a double-click on a region's header runs. */
|
|
945
|
+
declare const EDIT_CONTAINER_TITLE_ACTION_ID = "diagram.editContainerTitle";
|
|
946
|
+
/** The container, pool, or lane whose header holds `at`: the node under it, or a region around that. */
|
|
947
|
+
declare function regionHeaderAt(deps: ActionDeps | undefined, at: {
|
|
948
|
+
x: number;
|
|
949
|
+
y: number;
|
|
950
|
+
} | undefined): string | null;
|
|
951
|
+
/** The action that hands `commit` the region whose header a double-click landed on. It declines anywhere else. */
|
|
952
|
+
declare function editContainerTitleAction(commit: (id: string) => void): Action;
|
|
953
|
+
/** A double-click on a node's body; the action declines unless it lands in a region's header. */
|
|
954
|
+
declare function editContainerTitleBinding(): GestureBinding;
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Moving an edge label along and beside its edge.
|
|
958
|
+
*
|
|
959
|
+
* The label layer (`labelDragLayer`) claims the press; this action moves the
|
|
960
|
+
* label. The drag previews the label's own data at the station the pointer
|
|
961
|
+
* proposes, and the pose that data derives, so the preview stands where the
|
|
962
|
+
* commit will.
|
|
963
|
+
*/
|
|
964
|
+
|
|
965
|
+
/** The action that drags an edge label. */
|
|
966
|
+
declare const MOVE_LABEL_ACTION_ID = "diagram.moveLabel";
|
|
967
|
+
/** A label placed: where it now sits on its edge, or `null` to reset it to {@link LABEL_PLACEMENT}. */
|
|
968
|
+
interface LabelEdit {
|
|
969
|
+
labelId: string;
|
|
970
|
+
edgeId: string;
|
|
971
|
+
placement: DiagramLabel | null;
|
|
972
|
+
}
|
|
973
|
+
/** Options for {@link createLabelDragAction}. */
|
|
974
|
+
interface LabelDragOptions {
|
|
975
|
+
/** Defaults to {@link commitLabelToScene} against `deps.scene`. */
|
|
976
|
+
commit?: (edit: LabelEdit, ctx: InvocationCtx) => void;
|
|
977
|
+
id?: string;
|
|
978
|
+
}
|
|
979
|
+
/** `data` with its label trait at `spot`, owned by the author from now on:
|
|
980
|
+
* placement's `placed` is dropped, and placement won't move it again. */
|
|
981
|
+
declare function movedLabelData(data: unknown, spot: LabelSpot): Record<string, unknown>;
|
|
982
|
+
/** The default commit: the label's placement in `data.diagram.label`, as one
|
|
983
|
+
* history entry labeled "Move label", or "Reset label" for a `null` placement. */
|
|
984
|
+
declare function commitLabelToScene(edit: LabelEdit, ctx: InvocationCtx): void;
|
|
985
|
+
/** The `diagram.moveLabel` action: an ongoing drag moving one edge label along and beside its edge. */
|
|
986
|
+
declare function createLabelDragAction(opts?: LabelDragOptions): Action;
|
|
987
|
+
|
|
988
|
+
/**
|
|
989
|
+
* Handles on the ends of a selected edge — what makes an edge's end grabbable,
|
|
990
|
+
* so a drag can carry it onto another shape (`reconnect`).
|
|
991
|
+
*
|
|
992
|
+
* Built the way the port affordance is: point regions with a `null`
|
|
993
|
+
* `targetId` and no `hitKind`, composed into a layer whose id is the kind a
|
|
994
|
+
* press reports. See `portAffordance` for why both matter.
|
|
995
|
+
*/
|
|
996
|
+
|
|
997
|
+
/** The layer id the edge-end handles are composed into. */
|
|
998
|
+
declare const EDGE_END_LAYER_ID = "diagram-edge-ends";
|
|
999
|
+
/** The affordance kind a press on an edge-end handle reports. */
|
|
1000
|
+
declare const EDGE_END_AFFORDANCE_KIND: "layer:diagram-edge-ends";
|
|
1001
|
+
/** What a press on an edge-end handle hands the reconnect action, as
|
|
1002
|
+
* `InvocationCtx.drag.affordance.payload`. */
|
|
1003
|
+
interface EdgeEndScratch {
|
|
1004
|
+
targetId: string;
|
|
1005
|
+
edgeId: string;
|
|
1006
|
+
end: 'from' | 'to';
|
|
1007
|
+
}
|
|
1008
|
+
/** Read an edge-end press's scratch back off the hit an action was handed. */
|
|
1009
|
+
declare function edgeEndScratchOf(hit: {
|
|
1010
|
+
payload?: unknown;
|
|
1011
|
+
} | null | undefined): EdgeEndScratch | null;
|
|
1012
|
+
/** An edge as it stands: its trait, the participants at its two ends, and
|
|
1013
|
+
* where its routed path starts and ends. */
|
|
1014
|
+
interface EdgeEnds<TPose> {
|
|
1015
|
+
edge: ParticipantPose<TPose>;
|
|
1016
|
+
trait: DiagramEdge;
|
|
1017
|
+
from: ParticipantPose<TPose>;
|
|
1018
|
+
to: ParticipantPose<TPose>;
|
|
1019
|
+
points: {
|
|
1020
|
+
from: Vec2$1;
|
|
1021
|
+
to: Vec2$1;
|
|
1022
|
+
};
|
|
1023
|
+
/** The route as the edge's own `derivePath` draws it. */
|
|
1024
|
+
route: ResolvedRoute;
|
|
1025
|
+
}
|
|
1026
|
+
/** Options shared by the edge-end affordance and the reconnect action. */
|
|
1027
|
+
interface EdgeEndOptions<TPose> extends PortsOptions<TPose> {
|
|
1028
|
+
routers?: Readonly<Record<string, Router>>;
|
|
1029
|
+
}
|
|
1030
|
+
/** Options for {@link createEdgeEndAffordance}. */
|
|
1031
|
+
interface EdgeEndAffordanceOptions<TPose> extends EdgeEndOptions<TPose> {
|
|
1032
|
+
/** Also the chrome-caps visibility id. Default {@link EDGE_END_LAYER_ID}. */
|
|
1033
|
+
id?: string;
|
|
1034
|
+
/** Screen-pixel hit radius. Default 8. */
|
|
1035
|
+
hitRadiusPx?: number;
|
|
1036
|
+
/** Screen-pixel side of the painted square. Default 8; 0 paints nothing. */
|
|
1037
|
+
sizePx?: number;
|
|
1038
|
+
fill?: CommandFill;
|
|
1039
|
+
stroke?: CommandStroke;
|
|
1040
|
+
cursor?: CursorSpec;
|
|
1041
|
+
}
|
|
1042
|
+
/** The affordance: one point region on each end of each selected edge. */
|
|
1043
|
+
declare function createEdgeEndAffordance<TPose>(participants: ParticipantSource<TPose>, selected: () => readonly string[], opts?: EdgeEndAffordanceOptions<TPose>): Affordance;
|
|
1044
|
+
/** The composed layer, for `CanvasExtensionApi.registerLayer`. Register it
|
|
1045
|
+
* after the port layer: the last-registered layer is hit first, and an edge's
|
|
1046
|
+
* end sits on a port. */
|
|
1047
|
+
declare function edgeEndLayer<TPose>(participants: ParticipantSource<TPose>, selected: () => readonly string[], opts?: EdgeEndAffordanceOptions<TPose>): RenderLayer<unknown>;
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* Route editing — dragging a selected edge's waypoints and segments.
|
|
1051
|
+
*
|
|
1052
|
+
* The route handles (`waypointLayer`) claim the press; this action reshapes
|
|
1053
|
+
* the route. The drag previews the edge's own data with the new waypoints,
|
|
1054
|
+
* so its `derivePath` draws the preview exactly as the commit will.
|
|
1055
|
+
*/
|
|
1056
|
+
|
|
1057
|
+
/** The action that drags a route handle. */
|
|
1058
|
+
declare const ROUTE_EDIT_ACTION_ID = "diagram.editRoute";
|
|
1059
|
+
/** An edge's route edited: its waypoints as they now stand. */
|
|
1060
|
+
interface RouteEdit {
|
|
1061
|
+
edgeId: string;
|
|
1062
|
+
waypoints: readonly Vec2$1[];
|
|
1063
|
+
}
|
|
1064
|
+
/** Options for the route-editing actions: the drag, the double-click that removes, and Reset route. */
|
|
1065
|
+
interface RouteEditOptions<TPose> extends EdgeEndOptions<TPose> {
|
|
1066
|
+
participants: ParticipantSource<TPose>;
|
|
1067
|
+
/** The selected edge ids, whose routes show handles. */
|
|
1068
|
+
selected: () => readonly string[];
|
|
1069
|
+
/** Screen pixels within which a dragged handle lines up with a neighbor
|
|
1070
|
+
* or a port's axis. Default 6. */
|
|
1071
|
+
snapPx?: number;
|
|
1072
|
+
/** Screen-pixel reach of a handle, as the handle layer's `hitRadiusPx`. Default 7. */
|
|
1073
|
+
hitRadiusPx?: number;
|
|
1074
|
+
/** Defaults to {@link commitRouteToScene} against `deps.scene`. */
|
|
1075
|
+
commit?: (edit: RouteEdit, ctx: InvocationCtx) => void;
|
|
1076
|
+
id?: string;
|
|
1077
|
+
}
|
|
1078
|
+
/** `data` with its edge trait routed through `waypoints`: owned by the author
|
|
1079
|
+
* from now on, so layout's mark is dropped, and no waypoints at all when there are none. */
|
|
1080
|
+
declare function routedData(data: unknown, trait: DiagramEdge, waypoints: readonly Vec2$1[]): Record<string, unknown>;
|
|
1081
|
+
/** The default commit: the edge's new waypoints in `data.diagram`, as one history entry labeled "Edit route". */
|
|
1082
|
+
declare function commitRouteToScene(edit: RouteEdit, ctx: InvocationCtx): void;
|
|
1083
|
+
/** The `diagram.editRoute` action: an ongoing drag reshaping one edge's route. */
|
|
1084
|
+
declare function createRouteEditAction<TPose>(opts: RouteEditOptions<TPose>): Action;
|
|
1085
|
+
|
|
1086
|
+
/** Polyline arithmetic shared by the routers and route editing. */
|
|
1087
|
+
|
|
1088
|
+
/** `points` without repeats, and without any interior point lying straight
|
|
1089
|
+
* between its neighbors. The first and last always stay. */
|
|
1090
|
+
declare function simplifyStops(points: readonly Vec2$1[]): Vec2$1[];
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* Waypoint editing as pure math on an edge's route.
|
|
1094
|
+
*
|
|
1095
|
+
* The **stops** are the points a route must pass through: its `from` end, the
|
|
1096
|
+
* author's waypoints, and its `to` end. The **drawn** route is what the router
|
|
1097
|
+
* made of them. Every shipped router passes through each stop exactly, so the
|
|
1098
|
+
* drawn polyline splits at the stops and a leg's middle is found on it.
|
|
1099
|
+
*
|
|
1100
|
+
* Each edit answers the edge's new waypoints, never the whole route.
|
|
1101
|
+
*/
|
|
1102
|
+
|
|
1103
|
+
/** A handle a selected edge shows along its route. `at` is where it sits, in world units. */
|
|
1104
|
+
type RouteHandle =
|
|
1105
|
+
/** Waypoint `index`: dragging moves it. */
|
|
1106
|
+
{
|
|
1107
|
+
kind: 'vertex';
|
|
1108
|
+
index: number;
|
|
1109
|
+
at: Vec2$1;
|
|
1110
|
+
}
|
|
1111
|
+
/** The middle of leg `leg`, between stops `leg` and `leg + 1`: dragging inserts a waypoint there. */
|
|
1112
|
+
| {
|
|
1113
|
+
kind: 'insert';
|
|
1114
|
+
leg: number;
|
|
1115
|
+
at: Vec2$1;
|
|
1116
|
+
}
|
|
1117
|
+
/** Segment `index` of an orthogonal route, which runs along `axis`: dragging slides it across. */
|
|
1118
|
+
| {
|
|
1119
|
+
kind: 'segment';
|
|
1120
|
+
index: number;
|
|
1121
|
+
axis: 'x' | 'y';
|
|
1122
|
+
at: Vec2$1;
|
|
1123
|
+
};
|
|
1124
|
+
/** The axis a segment runs along, or null when it is a point or slanted. */
|
|
1125
|
+
declare function segmentAxis(a: Vec2$1, b: Vec2$1): 'x' | 'y' | null;
|
|
1126
|
+
/** The handles an edge shows: a bar per segment under `orthogonal` and
|
|
1127
|
+
* `avoid`, else a dot per waypoint and a hollow dot per leg. */
|
|
1128
|
+
declare function routeHandles(drawn: readonly Vec2$1[], stops: readonly Vec2$1[], router: Router): RouteHandle[];
|
|
1129
|
+
/** The waypoints with waypoint `index` moved to `to`. */
|
|
1130
|
+
declare function dragVertex(stops: readonly Vec2$1[], index: number, to: Vec2$1): Vec2$1[];
|
|
1131
|
+
/** The waypoints with one at `at` inserted on leg `leg`: it becomes waypoint `leg`. */
|
|
1132
|
+
declare function insertWaypoint(stops: readonly Vec2$1[], leg: number, at: Vec2$1): Vec2$1[];
|
|
1133
|
+
/** The waypoints without waypoint `index`. */
|
|
1134
|
+
declare function removeWaypoint(stops: readonly Vec2$1[], index: number): Vec2$1[];
|
|
1135
|
+
/**
|
|
1136
|
+
* The waypoints of `drawn`, an orthogonal route, with segment `index` slid
|
|
1137
|
+
* `offset` across its axis: every interior bend of the new route, since the
|
|
1138
|
+
* orthogonal router recomputes elbows between stops. A segment touching a
|
|
1139
|
+
* port keeps a short stub there and jogs over, so the port end stays square.
|
|
1140
|
+
*/
|
|
1141
|
+
declare function dragSegment(drawn: readonly Vec2$1[], index: number, offset: number): Vec2$1[];
|
|
1142
|
+
/**
|
|
1143
|
+
* The waypoints of an `avoid` route with segment `index` of `drawn` slid
|
|
1144
|
+
* `offset` across its axis and pinned there: its two ends join the author's
|
|
1145
|
+
* waypoints, in route order, and the router keeps the rest. A waypoint at one
|
|
1146
|
+
* of its ends moves with it, and a segment meeting a port jogs off it so the
|
|
1147
|
+
* port end stays square.
|
|
1148
|
+
*/
|
|
1149
|
+
declare function pinSegment(drawn: readonly Vec2$1[], stops: readonly Vec2$1[], index: number, offset: number): Vec2$1[];
|
|
1150
|
+
/** The waypoints of an `avoid` route without those at either end of segment
|
|
1151
|
+
* `index`, which hands the segment back to the router; null when neither end is one. */
|
|
1152
|
+
declare function unpinSegment(drawn: readonly Vec2$1[], stops: readonly Vec2$1[], index: number): Vec2$1[] | null;
|
|
1153
|
+
/**
|
|
1154
|
+
* The waypoints with segment `index` straightened away: its neighbors run in
|
|
1155
|
+
* parallel, and the one touching no port slides onto the other's line. Null
|
|
1156
|
+
* when it is the first or last segment, or both neighbors touch a port.
|
|
1157
|
+
*/
|
|
1158
|
+
declare function removeSegment(drawn: readonly Vec2$1[], index: number): Vec2$1[] | null;
|
|
1159
|
+
|
|
1160
|
+
/**
|
|
1161
|
+
* Handles along a selected edge's route — what makes its waypoints and
|
|
1162
|
+
* segments grabbable, so a drag can reshape the route (`waypointAction`).
|
|
1163
|
+
*
|
|
1164
|
+
* Built the way the edge-end handles are: point regions with a `null`
|
|
1165
|
+
* `targetId` and no `hitKind`, composed into a layer whose id is the kind a
|
|
1166
|
+
* press reports.
|
|
1167
|
+
*/
|
|
1168
|
+
|
|
1169
|
+
/** The layer id the route handles are composed into. */
|
|
1170
|
+
declare const WAYPOINT_LAYER_ID = "diagram-waypoints";
|
|
1171
|
+
/** The affordance kind a press on a route handle reports. */
|
|
1172
|
+
declare const WAYPOINT_AFFORDANCE_KIND: "layer:diagram-waypoints";
|
|
1173
|
+
/** What a press on a route handle hands the route-edit actions, as the hit's `payload`. */
|
|
1174
|
+
interface WaypointScratch {
|
|
1175
|
+
targetId: string;
|
|
1176
|
+
edgeId: string;
|
|
1177
|
+
handle: RouteHandle;
|
|
1178
|
+
}
|
|
1179
|
+
/** Read a route-handle press's scratch back off the hit an action was handed. */
|
|
1180
|
+
declare function waypointScratchOf(hit: {
|
|
1181
|
+
payload?: unknown;
|
|
1182
|
+
} | null | undefined): WaypointScratch | null;
|
|
1183
|
+
/** An edge's route as the handles read it: its resolved ends, its stops, the
|
|
1184
|
+
* route drawn through them, the router that drew it, and the handles it shows. */
|
|
1185
|
+
interface EdgeRouteState {
|
|
1186
|
+
from: Port;
|
|
1187
|
+
to: Port;
|
|
1188
|
+
stops: readonly Vec2$1[];
|
|
1189
|
+
drawn: readonly Vec2$1[];
|
|
1190
|
+
router: Router;
|
|
1191
|
+
handles: readonly RouteHandle[];
|
|
1192
|
+
}
|
|
1193
|
+
/** The route state of an edge whose ends `ends` resolved. */
|
|
1194
|
+
declare function routeStateOf(ends: EdgeEnds<unknown>, routers?: Readonly<Record<string, Router>>): EdgeRouteState;
|
|
1195
|
+
/** Options for {@link createWaypointAffordance}. */
|
|
1196
|
+
interface WaypointAffordanceOptions<TPose> extends EdgeEndOptions<TPose> {
|
|
1197
|
+
/** Also the chrome-caps visibility id. Default {@link WAYPOINT_LAYER_ID}. */
|
|
1198
|
+
id?: string;
|
|
1199
|
+
/** Screen-pixel hit radius. Default 7. */
|
|
1200
|
+
hitRadiusPx?: number;
|
|
1201
|
+
/** Screen-pixel diameter of a waypoint's dot; an insert dot is three
|
|
1202
|
+
* quarters of it, and a segment bar twice as long. Default 8; 0 paints nothing. */
|
|
1203
|
+
sizePx?: number;
|
|
1204
|
+
fill?: CommandFill;
|
|
1205
|
+
stroke?: CommandStroke;
|
|
1206
|
+
cursor?: CursorSpec;
|
|
1207
|
+
}
|
|
1208
|
+
/** A route handle's default screen-pixel hit radius. */
|
|
1209
|
+
declare const WAYPOINT_HIT_PX = 7;
|
|
1210
|
+
/** The affordance: a region on each route handle of each selected edge. */
|
|
1211
|
+
declare function createWaypointAffordance<TPose>(participants: ParticipantSource<TPose>, selected: () => readonly string[], opts?: WaypointAffordanceOptions<TPose>): Affordance;
|
|
1212
|
+
/** The composed layer, for `CanvasExtensionApi.registerLayer`. Register it
|
|
1213
|
+
* after the port layer and before the edge-end layer: the last registered is
|
|
1214
|
+
* hit first, and an edge's end handle must win over a handle beside it. */
|
|
1215
|
+
declare function waypointLayer<TPose>(participants: ParticipantSource<TPose>, selected: () => readonly string[], opts?: WaypointAffordanceOptions<TPose>): RenderLayer<unknown>;
|
|
1216
|
+
|
|
307
1217
|
/**
|
|
308
1218
|
* The plugin as a `Contribution` bundle — one object a consumer hands to
|
|
309
1219
|
* `<SceneCanvas ambient={…}>`.
|
|
@@ -335,6 +1245,347 @@ declare function diagramPorts<TPose>(opts: DiagramContributionOptions<TPose>): {
|
|
|
335
1245
|
layer: RenderLayer<unknown>;
|
|
336
1246
|
contribution: Contribution;
|
|
337
1247
|
};
|
|
1248
|
+
/** The action id that absorbs the rest of a press on a route handle. */
|
|
1249
|
+
declare const GRAB_WAYPOINT_ACTION_ID = "diagram.grabWaypoint";
|
|
1250
|
+
/**
|
|
1251
|
+
* Both halves of route editing: the handle layer to `registerLayer` — after
|
|
1252
|
+
* the port layer and before the edge-end layer, so an end handle wins over a
|
|
1253
|
+
* route handle beside it — and the contribution to pass as `ambient`, which
|
|
1254
|
+
* carries the drag, the double-click that removes, the
|
|
1255
|
+
* `diagram.resetRoute` command, the commands that set the selected
|
|
1256
|
+
* connectors' router (`SET_ROUTER_ACTION_IDS`), and the line jumps toggle
|
|
1257
|
+
* (`SET_HOPS_ACTION_ID`). Like `diagramPorts`, one without the other
|
|
1258
|
+
* fails quietly.
|
|
1259
|
+
*/
|
|
1260
|
+
declare function diagramWaypoints<TPose>(opts: RouteEditOptions<TPose> & Omit<WaypointAffordanceOptions<TPose>, 'id'>): {
|
|
1261
|
+
layer: RenderLayer<unknown>;
|
|
1262
|
+
contribution: Contribution;
|
|
1263
|
+
};
|
|
1264
|
+
/** The action id that absorbs a press on an edge label, so it reaches neither marquee nor pan. */
|
|
1265
|
+
declare const GRAB_LABEL_ACTION_ID = "diagram.grabLabel";
|
|
1266
|
+
/** The action id that selects a clicked label's edge. */
|
|
1267
|
+
declare const SELECT_LABEL_EDGE_ACTION_ID = "diagram.selectLabelEdge";
|
|
1268
|
+
/**
|
|
1269
|
+
* Both halves of label dragging: the label layer to `registerLayer` — before
|
|
1270
|
+
* the port layer, so a port or a route handle wins over a label beside it —
|
|
1271
|
+
* and the contribution to pass as `ambient`, which carries the drag
|
|
1272
|
+
* (`diagram.moveLabel`), a click that selects the label's edge, and a
|
|
1273
|
+
* double-click that edits the label's text through
|
|
1274
|
+
* `EDIT_EDGE_LABEL_ACTION_ID`, which the host registers. Like `diagramPorts`,
|
|
1275
|
+
* one without the other fails quietly.
|
|
1276
|
+
*/
|
|
1277
|
+
declare function diagramLabelDrag(opts: LabelDragOptions & {
|
|
1278
|
+
scene: Scene<unknown, string, unknown>;
|
|
1279
|
+
selected: () => readonly string[];
|
|
1280
|
+
cursor?: CursorSpec;
|
|
1281
|
+
}): {
|
|
1282
|
+
layer: RenderLayer<unknown>;
|
|
1283
|
+
contribution: Contribution;
|
|
1284
|
+
};
|
|
1285
|
+
|
|
1286
|
+
/**
|
|
1287
|
+
* The route edits that are not drags: a double-click on a route handle, and
|
|
1288
|
+
* the Reset route command.
|
|
1289
|
+
*/
|
|
1290
|
+
|
|
1291
|
+
/** The action that removes a waypoint, straightens a segment, or unpins an
|
|
1292
|
+
* `avoid` connector's segment, on a double-click of its handle. */
|
|
1293
|
+
declare const REMOVE_WAYPOINT_ACTION_ID = "diagram.removeWaypoint";
|
|
1294
|
+
/** The command that clears the selected edges' waypoints. */
|
|
1295
|
+
declare const RESET_ROUTE_ACTION_ID = "diagram.resetRoute";
|
|
1296
|
+
/** The `diagram.removeWaypoint` action: a double-click on a waypoint's dot
|
|
1297
|
+
* removes it, and on a segment's bar straightens that jog away. Where it
|
|
1298
|
+
* would remove nothing it declines, so the double-click reaches whatever is
|
|
1299
|
+
* under the handle, an edge's label editing among them. */
|
|
1300
|
+
declare function createRemoveWaypointAction<TPose>(opts: RouteEditOptions<TPose>): Action;
|
|
1301
|
+
/** The `diagram.resetRoute` command: clears the selected edges' waypoints,
|
|
1302
|
+
* in one history entry when they commit to the scene. */
|
|
1303
|
+
declare function createResetRouteAction<TPose>(opts: RouteEditOptions<TPose>): Action;
|
|
1304
|
+
|
|
1305
|
+
/**
|
|
1306
|
+
* The commands that set the selected connectors' router: Around shapes,
|
|
1307
|
+
* Orthogonal, Straight, and Curved. Leaving `avoid` drops the stored route;
|
|
1308
|
+
* joining it leaves the route to the edit pass `useAvoidRouting` installs,
|
|
1309
|
+
* which routes the connectors in the same history entry.
|
|
1310
|
+
*/
|
|
1311
|
+
|
|
1312
|
+
/** The router commands' ids, by router key. */
|
|
1313
|
+
declare const SET_ROUTER_ACTION_IDS: {
|
|
1314
|
+
readonly avoid: "diagram.router.avoid";
|
|
1315
|
+
readonly orthogonal: "diagram.router.orthogonal";
|
|
1316
|
+
readonly straight: "diagram.router.straight";
|
|
1317
|
+
readonly bezier: "diagram.router.bezier";
|
|
1318
|
+
};
|
|
1319
|
+
/** Each shipped router's name in a menu. */
|
|
1320
|
+
declare const ROUTER_LABELS: Readonly<Record<keyof typeof SET_ROUTER_ACTION_IDS, string>>;
|
|
1321
|
+
/** One connector's router changed. */
|
|
1322
|
+
interface RouterEdit {
|
|
1323
|
+
edgeId: string;
|
|
1324
|
+
router: string;
|
|
1325
|
+
}
|
|
1326
|
+
/** Options for {@link createSetRouterAction}. */
|
|
1327
|
+
interface SetRouterOptions<TPose> {
|
|
1328
|
+
participants: ParticipantSource<TPose>;
|
|
1329
|
+
/** The selected ids; the connectors among them are set. */
|
|
1330
|
+
selected: () => readonly string[];
|
|
1331
|
+
/** Defaults to {@link commitRouterToScene} against `deps.scene`. */
|
|
1332
|
+
commit?: (edit: RouterEdit, ctx: InvocationCtx) => void;
|
|
1333
|
+
}
|
|
1334
|
+
/** `data` with its edge trait on `router`, its stored route dropped. */
|
|
1335
|
+
declare function withRouter(data: unknown, trait: DiagramEdge, router: string): Record<string, unknown>;
|
|
1336
|
+
/** The default commit: the connector's `data.diagram.router`, written to the scene. */
|
|
1337
|
+
declare function commitRouterToScene(edit: RouterEdit, ctx: InvocationCtx): void;
|
|
1338
|
+
/** The command that puts the selected connectors on `router`, in one history
|
|
1339
|
+
* entry. Active while every selected connector is on it already. */
|
|
1340
|
+
declare function createSetRouterAction<TPose>(router: keyof typeof SET_ROUTER_ACTION_IDS, opts: SetRouterOptions<TPose>): Action;
|
|
1341
|
+
/** One command per shipped router, in menu order. */
|
|
1342
|
+
declare function routerActions<TPose>(opts: SetRouterOptions<TPose>): Action[];
|
|
1343
|
+
|
|
1344
|
+
/**
|
|
1345
|
+
* Waypoints ride along with a move: when a whole-node transform carries both
|
|
1346
|
+
* ends of an edge by the same offset, the edge's waypoints go with them.
|
|
1347
|
+
* Otherwise they stay put — a route the author placed is not bent by moving
|
|
1348
|
+
* one end.
|
|
1349
|
+
*/
|
|
1350
|
+
|
|
1351
|
+
/**
|
|
1352
|
+
* The transform follower that carries waypoints along with a move, for the
|
|
1353
|
+
* `transformFollowers` dep (`useTransformFollower`). `geometry` reads a pose's
|
|
1354
|
+
* bounds; default `AUTO_POSE_DESCRIPTOR`.
|
|
1355
|
+
*/
|
|
1356
|
+
declare function waypointFollower<TPose>(scene: Scene<unknown, string, TPose>, geometry?: PoseDescriptor<TPose>): TransformFollower;
|
|
1357
|
+
|
|
1358
|
+
/**
|
|
1359
|
+
* A diagram scene as the avoid router reads it: every participant, container,
|
|
1360
|
+
* pool, group box, and header as an obstacle, and every `avoid` connector not
|
|
1361
|
+
* split across pages, with the ports each end may use and its label. A split
|
|
1362
|
+
* connector's label, on its first stub, is an obstacle of its own.
|
|
1363
|
+
*/
|
|
1364
|
+
|
|
1365
|
+
/** How a scene is read for routing. */
|
|
1366
|
+
interface AvoidSceneOptions<TPose> extends PortsOptions<TPose> {
|
|
1367
|
+
/** The router key whose connectors are routed. Default `'avoid'`. */
|
|
1368
|
+
routerKey?: string;
|
|
1369
|
+
}
|
|
1370
|
+
/** The id of a container's header obstacle. */
|
|
1371
|
+
declare const headerIdOf: (id: string) => string;
|
|
1372
|
+
/**
|
|
1373
|
+
* What the router reads off `scene`: its obstacles and its `avoid` connectors,
|
|
1374
|
+
* each node at the pose `poseOf` gives it, else the one the document holds.
|
|
1375
|
+
*/
|
|
1376
|
+
declare function avoidSceneInput<TPose>(scene: Scene<unknown, string, TPose>, opts?: AvoidSceneOptions<TPose>, poseOf?: (id: string) => TPose | undefined): AvoidInput;
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* Obstacle-avoiding routing on a live scene: a scene edit pass that reroutes
|
|
1380
|
+
* whatever an edit disturbed, in that edit's own history entry, and a
|
|
1381
|
+
* transform follower that reroutes the connectors near a dragged shape each
|
|
1382
|
+
* frame.
|
|
1383
|
+
*/
|
|
1384
|
+
|
|
1385
|
+
/** Options for {@link installAvoidRouting} and `useAvoidRouting`. */
|
|
1386
|
+
interface AvoidRoutingOptions<TPose> extends AvoidSceneOptions<TPose>, AvoidOptions {
|
|
1387
|
+
/** World units one screen pixel covers now. A drag frame that moves
|
|
1388
|
+
* nothing further than this does no work. Default 1. */
|
|
1389
|
+
pixelSize?: () => number;
|
|
1390
|
+
/** Milliseconds one drag frame may spend rerouting. Default 4. */
|
|
1391
|
+
frameBudgetMs?: number;
|
|
1392
|
+
}
|
|
1393
|
+
/** Routing installed on a scene. */
|
|
1394
|
+
interface AvoidRouting {
|
|
1395
|
+
router: AvoidRouter;
|
|
1396
|
+
/** The drag half, for the `transformFollowers` dep (`useTransformFollower`). */
|
|
1397
|
+
follower: TransformFollower;
|
|
1398
|
+
/** Remove the edit pass. */
|
|
1399
|
+
dispose(): void;
|
|
1400
|
+
}
|
|
1401
|
+
/** The data writes that store `routes` on their edges, skipping any unchanged. */
|
|
1402
|
+
declare function routeDataOps(scene: Scene<unknown, string, unknown>, routes: AvoidRoutes): Op[];
|
|
1403
|
+
/**
|
|
1404
|
+
* Route `scene`'s `avoid` connectors around its shapes from now on. Every
|
|
1405
|
+
* live edit reroutes what it disturbed, in its own history entry; on install
|
|
1406
|
+
* nothing reroutes, and the routes the scene holds stand. A host without
|
|
1407
|
+
* React calls this; a component calls `useAvoidRouting`.
|
|
1408
|
+
*/
|
|
1409
|
+
declare function installAvoidRouting<TPose>(scene: Scene<unknown, string, TPose>, opts?: AvoidRoutingOptions<TPose>): AvoidRouting;
|
|
1410
|
+
|
|
1411
|
+
/**
|
|
1412
|
+
* Where each of the diagram's scene edit passes runs among the others
|
|
1413
|
+
* (`scene.addEditPass`'s `order`). Each pass hears what the ones before it
|
|
1414
|
+
* wrote: markers are placed before routing sees them, routes before labels
|
|
1415
|
+
* dodge them, and line jumps last, on the routes as they end up.
|
|
1416
|
+
*/
|
|
1417
|
+
declare const DIAGRAM_PASS_ORDER: {
|
|
1418
|
+
readonly offPage: 100;
|
|
1419
|
+
readonly avoid: 200;
|
|
1420
|
+
readonly labels: 300;
|
|
1421
|
+
readonly hops: 400;
|
|
1422
|
+
};
|
|
1423
|
+
|
|
1424
|
+
/**
|
|
1425
|
+
* Route `scene`'s `avoid` connectors around its shapes for the life of the
|
|
1426
|
+
* calling component: each edit reroutes what it disturbed in its own history
|
|
1427
|
+
* entry, and a drag reroutes the connectors near what it moves each frame.
|
|
1428
|
+
* Mount it as a child of `<SceneCanvas>`, where the drag's follower is heard,
|
|
1429
|
+
* after any `waypointFollower`, whose carried waypoints the drag routes through.
|
|
1430
|
+
* Options are read when the scene changes; `pixelSize` defaults to the
|
|
1431
|
+
* canvas's own view.
|
|
1432
|
+
*/
|
|
1433
|
+
declare function useAvoidRouting<TPose>(scene: Scene<unknown, string, TPose>, opts?: AvoidRoutingOptions<TPose>): void;
|
|
1434
|
+
|
|
1435
|
+
/**
|
|
1436
|
+
* A function from specs to the same specs with each edge on `avoid` and
|
|
1437
|
+
* holding its route. It holds one router across calls, so each call reroutes
|
|
1438
|
+
* only the edges the change since the last one disturbed.
|
|
1439
|
+
*/
|
|
1440
|
+
declare function createSpecRouter(options?: AvoidOptions): (specs: readonly DiagramSpec[]) => DiagramSpec[];
|
|
1441
|
+
|
|
1442
|
+
/**
|
|
1443
|
+
* A connector's route drawn with its hops: each one a half circle in place of
|
|
1444
|
+
* the stretch of route it spans.
|
|
1445
|
+
*/
|
|
1446
|
+
|
|
1447
|
+
/**
|
|
1448
|
+
* The open path through `points`, bowing over each of `hops` in a half circle
|
|
1449
|
+
* of its radius. A hop more than half a unit off the route, or too near a bend
|
|
1450
|
+
* or an end for its half circle to fit on one segment, is stale and does not
|
|
1451
|
+
* draw; nor does one overlapping the hop before it.
|
|
1452
|
+
*/
|
|
1453
|
+
declare function withHops(points: readonly Vec2$1[], hops: readonly EdgeHop[]): Path$1;
|
|
1454
|
+
|
|
1455
|
+
/**
|
|
1456
|
+
* Line jumps on a live scene: an edit pass that recomputes the hops an edit
|
|
1457
|
+
* disturbed, in that edit's own history entry, while the document's
|
|
1458
|
+
* line-jump setting is on.
|
|
1459
|
+
*/
|
|
1460
|
+
|
|
1461
|
+
/** Options for {@link installHops} and `useHops`: how a connector routes, as
|
|
1462
|
+
* its own `derivePath` does. */
|
|
1463
|
+
type HopsOptions<TPose> = EdgeRouteOptions<TPose>;
|
|
1464
|
+
/** Line jumps installed on a scene. */
|
|
1465
|
+
interface Hops {
|
|
1466
|
+
/** The drag half, for the `transformFollowers` dep (`useTransformFollower`). */
|
|
1467
|
+
follower: TransformFollower;
|
|
1468
|
+
/** Remove the edit pass. */
|
|
1469
|
+
dispose(): void;
|
|
1470
|
+
}
|
|
1471
|
+
/**
|
|
1472
|
+
* Hop `scene`'s crossing connectors while its `HOPS_DOC_KEY` value is set.
|
|
1473
|
+
* Turning the value on or off, or changing its size, recomputes or clears
|
|
1474
|
+
* every connector in that same entry; any other edit recomputes the
|
|
1475
|
+
* connectors it rerouted and those whose routes meet theirs. Installing
|
|
1476
|
+
* writes nothing. A host without React calls this; a component calls `useHops`.
|
|
1477
|
+
*/
|
|
1478
|
+
declare function installHops<TPose>(scene: Scene<unknown, string, TPose>, opts?: HopsOptions<TPose>): Hops;
|
|
1479
|
+
|
|
1480
|
+
/**
|
|
1481
|
+
* The transform follower that hides hops while a drag is in progress: each
|
|
1482
|
+
* frame previews the connectors it moves, and every connector hopping over
|
|
1483
|
+
* one, without their hops. A hop stays where the edit pass put it, so it
|
|
1484
|
+
* would sit off a moving route; on release the pass recomputes them in the
|
|
1485
|
+
* drag's entry. Register it after any follower that reroutes connectors, whose
|
|
1486
|
+
* previewed data it keeps.
|
|
1487
|
+
*/
|
|
1488
|
+
declare function hopFollower<TPose>(scene: Scene<unknown, string, TPose>): TransformFollower;
|
|
1489
|
+
|
|
1490
|
+
/**
|
|
1491
|
+
* Hop `scene`'s crossing connectors for the life of the calling component,
|
|
1492
|
+
* while its line-jump setting is on: each edit recomputes the hops it
|
|
1493
|
+
* disturbed in its own history entry, and a drag hides the hops on what it
|
|
1494
|
+
* moves. Mount it as a child of `<SceneCanvas>`, after any routing hook, so its
|
|
1495
|
+
* follower hears the routes that one previews. Options are read when the scene
|
|
1496
|
+
* changes.
|
|
1497
|
+
*/
|
|
1498
|
+
declare function useHops<TPose>(scene: Scene<unknown, string, TPose>, opts?: HopsOptions<TPose>): void;
|
|
1499
|
+
|
|
1500
|
+
/** The line jumps command's id. */
|
|
1501
|
+
declare const SET_HOPS_ACTION_ID = "diagram.hops";
|
|
1502
|
+
/** Options for {@link createSetHopsAction}. */
|
|
1503
|
+
interface SetHopsOptions {
|
|
1504
|
+
/** The radius hops take when the command turns them on. Default
|
|
1505
|
+
* {@link DEFAULT_HOP_SIZE}. */
|
|
1506
|
+
size?: number;
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* The command that turns line jumps on for the whole document, or off, by
|
|
1510
|
+
* writing its `HOPS_DOC_KEY` value: one history entry, which the hop pass
|
|
1511
|
+
* (`useHops`) joins with every connector's hops. Active while they are on.
|
|
1512
|
+
*/
|
|
1513
|
+
declare function createSetHopsAction(opts?: SetHopsOptions): Action;
|
|
1514
|
+
|
|
1515
|
+
/** A function from specs to the same specs with every edge's hops of radius
|
|
1516
|
+
* `r`, edges hopping those earlier in the list. An edge split across pages
|
|
1517
|
+
* takes no part. */
|
|
1518
|
+
declare function createSpecHops(r: number): (specs: readonly DiagramSpec[]) => DiagramSpec[];
|
|
1519
|
+
|
|
1520
|
+
/**
|
|
1521
|
+
* Reconnect — dragging a selected edge's end onto another port or shape.
|
|
1522
|
+
*
|
|
1523
|
+
* The edge-end handles (`edgeEndLayer`) claim the press; this action carries
|
|
1524
|
+
* the end. It lands where a connect from the edge's other end would land, by
|
|
1525
|
+
* the same resolver and the same `canConnect`, asked with the edge's from/to
|
|
1526
|
+
* order kept, so a reconnect can never make an edge a connect could not.
|
|
1527
|
+
*/
|
|
1528
|
+
|
|
1529
|
+
/** The action that drags an edge end onto a new port or body. */
|
|
1530
|
+
declare const RECONNECT_ACTION_ID = "diagram.reconnect";
|
|
1531
|
+
/** The action id that absorbs a press on an edge-end handle. */
|
|
1532
|
+
declare const GRAB_EDGE_END_ACTION_ID = "diagram.grabEdgeEnd";
|
|
1533
|
+
/** One end of one edge, moved onto `target`. */
|
|
1534
|
+
interface EndChange {
|
|
1535
|
+
edgeId: string;
|
|
1536
|
+
end: 'from' | 'to';
|
|
1537
|
+
target: ConnectEnd;
|
|
1538
|
+
}
|
|
1539
|
+
/** Options for {@link createReconnectAction}. `bodies` defaults to true: an end
|
|
1540
|
+
* may be dropped on a shape's body. */
|
|
1541
|
+
interface ReconnectOptions<TPose> extends Omit<ConnectActionOptions<TPose>, 'commit' | 'startFrom'> {
|
|
1542
|
+
/** The selected edge ids whose ends show handles. */
|
|
1543
|
+
selected: () => readonly string[];
|
|
1544
|
+
/** Defaults to {@link commitReconnectToScene} against `deps.scene`. */
|
|
1545
|
+
commit?: (change: EndChange, ctx: InvocationCtx) => void;
|
|
1546
|
+
}
|
|
1547
|
+
/**
|
|
1548
|
+
* The default commit: rewrites the moved end in `data.diagram` — `{ port }`,
|
|
1549
|
+
* or `{}` for a body — and points the edge's `dependsOn` at the new node, as
|
|
1550
|
+
* one history entry.
|
|
1551
|
+
*/
|
|
1552
|
+
declare function commitReconnectToScene(change: EndChange, ctx: InvocationCtx): void;
|
|
1553
|
+
/** The `diagram.reconnect` action: an ongoing drag carrying one edge end. */
|
|
1554
|
+
declare function createReconnectAction<TPose>(opts: ReconnectOptions<TPose>): Action;
|
|
1555
|
+
/** The binding that starts a reconnect: a drag pressed on an edge-end handle. */
|
|
1556
|
+
declare function reconnectBinding(actionId?: string): GestureBinding;
|
|
1557
|
+
/**
|
|
1558
|
+
* Both halves of reconnect: the handle layer to `registerLayer` — after the
|
|
1559
|
+
* port layer, since an edge's end sits on a port — and the contribution to
|
|
1560
|
+
* pass as `ambient`. Like `diagramPorts`, one without the other fails quietly.
|
|
1561
|
+
*/
|
|
1562
|
+
declare function diagramEdgeEnds<TPose>(opts: ReconnectOptions<TPose> & Omit<EdgeEndAffordanceOptions<TPose>, 'id'>): {
|
|
1563
|
+
layer: RenderLayer<unknown>;
|
|
1564
|
+
contribution: Contribution;
|
|
1565
|
+
};
|
|
1566
|
+
|
|
1567
|
+
/**
|
|
1568
|
+
* Reordering a group marked `reorder`: a member dragged along that axis among
|
|
1569
|
+
* its siblings, which slide into the places they would take, or the selected
|
|
1570
|
+
* one stepped with Alt and an arrow key. Nothing is written: the host hears
|
|
1571
|
+
* the new order, writes it to its data, and layout keeps it.
|
|
1572
|
+
*/
|
|
1573
|
+
|
|
1574
|
+
/** Alt and an arrow key: the selected member one place along. */
|
|
1575
|
+
declare const STEP_REORDER_ACTION_ID = "diagram.stepReorder";
|
|
1576
|
+
/** A reorderable group's members in their new order. */
|
|
1577
|
+
interface ReorderChange {
|
|
1578
|
+
group: string;
|
|
1579
|
+
order: readonly string[];
|
|
1580
|
+
}
|
|
1581
|
+
/** The members of the reorderable group a press at `at` carries one of, each
|
|
1582
|
+
* with everything drawn with it, or `null` off any such group. */
|
|
1583
|
+
declare function groupReorderSlots(deps: ActionDeps, at: Vec2): ReorderSlots | null;
|
|
1584
|
+
/** Steps the selected node's member one place toward the start (`-1`) or the end (`1`). */
|
|
1585
|
+
declare function createStepReorderAction(report: (change: ReorderChange) => void): Action;
|
|
1586
|
+
/** Everything `DiagramView` installs for `onReorder`: the reorder drag,
|
|
1587
|
+
* sliding, pressed on a node's body, and the step action. */
|
|
1588
|
+
declare function groupReorderContribution(report: (change: ReorderChange) => void): Contribution;
|
|
338
1589
|
|
|
339
1590
|
/** How a self-edge with no ports named leaves its node and comes back. */
|
|
340
1591
|
interface SelfLoop {
|
|
@@ -355,6 +1606,111 @@ interface SelfLoop {
|
|
|
355
1606
|
*/
|
|
356
1607
|
declare function selfLoop(ports: readonly Port[], standoff: number): SelfLoop | null;
|
|
357
1608
|
|
|
1609
|
+
/**
|
|
1610
|
+
* Edge labels: the one place a label node's spec is made, and the action that
|
|
1611
|
+
* adds or edits an edge's label on a double-click.
|
|
1612
|
+
*/
|
|
1613
|
+
|
|
1614
|
+
/** The box a label's text takes: measured width, and a height of the font size
|
|
1615
|
+
* whatever the measure reports. */
|
|
1616
|
+
declare function labelSize(text: string, style: RowTextStyle, measure?: MeasureRowText): {
|
|
1617
|
+
width: number;
|
|
1618
|
+
height: number;
|
|
1619
|
+
};
|
|
1620
|
+
/** Options for {@link edgeLabelSpec}. */
|
|
1621
|
+
interface EdgeLabelOptions<TLayer extends string> {
|
|
1622
|
+
layer: TLayer;
|
|
1623
|
+
/** Where along the edge it sits. Default {@link LABEL_PLACEMENT}. */
|
|
1624
|
+
label?: DiagramLabel;
|
|
1625
|
+
style?: RowTextStyle;
|
|
1626
|
+
/** Text color. */
|
|
1627
|
+
fill?: string;
|
|
1628
|
+
/** Sizes the box. Default: a per-character estimate. */
|
|
1629
|
+
measure?: MeasureRowText;
|
|
1630
|
+
}
|
|
1631
|
+
/** The label node for edge `edgeId`: a leaf that derives its pose from the edge's route. */
|
|
1632
|
+
declare function edgeLabelSpec<TLayer extends string>(edgeId: string, text: string, opts: EdgeLabelOptions<TLayer>): AddNodeSpec<unknown, TLayer, RectPose>;
|
|
1633
|
+
/**
|
|
1634
|
+
* Removes node `id` if it is an edge label left with no text, and says whether
|
|
1635
|
+
* it did. The default edit adds a label before its text is typed, so a host
|
|
1636
|
+
* passes this as its text edit's `onEnd` to drop one that ends empty.
|
|
1637
|
+
*/
|
|
1638
|
+
declare function dropEmptyEdgeLabel(scene: Scene<unknown, string, unknown>, id: string): boolean;
|
|
1639
|
+
/** The action that adds or edits an edge's label. */
|
|
1640
|
+
declare const EDIT_EDGE_LABEL_ACTION_ID = "diagram.editEdgeLabel";
|
|
1641
|
+
/** Options for {@link editEdgeLabelAction}. */
|
|
1642
|
+
interface EditEdgeLabelOptions {
|
|
1643
|
+
/** Runs in place of the default add-then-edit. */
|
|
1644
|
+
commit?: (edgeId: string, ctx: InvocationCtx) => void;
|
|
1645
|
+
/** The face a new label is set in. Default the diagram's, two sizes down. Ignored when `commit` is given. */
|
|
1646
|
+
style?: RowTextStyle;
|
|
1647
|
+
/** A new label's text color. Ignored when `commit` is given. */
|
|
1648
|
+
fill?: string;
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Creates an edge's label, or edits the one it has, where a double-click
|
|
1652
|
+
* lands on the edge. It declines a double-click on anything else.
|
|
1653
|
+
*
|
|
1654
|
+
* An immediate invoker is handed no `InvocationCtx`, so `commit` gets one
|
|
1655
|
+
* built from the deps and the click point.
|
|
1656
|
+
*/
|
|
1657
|
+
declare function editEdgeLabelAction(opts?: EditEdgeLabelOptions): Action;
|
|
1658
|
+
/** A double-click on a node's body; the action itself declines unless that node is an edge. */
|
|
1659
|
+
declare function editEdgeLabelBinding(actionId?: string): GestureBinding;
|
|
1660
|
+
|
|
1661
|
+
/**
|
|
1662
|
+
* What makes an edge label grabbable, so a drag can move it along and beside
|
|
1663
|
+
* its edge (`labelDragAction`).
|
|
1664
|
+
*
|
|
1665
|
+
* Built the way the route handles are: rect regions with a `null` `targetId`
|
|
1666
|
+
* and no paint, composed into a layer whose id is the kind a press reports.
|
|
1667
|
+
*/
|
|
1668
|
+
|
|
1669
|
+
/** The layer id the label regions are composed into. */
|
|
1670
|
+
declare const LABEL_DRAG_LAYER_ID = "diagram-edge-labels";
|
|
1671
|
+
/** The affordance kind a press on an edge label reports. */
|
|
1672
|
+
declare const LABEL_DRAG_AFFORDANCE_KIND: "layer:diagram-edge-labels";
|
|
1673
|
+
/** What a press on an edge label hands the label actions, as the hit's `payload`. */
|
|
1674
|
+
interface LabelScratch {
|
|
1675
|
+
targetId: string;
|
|
1676
|
+
labelId: string;
|
|
1677
|
+
edgeId: string;
|
|
1678
|
+
}
|
|
1679
|
+
/** Read a label press's scratch back off the hit an action was handed. */
|
|
1680
|
+
declare function labelScratchOf(hit: {
|
|
1681
|
+
payload?: unknown;
|
|
1682
|
+
} | null | undefined): LabelScratch | null;
|
|
1683
|
+
/** A label a press can pick up: its box as the document places it, and its edge's route. */
|
|
1684
|
+
interface DraggableLabel {
|
|
1685
|
+
labelId: string;
|
|
1686
|
+
edgeId: string;
|
|
1687
|
+
box: Bounds$2;
|
|
1688
|
+
path: Path$2;
|
|
1689
|
+
}
|
|
1690
|
+
/** Every editable label in `scene` whose edge derives a path, in render order. */
|
|
1691
|
+
declare function draggableLabels(scene: Scene<unknown, string, unknown>): Iterable<DraggableLabel>;
|
|
1692
|
+
/** The topmost draggable label whose box holds `at`, as its press scratch. */
|
|
1693
|
+
declare function labelUnder(scene: Scene<unknown, string, unknown>, at: Vec2$1): LabelScratch | null;
|
|
1694
|
+
/** The composed layer, for `CanvasExtensionApi.registerLayer`. Register it
|
|
1695
|
+
* before the port layer: the last registered is hit first, and a port or a
|
|
1696
|
+
* route handle must win over a label beside it. */
|
|
1697
|
+
declare function labelDragLayer(scene: Scene<unknown, string, unknown>, opts?: {
|
|
1698
|
+
cursor?: CursorSpec;
|
|
1699
|
+
}): RenderLayer<unknown>;
|
|
1700
|
+
|
|
1701
|
+
/**
|
|
1702
|
+
* The label edit that is not a drag: the Reset label command.
|
|
1703
|
+
*/
|
|
1704
|
+
|
|
1705
|
+
/** The command that puts the selected edges' dragged labels back where placement puts them. */
|
|
1706
|
+
declare const RESET_LABEL_ACTION_ID = "diagram.resetLabel";
|
|
1707
|
+
/** The `diagram.resetLabel` command: sets each selected edge's dragged label
|
|
1708
|
+
* back to `LABEL_PLACEMENT`, in one history entry when they commit to the scene. */
|
|
1709
|
+
declare function createResetLabelAction(opts: {
|
|
1710
|
+
selected: () => readonly string[];
|
|
1711
|
+
commit?: (edit: LabelEdit, ctx: InvocationCtx) => void;
|
|
1712
|
+
}): Action;
|
|
1713
|
+
|
|
358
1714
|
/**
|
|
359
1715
|
* A label on an edge: an ordinary leaf node that derives its *pose* from the
|
|
360
1716
|
* route it sits on.
|
|
@@ -365,285 +1721,329 @@ declare function selfLoop(ports: readonly Port[], standoff: number): SelfLoop |
|
|
|
365
1721
|
* data, styling, z-order and selection.
|
|
366
1722
|
*/
|
|
367
1723
|
|
|
368
|
-
/** Where along an edge a label sits. */
|
|
369
|
-
interface DiagramLabel {
|
|
370
|
-
/** `'start'`, `'mid'` and `'end'` are 0, 0.5 and 1; a number is that
|
|
371
|
-
* fraction of the route's length. */
|
|
372
|
-
at: 'start' | 'mid' | 'end' | number;
|
|
373
|
-
/** World units between the route and the label's near side, to the **left
|
|
374
|
-
* of the direction of travel** — above a left-to-right edge. Default 0,
|
|
375
|
-
* which centers the label on the line. */
|
|
376
|
-
offset?: number;
|
|
377
|
-
}
|
|
378
|
-
/** The label trait on a node's data, or `null`. */
|
|
379
|
-
declare function diagramLabelOf(node: {
|
|
380
|
-
data: unknown;
|
|
381
|
-
}): DiagramLabel | null;
|
|
382
1724
|
/** Options for {@link labelDerivePose}. `geometry` defaults to the kit's
|
|
383
1725
|
* `AUTO_POSE_DESCRIPTOR`. */
|
|
384
1726
|
interface LabelPoseOptions<TPose> {
|
|
385
1727
|
geometry?: PoseDescriptor<TPose>;
|
|
386
1728
|
}
|
|
387
1729
|
/**
|
|
388
|
-
* A `derivePose` that stations a label along its dependency's path.
|
|
389
|
-
*
|
|
390
|
-
* Returns `null` — nothing derived, so the node keeps its authored pose —
|
|
391
|
-
* when the node carries no label trait, when the dependency is gone, or when
|
|
392
|
-
* the dependency derives no path. A label that snapped to the origin because
|
|
393
|
-
* its edge was deleted is worse than one that stayed where the author left it.
|
|
1730
|
+
* A `derivePose` that stations a label along its dependency's path.
|
|
1731
|
+
*
|
|
1732
|
+
* Returns `null` — nothing derived, so the node keeps its authored pose —
|
|
1733
|
+
* when the node carries no label trait, when the dependency is gone, or when
|
|
1734
|
+
* the dependency derives no path. A label that snapped to the origin because
|
|
1735
|
+
* its edge was deleted is worse than one that stayed where the author left it.
|
|
1736
|
+
*/
|
|
1737
|
+
declare function labelDerivePose<TPose>(opts?: LabelPoseOptions<TPose>): (node: {
|
|
1738
|
+
pose: TPose;
|
|
1739
|
+
data: unknown;
|
|
1740
|
+
}, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null;
|
|
1741
|
+
/** Registry key for {@link LABEL_DERIVE_POSE}. */
|
|
1742
|
+
declare const DIAGRAM_LABEL = "diagram:label";
|
|
1743
|
+
/** The default label derivation, as one stable function reference so `toJSON`
|
|
1744
|
+
* can find its key. */
|
|
1745
|
+
declare const LABEL_DERIVE_POSE: (node: {
|
|
1746
|
+
pose: unknown;
|
|
1747
|
+
data: unknown;
|
|
1748
|
+
}, deps: readonly (DerivedDep<unknown, unknown, string> | undefined)[]) => unknown;
|
|
1749
|
+
|
|
1750
|
+
/**
|
|
1751
|
+
* Label placement on a live scene: a scene edit pass that moves the labels
|
|
1752
|
+
* an edit covered to the nearest clear station, in that edit's own history
|
|
1753
|
+
* entry. It runs after routing, so labels dodge the routes the edit made.
|
|
1754
|
+
*/
|
|
1755
|
+
|
|
1756
|
+
/** Options for {@link installLabelPlacement} and `useLabelPlacement`. */
|
|
1757
|
+
interface LabelPlacementOptions<TPose> extends PlaceLabelsOptions {
|
|
1758
|
+
geometry?: PoseDescriptor<TPose>;
|
|
1759
|
+
/** How a node's diagram trait is read. Default its own `data.diagram`. */
|
|
1760
|
+
read?: DiagramNodeReader;
|
|
1761
|
+
/** Sizes a label to the text an edit gives it. Default a per-character estimate. */
|
|
1762
|
+
measure?: MeasureRowText;
|
|
1763
|
+
}
|
|
1764
|
+
/** Placement installed on a scene. */
|
|
1765
|
+
interface LabelPlacement {
|
|
1766
|
+
/** Remove the edit pass. */
|
|
1767
|
+
dispose(): void;
|
|
1768
|
+
}
|
|
1769
|
+
/**
|
|
1770
|
+
* Move `scene`'s edge labels off whatever an edit leaves covering them, from
|
|
1771
|
+
* now on: each live edit places the labels it may have covered, in its own
|
|
1772
|
+
* history entry. Labels hold still during a drag and settle on release. A
|
|
1773
|
+
* host without React calls this; a component calls `useLabelPlacement`.
|
|
1774
|
+
*/
|
|
1775
|
+
declare function installLabelPlacement<TPose>(scene: Scene<unknown, string, TPose>, opts?: LabelPlacementOptions<TPose>): LabelPlacement;
|
|
1776
|
+
|
|
1777
|
+
/**
|
|
1778
|
+
* Move `scene`'s edge labels off whatever an edit leaves covering them, for
|
|
1779
|
+
* the life of the calling component, each edit's moves in its own history
|
|
1780
|
+
* entry. Options are read when the scene changes.
|
|
1781
|
+
*/
|
|
1782
|
+
declare function useLabelPlacement<TPose>(scene: Scene<unknown, string, TPose>, opts?: LabelPlacementOptions<TPose>): void;
|
|
1783
|
+
|
|
1784
|
+
/**
|
|
1785
|
+
* A function from specs to the same specs with each edge label placed off
|
|
1786
|
+
* whatever covers it. Every label is placed afresh, in id order, whenever
|
|
1787
|
+
* the shapes, routes, or labels change, and the last answer is reused while
|
|
1788
|
+
* they do not. Run it after any router, so labels dodge the routes drawn.
|
|
1789
|
+
*/
|
|
1790
|
+
declare function createSpecLabelPlacer(opts?: PlaceLabelsOptions): (specs: readonly DiagramSpec[]) => DiagramSpec[];
|
|
1791
|
+
|
|
1792
|
+
/**
|
|
1793
|
+
* An off-page tag: a text leaf with a background that names the far page and
|
|
1794
|
+
* the reference, and stations itself past the tip of its connector's stub.
|
|
1795
|
+
*/
|
|
1796
|
+
|
|
1797
|
+
/** How a tag is drawn: its face, its text color, and the box behind the text. */
|
|
1798
|
+
interface OffPageTagLook {
|
|
1799
|
+
style: RowTextStyle;
|
|
1800
|
+
fill: string;
|
|
1801
|
+
background: string;
|
|
1802
|
+
/** World units between the box and the text. Default {@link OFF_PAGE_TAG_PADDING}. */
|
|
1803
|
+
padding?: number;
|
|
1804
|
+
/** Sizes the text. Default: a per-character estimate. */
|
|
1805
|
+
measure?: MeasureRowText;
|
|
1806
|
+
}
|
|
1807
|
+
/** A tag's default padding, in world units. */
|
|
1808
|
+
declare const OFF_PAGE_TAG_PADDING = 3;
|
|
1809
|
+
/** A tag's look under `theme`: the theme's connector-label face and color, on its page color. */
|
|
1810
|
+
declare const offPageTagLook: (theme: DiagramTheme) => OffPageTagLook;
|
|
1811
|
+
/** What a tag reads: the far page's name and the connector's reference. */
|
|
1812
|
+
declare const offPageTagText: (pageName: string, ref: string) => string;
|
|
1813
|
+
/** What the tag at `end` of a split reads: the page at the other end, by name or place, else its raw id, and the reference. */
|
|
1814
|
+
declare function offPageFarText(pages: readonly PlacedPage[], split: OffPageSplit, end: 'from' | 'to'): string;
|
|
1815
|
+
/** The box a tag of `text` takes in `look`. */
|
|
1816
|
+
declare function offPageTagSize(text: string, look: OffPageTagLook): {
|
|
1817
|
+
width: number;
|
|
1818
|
+
height: number;
|
|
1819
|
+
};
|
|
1820
|
+
/** The tag `data` for end `end` of `edgeId`, reading `text` in `look`. */
|
|
1821
|
+
declare function offPageTagData(edgeId: string, end: 'from' | 'to', text: string, look: OffPageTagLook): {
|
|
1822
|
+
diagram: {
|
|
1823
|
+
offPageTag: {
|
|
1824
|
+
edge: string;
|
|
1825
|
+
end: "from" | "to";
|
|
1826
|
+
};
|
|
1827
|
+
};
|
|
1828
|
+
text: string;
|
|
1829
|
+
style: RowTextStyle;
|
|
1830
|
+
fill: {
|
|
1831
|
+
paint: {
|
|
1832
|
+
color: string;
|
|
1833
|
+
};
|
|
1834
|
+
};
|
|
1835
|
+
background: {
|
|
1836
|
+
paint: {
|
|
1837
|
+
color: string;
|
|
1838
|
+
};
|
|
1839
|
+
};
|
|
1840
|
+
padding: number;
|
|
1841
|
+
};
|
|
1842
|
+
/** The tag node at end `end` of connector `edgeId`, on `layer`: it derives its pose from the connector's stub. */
|
|
1843
|
+
declare function offPageTagSpec<TLayer extends string>(edgeId: string, end: 'from' | 'to', text: string, look: OffPageTagLook & {
|
|
1844
|
+
layer: TLayer;
|
|
1845
|
+
}): AddNodeSpec<unknown, TLayer, RectPose>;
|
|
1846
|
+
/** A split connector's two tag specs, `from` then `to`. */
|
|
1847
|
+
declare function offPageTagSpecs<TLayer extends string>(edgeId: string, split: OffPageSplit, pages: readonly PlacedPage[], look: OffPageTagLook & {
|
|
1848
|
+
layer: TLayer;
|
|
1849
|
+
}): AddNodeSpec<unknown, TLayer, RectPose>[];
|
|
1850
|
+
/**
|
|
1851
|
+
* A `derivePose` that stations a tag just past its stub's tip, on the far
|
|
1852
|
+
* side from the shape. `null`, so the tag keeps its authored pose, while its
|
|
1853
|
+
* connector draws no stub at that end.
|
|
394
1854
|
*/
|
|
395
|
-
declare function
|
|
1855
|
+
declare function offPageTagDerivePose<TPose>(opts?: {
|
|
1856
|
+
geometry?: PoseDescriptor<TPose>;
|
|
1857
|
+
}): (node: {
|
|
396
1858
|
pose: TPose;
|
|
397
1859
|
data: unknown;
|
|
398
1860
|
}, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null;
|
|
399
|
-
/** Registry key for {@link
|
|
400
|
-
declare const
|
|
401
|
-
/** The default
|
|
402
|
-
|
|
403
|
-
declare const LABEL_DERIVE_POSE: (node: {
|
|
1861
|
+
/** Registry key for {@link OFF_PAGE_TAG_DERIVE_POSE}. */
|
|
1862
|
+
declare const DIAGRAM_OFF_PAGE_TAG = "diagram:offPageTag";
|
|
1863
|
+
/** The default tag derivation, as one stable function reference so `toJSON` can find its key. */
|
|
1864
|
+
declare const OFF_PAGE_TAG_DERIVE_POSE: (node: {
|
|
404
1865
|
pose: unknown;
|
|
405
1866
|
data: unknown;
|
|
406
1867
|
}, deps: readonly (DerivedDep<unknown, unknown, string> | undefined)[]) => unknown;
|
|
407
1868
|
|
|
1869
|
+
/** The pages a {@link DiagramData} is drawn on, and the connectors that cross between them. */
|
|
1870
|
+
|
|
1871
|
+
/** `data`'s pages, placed in world space. */
|
|
1872
|
+
declare function diagramPages(data: DiagramData): PlacedPage[];
|
|
408
1873
|
/**
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
/** The point on the dependency's bounds, normalized as a port's is. */
|
|
423
|
-
at: PortAnchor;
|
|
424
|
-
/** The point on the node's own bounds that lands there. Default `at`, so
|
|
425
|
-
* `{ u: 0, v: 0 }` puts the node's top-left on the dependency's. */
|
|
426
|
-
self?: PortAnchor;
|
|
427
|
-
/** Then moved by this much, in world units. */
|
|
428
|
-
offset?: Vec2$1;
|
|
429
|
-
}
|
|
430
|
-
/** The group trait on a node's data, or `null`. */
|
|
431
|
-
declare function diagramGroupOf(node: {
|
|
432
|
-
data: unknown;
|
|
433
|
-
}): DiagramGroup | null;
|
|
434
|
-
/** The anchor trait on a node's data, or `null`. */
|
|
435
|
-
declare function diagramAnchorOf(node: {
|
|
436
|
-
data: unknown;
|
|
437
|
-
}): DiagramAnchor | null;
|
|
438
|
-
/** Options for {@link groupDerivePose} and {@link anchorDerivePose}.
|
|
439
|
-
* `geometry` defaults to the kit's `AUTO_POSE_DESCRIPTOR`. */
|
|
440
|
-
interface GroupPoseOptions<TPose> {
|
|
441
|
-
geometry?: PoseDescriptor<TPose>;
|
|
442
|
-
}
|
|
443
|
-
/** A `derivePose` function as the scene calls it: the node, then what it depends on, in `dependsOn` order. */
|
|
444
|
-
type DiagramDerivePose<TPose> = (node: {
|
|
445
|
-
pose: TPose;
|
|
446
|
-
data: unknown;
|
|
447
|
-
}, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null;
|
|
1874
|
+
* Which of `edges` cross between `pages`, lettered in their order, and the two
|
|
1875
|
+
* off-page tags of each that does. An edge with an end `boxOf` has no box for
|
|
1876
|
+
* is left whole.
|
|
1877
|
+
*/
|
|
1878
|
+
declare function dataOffPage(edges: readonly {
|
|
1879
|
+
id: string;
|
|
1880
|
+
from: string;
|
|
1881
|
+
to: string;
|
|
1882
|
+
}[], pages: readonly PlacedPage[], boxOf: (id: string) => Bounds$3 | undefined, look: OffPageTagLook): {
|
|
1883
|
+
splits: ReadonlyMap<string, OffPageSplit>;
|
|
1884
|
+
tags: DiagramSpec[];
|
|
1885
|
+
};
|
|
1886
|
+
|
|
448
1887
|
/**
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
* carries no group trait or every member is gone.
|
|
1888
|
+
* Which connectors cross from one page to another, as arithmetic: page
|
|
1889
|
+
* rects and end boxes in, splits out. Nothing here reads a scene.
|
|
452
1890
|
*/
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
* widened evenly to its `minWidth`. */
|
|
456
|
-
declare function boxAround(union: {
|
|
457
|
-
x: number;
|
|
458
|
-
y: number;
|
|
459
|
-
width: number;
|
|
460
|
-
height: number;
|
|
461
|
-
}, group: DiagramGroup): {
|
|
1891
|
+
|
|
1892
|
+
type Box$1 = {
|
|
462
1893
|
x: number;
|
|
463
1894
|
y: number;
|
|
464
1895
|
width: number;
|
|
465
1896
|
height: number;
|
|
466
1897
|
};
|
|
1898
|
+
/** One connector as {@link offPageSplits} reads it: its two ends' world boxes,
|
|
1899
|
+
* and the split it holds now, if any. */
|
|
1900
|
+
interface OffPageEdgeInput {
|
|
1901
|
+
id: string;
|
|
1902
|
+
from: Box$1;
|
|
1903
|
+
to: Box$1;
|
|
1904
|
+
offPage?: OffPageSplit | undefined;
|
|
1905
|
+
}
|
|
1906
|
+
/** What {@link offPageSplits} reads. */
|
|
1907
|
+
interface OffPageSplitInput {
|
|
1908
|
+
pages: readonly PlacedPage[];
|
|
1909
|
+
edges: readonly OffPageEdgeInput[];
|
|
1910
|
+
/** Refs held by split connectors not in `edges`, which no edge here may take. */
|
|
1911
|
+
used?: Iterable<string>;
|
|
1912
|
+
}
|
|
1913
|
+
/** The first ref, in A…Z, AA… order, that `used` does not hold. */
|
|
1914
|
+
declare function nextOffPageRef(used: ReadonlySet<string>): string;
|
|
467
1915
|
/**
|
|
468
|
-
*
|
|
469
|
-
*
|
|
1916
|
+
* Each connector's split, or `null` where it stays whole. A connector splits
|
|
1917
|
+
* when its two ends belong to different pages (`pageOfBounds`); an end in a
|
|
1918
|
+
* gap belongs to none, and never splits. A split keeps the ref it holds while
|
|
1919
|
+
* no earlier connector here or `used` holds it too; a new one takes the next
|
|
1920
|
+
* free ref.
|
|
470
1921
|
*/
|
|
471
|
-
declare function
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
declare const GROUP_DERIVE_POSE: DiagramDerivePose<unknown>;
|
|
478
|
-
/** The default anchor derivation, a stable reference for the same reason. */
|
|
479
|
-
declare const ANCHOR_DERIVE_POSE: DiagramDerivePose<unknown>;
|
|
1922
|
+
declare function offPageSplits(input: OffPageSplitInput): Map<string, OffPageSplit | null>;
|
|
1923
|
+
|
|
1924
|
+
/** The box `node` has in document space, which is where pages are: its pose through every ancestor's transform. */
|
|
1925
|
+
declare function documentBoundsOf<TPose>(scene: Scene<unknown, string, TPose>, node: {
|
|
1926
|
+
id: string;
|
|
1927
|
+
}, geometry?: PoseDescriptor<unknown>): Bounds$3;
|
|
480
1928
|
|
|
481
1929
|
/**
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
* counts unless `measure` is given, so layout runs without a canvas and gives
|
|
487
|
-
* the same answer in node and in a browser.
|
|
1930
|
+
* Off-page markers on a live scene: an edit pass that splits a connector
|
|
1931
|
+
* whose ends land on different pages, joins one whose ends share a page
|
|
1932
|
+
* again, and keeps each split connector's two tags, all in the entry of the
|
|
1933
|
+
* edit that caused it.
|
|
488
1934
|
*/
|
|
489
1935
|
|
|
490
|
-
/**
|
|
491
|
-
interface
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
ports?: readonly PortSpec[];
|
|
500
|
-
/** Layout leaves this node at `at`. */
|
|
501
|
-
pinned?: boolean;
|
|
502
|
-
/** Where the node starts, before layout. Unset, nodes start on the
|
|
503
|
-
* diagonal in source order, which is what within-rank order is seeded
|
|
504
|
-
* from. */
|
|
505
|
-
at?: Vec2$1;
|
|
506
|
-
/** The smallest the box may be. Its content grows it past this. */
|
|
507
|
-
width?: number;
|
|
508
|
-
height?: number;
|
|
509
|
-
/** Default `DiagramSceneOptions.padding`. */
|
|
510
|
-
padding?: number;
|
|
511
|
-
/** Default `DiagramSceneOptions.gap`. */
|
|
512
|
-
gap?: number;
|
|
513
|
-
/** Default `DiagramSceneOptions.verticalAlign`. */
|
|
514
|
-
verticalAlign?: BodySpec['verticalAlign'];
|
|
515
|
-
}
|
|
516
|
-
/** One edge of a {@link DiagramData}, between two nodes or groups by id. */
|
|
517
|
-
interface DataEdge {
|
|
518
|
-
/** A node's id, or a group's: an edge naming a group meets its box. */
|
|
519
|
-
from: string;
|
|
520
|
-
to: string;
|
|
521
|
-
/** The port to leave from or arrive at. Unset, the end facing the other
|
|
522
|
-
* node most directly. */
|
|
523
|
-
fromPort?: string;
|
|
524
|
-
toPort?: string;
|
|
525
|
-
label?: string;
|
|
526
|
-
/** Where along the edge the label sits. Default `DiagramSceneOptions.labelPlacement`. */
|
|
527
|
-
labelPlacement?: DiagramLabel;
|
|
528
|
-
/** Default `DiagramSceneOptions.router`. */
|
|
529
|
-
router?: DiagramRouter;
|
|
530
|
-
/** World points the route passes through. Layout does not move them. */
|
|
531
|
-
waypoints?: readonly Vec2$1[];
|
|
532
|
-
}
|
|
533
|
-
/** A box drawn around some nodes, which layout keeps together. */
|
|
534
|
-
interface DataGroup {
|
|
535
|
-
/** Shares one namespace with node ids. */
|
|
536
|
-
id: string;
|
|
537
|
-
/** Node ids, and the ids of groups nested in this one. A node or group a
|
|
538
|
-
* later group also names stays in this one; an id that is neither is
|
|
539
|
-
* ignored, and so is one that would put a group inside itself. */
|
|
540
|
-
members: readonly string[];
|
|
541
|
-
/** Drawn inside the box, above its members. */
|
|
542
|
-
label?: string;
|
|
543
|
-
/** Between the box and its members, and around the label. Default
|
|
544
|
-
* `DiagramSceneOptions.groupPadding`. */
|
|
545
|
-
padding?: number;
|
|
1936
|
+
/** Options for {@link installOffPageMarkers} and `useOffPageMarkers`. */
|
|
1937
|
+
interface OffPageMarkerOptions<TPose> {
|
|
1938
|
+
/** How node poses are measured. Default `AUTO_POSE_DESCRIPTOR`. */
|
|
1939
|
+
geometry?: PoseDescriptor<TPose>;
|
|
1940
|
+
/** The look a tag is given as it is made or retexted. Default the scene's
|
|
1941
|
+
* theme (`diagram:theme`), else `theme`. */
|
|
1942
|
+
look?: () => OffPageTagLook;
|
|
1943
|
+
/** The theme a scene naming none is drawn in. */
|
|
1944
|
+
theme?: DiagramTheme;
|
|
546
1945
|
}
|
|
547
|
-
/**
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
1946
|
+
/**
|
|
1947
|
+
* The ops that split, join, and tag the connectors `edges` names (every one,
|
|
1948
|
+
* for `'all'`), so each is split exactly when its ends sit on different
|
|
1949
|
+
* pages. Empty when nothing changes. The edit pass runs this; a host can run
|
|
1950
|
+
* it once over a document saved before it had off-page markers.
|
|
1951
|
+
*/
|
|
1952
|
+
declare function offPageOps<TPose>(scene: Scene<unknown, string, TPose>, edges: Iterable<string> | 'all', opts?: OffPageMarkerOptions<TPose>): Op[];
|
|
1953
|
+
/**
|
|
1954
|
+
* Split `scene`'s connectors across pages from now on: every live edit that
|
|
1955
|
+
* moves a connector's end, adds or rewrites a connector, or changes the pages
|
|
1956
|
+
* splits, joins, and retags what it reached, in its own history entry. On
|
|
1957
|
+
* install nothing is recomputed. Returns the remover. A host without React
|
|
1958
|
+
* calls this; a component calls `useOffPageMarkers`.
|
|
1959
|
+
*/
|
|
1960
|
+
declare function installOffPageMarkers<TPose>(scene: Scene<unknown, string, TPose>, opts?: OffPageMarkerOptions<TPose>): () => void;
|
|
1961
|
+
|
|
1962
|
+
/**
|
|
1963
|
+
* Split `scene`'s connectors across pages for the life of the calling
|
|
1964
|
+
* component: each edit that moves a connector's end or changes the pages
|
|
1965
|
+
* splits, joins, and retags what it reached, in its own history entry.
|
|
1966
|
+
* Options are read when the scene changes.
|
|
1967
|
+
*/
|
|
1968
|
+
declare function useOffPageMarkers<TPose>(scene: Scene<unknown, string, TPose>, opts?: OffPageMarkerOptions<TPose>): void;
|
|
1969
|
+
|
|
1970
|
+
/**
|
|
1971
|
+
* Following a connector off the page: a double-click on an off-page tag goes
|
|
1972
|
+
* to the page at the connector's far end and selects the shape there.
|
|
1973
|
+
*/
|
|
1974
|
+
|
|
1975
|
+
/** The action that follows an off-page tag to its far page. */
|
|
1976
|
+
declare const FOLLOW_OFF_PAGE_ACTION_ID = "diagram.followOffPage";
|
|
1977
|
+
/** Where a tag leads: the shape at its connector's far end, and that shape's page. */
|
|
1978
|
+
interface OffPageTarget {
|
|
1979
|
+
tag: string;
|
|
1980
|
+
edge: string;
|
|
1981
|
+
node: string;
|
|
1982
|
+
page: string;
|
|
563
1983
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
/** `
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
|
|
573
|
-
/** Default `stroke`. */
|
|
574
|
-
label?: string;
|
|
1984
|
+
type SceneReads = NonNullable<ActionDeps['scene']>;
|
|
1985
|
+
/** Where tag `tagId` leads, or `null` when it is no tag of a split connector. */
|
|
1986
|
+
declare function offPageTargetOf(scene: SceneReads, tagId: string): OffPageTarget | null;
|
|
1987
|
+
/** Options for {@link createFollowOffPageAction}. */
|
|
1988
|
+
interface FollowOffPageOptions {
|
|
1989
|
+
/** Runs in place of the default, which selects `target.node` and fits the view to `target.page`. */
|
|
1990
|
+
follow?: (target: OffPageTarget, ctx: InvocationCtx) => void;
|
|
1991
|
+
/** Screen pixels the default leaves around the page it fits. Default 24. */
|
|
1992
|
+
padding?: number;
|
|
575
1993
|
}
|
|
576
|
-
/**
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
1994
|
+
/**
|
|
1995
|
+
* Goes to the far page of the off-page tag a double-click lands on, and
|
|
1996
|
+
* selects the shape at the connector's far end there. It declines a
|
|
1997
|
+
* double-click on anything else.
|
|
1998
|
+
*/
|
|
1999
|
+
declare function createFollowOffPageAction(opts?: FollowOffPageOptions): Action;
|
|
2000
|
+
/** A double-click on a node's body; the action itself declines unless that node is an off-page tag. */
|
|
2001
|
+
declare function followOffPageBinding(actionId?: string): GestureBinding;
|
|
2002
|
+
/** Following off-page tags, as a contribution to pass as `ambient`. */
|
|
2003
|
+
declare function diagramOffPage(opts?: FollowOffPageOptions): {
|
|
2004
|
+
contribution: Contribution;
|
|
583
2005
|
};
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
/** Where a box's rows sit when it is taller than they need. Default `'center'`. */
|
|
626
|
-
verticalAlign?: BodySpec['verticalAlign'];
|
|
627
|
-
/** The narrowest a box may be. Default 64. */
|
|
628
|
-
minWidth?: number;
|
|
629
|
-
/** Where edge labels sit. Default `{ at: 'mid', offset: 9 }`. */
|
|
630
|
-
labelPlacement?: DiagramLabel;
|
|
631
|
-
nodeStyle?: (node: DataNode) => NodeStyle;
|
|
632
|
-
/** Default 12. */
|
|
633
|
-
groupPadding?: number;
|
|
634
|
-
/** A group's box and label. `text` colors the label. */
|
|
635
|
-
groupStyle?: (group: DataGroup) => NodeStyle;
|
|
636
|
-
edgeStyle?: (edge: DataEdge) => EdgeStyle;
|
|
637
|
-
}
|
|
638
|
-
/** The scene node id `diagramScene` gives an edge, built from its ends, ports, and label. */
|
|
639
|
-
declare const edgeIdOf: (e: DataEdge) => string;
|
|
640
|
-
/** Every spec carries an id — a node's own, `<id>/<k>` for its text,
|
|
641
|
-
* `<edge id>/label`, a group's own and `<group id>/label` — so a later call's
|
|
642
|
-
* specs can be reconciled against this one's. Throws on a repeated id among
|
|
643
|
-
* nodes and groups, which names two things as one. An edge whose
|
|
644
|
-
* end is not a node is dropped, and so is a repeat of an earlier edge with
|
|
645
|
-
* the same ends, ports and label: it would draw exactly on top of the first. */
|
|
646
|
-
declare function diagramScene(data: DiagramData, opts?: DiagramSceneOptions): DiagramSpec[];
|
|
2006
|
+
|
|
2007
|
+
/** Subpath `index` of `path` as a path of its own: the whole path for index 0
|
|
2008
|
+
* of one with a single subpath, or of a shape with no commands; null past the last. */
|
|
2009
|
+
declare function subpathOf(path: Path$1, index: number): Path$1 | null;
|
|
2010
|
+
|
|
2011
|
+
/**
|
|
2012
|
+
* `<SceneCanvas selectTool={{ resize: { resizable } }}>` for a diagram scene:
|
|
2013
|
+
* edges and edge labels take their geometry from what they are attached to,
|
|
2014
|
+
* so their own pose is a placeholder, and a resize handle on it sits at the
|
|
2015
|
+
* origin and resizes nothing. A group's box is its members' union, and a
|
|
2016
|
+
* pool's lane is sized by its pool's stack and resized by dragging its
|
|
2017
|
+
* boundary.
|
|
2018
|
+
*/
|
|
2019
|
+
declare function diagramResizable(scene: {
|
|
2020
|
+
get(id: never): {
|
|
2021
|
+
data: unknown;
|
|
2022
|
+
} | undefined;
|
|
2023
|
+
}): (id: string) => boolean;
|
|
2024
|
+
|
|
2025
|
+
/** A node's style: its colors over its role's under `theme`, else over {@link NODE}. */
|
|
2026
|
+
declare function dataNodeStyle(node: Pick<DataNode, 'style' | 'colors'>, theme?: DiagramTheme): NodeStyle;
|
|
2027
|
+
/** An edge's style: its colors over its role's stroke under `theme`, else over the theme's connector, else over {@link EDGE}. */
|
|
2028
|
+
declare function dataEdgeStyle(edge: Pick<DataEdge, 'style' | 'colors'>, theme?: DiagramTheme): EdgeStyle;
|
|
2029
|
+
/** A region as {@link dataRegionStyle} reads it: a container, a pool, or a lane. */
|
|
2030
|
+
interface StyledRegion {
|
|
2031
|
+
role: DataContainer['role'] | 'lane';
|
|
2032
|
+
style?: string;
|
|
2033
|
+
colors?: Partial<NodeStyle>;
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* A region's style: its colors over its theme role's, else over the theme's
|
|
2037
|
+
* container, its pool header, or the lane body at `laneIndex` in turn; with no
|
|
2038
|
+
* theme, over {@link NODE}.
|
|
2039
|
+
*/
|
|
2040
|
+
declare function dataRegionStyle(region: StyledRegion, theme?: DiagramTheme, laneIndex?: number): NodeStyle;
|
|
2041
|
+
|
|
2042
|
+
/**
|
|
2043
|
+
* A live layout's producers: what each frame of a run says about where the
|
|
2044
|
+
* participants are. `forceProducer` relaxes; `easedProducer` walks to a
|
|
2045
|
+
* destination it knows. `useLiveLayout` (`live.ts`) runs them.
|
|
2046
|
+
*/
|
|
647
2047
|
|
|
648
2048
|
/** What a live producer is told, and what it answers with. */
|
|
649
2049
|
interface LiveLayoutCtx<TPose> {
|
|
@@ -700,14 +2100,16 @@ interface EasedProducerOptions {
|
|
|
700
2100
|
* over.
|
|
701
2101
|
*/
|
|
702
2102
|
declare function easedProducer<TPose>(graph: Graph, algorithm: LayoutFn, opts?: EasedProducerOptions): LiveLayoutProducer<TPose>;
|
|
2103
|
+
|
|
703
2104
|
/** Options for {@link useLiveLayout}. Only `scene` and `source` are required. */
|
|
704
2105
|
interface UseLiveLayoutOptions<TPose> {
|
|
705
2106
|
scene: Scene<unknown, string, TPose>;
|
|
706
2107
|
/** Where the graph is read from. The same thunk the port affordance takes. */
|
|
707
2108
|
source: GraphSource<TPose>;
|
|
708
|
-
/** A key in `LAYOUTS`,
|
|
709
|
-
* continuously; anything else eases to its
|
|
710
|
-
|
|
2109
|
+
/** A key in `LAYOUTS`, a layout of the consumer's own, or a planner that
|
|
2110
|
+
* answers later. `'force'` relaxes continuously; anything else eases to its
|
|
2111
|
+
* answer. Default `'force'`. */
|
|
2112
|
+
algorithm?: string | LayoutFn | LayoutPlanner;
|
|
711
2113
|
layout?: LayoutOptions;
|
|
712
2114
|
/** The relaxation's forces, and when a live run of it counts as at rest. */
|
|
713
2115
|
force?: Omit<ForceProducerOptions<TPose>, 'geometry'>;
|
|
@@ -721,6 +2123,9 @@ interface UseLiveLayoutOptions<TPose> {
|
|
|
721
2123
|
/** Fires once the run has settled or been stopped and its poses are in the
|
|
722
2124
|
* document, with how many participants moved. */
|
|
723
2125
|
onSettle?: (moved: number) => void;
|
|
2126
|
+
/** Hears why a `LayoutPlanner` failed to answer, and no run starts. Unset,
|
|
2127
|
+
* the failure goes to `console.error`. */
|
|
2128
|
+
onError?: (error: unknown) => void;
|
|
724
2129
|
/** Whether a node or edge appearing or disappearing re-heats the run.
|
|
725
2130
|
* Default true — a diagram that ignores a new edge looks broken. */
|
|
726
2131
|
reheatOnGraphChange?: boolean;
|
|
@@ -730,9 +2135,11 @@ interface UseLiveLayoutOptions<TPose> {
|
|
|
730
2135
|
}
|
|
731
2136
|
/** Controls for a live layout run, from {@link useLiveLayout}. */
|
|
732
2137
|
interface LiveLayout {
|
|
733
|
-
/** Heat and run. Idempotent while running
|
|
2138
|
+
/** Heat and run. Idempotent while running, which includes waiting on a
|
|
2139
|
+
* planner's answer. */
|
|
734
2140
|
start(): void;
|
|
735
|
-
/** Finish now: commit where the nodes stand.
|
|
2141
|
+
/** Finish now: commit where the nodes stand. A planner's answer still to
|
|
2142
|
+
* come is dropped. */
|
|
736
2143
|
stop(): void;
|
|
737
2144
|
/** Abandon: the document keeps the poses it had. */
|
|
738
2145
|
cancel(): void;
|
|
@@ -756,20 +2163,11 @@ declare const EASED_LAYOUTS: Readonly<Record<string, LayoutFn>>;
|
|
|
756
2163
|
*
|
|
757
2164
|
* An edge running down the ranks leaves its source by the face toward the
|
|
758
2165
|
* next rank and arrives at its target's face toward the last, so it reads
|
|
759
|
-
* along the direction the diagram flows
|
|
760
|
-
*
|
|
761
|
-
*
|
|
762
|
-
*
|
|
763
|
-
* An edge running back up the ranks, or within one, is left to the ends'
|
|
764
|
-
* facing rule.
|
|
2166
|
+
* along the direction the diagram flows; one running back up the ranks does
|
|
2167
|
+
* the same the other way round. An edge that spans ranks runs through the
|
|
2168
|
+
* waypoints `layeredPlan` placed for it.
|
|
765
2169
|
*/
|
|
766
2170
|
|
|
767
|
-
type Rect = {
|
|
768
|
-
x: number;
|
|
769
|
-
y: number;
|
|
770
|
-
width: number;
|
|
771
|
-
height: number;
|
|
772
|
-
};
|
|
773
2171
|
/** One edge to route, by the ids of its ends: a node's or a group's. */
|
|
774
2172
|
interface RouteEdge {
|
|
775
2173
|
id: string;
|
|
@@ -782,27 +2180,73 @@ interface LayeredRoute {
|
|
|
782
2180
|
fromPort?: string;
|
|
783
2181
|
toPort?: string;
|
|
784
2182
|
waypoints?: readonly Vec2$1[];
|
|
2183
|
+
/** The point on the route layout left the edge's label room beside, as a
|
|
2184
|
+
* `DiagramLabel`'s `{ near }`. */
|
|
2185
|
+
labelAt?: Vec2$1;
|
|
785
2186
|
}
|
|
786
|
-
/** What {@link layeredRoutes} reads:
|
|
2187
|
+
/** What {@link layeredRoutes} reads: where `layeredPlan` put things. */
|
|
787
2188
|
interface LayeredRouteInput {
|
|
788
|
-
/** The graph layout ranked, for which rank each node is in. */
|
|
789
|
-
graph: Graph;
|
|
790
2189
|
edges: readonly RouteEdge[];
|
|
791
|
-
/**
|
|
792
|
-
|
|
2190
|
+
/** Each node's rank, from `layeredPlan`. Empty for a layout with none,
|
|
2191
|
+
* which names no ports. */
|
|
2192
|
+
ranks: ReadonlyMap<string, number>;
|
|
2193
|
+
/** Each spanning edge's waypoints, from `layeredPlan`. */
|
|
2194
|
+
waypoints: ReadonlyMap<string, readonly Vec2$1[]>;
|
|
2195
|
+
/** Where each labeled edge's label room is among its waypoints, from
|
|
2196
|
+
* `layeredPlan`. */
|
|
2197
|
+
labels?: ReadonlyMap<string, Vec2$1>;
|
|
793
2198
|
/** Each group's node members, through nested groups. */
|
|
794
2199
|
members: ReadonlyMap<string, readonly string[]>;
|
|
795
2200
|
/** Ids whose ports are the four compass midpoints, which are the only ones
|
|
796
2201
|
* a route names. */
|
|
797
2202
|
compass: ReadonlySet<string>;
|
|
798
2203
|
direction?: LayoutDirection;
|
|
799
|
-
/** How far a route keeps from the boxes it passes. */
|
|
800
|
-
clearance: number;
|
|
801
2204
|
}
|
|
802
2205
|
/** Ports and waypoints for each edge of a laid-out `layered` diagram that
|
|
803
2206
|
* needs any, keyed by edge id. */
|
|
804
2207
|
declare function layeredRoutes(input: LayeredRouteInput): Map<string, LayeredRoute>;
|
|
805
2208
|
|
|
2209
|
+
/**
|
|
2210
|
+
* The edge half of writing a layout to a scene: each edge's waypoints, and
|
|
2211
|
+
* where its label sits among them.
|
|
2212
|
+
*
|
|
2213
|
+
* Layout writes only what it owns. An edge's route is its own while the edge
|
|
2214
|
+
* has no waypoints or still has the ones layout last wrote (`laidOut`), and
|
|
2215
|
+
* is not an `avoid` connector, which only gets its ports named; a
|
|
2216
|
+
* label's place is its own while the label sits at the default middle or at a
|
|
2217
|
+
* `{ near }`, and its edge's route is layout's.
|
|
2218
|
+
*/
|
|
2219
|
+
|
|
2220
|
+
/** Edge routes for `applyLayout` to write alongside a layout's moves. */
|
|
2221
|
+
interface LayoutRoutes {
|
|
2222
|
+
/** Every edge the layout laid out. Each one layout owns gets its route
|
|
2223
|
+
* from `waypoints`, or loses the one a layout gave it before. */
|
|
2224
|
+
edges: ReadonlySet<string>;
|
|
2225
|
+
waypoints: ReadonlyMap<string, readonly Vec2$1[]>;
|
|
2226
|
+
labels?: ReadonlyMap<string, Vec2$1>;
|
|
2227
|
+
/** The ports layout names. Each end layout owns gets its port from here,
|
|
2228
|
+
* or loses the one a layout named before. */
|
|
2229
|
+
ports?: ReadonlyMap<string, LayoutPorts>;
|
|
2230
|
+
}
|
|
2231
|
+
/** The routes `plan` laid out for `graph`'s edges. A layout that routes
|
|
2232
|
+
* nothing routes every edge straight, taking back what `layered` wrote. */
|
|
2233
|
+
declare function routesOf(graph: Graph, plan: LayoutPlan): LayoutRoutes;
|
|
2234
|
+
/** A scene as {@link routeWrites} reads it. */
|
|
2235
|
+
interface RoutedScene {
|
|
2236
|
+
get(id: never): {
|
|
2237
|
+
data: unknown;
|
|
2238
|
+
} | undefined;
|
|
2239
|
+
isLocked(id: never): boolean;
|
|
2240
|
+
renderOrderNodes(): readonly {
|
|
2241
|
+
id: string;
|
|
2242
|
+
data: unknown;
|
|
2243
|
+
dependsOn?: readonly string[] | 'children';
|
|
2244
|
+
}[];
|
|
2245
|
+
}
|
|
2246
|
+
/** The new `data` for every edge and label whose route or place changes. A
|
|
2247
|
+
* locked edge or label is left as it is. */
|
|
2248
|
+
declare function routeWrites(scene: RoutedScene, routes: LayoutRoutes): Map<string, unknown>;
|
|
2249
|
+
|
|
806
2250
|
/**
|
|
807
2251
|
* Running a layout against a scene: `LAYOUTS`, one batch of pose writes, and
|
|
808
2252
|
* the action that reaches both. A layout is a pure function of the graph;
|
|
@@ -816,12 +2260,14 @@ interface ApplyLayoutOptions<TPose> {
|
|
|
816
2260
|
geometry?: PoseDescriptor<TPose>;
|
|
817
2261
|
/** The undo entry's name. Default `'Layout'`. */
|
|
818
2262
|
label?: string;
|
|
2263
|
+
/** Edge routes to write in the same batch, from `routesOf`. */
|
|
2264
|
+
routes?: LayoutRoutes;
|
|
819
2265
|
}
|
|
820
2266
|
/**
|
|
821
2267
|
* Write a layout's answer to the scene, as one undoable batch.
|
|
822
2268
|
*
|
|
823
|
-
* Returns how many nodes moved
|
|
824
|
-
*
|
|
2269
|
+
* Returns how many nodes moved. A layout with nothing to do, nodes or routes,
|
|
2270
|
+
* writes nothing and pushes no history entry.
|
|
825
2271
|
*
|
|
826
2272
|
* Nodes are **translated**, never re-posed from the layout's numbers: a node's
|
|
827
2273
|
* pose can be a path or anything else a consumer wired, and only its own
|
|
@@ -869,11 +2315,18 @@ declare function createLayoutAction<TPose>(opts: LayoutActionOptions<TPose>): Ac
|
|
|
869
2315
|
*/
|
|
870
2316
|
|
|
871
2317
|
/** The minimum a participant source needs from a scene. Narrower than `Scene`
|
|
872
|
-
* so a consumer can pass anything that answers these
|
|
2318
|
+
* so a consumer can pass anything that answers these. `layers` and each
|
|
2319
|
+
* node's `layer`, `parent`, `hidden` and `locked` feed `nodeGates`; a stand-in
|
|
2320
|
+
* without them gates nothing. */
|
|
873
2321
|
interface ParticipantScene<TPose> {
|
|
2322
|
+
readonly layers?: readonly GatedLayer[];
|
|
874
2323
|
renderOrderNodes(): readonly {
|
|
875
2324
|
id: string;
|
|
876
2325
|
kind: 'leaf' | 'container';
|
|
2326
|
+
layer?: string;
|
|
2327
|
+
parent?: string | null;
|
|
2328
|
+
hidden?: boolean;
|
|
2329
|
+
locked?: boolean;
|
|
877
2330
|
data: unknown;
|
|
878
2331
|
pose: TPose;
|
|
879
2332
|
dependsOn?: readonly string[] | 'children';
|
|
@@ -887,7 +2340,11 @@ interface ParticipantScene<TPose> {
|
|
|
887
2340
|
childrenOf(id: string): readonly string[];
|
|
888
2341
|
}
|
|
889
2342
|
/**
|
|
890
|
-
* Every node in `scene`, at the pose it is **painted** at
|
|
2343
|
+
* Every node in `scene`, at the pose it is **painted** at, marked `hidden` or
|
|
2344
|
+
* `locked` where the scene's `nodeGates` says so, and carrying its `layer` so
|
|
2345
|
+
* a view that does not paint that layer can turn its ports away too. The
|
|
2346
|
+
* marks keep ports off such a node; the graph reads past them, so a hidden
|
|
2347
|
+
* node is still laid out.
|
|
891
2348
|
*
|
|
892
2349
|
* `effectivePose`, not `node.pose`: an override is what a gesture is currently
|
|
893
2350
|
* showing, and a port that answers from the document pose while its node is
|
|
@@ -895,7 +2352,9 @@ interface ParticipantScene<TPose> {
|
|
|
895
2352
|
*
|
|
896
2353
|
* One source answers both the ports and the graph.
|
|
897
2354
|
*/
|
|
898
|
-
declare function sceneParticipants<TPose>(scene: ParticipantScene<TPose>):
|
|
2355
|
+
declare function sceneParticipants<TPose>(scene: ParticipantScene<TPose>): () => Iterable<ParticipantPose<TPose> & {
|
|
2356
|
+
node: GraphNodeLike;
|
|
2357
|
+
}>;
|
|
899
2358
|
/**
|
|
900
2359
|
* The composed layer, ready for `CanvasExtensionApi.registerLayer` — the only
|
|
901
2360
|
* attach route that is hit-tested. Handing this to `SceneCanvas`'s `layers`
|
|
@@ -937,11 +2396,139 @@ declare function diagramShape<TPose>(opts?: DiagramShapeOptions<TPose>): NodeSha
|
|
|
937
2396
|
*/
|
|
938
2397
|
declare function registerDiagramShape<TPose>(opts?: DiagramShapeOptions<TPose>): () => void;
|
|
939
2398
|
|
|
940
|
-
/**
|
|
2399
|
+
/**
|
|
2400
|
+
* DOM pinned to a diagram's nodes and edges: a settings card beside the picked
|
|
2401
|
+
* node, a button on an edge's midpoint. Each overlay is placed after every
|
|
2402
|
+
* paint, so it follows a pan, a zoom, a resize and a layout run's every frame.
|
|
2403
|
+
*/
|
|
2404
|
+
|
|
2405
|
+
/** One piece of DOM held against a node, a group or an edge. */
|
|
2406
|
+
interface DiagramOverlay {
|
|
2407
|
+
/** The node, group or edge it is held against. While no such id is in the
|
|
2408
|
+
* diagram it is not shown. */
|
|
2409
|
+
target: string;
|
|
2410
|
+
/** Beside the target's box, kept inside the view and flipped to the far
|
|
2411
|
+
* side when the near one has no room; or `'center'`, centered on it.
|
|
2412
|
+
* Default `'center'`. */
|
|
2413
|
+
placement?: Placement | 'center';
|
|
2414
|
+
/** Gap between the target's box and the overlay, in CSS pixels. Default 0. */
|
|
2415
|
+
offset?: number;
|
|
2416
|
+
/** Tells two overlays on one target apart. Default `target`. */
|
|
2417
|
+
key?: string;
|
|
2418
|
+
content: ReactNode;
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
/**
|
|
2422
|
+
* The regions half of `DiagramView`'s sync: where each container, pool, and
|
|
2423
|
+
* lane stands, and the region edits a change to that is reported as.
|
|
2424
|
+
*/
|
|
2425
|
+
|
|
2426
|
+
type Box = {
|
|
2427
|
+
x: number;
|
|
2428
|
+
y: number;
|
|
2429
|
+
width: number;
|
|
2430
|
+
height: number;
|
|
2431
|
+
};
|
|
2432
|
+
/**
|
|
2433
|
+
* A region edit, which `DiagramView` reports and does not keep: `box`, a
|
|
2434
|
+
* container or pool moved or resized (`parent` present when a drop changed
|
|
2435
|
+
* the region it is in, `null` for the top level); `lanes`, a pool's lanes
|
|
2436
|
+
* resized, reordered, or added to, every lane in stacking order with its size
|
|
2437
|
+
* (a new lane's id is minted by the view); `release`, Release members run on
|
|
2438
|
+
* a region; `title`, a double-click on a region's header.
|
|
2439
|
+
*/
|
|
2440
|
+
type ContainerEdit = {
|
|
2441
|
+
kind: 'box';
|
|
2442
|
+
id: string;
|
|
2443
|
+
box: Box;
|
|
2444
|
+
parent?: string | null;
|
|
2445
|
+
} | {
|
|
2446
|
+
kind: 'lanes';
|
|
2447
|
+
pool: string;
|
|
2448
|
+
lanes: readonly {
|
|
2449
|
+
id: string;
|
|
2450
|
+
size: number;
|
|
2451
|
+
}[];
|
|
2452
|
+
} | {
|
|
2453
|
+
kind: 'release';
|
|
2454
|
+
id: string;
|
|
2455
|
+
} | {
|
|
2456
|
+
kind: 'title';
|
|
2457
|
+
id: string;
|
|
2458
|
+
};
|
|
2459
|
+
|
|
2460
|
+
/**
|
|
2461
|
+
* `DiagramView`'s two-way sync with the data it was built from: new specs are
|
|
2462
|
+
* reconciled into the scene, and what a drag or a layout run changed is
|
|
2463
|
+
* reported back, so a consumer keeping the diagram as data can store it.
|
|
2464
|
+
* `diagramLayoutOf` reads the same report off a `diagramScene` build.
|
|
2465
|
+
*/
|
|
2466
|
+
|
|
2467
|
+
/** Where a moved node now stands. `parent` is present when a drop changed
|
|
2468
|
+
* the region it is in: that container's or lane's id, or `null` for the top
|
|
2469
|
+
* level. The host moves the id from one `members` list to the other. */
|
|
941
2470
|
interface NodeMove {
|
|
942
2471
|
id: string;
|
|
943
2472
|
x: number;
|
|
944
2473
|
y: number;
|
|
2474
|
+
parent?: string | null;
|
|
2475
|
+
}
|
|
2476
|
+
/** An edge whose route or ports a layout run rewrote. `id` is the edge's
|
|
2477
|
+
* scene id, `edgeIdOf` of its data edge; `waypoints` is empty when the run
|
|
2478
|
+
* took a route away and left the edge straight, and `ports` names the ends
|
|
2479
|
+
* layout owns. Store them as the data edge's `routed` and `routedPorts`,
|
|
2480
|
+
* which stay layout's, not as `waypoints`, `fromPort` and `toPort`, which
|
|
2481
|
+
* would be the author's and rename the edge. */
|
|
2482
|
+
interface EdgeRoute {
|
|
2483
|
+
id: string;
|
|
2484
|
+
waypoints: readonly Vec2$1[];
|
|
2485
|
+
ports: LayoutPorts;
|
|
2486
|
+
}
|
|
2487
|
+
/** What layout placed in a `diagramScene` build, in the shapes `DiagramView`
|
|
2488
|
+
* reports: every node not pinned, where it stands, every edge whose route
|
|
2489
|
+
* or ports layout wrote, and the box of every container and pool not pinned
|
|
2490
|
+
* whose box is its own rather than fitted. Store them the way `onMove` and
|
|
2491
|
+
* `onEditContainer` say and the next build leaves them where they are. */
|
|
2492
|
+
declare function diagramLayoutOf(specs: readonly DiagramSpec[]): {
|
|
2493
|
+
moves: NodeMove[];
|
|
2494
|
+
routes: EdgeRoute[];
|
|
2495
|
+
containers: ContainerEdit[];
|
|
2496
|
+
};
|
|
2497
|
+
|
|
2498
|
+
/** One end of a data edge moved onto node `node`, at `port` or on its body. */
|
|
2499
|
+
interface ReconnectChange {
|
|
2500
|
+
/** The data edge's id, `edgeIdOf` of it. */
|
|
2501
|
+
edge: string;
|
|
2502
|
+
end: 'from' | 'to';
|
|
2503
|
+
node: string;
|
|
2504
|
+
port?: string;
|
|
2505
|
+
}
|
|
2506
|
+
/** A data edge's route as a drag or a double-click left it. */
|
|
2507
|
+
interface RouteChange {
|
|
2508
|
+
/** The data edge's id, `edgeIdOf` of it. */
|
|
2509
|
+
edge: string;
|
|
2510
|
+
/** Empty when the edge no longer has any. */
|
|
2511
|
+
waypoints: readonly Vec2$1[];
|
|
2512
|
+
}
|
|
2513
|
+
/** Where a drag left a data edge's label, or `null` for Reset label. */
|
|
2514
|
+
interface LabelMove {
|
|
2515
|
+
/** The data edge's id, `edgeIdOf` of it. */
|
|
2516
|
+
edge: string;
|
|
2517
|
+
placement: DiagramLabel | null;
|
|
2518
|
+
}
|
|
2519
|
+
/** A node's box as a resize handle's drag left it: its place too, since a
|
|
2520
|
+
* handle on its top or left edge moves it. */
|
|
2521
|
+
interface NodeResize {
|
|
2522
|
+
id: string;
|
|
2523
|
+
x: number;
|
|
2524
|
+
y: number;
|
|
2525
|
+
width: number;
|
|
2526
|
+
height: number;
|
|
2527
|
+
}
|
|
2528
|
+
/** What a delete would take: the data nodes, and every data edge that goes with them. */
|
|
2529
|
+
interface DeleteReport {
|
|
2530
|
+
nodes: readonly string[];
|
|
2531
|
+
edges: readonly string[];
|
|
945
2532
|
}
|
|
946
2533
|
/** Props for `DiagramView`. */
|
|
947
2534
|
interface DiagramViewProps {
|
|
@@ -950,24 +2537,104 @@ interface DiagramViewProps {
|
|
|
950
2537
|
* selection and anything moved since stay put unless the new specs change
|
|
951
2538
|
* them. Pass a new `key` to start over instead. */
|
|
952
2539
|
specs: readonly DiagramSpec[];
|
|
953
|
-
|
|
954
|
-
|
|
2540
|
+
/** `'avoid'` routes every edge around the shapes, holding one router across
|
|
2541
|
+
* new `specs` so each reroutes only what it disturbed. The routes derive
|
|
2542
|
+
* from the specs and are never reported. */
|
|
2543
|
+
router?: 'avoid';
|
|
2544
|
+
/** `'dodge'` moves each edge label off whatever covers it, along its
|
|
2545
|
+
* route or across it, after any `router` has run. Placement derives from
|
|
2546
|
+
* the specs and is never reported. */
|
|
2547
|
+
labels?: 'dodge';
|
|
2548
|
+
/** Line jumps of this radius: where two edges cross, the later one bows
|
|
2549
|
+
* over the earlier in a half circle. Applied after `router` and `labels`; derived from
|
|
2550
|
+
* the specs and never reported. */
|
|
2551
|
+
hops?: number;
|
|
2552
|
+
/** The view opens fitted to the diagram, and fits again when the size or a
|
|
2553
|
+
* fit option changes or a layout run settles, until the user pans or zooms;
|
|
2554
|
+
* from then on the view is theirs. Omit both to fill the parent, which
|
|
2555
|
+
* then needs a size of its own; a resize of the parent is a size change. */
|
|
2556
|
+
width?: number;
|
|
2557
|
+
height?: number;
|
|
955
2558
|
/** A participant id, or null for none. */
|
|
956
2559
|
selected?: string | null;
|
|
957
2560
|
/** Reports what each click leaves picked, `null` for none — a re-click on the
|
|
958
2561
|
* picked node reports it again. The canvas keeps the pick even if
|
|
959
2562
|
* `selected` does not follow it; only a change to `selected` is pushed in. */
|
|
960
2563
|
onSelect?: (id: string | null) => void;
|
|
2564
|
+
/** Reports the node, group or edge the pointer comes to be over, and `null`
|
|
2565
|
+
* once it is over none or leaves the canvas. An edge answers only while
|
|
2566
|
+
* edges are picked (`pickEdges`). */
|
|
2567
|
+
onHover?: (id: string | null) => void;
|
|
2568
|
+
/** Whether a click or a hover can land on an edge, which is then picked
|
|
2569
|
+
* like a node. Default: on when `onReconnect`, `onEditRoute`, `onDelete`,
|
|
2570
|
+
* `onEditLabel` or `onMoveLabel` is set. */
|
|
2571
|
+
pickEdges?: boolean;
|
|
2572
|
+
/** DOM held against nodes, groups and edges, kept in place through pans,
|
|
2573
|
+
* zooms, resizes and layout runs. The view's box is their containing
|
|
2574
|
+
* block; their content takes the pointer, and the canvas beneath does not
|
|
2575
|
+
* see it. */
|
|
2576
|
+
overlays?: readonly DiagramOverlay[];
|
|
961
2577
|
/** Set to let nodes be dragged. Reports every node a drag or a layout run
|
|
962
|
-
* moved
|
|
963
|
-
*
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
2578
|
+
* moved, and every edge whose route or ports a layout run rewrote. Store
|
|
2579
|
+
* each move as the data node's `at` with `pinned: true`, and each route as
|
|
2580
|
+
* the data edge's `routed` and `routedPorts`, or the next `diagramScene`
|
|
2581
|
+
* lays them out again. */
|
|
2582
|
+
onMove?: (moves: readonly NodeMove[], routes: readonly EdgeRoute[]) => void;
|
|
2583
|
+
/** Set to give a selected node resize handles. The box resizes live while
|
|
2584
|
+
* a handle is dragged; on release the new box is reported and the view
|
|
2585
|
+
* draws it only once the specs do. Store it as the data node's `width`,
|
|
2586
|
+
* `height`, and `at` with `pinned: true`; the size is a minimum, so a box
|
|
2587
|
+
* dragged smaller than its rows grows back to them. */
|
|
2588
|
+
onResize?: (resizes: readonly NodeResize[]) => void;
|
|
2589
|
+
/** Ports are grabbable when this is set, unless `ports` says otherwise. Dragging one port onto another reports the
|
|
2590
|
+
* edge it describes and draws nothing; add it to the data to keep it. An
|
|
2591
|
+
* end on a shape's body (`connectBodies`) has no port field. */
|
|
967
2592
|
onConnect?: (edge: DataEdge) => void;
|
|
2593
|
+
/** Set to let a selected edge's ends be dragged onto another port, or with
|
|
2594
|
+
* `connectBodies` onto a shape's body. Reports the move and draws nothing; change the data edge to keep it. */
|
|
2595
|
+
onReconnect?: (change: ReconnectChange) => void;
|
|
2596
|
+
/** Set to give a selected edge handles along its route: drag one to move or
|
|
2597
|
+
* insert a waypoint, or slide an orthogonal segment; double-click one to
|
|
2598
|
+
* remove it. Reports the edge's new waypoints and draws nothing; store them
|
|
2599
|
+
* as the data edge's `waypoints` and clear its `routed`. */
|
|
2600
|
+
onEditRoute?: (change: RouteChange) => void;
|
|
2601
|
+
/** Set to let Delete and Backspace remove the selection. Reports the
|
|
2602
|
+
* selected data nodes (a selected group, not its members; a selected
|
|
2603
|
+
* container, pool, or lane with everything inside it) and every edge
|
|
2604
|
+
* selected or ending on one of them, and removes nothing. */
|
|
2605
|
+
onDelete?: (removed: DeleteReport) => void;
|
|
2606
|
+
/** Set to let a member of a group marked `reorder` be dragged along that
|
|
2607
|
+
* axis among its siblings, or the selected one stepped with Alt and an
|
|
2608
|
+
* arrow key. Reports the members' new order and moves nothing: write it to
|
|
2609
|
+
* the group's `members`, which layered layout keeps. */
|
|
2610
|
+
onReorder?: (change: ReorderChange) => void;
|
|
2611
|
+
/** Set to report a double-click on an edge, for its label to be edited. */
|
|
2612
|
+
onEditLabel?: (edge: string) => void;
|
|
2613
|
+
/** Set to let an edge's label be dragged along and beside it, and to enable
|
|
2614
|
+
* Reset label for the selected edge. Reports the placement and draws
|
|
2615
|
+
* nothing; store it as the data edge's `labelPlacement`, and delete that
|
|
2616
|
+
* field for `null`. */
|
|
2617
|
+
onMoveLabel?: (change: LabelMove) => void;
|
|
2618
|
+
/** Set to edit `DiagramData` containers and pools: drag a lane's boundary,
|
|
2619
|
+
* click a pool's add-lane button, drag a lane by its header to reorder,
|
|
2620
|
+
* move or resize a region, double-click a header, or run Release members.
|
|
2621
|
+
* Each is reported and nothing is kept until the specs follow. A region's
|
|
2622
|
+
* move also reports what it carried to `onMove`, and a lane resize the
|
|
2623
|
+
* members of the lanes it shifts. Store a `box` edit as the container's
|
|
2624
|
+
* `box` with `pinned: true`. */
|
|
2625
|
+
onEditContainer?: (edit: ContainerEdit) => void;
|
|
2626
|
+
/** Whether a connect or a reconnect may end on a shape's body, away from
|
|
2627
|
+
* its ports. Default false. */
|
|
2628
|
+
connectBodies?: boolean;
|
|
2629
|
+
/** Contributions to install after the view's own: a tool's bindings, a key. */
|
|
2630
|
+
ambient?: readonly Contribution[];
|
|
2631
|
+
/** Whether ports are drawn. `'connect'` draws them and lets one be dragged
|
|
2632
|
+
* onto another; `'show'` only draws them. Default: `'connect'` when
|
|
2633
|
+
* `onConnect` is set, else `'none'`. */
|
|
2634
|
+
ports?: 'connect' | 'show' | 'none';
|
|
968
2635
|
/** Whether the canvas's keyboard shortcuts — held Space to pan among them —
|
|
969
2636
|
* run. They listen page-wide, so a view-only diagram beside other UI would
|
|
970
|
-
* claim keys meant for the page. Default: on when
|
|
2637
|
+
* claim keys meant for the page. Default: on when any callback that edits
|
|
971
2638
|
* is set. */
|
|
972
2639
|
enableKeybindings?: boolean;
|
|
973
2640
|
/** Which ports may be joined. Default: a port may not join itself, and two
|
|
@@ -975,28 +2642,35 @@ interface DiagramViewProps {
|
|
|
975
2642
|
canConnect?: CanConnect;
|
|
976
2643
|
/** How ports look and answer the pointer, and the router a connect's
|
|
977
2644
|
* preview draws with. */
|
|
978
|
-
portOptions?: Pick<DiagramContributionOptions<RectPose>, 'fill' | 'stroke' | 'sizePx' | 'hitRadiusPx' | 'cursor' | 'shows' | 'snapRadius' | 'router'>;
|
|
2645
|
+
portOptions?: Pick<DiagramContributionOptions<RectPose>, 'fill' | 'stroke' | 'shape' | 'sizePx' | 'hitRadiusPx' | 'cursor' | 'shows' | 'showsPort' | 'snapRadius' | 'router'>;
|
|
979
2646
|
/** How a layout run from {@link DiagramViewApi.layout} behaves: its forces,
|
|
980
|
-
* how many frames an eased layout takes, its easing
|
|
2647
|
+
* how many frames an eased layout takes, its easing, and `onError`, which
|
|
2648
|
+
* hears a `LayoutPlanner` that failed to answer. */
|
|
981
2649
|
live?: Omit<UseLiveLayoutOptions<RectPose>, 'scene' | 'source' | 'algorithm'>;
|
|
982
|
-
/** The smallest scale the
|
|
2650
|
+
/** The smallest scale the fit may use. Unset, the whole diagram fits
|
|
983
2651
|
* however small that makes it; set, it stops here and the rest is a pan away. */
|
|
984
2652
|
minScale?: number;
|
|
985
|
-
/** The largest scale the
|
|
2653
|
+
/** The largest scale the fit may use. Default 1, so a small
|
|
986
2654
|
* diagram opens at its own size rather than blown up. */
|
|
987
2655
|
maxScale?: number;
|
|
988
2656
|
/** Which part of a diagram too big for the box it opens on: its middle
|
|
989
2657
|
* (default) or its top-left, where a layered flow begins. */
|
|
990
2658
|
anchor?: 'center' | 'start';
|
|
991
|
-
/** Space kept clear around the diagram by the
|
|
2659
|
+
/** Space kept clear around the diagram by the fit, in CSS pixels.
|
|
992
2660
|
* Default 16. */
|
|
993
2661
|
fitPadding?: number;
|
|
994
2662
|
/** What the canvas paints behind the diagram. Unset, it is transparent. */
|
|
995
2663
|
background?: Paint;
|
|
996
|
-
/**
|
|
2664
|
+
/** Sheets painted under the diagram, one filled rect per page; `diagramPages(data)`
|
|
2665
|
+
* places them. The default fit takes in every page. */
|
|
2666
|
+
pages?: {
|
|
2667
|
+
placed: readonly PlacedPage[];
|
|
2668
|
+
fill: string;
|
|
2669
|
+
};
|
|
2670
|
+
/** The view, controlled. Set it and the fit is skipped; pair it
|
|
997
2671
|
* with `onViewChange` or panning does nothing. */
|
|
998
2672
|
view?: View;
|
|
999
|
-
/** Every view change, from a pan, a zoom or
|
|
2673
|
+
/** Every view change, from a pan, a zoom or a refit. */
|
|
1000
2674
|
onViewChange?: (view: View) => void;
|
|
1001
2675
|
className?: string;
|
|
1002
2676
|
}
|
|
@@ -1004,13 +2678,42 @@ interface DiagramViewProps {
|
|
|
1004
2678
|
interface DiagramViewApi {
|
|
1005
2679
|
/** Lay the diagram out again from where its nodes stand, animated. `'force'`
|
|
1006
2680
|
* (default) relaxes until it settles; any other layout eases to its answer.
|
|
1007
|
-
*
|
|
1008
|
-
|
|
2681
|
+
* A `LayoutPlanner` is handed the diagram's graph and eased to once it
|
|
2682
|
+
* answers; a drag, an edit or another `layout` call before then drops the
|
|
2683
|
+
* answer. What moved is reported to `onMove` once the run settles. */
|
|
2684
|
+
layout(algorithm?: DiagramLayout): void;
|
|
1009
2685
|
/** The run `layout` started: stop it where it stands, or cancel it. */
|
|
1010
2686
|
live: LiveLayout;
|
|
2687
|
+
/** The world point under a client point: where a drop from outside the canvas lands. */
|
|
2688
|
+
worldAt(clientX: number, clientY: number): Vec2$1;
|
|
2689
|
+
/** The world rect the canvas shows, or `null` before it has a size. */
|
|
2690
|
+
visible(): {
|
|
2691
|
+
x: number;
|
|
2692
|
+
y: number;
|
|
2693
|
+
width: number;
|
|
2694
|
+
height: number;
|
|
2695
|
+
} | null;
|
|
2696
|
+
/** Where a node, group or edge is drawn, in client coordinates — for an
|
|
2697
|
+
* edge, an empty rect at the midpoint along its route. `null` for an id the
|
|
2698
|
+
* diagram does not hold, or before the canvas mounts. Read it again from
|
|
2699
|
+
* {@link subscribeFrame}, after every paint. */
|
|
2700
|
+
rectOf(id: string): {
|
|
2701
|
+
x: number;
|
|
2702
|
+
y: number;
|
|
2703
|
+
width: number;
|
|
2704
|
+
height: number;
|
|
2705
|
+
} | null;
|
|
2706
|
+
/** Run `fn` after every paint: a pan, a zoom, a layout frame, a change of
|
|
2707
|
+
* specs. Returns an unsubscribe; a call before the canvas mounts returns one
|
|
2708
|
+
* and never runs `fn`. */
|
|
2709
|
+
subscribeFrame(fn: () => void): () => void;
|
|
1011
2710
|
}
|
|
2711
|
+
/** What {@link DiagramViewApi.layout} runs. */
|
|
2712
|
+
type DiagramLayout = 'layered' | 'tree' | 'force' | 'chain' | LayoutFn | LayoutPlanner;
|
|
2713
|
+
|
|
1012
2714
|
/** A diagram: drag or wheel to pan, zoom, and pick a node; drag nodes with
|
|
1013
|
-
* `onMove`, join ports with `onConnect`.
|
|
2715
|
+
* `onMove`, join ports with `onConnect`. Every edit is reported, never
|
|
2716
|
+
* written: change the specs to keep it. Labels paint only in a registered
|
|
1014
2717
|
* font family; `diagramScene` defaults to sans-serif, so call
|
|
1015
2718
|
* `registerCanvasFont('sans-serif')` or text renders blank. */
|
|
1016
2719
|
declare const DiagramView: react.ForwardRefExoticComponent<DiagramViewProps & react.RefAttributes<DiagramViewApi>>;
|
|
@@ -1021,4 +2724,216 @@ declare const DiagramView: react.ForwardRefExoticComponent<DiagramViewProps & re
|
|
|
1021
2724
|
* `<SceneCanvas onClick>`. */
|
|
1022
2725
|
declare function useMirroredSelection(selection: Pick<SelectionApi, 'get' | 'set'>, selected: string | null | undefined, onSelect: ((id: string | null) => void) | undefined): () => void;
|
|
1023
2726
|
|
|
1024
|
-
|
|
2727
|
+
/** The themes that ship, by id, in the order a picker lists them. `paper` is ink on white;
|
|
2728
|
+
* `night` is the effect looks' own dark colors. */
|
|
2729
|
+
declare const DIAGRAM_THEMES: Readonly<Record<string, DiagramTheme>>;
|
|
2730
|
+
|
|
2731
|
+
/**
|
|
2732
|
+
* A theme matching its host's chrome, built from resolved `--wzl-*` values:
|
|
2733
|
+
* `read` answers a custom property's value, as `getComputedStyle(el)
|
|
2734
|
+
* .getPropertyValue` does. A token that reads empty takes `paper`'s color.
|
|
2735
|
+
*/
|
|
2736
|
+
declare function diagramThemeFromTokens(read: (token: string) => string, opts?: {
|
|
2737
|
+
id?: string;
|
|
2738
|
+
name?: string;
|
|
2739
|
+
}): DiagramTheme;
|
|
2740
|
+
|
|
2741
|
+
/** The style a shape naming `role` is drawn in: that role's, or the theme's default role's. */
|
|
2742
|
+
declare function roleStyle(theme: DiagramTheme, role?: string): NodeStyle;
|
|
2743
|
+
/** The style a connector naming `role` is drawn in: the role's stroke, its label in that stroke too;
|
|
2744
|
+
* with no role, the theme's own connector and label colors. */
|
|
2745
|
+
declare function roleEdgeStyle(theme: DiagramTheme, role?: string): EdgeStyle;
|
|
2746
|
+
/** The stroke a connector drawn under `theme` starts with, for a connect action's `edgeStroke`. */
|
|
2747
|
+
declare function themeEdgeStroke(theme: DiagramTheme): Stroke;
|
|
2748
|
+
/** The theme's face as `diagramScene` and the stencils take one. */
|
|
2749
|
+
declare const themeFont: (theme: DiagramTheme) => {
|
|
2750
|
+
fontFamily: string;
|
|
2751
|
+
fontSize: number;
|
|
2752
|
+
};
|
|
2753
|
+
/** The face edge labels are sized from, before `labelStyleOf` takes two sizes off: the theme's label
|
|
2754
|
+
* face where it names one, else `font`. */
|
|
2755
|
+
declare const themeLabelFont: (theme: DiagramTheme, font?: {
|
|
2756
|
+
fontFamily: string;
|
|
2757
|
+
fontSize: number;
|
|
2758
|
+
}) => {
|
|
2759
|
+
fontFamily: string;
|
|
2760
|
+
fontSize: number;
|
|
2761
|
+
};
|
|
2762
|
+
/** The face a new connector label is set in under `theme`. */
|
|
2763
|
+
declare const themeLabelStyle: (theme: DiagramTheme) => {
|
|
2764
|
+
fontSize: number;
|
|
2765
|
+
fontFamily: string;
|
|
2766
|
+
};
|
|
2767
|
+
/** The theme a document value names: a shipped theme by id, or a whole theme. `fallback` for none,
|
|
2768
|
+
* or for an id no shipped theme has. */
|
|
2769
|
+
declare function diagramThemeFrom(value: unknown, fallback?: DiagramTheme): DiagramTheme;
|
|
2770
|
+
/** The theme a scene's `diagram:theme` value names. */
|
|
2771
|
+
declare function diagramThemeOf(scene: {
|
|
2772
|
+
doc: {
|
|
2773
|
+
get(key: string): unknown;
|
|
2774
|
+
};
|
|
2775
|
+
}, fallback?: DiagramTheme): DiagramTheme;
|
|
2776
|
+
/** What `diagram:theme` holds for `theme`: a shipped theme's id, or the whole theme. */
|
|
2777
|
+
declare const themeDocValue: (theme: DiagramTheme) => string | DiagramTheme;
|
|
2778
|
+
|
|
2779
|
+
/** A scene node as {@link themeWrites} reads it. */
|
|
2780
|
+
interface ThemedNode {
|
|
2781
|
+
id: string;
|
|
2782
|
+
parent: string | null;
|
|
2783
|
+
data: unknown;
|
|
2784
|
+
dependsOn?: readonly string[] | 'children';
|
|
2785
|
+
}
|
|
2786
|
+
/** A scene as {@link themeWrites} reads it. */
|
|
2787
|
+
interface ThemedScene {
|
|
2788
|
+
get(id: never): ThemedNode | undefined;
|
|
2789
|
+
renderOrderNodes(): readonly ThemedNode[];
|
|
2790
|
+
childrenOf(id: never): readonly string[];
|
|
2791
|
+
}
|
|
2792
|
+
/**
|
|
2793
|
+
* The new `data` for every node `theme` recolors: shapes, their text rows,
|
|
2794
|
+
* groups and containers and their titles, connectors and their labels. Given
|
|
2795
|
+
* `ids`, only those boxes and connectors, and the text that belongs to them.
|
|
2796
|
+
* Given `from`, the theme the scene was in, text moves by the step between the
|
|
2797
|
+
* two themes' sizes, except where its owner's author set the size. A node
|
|
2798
|
+
* already as the theme draws it is left out.
|
|
2799
|
+
*/
|
|
2800
|
+
declare function themeWrites(scene: ThemedScene, theme: DiagramTheme, ids?: ReadonlySet<string>, from?: DiagramTheme): Map<string, unknown>;
|
|
2801
|
+
|
|
2802
|
+
/**
|
|
2803
|
+
* Measures a row's text as the kit's text renderer lays it out, from the
|
|
2804
|
+
* registered font's metrics, so a body sized by it holds the text it draws.
|
|
2805
|
+
* The line height is 1.2 sizes, as `canvasMeasure`'s is. Needs the family
|
|
2806
|
+
* registered; an unregistered one measures as the fallback glyph.
|
|
2807
|
+
*/
|
|
2808
|
+
declare const rendererMeasure: MeasureRowText;
|
|
2809
|
+
|
|
2810
|
+
/**
|
|
2811
|
+
* Laying a built body out again once its text changes size. A body whose
|
|
2812
|
+
* rows are all text records how it stacks them (`DiagramNode.body`), and each
|
|
2813
|
+
* text row records its place (`bodyRow`), so the rows can be read back from
|
|
2814
|
+
* the scene and handed to the same layout `buildBody` used.
|
|
2815
|
+
*/
|
|
2816
|
+
|
|
2817
|
+
/** A scene as {@link relayoutBodies} reads and writes it. */
|
|
2818
|
+
interface RelayoutScene {
|
|
2819
|
+
get(id: never): {
|
|
2820
|
+
pose: unknown;
|
|
2821
|
+
data: unknown;
|
|
2822
|
+
} | undefined;
|
|
2823
|
+
childrenOf(id: never): readonly string[];
|
|
2824
|
+
setPose(id: never, pose: never): void;
|
|
2825
|
+
}
|
|
2826
|
+
/**
|
|
2827
|
+
* Lays each body among `ids` out again from its text rows as they are now:
|
|
2828
|
+
* the body grows to what its rows need, never shrinks, and its rows are
|
|
2829
|
+
* stacked again inside it. Anything that is not a body carrying a `body`
|
|
2830
|
+
* record is left alone. Call inside the batch that changed the text, so it is
|
|
2831
|
+
* the same undo entry.
|
|
2832
|
+
*/
|
|
2833
|
+
declare function relayoutBodies(scene: RelayoutScene, ids: Iterable<string>, measure?: MeasureRowText): void;
|
|
2834
|
+
|
|
2835
|
+
/**
|
|
2836
|
+
* The edits a theme makes to a scene, each one undo entry: applying a theme,
|
|
2837
|
+
* naming a shape's or connector's role, and setting a color by hand.
|
|
2838
|
+
*/
|
|
2839
|
+
|
|
2840
|
+
type AnyScene = Scene<unknown, string, unknown>;
|
|
2841
|
+
/** What a styleable node says about its style: a shape or a connector, the role it names, and the
|
|
2842
|
+
* colors its author set by hand. */
|
|
2843
|
+
interface DiagramStyleState {
|
|
2844
|
+
kind: 'shape' | 'connector';
|
|
2845
|
+
role?: string;
|
|
2846
|
+
own: readonly StyleField[];
|
|
2847
|
+
/** The parts of its text face the author set: a theme's size change leaves those. */
|
|
2848
|
+
ownFont: readonly FontField[];
|
|
2849
|
+
}
|
|
2850
|
+
/** The style state of a shape (a body) or a connector, or `null` for anything else — a text row,
|
|
2851
|
+
* a label, a group, a container. */
|
|
2852
|
+
declare function diagramStyleOf(node: {
|
|
2853
|
+
data: unknown;
|
|
2854
|
+
}): DiagramStyleState | null;
|
|
2855
|
+
/** Options for {@link applyDiagramTheme}. */
|
|
2856
|
+
interface ApplyDiagramThemeOptions {
|
|
2857
|
+
/** Fold this apply into the undo entry before it when that one was made under the same key, so a
|
|
2858
|
+
* run of applies, such as a theme color dragged, undoes as one. See `scene.batch`. */
|
|
2859
|
+
coalesceKey?: string;
|
|
2860
|
+
/** The theme the scene is in now, whose font size text moves from. Default the scene's own
|
|
2861
|
+
* `diagram:theme`; a host that draws a scene naming none in another theme passes that. */
|
|
2862
|
+
from?: DiagramTheme;
|
|
2863
|
+
/** Measures text, for laying out again a body whose text changed size. Default an estimate. */
|
|
2864
|
+
measure?: MeasureRowText;
|
|
2865
|
+
}
|
|
2866
|
+
/** Recolors the whole scene in `theme` and saves it as the `diagram:theme` document value, as one
|
|
2867
|
+
* undo entry. Colors the author set by hand stay. */
|
|
2868
|
+
declare function applyDiagramTheme(scene: AnyScene, theme: DiagramTheme, label?: string, opts?: ApplyDiagramThemeOptions): void;
|
|
2869
|
+
/** Options for {@link setDiagramStyle} and {@link setDiagramColor}. */
|
|
2870
|
+
interface DiagramStyleEditOptions {
|
|
2871
|
+
/** The theme to color by. Default the scene's own `diagram:theme`. */
|
|
2872
|
+
theme?: DiagramTheme;
|
|
2873
|
+
label?: string;
|
|
2874
|
+
}
|
|
2875
|
+
/**
|
|
2876
|
+
* Names `role` on every shape and connector among `ids` and recolors them in
|
|
2877
|
+
* it, as one undo entry. Choosing a role hands back any color the author had
|
|
2878
|
+
* set, so the role shows.
|
|
2879
|
+
*/
|
|
2880
|
+
declare function setDiagramStyle(scene: AnyScene, ids: readonly string[], role: string, opts?: DiagramStyleEditOptions): void;
|
|
2881
|
+
/**
|
|
2882
|
+
* Sets `field` to `color` on every shape and connector among `ids` — `text`
|
|
2883
|
+
* reaching a shape's rows and a connector's label — and records it in their
|
|
2884
|
+
* `ownStyle`, so a theme change leaves it. One undo entry. A connector has no
|
|
2885
|
+
* fill, and ignores one.
|
|
2886
|
+
*/
|
|
2887
|
+
declare function setDiagramColor(scene: AnyScene, ids: readonly string[], field: StyleField, color: string, opts?: Pick<DiagramStyleEditOptions, 'label'>): void;
|
|
2888
|
+
/**
|
|
2889
|
+
* Sets the text of every shape and connector among `ids` — a shape's rows, a
|
|
2890
|
+
* connector's label — to `size`, and records it in their `ownFont`, so a
|
|
2891
|
+
* theme's size change leaves it. One undo entry.
|
|
2892
|
+
*/
|
|
2893
|
+
declare function setDiagramFontSize(scene: AnyScene, ids: readonly string[], size: number, opts?: Pick<DiagramStyleEditOptions, 'label'> & {
|
|
2894
|
+
measure?: MeasureRowText;
|
|
2895
|
+
}): void;
|
|
2896
|
+
|
|
2897
|
+
type BoxField = 'fill' | 'stroke' | 'text';
|
|
2898
|
+
/** Where one value sits in a {@link DiagramTheme}. */
|
|
2899
|
+
type ThemePath = readonly ['roles', string, BoxField] | readonly ['edge', 'stroke'] | readonly ['label', 'fill'] | readonly ['container', BoxField] | readonly ['lane', 'header', BoxField] | readonly ['lane', 'bodies', number, BoxField] | readonly ['page'] | readonly ['font', 'family'] | readonly ['font', 'size'] | readonly ['series', number];
|
|
2900
|
+
/** Whether `theme` is one of {@link DIAGRAM_THEMES} itself, which no edit may change. */
|
|
2901
|
+
declare const isShippedTheme: (theme: DiagramTheme) => boolean;
|
|
2902
|
+
/** A custom copy of `theme`, named "<name> (edited)", for a document to keep and change. */
|
|
2903
|
+
declare function forkTheme(theme: DiagramTheme): DiagramTheme;
|
|
2904
|
+
/** `theme` when it is already a custom theme, else a fork of it: what the first edit to a shipped
|
|
2905
|
+
* theme starts from. */
|
|
2906
|
+
declare const editableTheme: (theme: DiagramTheme) => DiagramTheme;
|
|
2907
|
+
/** The value at `path` in `theme`. */
|
|
2908
|
+
declare function themeValue(theme: DiagramTheme, path: ThemePath): unknown;
|
|
2909
|
+
/** `theme` with `value` at `path`; everything else shared with it. */
|
|
2910
|
+
declare const setThemeValue: (theme: DiagramTheme, path: ThemePath, value: string | number) => DiagramTheme;
|
|
2911
|
+
/** Every role `theme` styles with the name a picker shows: the shipped roles first, in their order,
|
|
2912
|
+
* then the theme's own. */
|
|
2913
|
+
declare function themeRoles(theme: DiagramTheme): {
|
|
2914
|
+
id: string;
|
|
2915
|
+
label: string;
|
|
2916
|
+
}[];
|
|
2917
|
+
/** `theme` with a role named `label`, in the default role's colors, and the id it was given. */
|
|
2918
|
+
declare function addThemeRole(theme: DiagramTheme, label: string): {
|
|
2919
|
+
theme: DiagramTheme;
|
|
2920
|
+
id: string;
|
|
2921
|
+
};
|
|
2922
|
+
/** `theme` with role `id` shown as `label`. The id, which shapes name the role by, stays. */
|
|
2923
|
+
declare const renameThemeRole: (theme: DiagramTheme, id: string, label: string) => DiagramTheme;
|
|
2924
|
+
/** `theme` without role `id`; its shapes fall to the default role when the theme is next applied.
|
|
2925
|
+
* The default role stays: `theme` comes back unchanged. */
|
|
2926
|
+
declare function removeThemeRole(theme: DiagramTheme, id: string): DiagramTheme;
|
|
2927
|
+
|
|
2928
|
+
/** The extension a theme file is saved with. */
|
|
2929
|
+
declare const DIAGRAM_THEME_EXTENSION = ".weasel-theme.json";
|
|
2930
|
+
/** `theme` as the text of a theme file. */
|
|
2931
|
+
declare const themeToJson: (theme: DiagramTheme) => string;
|
|
2932
|
+
/** The theme a theme file holds, or what is wrong with it, each error naming where. */
|
|
2933
|
+
declare function parseDiagramTheme(json: string): {
|
|
2934
|
+
theme: DiagramTheme;
|
|
2935
|
+
} | {
|
|
2936
|
+
errors: string[];
|
|
2937
|
+
};
|
|
2938
|
+
|
|
2939
|
+
export { ADD_LANE_ACTION_ID, type ApplyDiagramThemeOptions, type ApplyLayoutOptions, AvoidInput, AvoidOptions, AvoidRouter, AvoidRoutes, type AvoidRouting, type AvoidRoutingOptions, type AvoidSceneOptions, type BodyEnd, type BodyHit, Bounds$2 as Bounds, CONNECTOR_ACTION_ID, CONNECTOR_TOOL_ID, CONNECT_ACTION_ID, CONTAINER_HEADER, CONTAINER_LAYOUTS, CONTAINER_STENCILS, type CanConnect, type ConnectActionOptions, type ConnectEnd, type ConnectView, type ContainerBuildOptions, type ContainerEdit, ContainerHeader, type ContainerLayoutOptions, ContainerRole, type ContainerStencil, DEFAULT_EDGE_STROKE, DIAGRAM_CONTAINER_LAYOUT, DIAGRAM_EDGE, DIAGRAM_LABEL, DIAGRAM_LANE_COLUMNS_LAYOUT, DIAGRAM_LANE_ROWS_LAYOUT, DIAGRAM_OFF_PAGE_TAG, DIAGRAM_PASS_ORDER, DIAGRAM_POOL_COLUMNS_LAYOUT, DIAGRAM_POOL_ROWS_LAYOUT, DIAGRAM_THEMES, DIAGRAM_THEME_EXTENSION, DataContainer, DataEdge, DataNode, type DeleteReport, DiagramContainer, type DiagramContributionOptions, DiagramData, DiagramEdge, DiagramLabel, type DiagramLayout, DiagramNodeLike, DiagramNodeReader, type DiagramOverlay, DiagramSceneData, DiagramSceneOptions, type DiagramShapeOptions, DiagramSpec, type DiagramStencil, type DiagramStyleEditOptions, type DiagramStyleState, DiagramTheme, DiagramView, type DiagramViewApi, type DiagramViewProps, type DraggableLabel, type DropParentScene, EASED_LAYOUTS, EDGE_DERIVE_PATH, EDGE_END_AFFORDANCE_KIND, EDGE_END_LAYER_ID, EDIT_CONTAINER_TITLE_ACTION_ID, EDIT_EDGE_LABEL_ACTION_ID, type EasedProducerOptions, EdgeEnd, type EdgeEndAffordanceOptions, type EdgeEndScratch, EdgeHop, type EdgeLabelOptions, type EdgeRoute, type EdgeRouteOptions, type EdgeRouteState, EdgeStyle, type EditEdgeLabelOptions, type EndChange, FLOWCHART_STENCILS, FOLLOW_OFF_PAGE_ACTION_ID, type FollowOffPageOptions, FontField, ForceOptions, type ForceProducerOptions, GRAB_EDGE_END_ACTION_ID, GRAB_LABEL_ACTION_ID, GRAB_PORT_ACTION_ID, GRAB_WAYPOINT_ACTION_ID, Graph, GraphNodeLike, GraphSource, type Hops, type HopsOptions, LABEL_DERIVE_POSE, LABEL_DRAG_AFFORDANCE_KIND, LABEL_DRAG_LAYER_ID, LANE_AFFORDANCE_KIND, LANE_HEADER_SIZE, LANE_LAYER_ID, LANE_RESIZE_ACTION_ID, LAYOUTS, LAYOUT_ACTION_ID, type LabelDragOptions, type LabelEdit, type LabelMove, type LabelPlacement, type LabelPlacementOptions, type LabelPoseOptions, type LabelScratch, LabelSpot, type LaneActionOptions, type LaneLayerOptions, type LaneResize, type LaneScratch, type LaneStackOptions, type LayeredRoute, type LayeredRouteInput, type LayoutActionOptions, LayoutDirection, LayoutFn, LayoutOptions, LayoutPlan, LayoutPlanner, LayoutPorts, LayoutResult, type LayoutRoutes, type LiveLayout, type LiveLayoutCtx, type LiveLayoutFrame, type LiveLayoutProducer, MIN_LANE_SIZE, MOVE_LABEL_ACTION_ID, MeasureRowText, type MovingEnd, type NodeMove, type NodeResize, NodeStyle, OFF_PAGE_STUB, OFF_PAGE_TAG_DERIVE_POSE, OFF_PAGE_TAG_PADDING, type OffPageEdgeInput, type OffPageMarkerOptions, OffPageSplit, type OffPageSplitInput, type OffPageTagLook, type OffPageTarget, Outline, POOL_HEADER_SIZE, PORT_AFFORDANCE_KIND, PORT_LAYER_ID, type ParticipantPose, type ParticipantScene, type ParticipantSource, type PendingEdge, PlaceLabelsOptions, type PoolLanes, Port, type PortAffordanceOptions, type PortScratch, PortsOptions, RECONNECT_ACTION_ID, RELEASE_MEMBERS_ACTION_ID, REMOVE_WAYPOINT_ACTION_ID, REORDER_ACTION_ID, RESET_LABEL_ACTION_ID, RESET_ROUTE_ACTION_ID, ROUTERS, ROUTER_LABELS, ROUTE_EDIT_ACTION_ID, type ReconnectChange, type ReconnectOptions, type RegionOptions, type RegionSpec, type RelayoutScene, type ReorderChange, type ReorderGap, type ReorderItem, type ReorderMove, type ReorderOptions, type ReorderSlots, type ResolvedRoute, type RouteChange, type RouteEdge, type RouteEdit, type RouteEditOptions, type RouteHandle, type RouteRequest, type RoutedScene, type Router, type RouterEdit, Row, RowTextStyle, SELECT_LABEL_EDGE_ACTION_ID, SET_HOPS_ACTION_ID, SET_ROUTER_ACTION_IDS, STEP_REORDER_ACTION_ID, type SelfLoop, type SetHopsOptions, type SetRouterOptions, type StencilInsertOptions, StyleField, type StyledRegion, type ThemePath, type ThemedNode, type ThemedScene, type UseLiveLayoutOptions, WAYPOINT_AFFORDANCE_KIND, WAYPOINT_HIT_PX, WAYPOINT_LAYER_ID, type WaypointAffordanceOptions, type WaypointScratch, addLane, addThemeRole, applyDiagramTheme, applyLayout, avoid, avoidSceneInput, bezier, bodyAt, commitEdgeToScene, commitLabelToScene, commitLaneResizeToScene, commitReconnectToScene, commitRouteToScene, commitRouterToScene, connectBinding, connectorTool, containerBuild, containerShape, createAddLaneAction, createConnectAction, createDiagramContribution, createEdgeEndAffordance, createFollowOffPageAction, createLabelDragAction, createLaneAffordance, createLaneResizeAction, createLayoutAction, createPortAffordance, createReconnectAction, createReleaseMembersAction, createRemoveWaypointAction, createReorderAction, createResetLabelAction, createResetRouteAction, createRouteEditAction, createSetHopsAction, createSetRouterAction, createSpecHops, createSpecLabelPlacer, createSpecRouter, createStepReorderAction, createWaypointAffordance, dataEdgeStyle, dataNodeStyle, dataOffPage, dataRegionStyle, defaultCanConnect, diagramCanDropInto, diagramContainerLayout, diagramContainers, diagramDropParentAt, diagramEdgeEnds, diagramLabelDrag, diagramLayoutOf, diagramOffPage, diagramPages, diagramPorts, diagramResizable, diagramScene, diagramShape, diagramStyleOf, diagramThemeFrom, diagramThemeFromTokens, diagramThemeOf, diagramWaypoints, documentBoundsOf, dragSegment, dragVertex, draggableLabels, dropEmptyEdgeLabel, easedProducer, edgeDerivePath, edgeEndLayer, edgeEndScratchOf, edgeIdOf, edgeLabelSpec, edgeRouter, editContainerTitleAction, editContainerTitleBinding, editEdgeLabelAction, editEdgeLabelBinding, editableTheme, firstLanes, followOffPageBinding, forceProducer, forkTheme, grabPortAction, grabPortBindings, groupReorderContribution, groupReorderSlots, headerIdOf, hopFollower, insertWaypoint, installAvoidRouting, installHops, installLabelPlacement, installOffPageMarkers, isBodyEnd, isShippedTheme, labelDerivePose, labelDragLayer, labelScratchOf, labelSize, labelUnder, laneHeader, laneLayer, laneResizeFrame, laneScratchOf, laneStackLayout, lanesOf, layeredRoutes, layoutPoses, movedLabelData, nextOffPageRef, offPageFarText, offPageOps, offPageSplits, offPageTagData, offPageTagDerivePose, offPageTagLook, offPageTagSize, offPageTagSpec, offPageTagSpecs, offPageTagText, offPageTargetOf, orthogonal, parseDiagramTheme, pinSegment, poolAxisOf, poolHeader, poolsOf, portLayer, portScratchOf, reconnectBinding, regionHeaderAt, regionSpecs, registerDiagramShape, relayoutBodies, releaseMembers, removeSegment, removeThemeRole, removeWaypoint, renameThemeRole, rendererMeasure, reorderBinding, reorderContribution, resolveEnd, roleEdgeStyle, roleStyle, routeDataOps, routeHandles, routeStateOf, routeWrites, routedData, routerActions, routesOf, sceneParticipants, segmentAxis, selfLoop, sequenceSlots, setDiagramColor, setDiagramFontSize, setDiagramStyle, setThemeValue, simplifyStops, stackedLanes, stencilBuild, stencilIdOf, stencilKind, stencilTool, straight, subpathOf, themeDocValue, themeEdgeStroke, themeFont, themeLabelFont, themeLabelStyle, themeRoles, themeToJson, themeValue, themeWrites, titlePose, unpinSegment, useAvoidRouting, useConnectorTool, useHops, useLabelPlacement, useLiveLayout, useMirroredSelection, useOffPageMarkers, useStencilInsert, useStencilTool, waypointFollower, waypointLayer, waypointScratchOf, withDiagramRegistry, withHops, withRouter };
|