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