@weasel-js/diagram 1.10.1 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,553 @@
1
+ import { DerivedDep, PoseDescriptor, NodeShapeEntry, MarkerRef, Page, PageLayoutOptions, AddNodeSpec, Stroke, RectPose } from '@weasel-js/core';
2
+ import { Vec2 } from '@weasel-js/core/math';
3
+ import { E as EdgeHop, S as StyleField, P as PortAnchor, D as DiagramGroup, R as RowTextStyle, a as Row, O as Outline, b as PortSpec, B as BodySpec, c as DiagramLabel, L as LayoutPorts, d as LayoutFn, e as LayoutOptions, M as MeasureRowText, f as DiagramNode } from './types-BbHunLXm.js';
4
+
5
+ /**
6
+ * Off-page markers as data: what a connector cut at the page gap holds, and
7
+ * what each of its two tags holds. The pass that writes both is `install`.
8
+ */
9
+ /** A connector whose ends sit on different pages: its reference letter, and
10
+ * the pages its `from` and `to` ends are on. */
11
+ interface OffPageSplit {
12
+ ref: string;
13
+ from: string;
14
+ to: string;
15
+ }
16
+ /** Which end of which connector a tag names the far page for. */
17
+ interface OffPageTag {
18
+ edge: string;
19
+ end: 'from' | 'to';
20
+ }
21
+ /** The id of the tag at end `end` of connector `edgeId`. */
22
+ declare const offPageTagId: (edgeId: string, end: "from" | "to") => string;
23
+ /** The off-page tag trait on a node's data (`data.diagram.offPageTag`), or `null`. */
24
+ declare function offPageTagOf(node: {
25
+ data: unknown;
26
+ }): OffPageTag | null;
27
+
28
+ /**
29
+ * The edge trait: what an edge's `data` says about its ends and its route, and
30
+ * who owns each. Data only — the routers and the scene wiring are in `edge`,
31
+ * so layout can read an edge without reaching the scene.
32
+ */
33
+
34
+ /** Where an edge attaches at one end. */
35
+ interface EdgeEnd {
36
+ /** The port to leave from, when the endpoint declares one. Falls back to
37
+ * the nearest port, so an edge drawn before ports were thought about still
38
+ * meets the shape. */
39
+ port?: string;
40
+ /** The port layout last named here. While `port` still equals it, or names
41
+ * none, layout owns the end and names it again on its next run. */
42
+ laidOut?: string;
43
+ }
44
+ /** Whether layout may name this end's port: it names none, or only the one
45
+ * layout last named. */
46
+ declare function layoutOwnsPort(end: EdgeEnd): boolean;
47
+ /** The trait on an edge's `data`, under the same key participants use. */
48
+ interface DiagramEdge {
49
+ from: EdgeEnd;
50
+ to: EdgeEnd;
51
+ /** Registry key for the router. Resolved by whoever builds the edge's
52
+ * `derivePath`; unknown keys fall back to `straight`. */
53
+ router?: string;
54
+ /** Points in world coordinates the route must pass through, in order. The
55
+ * author owns these; the router owns everything between them. */
56
+ waypoints?: readonly Vec2[];
57
+ /** The waypoints layout last wrote here. While `waypoints` still equals
58
+ * them, layout owns the route and rewrites it on its next run; once anyone
59
+ * edits them, they are the author's and layout leaves them alone. */
60
+ laidOut?: readonly Vec2[];
61
+ /** The bends between the ends that the obstacle-avoiding router last
62
+ * computed, kept so the edge draws without rerouting. The router owns it,
63
+ * and while it is here each end aims at its nearest bend. */
64
+ route?: readonly Vec2[];
65
+ /** Where it bows over the connectors drawn before it, as the line-jump
66
+ * pass last computed. Literal, so any reader draws them. */
67
+ hops?: readonly EdgeHop[];
68
+ /** Set while its ends sit on different pages, when it draws as two stubs
69
+ * ending at off-page tags. The off-page pass owns it (`installOffPageMarkers`). */
70
+ offPage?: OffPageSplit;
71
+ /** The theme role it is drawn in. Unset, the theme's own connector style. */
72
+ style?: string;
73
+ /** The colors the author set by hand, which a theme leaves as they are. */
74
+ ownStyle?: readonly StyleField[];
75
+ }
76
+ /** Whether layout may rewrite this edge's route: it has no waypoints, or only
77
+ * the ones layout last wrote. */
78
+ declare function layoutOwnsRoute(edge: DiagramEdge): boolean;
79
+ /** Whether layout writes this edge's waypoints: it owns the route, and the
80
+ * edge is not routed around obstacles, whose bends are never stops. */
81
+ declare function layoutWritesRoute(edge: DiagramEdge): boolean;
82
+ /** The edge trait on a node's data, or `null`. */
83
+ declare function diagramEdgeOf(node: {
84
+ data: unknown;
85
+ }): DiagramEdge | null;
86
+
87
+ /**
88
+ * A group's box, and anything pinned to a point on another node.
89
+ *
90
+ * The box is an ordinary node that depends on its members and derives its pose
91
+ * from theirs: their union, grown by the inset. Drag a member and the box
92
+ * follows; lay the diagram out and the box lands around wherever the members
93
+ * went. Nothing has to keep it in sync, because nothing stores it.
94
+ *
95
+ * An anchored node — a group's title is the first — derives its pose from one
96
+ * dependency's bounds the same way, so it travels with the box it labels.
97
+ */
98
+
99
+ /** Where an anchored node sits on its dependency. */
100
+ interface DiagramAnchor {
101
+ /** The point on the dependency's bounds, normalized as a port's is. */
102
+ at: PortAnchor;
103
+ /** The point on the node's own bounds that lands there. Default `at`, so
104
+ * `{ u: 0, v: 0 }` puts the node's top-left on the dependency's. */
105
+ self?: PortAnchor;
106
+ /** Then moved by this much, in world units. */
107
+ offset?: Vec2;
108
+ }
109
+ /** The group trait on a node's data, or `null`. */
110
+ declare function diagramGroupOf(node: {
111
+ data: unknown;
112
+ }): DiagramGroup | null;
113
+ /** The anchor trait on a node's data, or `null`. */
114
+ declare function diagramAnchorOf(node: {
115
+ data: unknown;
116
+ }): DiagramAnchor | null;
117
+ /** Options for {@link groupDerivePose} and {@link anchorDerivePose}.
118
+ * `geometry` defaults to the kit's `AUTO_POSE_DESCRIPTOR`. */
119
+ interface GroupPoseOptions<TPose> {
120
+ geometry?: PoseDescriptor<TPose>;
121
+ }
122
+ /** A `derivePose` function as the scene calls it: the node, then what it depends on, in `dependsOn` order. */
123
+ type DiagramDerivePose<TPose> = (node: {
124
+ pose: TPose;
125
+ data: unknown;
126
+ }, deps: readonly (DerivedDep<TPose> | undefined)[]) => TPose | null;
127
+ /**
128
+ * A `derivePose` that draws a group's box around its members: the union of
129
+ * what each takes up, its `margin` included, grown by the trait's inset. `null` — the authored pose stands — when the node
130
+ * carries no group trait or every member is gone.
131
+ */
132
+ declare function groupDerivePose<TPose>(opts?: GroupPoseOptions<TPose>): DiagramDerivePose<TPose>;
133
+ /** A group's box around the union of its members: grown by its inset, and
134
+ * widened evenly to its `minWidth`. */
135
+ declare function boxAround(union: {
136
+ x: number;
137
+ y: number;
138
+ width: number;
139
+ height: number;
140
+ }, group: DiagramGroup): {
141
+ x: number;
142
+ y: number;
143
+ width: number;
144
+ height: number;
145
+ };
146
+ /**
147
+ * A `derivePose` that keeps a node at a point on its dependency's bounds.
148
+ * `null` when the node carries no anchor trait or the dependency is gone.
149
+ */
150
+ declare function anchorDerivePose<TPose>(opts?: GroupPoseOptions<TPose>): DiagramDerivePose<TPose>;
151
+ /** Registry key for {@link GROUP_DERIVE_POSE}. */
152
+ declare const DIAGRAM_GROUP = "diagram:group";
153
+ /** Registry key for {@link ANCHOR_DERIVE_POSE}. */
154
+ declare const DIAGRAM_ANCHOR = "diagram:anchor";
155
+ /** The default group derivation, a stable reference so `toJSON` can find its key. */
156
+ declare const GROUP_DERIVE_POSE: DiagramDerivePose<unknown>;
157
+ /** The default anchor derivation, a stable reference for the same reason. */
158
+ declare const ANCHOR_DERIVE_POSE: DiagramDerivePose<unknown>;
159
+
160
+ /**
161
+ * Marks: what a data node draws besides its rows. A drawn mark is SVG path
162
+ * data in a unit square, stretched over the node's box, so it follows the node
163
+ * wherever layout or a drag puts it. A text mark is pinned to a point on the box.
164
+ */
165
+
166
+ /** One mark on a `DataNode`. Colors default to the node's stroke and text. */
167
+ type DataMark = {
168
+ d: string;
169
+ fill?: string;
170
+ stroke?: string;
171
+ strokeWidth?: number;
172
+ dash?: number[];
173
+ opacity?: number;
174
+ } | {
175
+ text: string;
176
+ at: PortAnchor;
177
+ self?: PortAnchor;
178
+ offset?: Vec2;
179
+ color?: string;
180
+ style?: RowTextStyle;
181
+ };
182
+ /** The trait on a drawn mark's `data`: path data in a unit square. */
183
+ interface DiagramMark {
184
+ d: string;
185
+ }
186
+ /** The mark a scene node carries, or null for a node that is not a drawn
187
+ * mark: how `markShape` tells which nodes it paints. */
188
+ declare function diagramMarkOf(node: {
189
+ data: unknown;
190
+ }): DiagramMark | null;
191
+ /** The painter for a drawn mark. */
192
+ declare function markShape<TPose>(opts?: {
193
+ geometry?: PoseDescriptor<TPose>;
194
+ }): NodeShapeEntry<unknown, TPose>;
195
+ /** Register {@link markShape}; returns the disposer. */
196
+ declare function registerMarkShape<TPose>(opts?: {
197
+ geometry?: PoseDescriptor<TPose>;
198
+ }): () => void;
199
+
200
+ /** The face a diagram node's text is set in. */
201
+ type DiagramTextStyle = {
202
+ fontFamily: string;
203
+ fontSize: number;
204
+ fontWeight?: number;
205
+ align?: 'center';
206
+ };
207
+ type Font = {
208
+ fontFamily: string;
209
+ fontSize: number;
210
+ };
211
+ /** The face a body row's text is set in. A label row's is centered in the row. */
212
+ declare function rowTextStyle(row: Row | undefined, font: Font): DiagramTextStyle;
213
+
214
+ /** The roles every shipped theme styles, with the name a picker shows. */
215
+ declare const DIAGRAM_ROLES: readonly [{
216
+ readonly id: "default";
217
+ readonly label: "Default";
218
+ }, {
219
+ readonly id: "accent";
220
+ readonly label: "Accent";
221
+ }, {
222
+ readonly id: "muted";
223
+ readonly label: "Muted";
224
+ }, {
225
+ readonly id: "positive";
226
+ readonly label: "Positive";
227
+ }, {
228
+ readonly id: "warning";
229
+ readonly label: "Warning";
230
+ }, {
231
+ readonly id: "negative";
232
+ readonly label: "Negative";
233
+ }];
234
+ /** The id of one of {@link DIAGRAM_ROLES}. A theme may style roles of its own besides. */
235
+ type DiagramRole = (typeof DIAGRAM_ROLES)[number]['id'];
236
+
237
+ /** The face a theme sets diagram text in. A text row keeps its own size. */
238
+ interface DiagramFont {
239
+ family: string;
240
+ size: number;
241
+ }
242
+ /**
243
+ * A document's colors and face. Applying one writes literal colors into the
244
+ * scene, so nothing that reads the scene needs the theme to draw it.
245
+ */
246
+ interface DiagramTheme {
247
+ id: string;
248
+ name: string;
249
+ /** A shape's fill, stroke and text by role id. A connector given a role takes that role's stroke. */
250
+ roles: Readonly<Record<string, NodeStyle>>;
251
+ /** The names a picker shows for roles beyond {@link DIAGRAM_ROLES}, or for a shipped role renamed. */
252
+ roleLabels?: Readonly<Record<string, string>>;
253
+ /** The role a shape or connector naming none, or naming one this theme lacks, is drawn in. */
254
+ defaultRole: string;
255
+ /** A connector naming no role. */
256
+ edge: EdgeStyle;
257
+ /** A connector's label, where the connector names no role. */
258
+ label: {
259
+ fill: string;
260
+ font?: DiagramFont;
261
+ };
262
+ /** A group's or a container's box, its `text` the title's color. */
263
+ container: NodeStyle;
264
+ /** A pool's header, and its lanes' bodies in turn. */
265
+ lane: {
266
+ header: NodeStyle;
267
+ bodies: readonly NodeStyle[];
268
+ };
269
+ /** The page a document is drawn on. */
270
+ page: string;
271
+ font: DiagramFont;
272
+ /** Colors for a series of things the theme cannot name in advance: an effect look's value types. */
273
+ series: readonly string[];
274
+ }
275
+ /** The document value a theme is saved under: a shipped theme's id, or a whole custom theme. */
276
+ declare const DIAGRAM_THEME_KEY = "diagram:theme";
277
+
278
+ /**
279
+ * The plain data `diagramScene` reads, and the options and styles it takes.
280
+ */
281
+
282
+ /** One node of a {@link DiagramData}: its rows of text, and optionally its outline, ports, size, and starting place. */
283
+ interface DataNode {
284
+ id: string;
285
+ /** Shorthand for one `label` row per line. Ignored when `rows` is given. */
286
+ lines?: readonly string[];
287
+ rows?: readonly Row[];
288
+ /** Default `DiagramSceneOptions.outline`, which defaults to `'rect'`. */
289
+ outline?: Outline;
290
+ /** Perimeter ports, replacing the four compass midpoints. */
291
+ ports?: readonly PortSpec[];
292
+ /** Labels for the perimeter ports by id, drawn outside the box beside each. */
293
+ portLabels?: Readonly<Record<string, string>>;
294
+ /** Layout leaves this node at `at`. */
295
+ pinned?: boolean;
296
+ /** Where the node starts, before layout. Unset, nodes start on the
297
+ * diagonal in source order, which is what within-rank order is seeded
298
+ * from. */
299
+ at?: Vec2;
300
+ /** The smallest the box may be. Its content grows it past this. */
301
+ width?: number;
302
+ height?: number;
303
+ /** Default `DiagramSceneOptions.padding`. */
304
+ padding?: number;
305
+ /** Default `DiagramSceneOptions.gap`. */
306
+ gap?: number;
307
+ /** Default `DiagramSceneOptions.verticalAlign`. */
308
+ verticalAlign?: BodySpec['verticalAlign'];
309
+ /** Drawn over the box besides its rows: shapes in a unit square stretched
310
+ * over it, and text pinned to a point on it. */
311
+ marks?: readonly DataMark[];
312
+ /** The theme role it is drawn in, under `DiagramSceneOptions.theme`. Kept on its trait. */
313
+ style?: string;
314
+ /** Colors of its own, over its role's. Each one set is listed in the trait's `ownStyle`, so a
315
+ * theme change leaves it. */
316
+ colors?: Partial<NodeStyle>;
317
+ }
318
+ /** One edge of a {@link DiagramData}, between two nodes or groups by id. */
319
+ interface DataEdge {
320
+ /** The scene node id this edge gets, for an editor that must find it again
321
+ * after its ends, ports or label change. Unset, {@link edgeIdOf} derives
322
+ * one from those. */
323
+ id?: string;
324
+ /** A node's id, or a group's: an edge naming a group meets its box. */
325
+ from: string;
326
+ to: string;
327
+ /** The port to leave from or arrive at. Unset, the end facing the other
328
+ * node most directly. */
329
+ fromPort?: string;
330
+ toPort?: string;
331
+ label?: string;
332
+ /** Where along the edge the label sits. Unset or at `'mid'`, under
333
+ * `layered` the label sits in the room layout leaves it beside its wire,
334
+ * at this placement's offset, else `DiagramSceneOptions.labelPlacement`'s;
335
+ * otherwise at the placement. */
336
+ labelPlacement?: DiagramLabel;
337
+ /** Default `DiagramSceneOptions.router`. */
338
+ router?: DiagramRouter;
339
+ /** World points the route passes through. Layout does not move them. */
340
+ waypoints?: readonly Vec2[];
341
+ /** A route a layout run wrote, as `DiagramView`'s `onMove` reports it: drawn
342
+ * until layout runs again, which may replace it. `waypoints` wins. */
343
+ routed?: readonly Vec2[];
344
+ /** Ports a layout run named, as `onMove` reports them: used like `routed`,
345
+ * and not part of the edge's id. `fromPort` and `toPort` win. */
346
+ routedPorts?: LayoutPorts;
347
+ /** The theme role it is drawn in, under `DiagramSceneOptions.theme`: that role's stroke. Kept on its trait. */
348
+ style?: string;
349
+ /** Its stroke, markers, and label color of its own, over the theme's. `stroke` and `label` are
350
+ * listed in the trait's `ownStyle` (as `stroke` and `text`), so a theme change leaves them. */
351
+ colors?: Partial<EdgeStyle>;
352
+ }
353
+ /** A box drawn around some nodes, which layout keeps together. */
354
+ interface DataGroup {
355
+ /** Shares one namespace with node ids. */
356
+ id: string;
357
+ /** Node ids, and the ids of groups nested in this one. A node or group a
358
+ * later group also names stays in this one; an id that is neither is
359
+ * ignored, and so is one that would put a group inside itself. */
360
+ members: readonly string[];
361
+ /** Drawn inside the box, above its members. */
362
+ label?: string;
363
+ /** Between the box and its members, and around the label. Default
364
+ * `DiagramSceneOptions.groupPadding`. */
365
+ padding?: number;
366
+ /** The axis its members can be dragged along to change their order, in a
367
+ * `DiagramView` given `onReorder`. A member that is a group carries
368
+ * everything inside it. */
369
+ reorder?: 'x' | 'y';
370
+ }
371
+ /** A diagram as plain data, the input to `diagramScene`. */
372
+ interface DiagramData {
373
+ nodes: readonly DataNode[];
374
+ edges: readonly DataEdge[];
375
+ /** A group may be a member of another. `layered`, `tree`, `force`, and `chain`
376
+ * keep each group's members together; `'none'` ignores groups but still
377
+ * draws them. */
378
+ groups?: readonly DataGroup[];
379
+ /** Containers and pools: regions drawn as scene containers that hold their
380
+ * members, which a `DiagramView` drags shapes into and out of. */
381
+ containers?: readonly DataContainer[];
382
+ /** The sheets the diagram is drawn on, in world space as `layoutPages` places them; a node
383
+ * belongs to the page its box overlaps most (`pageOfBounds`). A connector whose ends belong
384
+ * to different pages is split into two stubs, each with an off-page tag. A node in the gap
385
+ * between pages belongs to none, and its connectors stay whole. */
386
+ pages?: readonly Page[];
387
+ /** How `pages` are laid out in world space. */
388
+ pageLayout?: PageLayoutOptions;
389
+ }
390
+ /**
391
+ * A container or a pool, drawn as a region that holds its members. Its id
392
+ * shares one namespace with node, group, and lane ids.
393
+ *
394
+ * With a `box` it is laid out as one node of that size, and its members ride
395
+ * along with it: a member with no `at` is seeded inside its body, in rows.
396
+ * With none, a container is laid out as a group and its box fits its members.
397
+ * A pool always has a box, {@link DEFAULT_POOL_ACROSS} across and
398
+ * {@link DEFAULT_LANE_SIZE} along per lane when none is given. An edge with
399
+ * an end inside a boxed region ranks against the outermost one holding it.
400
+ */
401
+ interface DataContainer {
402
+ id: string;
403
+ role: 'container' | 'pool';
404
+ /** Its title, drawn in its header. */
405
+ label?: string;
406
+ /** A container's direct members: node ids and container ids. A member
407
+ * already claimed by an earlier container, a pool, an unknown id, and one
408
+ * that would put a container inside itself are ignored. */
409
+ members?: readonly string[];
410
+ /** A pool's lanes, in the order they stack. */
411
+ lanes?: readonly DataLane[];
412
+ /** The axis a pool stacks its lanes along: `'y'` for rows. Default `'y'`. */
413
+ axis?: 'x' | 'y';
414
+ /** Where it stands and how big it is, in world units. A pool's size along
415
+ * its stack is shared by the lanes that give no `size`. */
416
+ box?: {
417
+ x: number;
418
+ y: number;
419
+ width: number;
420
+ height: number;
421
+ };
422
+ /** Layout leaves its box where it is. */
423
+ pinned?: boolean;
424
+ /** The theme role it is drawn in. Unset, a container takes the theme's
425
+ * `container` style, a pool its `lane.header`. */
426
+ style?: string;
427
+ /** Colors of its own, over its style's, listed in its trait's `ownStyle` as a node's are. */
428
+ colors?: Partial<NodeStyle>;
429
+ }
430
+ /** One lane of a pool. Its id shares the node id namespace. */
431
+ interface DataLane {
432
+ id: string;
433
+ label?: string;
434
+ /** Its depth along the pool's stack, in world units. */
435
+ size?: number;
436
+ /** Node ids and container ids, claimed as a container's are. */
437
+ members?: readonly string[];
438
+ /** Colors of its own, as a container's. A lane draws no fill. */
439
+ colors?: Partial<NodeStyle>;
440
+ }
441
+ /** A pool's size across its stack when it gives no box. */
442
+ declare const DEFAULT_POOL_ACROSS = 600;
443
+ /** A lane's size along its pool's stack when neither it nor the pool's box gives one. */
444
+ declare const DEFAULT_LANE_SIZE = 120;
445
+ /** The colors and outline a node is drawn with. */
446
+ interface NodeStyle {
447
+ fill: string;
448
+ stroke: string;
449
+ text: string;
450
+ strokeWidth?: number;
451
+ dash?: number[];
452
+ }
453
+ /** A node's or region's outline width when its style gives none. */
454
+ declare const NODE_STROKE_WIDTH = 2;
455
+ /** A lane's outline width, which its style does not change. */
456
+ declare const LANE_STROKE_WIDTH = 1;
457
+ /** An edge's stroke width when its style gives none. */
458
+ declare const EDGE_STROKE_WIDTH = 1.5;
459
+ /** The stroke, markers, and label color an edge is drawn with. */
460
+ interface EdgeStyle {
461
+ stroke: string;
462
+ width?: number;
463
+ dash?: number[];
464
+ /** `null` for none. Default none. */
465
+ markerStart?: MarkerRef | null;
466
+ /** `null` for none. Default `'arrow'`. */
467
+ markerEnd?: MarkerRef | null;
468
+ /** Default `stroke`. */
469
+ label?: string;
470
+ }
471
+ /** How an edge is drawn between its ends. */
472
+ type DiagramRouter = 'straight' | 'bezier' | 'orthogonal' | 'avoid';
473
+ /** The `data` of a scene node `diagramScene` makes: its diagram role, and what it paints. */
474
+ interface DiagramSceneData {
475
+ diagram?: DiagramNode | DiagramEdge | {
476
+ label: DiagramLabel;
477
+ } | {
478
+ anchor: DiagramAnchor;
479
+ } | {
480
+ mark: DiagramMark;
481
+ } | {
482
+ offPageTag: OffPageTag;
483
+ };
484
+ fill?: {
485
+ paint: {
486
+ color: string;
487
+ opacity?: number;
488
+ };
489
+ };
490
+ stroke?: Stroke;
491
+ text?: string;
492
+ style?: DiagramTextStyle;
493
+ verticalAlign?: 'top' | 'center' | 'bottom';
494
+ /** What a slot is filled with: an image the kit's image painter draws. */
495
+ image?: {
496
+ src: string;
497
+ opacity?: number;
498
+ };
499
+ /** A body's text row: its place among the body's rows (see `DiagramNode.body`). */
500
+ bodyRow?: number;
501
+ /** An off-page tag's box, behind its text, and the room between them. */
502
+ background?: {
503
+ paint: {
504
+ color: string;
505
+ };
506
+ };
507
+ padding?: number;
508
+ }
509
+ /** A scene node spec, as `diagramScene` returns them. */
510
+ type DiagramSpec<TLayer extends string = 'main'> = AddNodeSpec<DiagramSceneData, TLayer, RectPose>;
511
+ /** How `diagramScene` lays out, routes, and styles a {@link DiagramData}. */
512
+ interface DiagramSceneOptions<TLayer extends string = 'main'> {
513
+ /** The layer every spec goes on. Default `'main'`. */
514
+ layer?: TLayer;
515
+ /** A layout by name, or any `LayoutFn`. Default `'layered'`. `'none'`
516
+ * leaves every node at its `at`. */
517
+ layout?: 'layered' | 'tree' | 'force' | 'chain' | 'none' | LayoutFn;
518
+ /** Merged over `{ order: 'barycenter' }`. */
519
+ layoutOptions?: LayoutOptions;
520
+ /** Default `'bezier'`. */
521
+ router?: DiagramRouter;
522
+ /** The text style rows fall back on. Default 12px sans-serif. */
523
+ font?: {
524
+ fontFamily: string;
525
+ fontSize: number;
526
+ };
527
+ /** Measures one run of text. Default an estimate from character count, so
528
+ * layout needs no canvas; pass `canvasMeasure(ctx)` for real widths. */
529
+ measure?: MeasureRowText;
530
+ /** Default `'rect'`. */
531
+ outline?: Outline;
532
+ /** Between a box's outline and its rows. Default 8. */
533
+ padding?: number;
534
+ /** Between adjacent rows. Default 4. */
535
+ gap?: number;
536
+ /** Where a box's rows sit when it is taller than they need. Default `'center'`. */
537
+ verticalAlign?: BodySpec['verticalAlign'];
538
+ /** The narrowest a box may be. Default 64. */
539
+ minWidth?: number;
540
+ /** Where edge labels sit. Default `{ at: 'mid', offset: 9 }`. */
541
+ labelPlacement?: DiagramLabel;
542
+ nodeStyle?: (node: DataNode) => NodeStyle;
543
+ /** Default 12. */
544
+ groupPadding?: number;
545
+ /** A group's box and label. `text` colors the label. */
546
+ groupStyle?: (group: DataGroup) => NodeStyle;
547
+ edgeStyle?: (edge: DataEdge) => EdgeStyle;
548
+ /** Styles nodes by their `style` role, and edges, groups and text by the theme, where the
549
+ * functions above leave them; and its face is the default `font`. */
550
+ theme?: DiagramTheme;
551
+ }
552
+
553
+ export { ANCHOR_DERIVE_POSE as A, type GroupPoseOptions as B, NODE_STROKE_WIDTH as C, type DiagramTheme as D, type EdgeStyle as E, type OffPageTag as F, GROUP_DERIVE_POSE as G, anchorDerivePose as H, boxAround as I, diagramAnchorOf as J, diagramEdgeOf as K, LANE_STROKE_WIDTH as L, diagramGroupOf as M, type NodeStyle as N, type OffPageSplit as O, diagramMarkOf as P, groupDerivePose as Q, layoutOwnsPort as R, layoutOwnsRoute as S, layoutWritesRoute as T, markShape as U, offPageTagId as V, offPageTagOf as W, registerMarkShape as X, rowTextStyle as Y, type DiagramData as a, type DiagramSceneOptions as b, type DataEdge as c, type DataNode as d, type DiagramRouter as e, type DiagramSpec as f, type EdgeEnd as g, type DiagramSceneData as h, type DiagramEdge as i, type DataContainer as j, DEFAULT_LANE_SIZE as k, DEFAULT_POOL_ACROSS as l, DIAGRAM_ANCHOR as m, DIAGRAM_GROUP as n, DIAGRAM_ROLES as o, DIAGRAM_THEME_KEY as p, type DataGroup as q, type DataLane as r, type DataMark as s, type DiagramAnchor as t, type DiagramDerivePose as u, type DiagramFont as v, type DiagramMark as w, type DiagramRole as x, type DiagramTextStyle as y, EDGE_STROKE_WIDTH as z };