@invana/canvas-react 0.0.2

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,2291 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, CSSProperties, ComponentType, ReactElement } from 'react';
3
+ import { CanvasOptions, Canvas as Canvas$1, BackgroundLayerOptions, DragPanBehaviourOptions, WheelZoomBehaviourOptions, PinchZoomBehaviourOptions, KeyboardCameraInputBehaviourOptions, Rect, CanvasGlobalEvents } from '@invana/canvas';
4
+ import { GraphHistory, GraphClipboard, Vec2, GraphLayerOptions, GraphData, MiniMapLayerOptions, DragNodeBehaviourOptions, ContextMenuBehaviourOptions, CreateNodeBehaviourOptions, DrawEdgeBehaviourOptions, EraseBehaviourOptions, HoverActivateBehaviourOptions, ClickSelectBehaviourOptions, ClickInspectBehaviourOptions, BrushSelectBehaviourOptions, LassoSelectBehaviourOptions, CollapseExpandBehaviourOptions, NodeResizeBehaviourOptions, LabelCollisionBehaviourOptions, LabelResolutionLODBehaviourOptions, NodeSizeLODBehaviourOptions, EdgeSizeLODBehaviourOptions, ParallelEdgeBehaviourOptions, DegreeSizeBehaviourOptions, ResponsiveThemeBehaviourOptions, InspectTarget, ThemeKind, ThemeMode, EdgePathType, GraphNode, GraphEdge, ErasedElement } from '@invana/graph';
5
+ import * as react_jsx_runtime from 'react/jsx-runtime';
6
+ import { D3ForceLayout as D3ForceLayout$1 } from '@invana/graph-layout-d3-force';
7
+ import { MenuItem } from '@invana/ui';
8
+
9
+ interface CanvasProps extends Omit<CanvasOptions, 'container'> {
10
+ /**
11
+ * JSX children — layer / behaviour / layout wrappers. They aren't mounted
12
+ * until the engine has finished initialising, so child effects can assume
13
+ * `useCanvas()` returns a live, initialised engine.
14
+ */
15
+ children?: ReactNode;
16
+ /** Inline style on the host `<div>`. Defaults to `width: '100%', height: '100%'`. */
17
+ style?: CSSProperties;
18
+ /** Class name on the host `<div>`. */
19
+ className?: string;
20
+ }
21
+ /**
22
+ * React root for the canvas engine. Renders a sized host `<div>`, creates an
23
+ * `EngineCanvas` once on mount, calls `init({ container, ...opts })`, and
24
+ * provides the initialised instance to descendants via {@link CanvasContext}.
25
+ *
26
+ * The component is `forwardRef`'d — `ref.current` is the underlying
27
+ * `EngineCanvas` (or `null` until init resolves). Use it as the imperative
28
+ * escape hatch: `ref.current?.layers.get(...)`, `ref.current?.events.tap(...)`,
29
+ * `ref.current?.camera.fitContent(...)`.
30
+ *
31
+ * StrictMode-safe: the init promise is guarded by a cancelled flag so a
32
+ * double-mount cleans up the partially-initialised engine.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * const canvasRef = useRef<EngineCanvas>(null);
37
+ *
38
+ * <Canvas ref={canvasRef} autoResize>
39
+ * <DragPanBehaviour />
40
+ * <WheelZoomBehaviour />
41
+ * <GraphLayer id="graph" data={data} />
42
+ * <D3ForceLayout targetLayerId="graph" />
43
+ * </Canvas>
44
+ * ```
45
+ */
46
+ declare const Canvas: react.ForwardRefExoticComponent<CanvasProps & react.RefAttributes<Canvas$1>>;
47
+
48
+ /**
49
+ * Holds the initialised engine `Canvas` for all descendant child wrappers.
50
+ * `<Canvas>` only renders children once the engine is ready, so the context
51
+ * value inside a wrapper is always non-null.
52
+ */
53
+ declare const CanvasContext: react.Context<Canvas$1 | null>;
54
+ /**
55
+ * Read the engine `Canvas` from context. Throws when used outside a
56
+ * `<Canvas>` so misuse fails loudly during render instead of silently
57
+ * skipping the effect that would have registered a layer or behaviour.
58
+ */
59
+ declare function useCanvas(): Canvas$1;
60
+
61
+ /**
62
+ * Holds the `GraphHistory` constructed by a `<GraphHistoryProvider>` for all
63
+ * descendant hooks (`useHistory`) and self-wiring buttons (Undo/Redo/Redraw).
64
+ * `null` until the provider's effect has built the instance, or when no provider
65
+ * is present — consumers must guard.
66
+ */
67
+ declare const HistoryContext: react.Context<GraphHistory | null>;
68
+
69
+ /**
70
+ * Holds the `GraphClipboard` constructed by a `<GraphClipboardProvider>` for all
71
+ * descendant hooks (`useClipboard`) and self-wiring buttons (Cut/Copy/Paste/
72
+ * Delete). `null` until the provider's effect has built the instance, or when no
73
+ * provider is present — consumers must guard.
74
+ */
75
+ declare const ClipboardContext: react.Context<GraphClipboard | null>;
76
+
77
+ /**
78
+ * The active modelling tool. `'select'` is the neutral pointer (drag / select);
79
+ * `'add'` drops nodes; `'connect'` draws edges; `'delete'` erases on click.
80
+ * A string-literal union, but consumers may treat it opaquely — the
81
+ * {@link ModellerToolbar} only renders the tools it's told to.
82
+ */
83
+ type GraphTool = 'select' | 'add' | 'connect' | 'delete';
84
+ /** Shared modeller state surfaced by {@link GraphToolProvider}. */
85
+ interface ToolContextValue {
86
+ /** The currently active tool. */
87
+ tool: GraphTool;
88
+ /** Switch the active tool. */
89
+ setTool: (tool: GraphTool) => void;
90
+ /**
91
+ * The node "kind" the **Add** tool drops next (an opaque key like `'circle'`
92
+ * / `'rect'`). The consumer maps it to a concrete `NodeStyle` in its
93
+ * `CreateNodeBehaviour` `createNode` factory.
94
+ */
95
+ nodeKind: string;
96
+ /** Choose the node kind the Add tool drops next. */
97
+ setNodeKind: (kind: string) => void;
98
+ }
99
+ /**
100
+ * Holds the active {@link GraphTool} + node kind for a modeller, set by a
101
+ * `<GraphToolProvider>` and read by `useTool` / `<ModellerToolbar>`. `null` when
102
+ * no provider is present — `useTool` throws in that case (a modeller toolbar
103
+ * without a provider is a wiring bug, not a graceful-degrade case).
104
+ */
105
+ declare const ToolContext: react.Context<ToolContextValue | null>;
106
+
107
+ interface GraphHistoryProviderProps {
108
+ /** Id of the `GraphLayer` whose store the history journals. Default `'graph'`. */
109
+ layerId?: string;
110
+ /** Maximum undo depth. Forwarded to `GraphHistory`. Default `100`. */
111
+ limit?: number;
112
+ /** Explicit canvas instance; defaults to the context canvas. */
113
+ canvas?: Canvas$1 | null;
114
+ children?: ReactNode;
115
+ }
116
+ /**
117
+ * Constructs a `GraphHistory` over the target layer's store and provides it via
118
+ * {@link HistoryContext}. Place it **inside** `<Canvas>` and **after** the
119
+ * `<GraphLayer>` it targets, so the layer (and its store) exist when the effect
120
+ * runs. Descendant `useHistory` / Undo-Redo-Redraw buttons resolve the history
121
+ * from here.
122
+ *
123
+ * Node **drags** are captured as one undoable "move" entry per gesture (snapshot
124
+ * at `node:drag-start`, net change pushed at `node:drag-end`) — reusing
125
+ * `history.push`, so per-frame writes and layout sim ticks never enter the stack.
126
+ *
127
+ * The history is rebuilt (and its stacks cleared) if `layerId`, `limit`, or the
128
+ * resolved canvas change.
129
+ */
130
+ declare function GraphHistoryProvider({ layerId, limit, canvas, children, }: GraphHistoryProviderProps): react_jsx_runtime.JSX.Element;
131
+
132
+ interface GraphClipboardProviderProps {
133
+ /** Id of the `GraphLayer` whose store the clipboard reads/writes. Default `'graph'`. */
134
+ layerId?: string;
135
+ /** Offset applied to pasted node positions. Forwarded to `GraphClipboard`. */
136
+ pasteOffset?: Vec2;
137
+ /** Explicit canvas instance; defaults to the context canvas. */
138
+ canvas?: Canvas$1 | null;
139
+ children?: ReactNode;
140
+ }
141
+ /**
142
+ * Constructs a `GraphClipboard` over the target layer's store and provides it
143
+ * via {@link ClipboardContext}. Place it **inside** `<Canvas>` and **after** the
144
+ * `<GraphLayer>` it targets. Descendant `useClipboard` / Cut-Copy-Paste-Delete
145
+ * buttons resolve the clipboard from here. Pair with a `<GraphHistoryProvider>`
146
+ * to make cut/paste/delete undoable.
147
+ */
148
+ declare function GraphClipboardProvider({ layerId, pasteOffset, canvas, children, }: GraphClipboardProviderProps): react_jsx_runtime.JSX.Element;
149
+
150
+ interface GraphToolProviderProps {
151
+ /** Tool active on mount. Default `'select'`. */
152
+ defaultTool?: GraphTool;
153
+ /** Node kind the Add tool drops first. Default `'circle'`. */
154
+ defaultNodeKind?: string;
155
+ /**
156
+ * Pressing <kbd>Esc</kbd> returns to the `'select'` tool (cancelling any
157
+ * in-progress draw). Default `true`. Set `false` to handle Esc yourself.
158
+ */
159
+ escapeToSelect?: boolean;
160
+ children?: ReactNode;
161
+ }
162
+ /**
163
+ * Holds the active modelling {@link GraphTool} + node kind and provides them via
164
+ * {@link ToolContext}. The modeller equivalent of `<GraphHistoryProvider>`:
165
+ * descendant `useTool` / `<ModellerToolbar>` read and switch the tool; the
166
+ * consumer gates its drawing behaviours' `enabled` on `useTool().tool`.
167
+ *
168
+ * Place it anywhere above both the toolbar and the `<Canvas>` (it owns no engine
169
+ * reference — it's pure React state), typically wrapping the whole modeller.
170
+ */
171
+ declare function GraphToolProvider({ defaultTool, defaultNodeKind, escapeToSelect, children, }: GraphToolProviderProps): react_jsx_runtime.JSX.Element;
172
+
173
+ interface GraphLayerProps extends Omit<GraphLayerOptions, 'store'> {
174
+ /** Layer id; default `'graph'`. Changing this remounts the layer. */
175
+ id?: string;
176
+ /**
177
+ * Graph data — nodes + edges. Reactive: when this prop changes the wrapper
178
+ * calls `layer.setData(data)`, which clears and refills the store in one
179
+ * batch. Pass `undefined` to skip the initial data load.
180
+ */
181
+ data?: GraphData;
182
+ /**
183
+ * Pre-built `GraphStore`. Forwarded to the engine layer. Init-only.
184
+ */
185
+ store?: GraphLayerOptions['store'];
186
+ }
187
+ /**
188
+ * Declarative wrapper for `@invana/graph` `GraphLayer`.
189
+ *
190
+ * Init-only: `id`, `node`, `edge`, `useDefaultStates`, `store`, etc. — change
191
+ * the `id` (or the component's `key`) to recreate with new options.
192
+ *
193
+ * Reactive: `data`. The wrapper calls `layer.setData(data)` whenever the
194
+ * referenced `GraphData` object changes — make sure the prop is a stable
195
+ * reference between renders unless you actually want a re-load.
196
+ */
197
+ declare function GraphLayer({ id, data, store, ...rest }: GraphLayerProps): null;
198
+
199
+ interface BackgroundLayerProps extends BackgroundLayerOptions {
200
+ /** Layer id; default `'background'`. Changing this remounts the layer. */
201
+ id?: string;
202
+ }
203
+ /**
204
+ * Declarative wrapper for `@invana/canvas` `BackgroundLayer`.
205
+ *
206
+ * Reactive: all style options (`type`, `patternType`, `color`,
207
+ * `backgroundColor`, `size`, `spacing`, `alpha`, `followCamera`, `mode`) — a
208
+ * change calls `layer.setOptions(...)` and re-renders in place (no remount).
209
+ * Only `id` forces a remount.
210
+ */
211
+ declare function BackgroundLayer({ id, ...options }: BackgroundLayerProps): null;
212
+
213
+ interface MiniMapLayerProps extends Omit<MiniMapLayerOptions, 'graphLayerId'> {
214
+ /** Layer id; default `'minimap'`. Changing this remounts the layer. */
215
+ id?: string;
216
+ /** Source `GraphLayer` id this minimap mirrors; default `'graph'`. */
217
+ graphLayerId?: string;
218
+ }
219
+ /**
220
+ * Declarative wrapper for `@invana/graph` `MiniMapLayer`.
221
+ *
222
+ * Mount/unmount toggles visibility — conditionally render this component
223
+ * (`{showMinimap && <MiniMapLayer/>}`) to show/hide the minimap.
224
+ *
225
+ * Reactive: appearance options (size, colours, viewport indicator, position,
226
+ * margin) via `layer.setOptions(...)`. `id` and `graphLayerId` are identity —
227
+ * changing either remounts.
228
+ */
229
+ declare function MiniMapLayer({ id, graphLayerId, ...options }: MiniMapLayerProps): null;
230
+
231
+ interface DragPanBehaviourProps extends Omit<DragPanBehaviourOptions, 'id'> {
232
+ /** Behaviour id; default `'pan'`. Changing this remounts the behaviour. */
233
+ id?: string;
234
+ }
235
+ /**
236
+ * Declarative wrapper for `@invana/canvas` `DragPanBehaviour`.
237
+ *
238
+ * `enabled` is reactive (toggles in place). Other options are init-only —
239
+ * change `id` or the component `key` to recreate with new options.
240
+ */
241
+ declare function DragPanBehaviour({ id, enabled, ...rest }: DragPanBehaviourProps): null;
242
+
243
+ interface WheelZoomBehaviourProps extends Omit<WheelZoomBehaviourOptions, 'id'> {
244
+ /** Behaviour id; default `'zoom'`. Changing this remounts the behaviour. */
245
+ id?: string;
246
+ }
247
+ /**
248
+ * Declarative wrapper for `@invana/canvas` `WheelZoomBehaviour`.
249
+ *
250
+ * `enabled` is reactive (toggles in place). Other options are init-only —
251
+ * change `id` or the component `key` to recreate.
252
+ */
253
+ declare function WheelZoomBehaviour({ id, enabled, ...rest }: WheelZoomBehaviourProps): null;
254
+
255
+ interface PinchZoomBehaviourProps extends Omit<PinchZoomBehaviourOptions, 'id'> {
256
+ /** Behaviour id; default `'pinch'`. Changing this remounts the behaviour. */
257
+ id?: string;
258
+ }
259
+ /**
260
+ * Declarative wrapper for `@invana/canvas` `PinchZoomBehaviour`
261
+ * (two-finger / trackpad pinch zoom).
262
+ *
263
+ * `enabled` is reactive; other options are init-only — change `id` / `key`.
264
+ */
265
+ declare function PinchZoomBehaviour({ id, enabled, ...rest }: PinchZoomBehaviourProps): null;
266
+
267
+ interface KeyboardCameraInputBehaviourProps extends Omit<KeyboardCameraInputBehaviourOptions, 'id'> {
268
+ /** Behaviour id; default `'keyboard-camera'`. Changing this remounts the behaviour. */
269
+ id?: string;
270
+ }
271
+ /**
272
+ * Declarative wrapper for `@invana/canvas` `KeyboardCameraInputBehaviour`
273
+ * (arrow-key pan, +/- zoom, 0 reset).
274
+ *
275
+ * `enabled` is reactive; other options are init-only — change `id` / `key`.
276
+ */
277
+ declare function KeyboardCameraInputBehaviour({ id, enabled, ...rest }: KeyboardCameraInputBehaviourProps): null;
278
+
279
+ interface DragNodeBehaviourProps extends Omit<DragNodeBehaviourOptions, 'id' | 'layerId'> {
280
+ /** Behaviour id; default `'drag-node'`. Changing this remounts the behaviour. */
281
+ id?: string;
282
+ /** GraphLayer id whose nodes this behaviour drags; default `'graph'`. */
283
+ layerId?: string;
284
+ }
285
+ /**
286
+ * Declarative wrapper for `@invana/graph` `DragNodeBehaviour`.
287
+ *
288
+ * `enabled` is reactive (toggles in place). Other options are init-only —
289
+ * change `id` / `layerId` (or the `key`) to recreate.
290
+ */
291
+ declare function DragNodeBehaviour({ id, layerId, enabled, ...rest }: DragNodeBehaviourProps): null;
292
+
293
+ interface ContextMenuBehaviourProps extends Omit<ContextMenuBehaviourOptions, 'id' | 'layerId'> {
294
+ /** Behaviour id; default `'context-menu'`. Changing this remounts the behaviour. */
295
+ id?: string;
296
+ /** GraphLayer id whose nodes/edges this behaviour watches; default `'graph'`. */
297
+ layerId?: string;
298
+ }
299
+ /**
300
+ * Declarative wrapper for `@invana/graph` `ContextMenuBehaviour`.
301
+ *
302
+ * Headless — pass `onContextMenu` to receive node/edge/canvas right-click
303
+ * events and render your own menu. `enabled` is reactive (toggles in place);
304
+ * other options are init-only — change `id` / `layerId` (or the `key`) to
305
+ * recreate.
306
+ */
307
+ declare function ContextMenuBehaviour({ id, layerId, enabled, ...rest }: ContextMenuBehaviourProps): null;
308
+
309
+ interface CreateNodeBehaviourProps extends Omit<CreateNodeBehaviourOptions, 'id' | 'layerId'> {
310
+ /** Behaviour id; default `'create-node'`. Changing this remounts the behaviour. */
311
+ id?: string;
312
+ /** GraphLayer id this behaviour adds nodes to; default `'graph'`. */
313
+ layerId?: string;
314
+ }
315
+ /**
316
+ * Declarative wrapper for `@invana/graph` `CreateNodeBehaviour` — click empty
317
+ * canvas to add a node.
318
+ *
319
+ * `enabled` is reactive (toggle it from a tool-mode switch); other options are
320
+ * init-only — change `id` / `layerId` (or the `key`) to recreate.
321
+ */
322
+ declare function CreateNodeBehaviour({ id, layerId, enabled, ...rest }: CreateNodeBehaviourProps): null;
323
+
324
+ interface DrawEdgeBehaviourProps extends Omit<DrawEdgeBehaviourOptions, 'id' | 'layerId'> {
325
+ /** Behaviour id; default `'draw-edge'`. Changing this remounts the behaviour. */
326
+ id?: string;
327
+ /** GraphLayer id this behaviour draws edges in; default `'graph'`. */
328
+ layerId?: string;
329
+ }
330
+ /**
331
+ * Declarative wrapper for `@invana/graph` `DrawEdgeBehaviour` — drag from a
332
+ * source node to a target node to create an edge (rubber-band preview).
333
+ *
334
+ * `enabled` is reactive (toggle it from a tool-mode switch). Don't enable this
335
+ * and `DragNodeBehaviour` at once — both start on node pointer-down. Other
336
+ * options are init-only — change `id` / `layerId` (or the `key`) to recreate.
337
+ */
338
+ declare function DrawEdgeBehaviour({ id, layerId, enabled, ...rest }: DrawEdgeBehaviourProps): null;
339
+
340
+ interface EraseBehaviourProps extends Omit<EraseBehaviourOptions, 'id' | 'layerId'> {
341
+ /** Behaviour id; default `'erase'`. Changing this remounts the behaviour. */
342
+ id?: string;
343
+ /** GraphLayer id this behaviour erases from; default `'graph'`. */
344
+ layerId?: string;
345
+ }
346
+ /**
347
+ * Declarative wrapper for `@invana/graph` `EraseBehaviour` — click a node
348
+ * (cascades its edges) or an edge to delete it.
349
+ *
350
+ * `enabled` is reactive (toggle it from a tool-mode switch); other options are
351
+ * init-only — change `id` / `layerId` (or the `key`) to recreate. Pair `onErase`
352
+ * with `useDrawHistory().onErase` to make deletes undoable.
353
+ */
354
+ declare function EraseBehaviour({ id, layerId, enabled, ...rest }: EraseBehaviourProps): null;
355
+
356
+ interface HoverActivateBehaviourProps extends Omit<HoverActivateBehaviourOptions, 'id' | 'layerId'> {
357
+ /** Behaviour id; default `'hover'`. Changing this remounts the behaviour. */
358
+ id?: string;
359
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
360
+ layerId?: string;
361
+ }
362
+ /**
363
+ * Declarative wrapper for `@invana/graph` `HoverActivateBehaviour`.
364
+ *
365
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
366
+ */
367
+ declare function HoverActivateBehaviour({ id, layerId, enabled, ...rest }: HoverActivateBehaviourProps): null;
368
+
369
+ interface ClickSelectBehaviourProps extends Omit<ClickSelectBehaviourOptions, 'id' | 'layerId'> {
370
+ /** Behaviour id; default `'click-select'`. Changing this remounts the behaviour. */
371
+ id?: string;
372
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
373
+ layerId?: string;
374
+ }
375
+ /**
376
+ * Declarative wrapper for `@invana/graph` `ClickSelectBehaviour`.
377
+ *
378
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
379
+ */
380
+ declare function ClickSelectBehaviour({ id, layerId, enabled, ...rest }: ClickSelectBehaviourProps): null;
381
+
382
+ interface ClickInspectBehaviourProps extends Omit<ClickInspectBehaviourOptions, 'id' | 'layerId'> {
383
+ /** Behaviour id; default `'click-inspect'`. Changing this remounts the behaviour. */
384
+ id?: string;
385
+ /** GraphLayer id this behaviour reads clicks from; default `'graph'`. */
386
+ layerId?: string;
387
+ }
388
+ /**
389
+ * Declarative wrapper for `@invana/graph` `ClickInspectBehaviour` — tracks the
390
+ * single node/edge clicked for editing, decoupled from selection. Pair with
391
+ * `<InspectorPanel>` (which reads this behaviour's target by id).
392
+ *
393
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
394
+ */
395
+ declare function ClickInspectBehaviour({ id, layerId, enabled, ...rest }: ClickInspectBehaviourProps): null;
396
+
397
+ interface BrushSelectBehaviourProps extends Omit<BrushSelectBehaviourOptions, 'id' | 'layerId'> {
398
+ /** Behaviour id; default `'brush-select'`. Changing this remounts the behaviour. */
399
+ id?: string;
400
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
401
+ layerId?: string;
402
+ }
403
+ /**
404
+ * Declarative wrapper for `@invana/graph` `BrushSelectBehaviour`
405
+ * (rectangular rubber-band selection).
406
+ *
407
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
408
+ */
409
+ declare function BrushSelectBehaviour({ id, layerId, enabled, ...rest }: BrushSelectBehaviourProps): null;
410
+
411
+ interface LassoSelectBehaviourProps extends Omit<LassoSelectBehaviourOptions, 'id' | 'layerId'> {
412
+ /** Behaviour id; default `'lasso-select'`. Changing this remounts the behaviour. */
413
+ id?: string;
414
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
415
+ layerId?: string;
416
+ }
417
+ /**
418
+ * Declarative wrapper for `@invana/graph` `LassoSelectBehaviour`
419
+ * (freeform polygon selection).
420
+ *
421
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
422
+ */
423
+ declare function LassoSelectBehaviour({ id, layerId, enabled, ...rest }: LassoSelectBehaviourProps): null;
424
+
425
+ interface CollapseExpandBehaviourProps extends Omit<CollapseExpandBehaviourOptions, 'id' | 'layerId'> {
426
+ /** Behaviour id; default `'collapse-expand'`. Changing this remounts the behaviour. */
427
+ id?: string;
428
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
429
+ layerId?: string;
430
+ }
431
+ /**
432
+ * Declarative wrapper for `@invana/graph` `CollapseExpandBehaviour`
433
+ * (click a group's +/- toggle to collapse/expand).
434
+ *
435
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
436
+ */
437
+ declare function CollapseExpandBehaviour({ id, layerId, enabled, ...rest }: CollapseExpandBehaviourProps): null;
438
+
439
+ interface NodeResizeBehaviourProps extends Omit<NodeResizeBehaviourOptions, 'id' | 'layerId'> {
440
+ /** Behaviour id; default `'node-resize'`. Changing this remounts the behaviour. */
441
+ id?: string;
442
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
443
+ layerId?: string;
444
+ }
445
+ /**
446
+ * Declarative wrapper for `@invana/graph` `NodeResizeBehaviour`
447
+ * (drag corner handles to resize a node).
448
+ *
449
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
450
+ */
451
+ declare function NodeResizeBehaviour({ id, layerId, enabled, ...rest }: NodeResizeBehaviourProps): null;
452
+
453
+ interface LabelCollisionBehaviourProps extends Omit<LabelCollisionBehaviourOptions, 'id' | 'layerId'> {
454
+ /** Behaviour id; default `'label-collision'`. Changing this remounts the behaviour. */
455
+ id?: string;
456
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
457
+ layerId?: string;
458
+ }
459
+ /**
460
+ * Declarative wrapper for `@invana/graph` `LabelCollisionBehaviour`
461
+ * (hide/show overlapping labels by priority).
462
+ *
463
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
464
+ */
465
+ declare function LabelCollisionBehaviour({ id, layerId, enabled, ...rest }: LabelCollisionBehaviourProps): null;
466
+
467
+ interface LabelResolutionLODBehaviourProps extends Omit<LabelResolutionLODBehaviourOptions, 'id' | 'layerId'> {
468
+ /** Behaviour id; default `'label-lod'`. Changing this remounts the behaviour. */
469
+ id?: string;
470
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
471
+ layerId?: string;
472
+ }
473
+ /**
474
+ * Declarative wrapper for `@invana/graph` `LabelResolutionLODBehaviour`
475
+ * (show/hide labels by camera zoom tier).
476
+ *
477
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
478
+ */
479
+ declare function LabelResolutionLODBehaviour({ id, layerId, enabled, ...rest }: LabelResolutionLODBehaviourProps): null;
480
+
481
+ interface NodeSizeLODBehaviourProps extends Omit<NodeSizeLODBehaviourOptions, 'id' | 'layerId'> {
482
+ /** Behaviour id; default `'node-size-lod'`. Changing this remounts the behaviour. */
483
+ id?: string;
484
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
485
+ layerId?: string;
486
+ }
487
+ /**
488
+ * Declarative wrapper for `@invana/graph` `NodeSizeLODBehaviour`
489
+ * (rescale node sizes per camera zoom).
490
+ *
491
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
492
+ */
493
+ declare function NodeSizeLODBehaviour({ id, layerId, enabled, ...rest }: NodeSizeLODBehaviourProps): null;
494
+
495
+ interface EdgeSizeLODBehaviourProps extends Omit<EdgeSizeLODBehaviourOptions, 'id' | 'layerId'> {
496
+ /** Behaviour id; default `'edge-size-lod'`. Changing this remounts the behaviour. */
497
+ id?: string;
498
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
499
+ layerId?: string;
500
+ }
501
+ /**
502
+ * Declarative wrapper for `@invana/graph` `EdgeSizeLODBehaviour`
503
+ * (rescale edge stroke widths per camera zoom).
504
+ *
505
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
506
+ */
507
+ declare function EdgeSizeLODBehaviour({ id, layerId, enabled, ...rest }: EdgeSizeLODBehaviourProps): null;
508
+
509
+ interface ParallelEdgeBehaviourProps extends Omit<ParallelEdgeBehaviourOptions, 'id' | 'layerId'> {
510
+ /** Behaviour id; default `'parallel-edge'`. Changing this remounts the behaviour. */
511
+ id?: string;
512
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
513
+ layerId?: string;
514
+ }
515
+ /**
516
+ * Declarative wrapper for `@invana/graph` `ParallelEdgeBehaviour`
517
+ * (fan out edges that share the same source/target pair).
518
+ *
519
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
520
+ */
521
+ declare function ParallelEdgeBehaviour({ id, layerId, enabled, ...rest }: ParallelEdgeBehaviourProps): null;
522
+
523
+ interface DegreeSizeBehaviourProps extends Omit<DegreeSizeBehaviourOptions, 'id' | 'layerId'> {
524
+ /** Behaviour id; default `'degree-size'`. Changing this remounts the behaviour. */
525
+ id?: string;
526
+ /** GraphLayer id this behaviour drives; default `'graph'`. */
527
+ layerId?: string;
528
+ }
529
+ /**
530
+ * Declarative wrapper for `@invana/graph` `DegreeSizeBehaviour`
531
+ * (size nodes by in/out degree).
532
+ *
533
+ * `enabled` is reactive; other options are init-only — change `id` / `layerId`.
534
+ */
535
+ declare function DegreeSizeBehaviour({ id, layerId, enabled, ...rest }: DegreeSizeBehaviourProps): null;
536
+
537
+ interface ResponsiveThemeBehaviourProps extends Omit<ResponsiveThemeBehaviourOptions, 'id' | 'layerId'> {
538
+ /** Behaviour id; default `'responsive-theme'`. Changing this remounts the behaviour. */
539
+ id?: string;
540
+ /** GraphLayer id this behaviour themes; default `'graph'`. */
541
+ layerId?: string;
542
+ }
543
+ /**
544
+ * Declarative wrapper for `@invana/graph` `ResponsiveThemeBehaviour`.
545
+ *
546
+ * Keeps the graph's theme-dependent node / edge styling in sync with the host's
547
+ * `prefers-color-scheme` (or a pinned `mode`). `enabled` is reactive; the
548
+ * `node` / `edge` / `mode` options are init-only — change `id` / `layerId` (or
549
+ * the component `key`) to recreate with new variants.
550
+ */
551
+ declare function ResponsiveThemeBehaviour({ id, layerId, enabled, ...rest }: ResponsiveThemeBehaviourProps): null;
552
+
553
+ type D3ForceLayoutCtorOptions = ConstructorParameters<typeof D3ForceLayout$1>[0];
554
+ interface D3ForceLayoutProps {
555
+ /**
556
+ * Id of the `<GraphLayer>` this layout drives. Default `'graph'`. The
557
+ * wrapper looks the layer up at mount time; if it isn't registered yet,
558
+ * mount the layout *after* the layer in JSX order.
559
+ */
560
+ targetLayerId?: string;
561
+ /**
562
+ * Padding in screen pixels for the auto-fit that runs when the simulation
563
+ * settles. `null` disables auto-fit. Default `80`.
564
+ */
565
+ fitPadding?: number | null;
566
+ /** D3ForceLayout constructor options (`charge`, `link`, `center`, …). */
567
+ options?: D3ForceLayoutCtorOptions;
568
+ }
569
+ /**
570
+ * Declarative wrapper for `@invana/graph-layout-d3-force` `D3ForceLayout`.
571
+ *
572
+ * Mount: builds a new layout, wires `end → camera.fitContent(...)` (unless
573
+ * `fitPadding` is `null`), then calls `layout.apply(layer)`.
574
+ *
575
+ * Unmount: `layout.stop()`. The simulation cancels and emits its final
576
+ * `end` event with `reason: 'stopped'`.
577
+ *
578
+ * All inputs are init-only — remount with a new `key` to reseed the sim.
579
+ */
580
+ declare function D3ForceLayout({ targetLayerId, fitPadding, options, }: D3ForceLayoutProps): null;
581
+
582
+ interface UseCameraResult {
583
+ /** Multiply scale by `factor` (default 1.2), anchored at the viewport centre. */
584
+ zoomIn: (factor?: number) => void;
585
+ /** Divide scale by `factor` (default 1.2), anchored at the viewport centre. */
586
+ zoomOut: (factor?: number) => void;
587
+ /** Set an absolute scale, anchored at the viewport centre. */
588
+ setZoom: (scale: number) => void;
589
+ /** Set an absolute scale around an arbitrary screen point (defaults to centre). */
590
+ zoomTo: (scale: number, centerX?: number, centerY?: number) => void;
591
+ /** Pan by `(dx, dy)` screen pixels. */
592
+ pan: (dx: number, dy: number) => void;
593
+ /** Fit a world-space rectangle into the viewport. */
594
+ fitContent: (worldRect: Rect, padding?: number) => void;
595
+ /** Read the current uniform scale (does not subscribe — use `useZoom` for live state). */
596
+ getZoom: () => number;
597
+ }
598
+ /**
599
+ * Imperative camera actions for the resolved canvas — the wiring the
600
+ * GraphVisualiser story used to hand-write inline (`camera.zoomAt(1.2)` etc.),
601
+ * promoted to a reusable, multi-canvas-safe hook. Pure actions, no
602
+ * subscriptions; callbacks are stable per resolved `canvas`. For a live zoom
603
+ * value that re-renders, use {@link useZoom}.
604
+ *
605
+ * @param canvas Optional explicit instance; defaults to the context canvas.
606
+ */
607
+ declare function useCamera(canvas?: Canvas$1 | null): UseCameraResult;
608
+
609
+ interface UseZoomResult {
610
+ /** Live uniform scale — re-renders whenever the camera zooms (interactively or programmatically). */
611
+ zoom: number;
612
+ zoomIn: (factor?: number) => void;
613
+ zoomOut: (factor?: number) => void;
614
+ setZoom: (scale: number) => void;
615
+ zoomTo: (scale: number, centerX?: number, centerY?: number) => void;
616
+ }
617
+ /**
618
+ * Live zoom state + zoom actions for the resolved canvas. Subscribes to
619
+ * `camera:zoom`, so the returned `zoom` tracks wheel / pinch / programmatic
620
+ * zoom and re-renders the component.
621
+ *
622
+ * Multi-canvas-safe: the subscription effect is keyed on the resolved instance,
623
+ * so two `<Canvas>` trees (or two explicit instances) never share zoom state.
624
+ *
625
+ * @param canvas Optional explicit instance; defaults to the context canvas.
626
+ */
627
+ declare function useZoom(canvas?: Canvas$1 | null): UseZoomResult;
628
+
629
+ interface UseFitContentResult {
630
+ /** Fit the viewport to the target layer's content bounds. No-op until the layer exists. */
631
+ fitContent: (padding?: number) => void;
632
+ /** Whether the target layer is currently mounted (drives e.g. button disabled state). */
633
+ hasContent: boolean;
634
+ }
635
+ /**
636
+ * Fit-to-content (zoom-to-extent) for a specific layer on the resolved canvas.
637
+ * The layer is resolved lazily *inside* the returned callback, so the hook
638
+ * tolerates the layer mounting after the hook runs (common, since layer
639
+ * wrappers register in effects). `hasContent` tracks layer mount/unmount via
640
+ * the `layer:added` / `layer:removed` canvas events.
641
+ *
642
+ * @param layerId Target layer id (e.g. `'graph'`).
643
+ * @param canvas Optional explicit instance; defaults to the context canvas.
644
+ */
645
+ declare function useFitContent(layerId: string, canvas?: Canvas$1 | null): UseFitContentResult;
646
+
647
+ /**
648
+ * Subscribe to a typed canvas-wide event (`camera:zoom`, `camera:pan`,
649
+ * `layer:added`, …) for the lifetime of the calling component. Fully typed off
650
+ * the engine's exported {@link CanvasGlobalEvents} map.
651
+ *
652
+ * The handler is held in a ref so changing it between renders does **not** tear
653
+ * down and re-create the subscription; only a change of the resolved `canvas`
654
+ * (or the `event` name) does. That keeps subscriptions stable and — because the
655
+ * effect is keyed on the resolved instance — correct across multiple canvases.
656
+ *
657
+ * @param event Event name from {@link CanvasGlobalEvents}.
658
+ * @param handler Fired with the event payload.
659
+ * @param canvas Optional explicit instance; defaults to the context canvas.
660
+ */
661
+ declare function useCanvasEvent<E extends keyof CanvasGlobalEvents>(event: E, handler: (payload: CanvasGlobalEvents[E]) => void, canvas?: Canvas$1 | null): void;
662
+
663
+ interface UseClearGraphResult {
664
+ /** Remove every node and edge from the target layer. No-op if the layer doesn't exist yet. */
665
+ clear: () => void;
666
+ }
667
+ /**
668
+ * Clear-graph action for a specific layer on the resolved canvas.
669
+ *
670
+ * When a `<GraphHistoryProvider>` is present, the clear runs as a single
671
+ * undoable `history.transaction('clear', …)` — removing every node (edges
672
+ * cascade) so Undo restores the whole graph and Redo clears it again. Without a
673
+ * history provider it falls back to the layer's fast `clear()`.
674
+ *
675
+ * Uses structural duck-types (`clear()` / `store.nodes()`) so it works with any
676
+ * compatible layer without a hard `@invana/graph` import.
677
+ *
678
+ * @param layerId Target layer id (e.g. `'graph'`).
679
+ * @param canvas Optional explicit instance; defaults to the context canvas.
680
+ */
681
+ declare function useClearGraph(layerId: string, canvas?: Canvas$1 | null): UseClearGraphResult;
682
+
683
+ interface UseSelectionOptions {
684
+ /** Id of the `ClickSelectBehaviour` to read selection from. Default `'click-select'`. */
685
+ clickSelectId?: string;
686
+ }
687
+ interface UseSelectionResult {
688
+ /** Currently selected node ids. */
689
+ selectedNodeIds: string[];
690
+ /** Currently selected edge ids. */
691
+ selectedEdgeIds: string[];
692
+ /** Total selected (nodes + edges). */
693
+ count: number;
694
+ /** Clear the selection. */
695
+ clear: () => void;
696
+ }
697
+ /**
698
+ * Reactive view of the current graph selection, driven by a
699
+ * `ClickSelectBehaviour`'s `selection:change` event (brush/lasso flow through it
700
+ * by delegation, so all three selection modes are covered by this one hook).
701
+ *
702
+ * Requires a registered `ClickSelectBehaviour`; if absent, the selection is
703
+ * empty and `clear` is a no-op.
704
+ */
705
+ declare function useSelection(options?: UseSelectionOptions, canvas?: Canvas$1 | null): UseSelectionResult;
706
+
707
+ interface UseInspectTargetOptions {
708
+ /** Id of the `ClickInspectBehaviour` to read the target from. Default `'click-inspect'`. */
709
+ inspectId?: string;
710
+ }
711
+ /**
712
+ * Reactive view of the single node/edge currently targeted for editing, driven
713
+ * by a `ClickInspectBehaviour`'s `inspect:change` event. Returns `null` when no
714
+ * element is targeted (or the behaviour isn't registered).
715
+ *
716
+ * Distinct from {@link useSelection}: selection can hold many elements (for
717
+ * highlighting / multi-drag), whereas this is always the *one* element a
718
+ * property editor should edit.
719
+ */
720
+ declare function useInspectTarget(options?: UseInspectTargetOptions, canvas?: Canvas$1 | null): InspectTarget | null;
721
+
722
+ interface UseHistoryOptions {
723
+ /** Layer id whose `redraw()` the `redraw` action targets. Default `'graph'`. */
724
+ layerId?: string;
725
+ }
726
+ interface UseHistoryResult {
727
+ /** Revert the most recent change. No-op when `!canUndo`. */
728
+ undo: () => void;
729
+ /** Re-apply the most recently undone change. No-op when `!canRedo`. */
730
+ redo: () => void;
731
+ /** Force a full re-render of the target layer (render pass; not undoable). */
732
+ redraw: () => void;
733
+ canUndo: boolean;
734
+ canRedo: boolean;
735
+ }
736
+ /**
737
+ * Undo/redo + redraw, wired to the `GraphHistory` from a
738
+ * `<GraphHistoryProvider>` ancestor. `canUndo`/`canRedo` stay reactive via the
739
+ * history's `change` event. Without a provider, undo/redo are no-ops and the
740
+ * flags are `false` (redraw still works — it goes straight to the layer).
741
+ */
742
+ declare function useHistory(options?: UseHistoryOptions, canvas?: Canvas$1 | null): UseHistoryResult;
743
+
744
+ interface UseClipboardOptions {
745
+ /** Id of the `ClickSelectBehaviour` selection is read from / re-applied to. Default `'click-select'`. */
746
+ clickSelectId?: string;
747
+ }
748
+ interface UseClipboardResult {
749
+ /** Copy the selection to the buffer, then delete it (one undoable step). */
750
+ cut: () => void;
751
+ /** Copy the selection to the buffer. */
752
+ copy: () => void;
753
+ /** Paste the buffer (offset + re-id'd) and select the pasted items. */
754
+ paste: () => void;
755
+ /** Delete the selection (one undoable step). */
756
+ remove: () => void;
757
+ /** True iff the buffer has content to paste. */
758
+ canPaste: boolean;
759
+ /** True iff something is selected. */
760
+ hasSelection: boolean;
761
+ }
762
+ /**
763
+ * Cut / copy / paste / delete for the current selection, wired to the
764
+ * `GraphClipboard` from a `<GraphClipboardProvider>` ancestor. Operations route
765
+ * through the `<GraphHistoryProvider>`'s history when present, so they're
766
+ * undoable. Reads the selection (and re-selects pasted items) via a
767
+ * `ClickSelectBehaviour`.
768
+ *
769
+ * `canPaste` tracks the buffer (recomputed after each op); `hasSelection` is
770
+ * reactive via {@link useSelection}.
771
+ */
772
+ declare function useClipboard(options?: UseClipboardOptions, canvas?: Canvas$1 | null): UseClipboardResult;
773
+
774
+ type PatternType$2 = NonNullable<BackgroundLayerOptions['patternType']>;
775
+ interface UseGridOptions {
776
+ /** Id of the `BackgroundLayer` to toggle. Default `'background'`. */
777
+ backgroundLayerId?: string;
778
+ /**
779
+ * Pattern to switch to when the grid is shown. When omitted, the layer's
780
+ * existing `patternType` is preserved (only `type` is toggled).
781
+ */
782
+ patternType?: PatternType$2;
783
+ }
784
+ interface UseGridResult {
785
+ /** Whether the background pattern (grid/dots/lines) is currently shown. */
786
+ showGrid: boolean;
787
+ /** Toggle the grid on/off. */
788
+ toggleGrid: () => void;
789
+ /** Set the grid on/off explicitly. */
790
+ setGrid: (on: boolean) => void;
791
+ }
792
+ /**
793
+ * Toggle a `BackgroundLayer`'s pattern on/off. "Grid shown" maps to
794
+ * `type: 'pattern'`, "hidden" to `type: 'solid'`. Pass `patternType` to force a
795
+ * specific pattern (e.g. `'grid'`) when turning it on; otherwise the layer's
796
+ * configured pattern is kept.
797
+ *
798
+ * State is owned by the hook (the background layer emits no option-change event)
799
+ * and seeded from `getOptions()` on mount.
800
+ */
801
+ declare function useGrid(options?: UseGridOptions, canvas?: Canvas$1 | null): UseGridResult;
802
+
803
+ interface UseThemeOptions {
804
+ /** Id of the `ResponsiveThemeBehaviour` to drive. Default `'responsive-theme'`. */
805
+ behaviourId?: string;
806
+ /**
807
+ * Optional id of a `BackgroundLayer` to flip in lockstep. When set, switching
808
+ * the theme also switches the background's `mode`, so the whole canvas changes
809
+ * appearance together instead of the background staying on its own
810
+ * `prefers-color-scheme`. Omit to leave the background alone.
811
+ */
812
+ backgroundLayerId?: string;
813
+ /**
814
+ * Called after the theme switches, with the new resolved kind + mode. Use it
815
+ * to flip *app chrome* that lives outside the canvas (e.g. a design-system
816
+ * `data-theme` attribute) so floating controls stay legible against the
817
+ * canvas. The hook never touches chrome itself — that's app policy.
818
+ */
819
+ onChange?: (kind: ThemeKind, mode: ThemeMode) => void;
820
+ }
821
+ interface UseThemeResult {
822
+ /** Current mode setting (`'auto' | 'light' | 'dark'`). */
823
+ mode: ThemeMode;
824
+ /** Concrete kind currently resolved (`'light' | 'dark'`). */
825
+ kind: ThemeKind;
826
+ /** Set the mode explicitly. `'auto'` re-follows `prefers-color-scheme`. */
827
+ setMode: (mode: ThemeMode) => void;
828
+ /** Flip between pinned light and dark, based on the current resolved kind. */
829
+ toggle: () => void;
830
+ }
831
+ /**
832
+ * Drive a registered `ResponsiveThemeBehaviour` (from `@invana/graph`) — read its
833
+ * mode / resolved kind and switch it. Useful for a theme-toggle control.
834
+ *
835
+ * Pass `backgroundLayerId` to also flip a `BackgroundLayer`'s mode in lockstep so
836
+ * the background switches with the graph content (otherwise the background keeps
837
+ * following the OS `prefers-color-scheme` and dark-theme content can land on a
838
+ * light background). Pass `onChange` to switch app chrome to match.
839
+ *
840
+ * State is owned by the hook (neither the behaviour nor the layer emits a
841
+ * mode-change event) and seeded once they are registered. Each action looks the
842
+ * targets up fresh, so it tolerates them mounting after this hook.
843
+ */
844
+ declare function useTheme(options?: UseThemeOptions, canvas?: Canvas$1 | null): UseThemeResult;
845
+
846
+ /** Minimal structural shape of a layout instance the hook can apply + stop. */
847
+ interface ApplicableLayout {
848
+ apply(layer: unknown): Promise<void> | void;
849
+ stop?: () => void;
850
+ }
851
+ /** Factory producing a fresh layout instance per application. */
852
+ type LayoutFactory = () => ApplicableLayout;
853
+ interface UseLayoutOptions {
854
+ /** Target `GraphLayer` id. Default `'graph'`. */
855
+ layerId?: string;
856
+ /** Padding for the post-layout `camera.fitContent`. Default `80`. */
857
+ fitPadding?: number;
858
+ /** Initially-selected key. Default: first key of `layouts`. */
859
+ initial?: string;
860
+ /** Optional key → human label map for the picker. Default: identity. */
861
+ labels?: Record<string, string>;
862
+ /** Apply the initial layout once the target layer is mounted. Default `true`. */
863
+ applyInitial?: boolean;
864
+ }
865
+ interface UseLayoutResult {
866
+ /** Currently-applied layout key. */
867
+ layout: string;
868
+ /** Key → label map for a picker. */
869
+ layoutOptions: Record<string, string>;
870
+ /** Apply the layout registered under `key`, then fit the view. */
871
+ applyLayout: (key: string) => void;
872
+ /** True while a layout's `apply` promise is in flight. */
873
+ isRunning: boolean;
874
+ }
875
+ /**
876
+ * Imperative layout switching, lifting the common "instantiate → `apply(layer)`
877
+ * → `camera.fitContent`" pattern into a hook. Layouts live in separate packages
878
+ * (`@invana/graph-layout-*`) with no registry, so the consumer supplies a map of
879
+ * **factories**; this hook can't be turnkey.
880
+ *
881
+ * Memoize the `layouts` map (module scope or `useMemo`) so `applyLayout` stays
882
+ * stable across renders.
883
+ */
884
+ declare function useLayout(layouts: Record<string, LayoutFactory>, options?: UseLayoutOptions, canvas?: Canvas$1 | null): UseLayoutResult;
885
+
886
+ interface UseSelectModeOptions {
887
+ /** Initially-active mode key. Default: first key of `behaviourIds`. */
888
+ initial?: string;
889
+ /** Optional key → human label map for a picker. Default: identity. */
890
+ labels?: Record<string, string>;
891
+ }
892
+ interface UseSelectModeResult {
893
+ /** Currently-active mode key. */
894
+ mode: string;
895
+ /** Key → label map for a picker. */
896
+ modeOptions: Record<string, string>;
897
+ /** Switch mode: enables that mode's behaviour, disables the others. */
898
+ setMode: (mode: string) => void;
899
+ }
900
+ /**
901
+ * Mutually-exclusive selection-mode switch. Maps mode keys to behaviour ids
902
+ * (e.g. `{ click: 'click-select', brush: 'brush-select', lasso: 'lasso-select' }`)
903
+ * and toggles their `enabled` so exactly one is active. The consumer must have
904
+ * registered those behaviours; this hook can't be turnkey.
905
+ *
906
+ * The initial mode is enabled on mount. Memoize `behaviourIds` (module scope or
907
+ * `useMemo`) so `setMode` stays stable.
908
+ */
909
+ declare function useSelectMode(behaviourIds: Record<string, string>, options?: UseSelectModeOptions, canvas?: Canvas$1 | null): UseSelectModeResult;
910
+
911
+ /**
912
+ * Default path types surfaced by an edge-type picker, in display order. A
913
+ * curated subset of {@link EdgePathType} that maps cleanly to the three common
914
+ * routing styles plus their rounded/smooth orthogonal variants.
915
+ */
916
+ declare const DEFAULT_EDGE_TYPES: readonly EdgePathType[];
917
+ /** Human labels for the built-in {@link EdgePathType} values (picker display). */
918
+ declare const DEFAULT_EDGE_TYPE_LABELS: Record<string, string>;
919
+ interface UseEdgeTypeOptions {
920
+ /** Target `GraphLayer` id. Default `'graph'`. */
921
+ layerId?: string;
922
+ /**
923
+ * Initially-selected path type. When omitted, the hook seeds from the layer's
924
+ * current `edgeDefaults.shape.pathType` on mount, falling back to the first
925
+ * entry of `types`.
926
+ */
927
+ initial?: EdgePathType;
928
+ /** Path types to expose, in order. Default {@link DEFAULT_EDGE_TYPES}. */
929
+ types?: readonly EdgePathType[];
930
+ /** Optional key → human label map. Default {@link DEFAULT_EDGE_TYPE_LABELS}. */
931
+ labels?: Record<string, string>;
932
+ }
933
+ interface UseEdgeTypeResult {
934
+ /** Currently-selected path type key. */
935
+ edgeType: string;
936
+ /** Key → label map for a picker. */
937
+ edgeTypeOptions: Record<string, string>;
938
+ /**
939
+ * Switch the path type for **every** edge in the layer and make it the
940
+ * default for future edges (via `GraphLayer.setEdgeDefaults`).
941
+ */
942
+ setEdgeType: (type: string) => void;
943
+ }
944
+ /**
945
+ * Layer-wide edge routing switch. Patches the `GraphLayer` edge template
946
+ * (`options.edge.style.shape.pathType`) via {@link GraphLayer.setEdgeDefaults},
947
+ * which re-renders every edge and becomes the default for edges added later —
948
+ * the engine-side `pathType` shorthand resolves to the right router + pathStyle
949
+ * pair (e.g. `'orth'`, `'bezier'`, `'rounded'`).
950
+ *
951
+ * The prior `shape` is spread before patching so anchors / waypoints survive
952
+ * (`setEdgeDefaults` replaces structured fields wholesale). State is owned by
953
+ * the hook and seeded from `layer.edgeDefaults` on mount.
954
+ */
955
+ declare function useEdgeType(options?: UseEdgeTypeOptions, canvas?: Canvas$1 | null): UseEdgeTypeResult;
956
+
957
+ interface UseLockOptions {
958
+ /**
959
+ * Behaviour ids disabled while locked (re-enabled on unlock). Default
960
+ * `['pan', 'drag-node']` — pan + node drag, leaving zoom available.
961
+ */
962
+ behaviourIds?: string[];
963
+ /** Initial locked state. Default `false`. */
964
+ initialLocked?: boolean;
965
+ }
966
+ interface UseLockResult {
967
+ locked: boolean;
968
+ toggleLock: () => void;
969
+ setLock: (locked: boolean) => void;
970
+ }
971
+ /**
972
+ * View lock — disables a configurable set of behaviours (pan + node drag by
973
+ * default) while keeping zoom available. "Lock" is app policy, not an engine
974
+ * concept, so which behaviours it disables is configurable. State is owned by
975
+ * the hook.
976
+ */
977
+ declare function useLock(options?: UseLockOptions, canvas?: Canvas$1 | null): UseLockResult;
978
+
979
+ /**
980
+ * Read + switch the active modelling tool (and Add-tool node kind) from a
981
+ * `<GraphToolProvider>` ancestor.
982
+ *
983
+ * Gate your drawing behaviours on the result, e.g.
984
+ * `<CreateNodeBehaviour enabled={useTool().tool === 'add'} />`.
985
+ *
986
+ * @throws if no `<GraphToolProvider>` is above — a modeller without one is a
987
+ * wiring bug, so this fails loudly rather than silently doing nothing.
988
+ */
989
+ declare function useTool(): ToolContextValue;
990
+
991
+ interface UseDrawHistoryResult {
992
+ /** Journal a just-created node as an undoable `add node` entry. */
993
+ onNodeCreate: (node: GraphNode) => void;
994
+ /** Journal a just-created edge as an undoable `connect` entry. */
995
+ onEdgeCreate: (edge: GraphEdge) => void;
996
+ /** Journal a just-erased node/edge as an undoable `delete` entry. */
997
+ onErase: (removed: ErasedElement) => void;
998
+ }
999
+ /**
1000
+ * Ready-made callbacks that make `CreateNodeBehaviour` / `DrawEdgeBehaviour` /
1001
+ * `EraseBehaviour` **undoable**. Wire them to the behaviours' `onNodeCreate` /
1002
+ * `onEdgeCreate` / `onErase` props — each pushes the already-applied mutation as
1003
+ * one entry on the `GraphHistory` from a `<GraphHistoryProvider>` ancestor
1004
+ * (mirroring how the provider records drags via `history.push`).
1005
+ *
1006
+ * The behaviours mutate the store themselves; these only *journal* the change,
1007
+ * so they pair with — they don't replace — the behaviour's own mutation.
1008
+ *
1009
+ * Without a history provider the callbacks are harmless no-ops (drawing still
1010
+ * works; it just isn't undoable). The returned functions are referentially
1011
+ * stable, so they're safe to capture once in a behaviour that reads its
1012
+ * callbacks at construction.
1013
+ */
1014
+ declare function useDrawHistory(): UseDrawHistoryResult;
1015
+
1016
+ /** The values a {@link PropertiesEditor} edits: a label + a flat string→string data map. */
1017
+ interface PropertiesEditorValues {
1018
+ /** The element's label text. */
1019
+ label: string;
1020
+ /** The element's free-form type tag (maps to `node.type` / `edge.type`). Only edited when `showType`. */
1021
+ type?: string;
1022
+ /** Arbitrary key/value metadata (maps to `node.data` / `edge.data`). */
1023
+ data: Record<string, string>;
1024
+ }
1025
+ interface PropertiesEditorProps {
1026
+ /** Heading shown above the form, e.g. `'Node'` / `'Edge'`. */
1027
+ title?: string;
1028
+ /**
1029
+ * Initial values, loaded into local state **once** on mount (same as
1030
+ * `NodeStyleEditor`). To reload for a different element, remount via `key`.
1031
+ */
1032
+ defaults?: Partial<PropertiesEditorValues>;
1033
+ /** Called with the edited values when the user clicks Apply. */
1034
+ onSubmit: (values: PropertiesEditorValues) => void;
1035
+ /** Submit button label. Default `'Apply'`. */
1036
+ submitLabel?: string;
1037
+ /** Show the label field. Default `true`. */
1038
+ showLabel?: boolean;
1039
+ /** Show an editable `type` field above the properties list. Default `false`. */
1040
+ showType?: boolean;
1041
+ /**
1042
+ * When provided, render a "Reverse direction" button in the footer that
1043
+ * invokes this callback immediately (i.e. not on Apply). Used for edges to
1044
+ * swap source/target. Omit for elements that have no direction.
1045
+ */
1046
+ onReverse?: () => void;
1047
+ className?: string;
1048
+ }
1049
+ /**
1050
+ * Dumb, engine-agnostic editor for an element's **label + key/value
1051
+ * properties** — the canvas counterpart of `@invana/canvas-ui`'s
1052
+ * `NodeStyleEditor`, but for arbitrary `data` rather than visual style (which
1053
+ * `@invana/forms`' fixed field types can't express as a dynamic list).
1054
+ *
1055
+ * Props in / `onSubmit` out: it owns the row state, lets the user add / remove /
1056
+ * rename fields, and on Apply emits `{ label, data }`. It holds **no** engine /
1057
+ * layer / commit logic — the consumer (see {@link InspectorPanel}) wires
1058
+ * `onSubmit` to the store. Blank-keyed rows are dropped on submit; on duplicate
1059
+ * keys the last row wins.
1060
+ *
1061
+ * The text fields are styled native `<input>`s: the `@invana/ui` build this
1062
+ * package resolves doesn't export a plain `Input`, and the dynamic key/value
1063
+ * list isn't expressible via the `@invana/forms` schema generator. `Button`
1064
+ * still comes from `@invana/ui` (no raw `<button>`).
1065
+ */
1066
+ declare function PropertiesEditor({ title, defaults, onSubmit, submitLabel, showLabel, showType, onReverse, className, }: PropertiesEditorProps): react_jsx_runtime.JSX.Element;
1067
+
1068
+ interface UseEntityEditorOptions {
1069
+ /** GraphLayer to read/write. Default `'graph'`. */
1070
+ layerId?: string;
1071
+ /** Id of the `ClickInspectBehaviour` the edit target is read from. Default `'click-inspect'`. */
1072
+ inspectId?: string;
1073
+ /**
1074
+ * Modeller mode: edit a single `type` field on **both** nodes and edges whose
1075
+ * value also drives the displayed label (mirrored to `style.labelText`) — in a
1076
+ * modeller the type *is* what's drawn on the element. Off by default, in which
1077
+ * case nodes edit their `label` (`style.labelText`) and edges edit their `type`,
1078
+ * each as a separate field.
1079
+ */
1080
+ typeAsLabel?: boolean;
1081
+ }
1082
+ /** The single selected node/edge, its current label + data, and a commit action. */
1083
+ interface EntityEditorTarget {
1084
+ kind: 'node' | 'edge';
1085
+ id: string;
1086
+ /** Effective (resolved) label text. Empty for edges (they have no label field). */
1087
+ label: string;
1088
+ /** The element's free-form `type` tag. Present for edges (`'' ` when unset). */
1089
+ type?: string;
1090
+ /** Current `data` as a flat string map (non-string values are stringified). */
1091
+ data: Record<string, string>;
1092
+ /**
1093
+ * Write the editor's values back to the store, undoable as one entry when a
1094
+ * `<GraphHistoryProvider>` is present (a direct mutation otherwise). Replaces
1095
+ * `data` wholesale. A **node** also overwrites `style.labelText` (spreading the
1096
+ * prior style); an **edge** writes its `type` instead — edges have no label.
1097
+ */
1098
+ commit: (values: PropertiesEditorValues) => void;
1099
+ /**
1100
+ * Swap an edge's `source`/`target` (reverse its direction). Present only for
1101
+ * edges; undoable as one entry when a `<GraphHistoryProvider>` is present.
1102
+ */
1103
+ reverse?: () => void;
1104
+ }
1105
+ /**
1106
+ * Click-driven property editing for an inspector. Returns the **single** node or
1107
+ * edge the user clicked to edit — its effective label + `data` and a `commit`
1108
+ * that writes edits back undoably — or `null` when nothing is targeted (so a
1109
+ * panel can render nothing). Reads the target via {@link useInspectTarget}
1110
+ * (needs a `ClickInspectBehaviour`, independent of selection); commits via the
1111
+ * `GraphHistory` from a `<GraphHistoryProvider>` ancestor when present.
1112
+ *
1113
+ * The view (`<PropertiesEditor>`) and placement (`<Panel>`) are the consumer's —
1114
+ * see {@link InspectorPanel} for the turnkey wiring.
1115
+ */
1116
+ declare function useEntityEditor(options?: UseEntityEditorOptions, canvas?: Canvas$1 | null): EntityEditorTarget | null;
1117
+
1118
+ /** Open menu: where it sits (screen / canvas-relative px) + what it carries. */
1119
+ interface ContextMenuState<T> {
1120
+ /** Left offset in px, relative to the positioned ancestor (the `<Canvas>` host). */
1121
+ x: number;
1122
+ /** Top offset in px, relative to the positioned ancestor. */
1123
+ y: number;
1124
+ /** Caller-defined payload — typically the per-target menu items to render. */
1125
+ items: T;
1126
+ }
1127
+ interface UseContextMenuResult<T> {
1128
+ /** Current open menu, or `null` when closed. */
1129
+ menu: ContextMenuState<T> | null;
1130
+ /** Open (or move) the menu at `(x, y)` carrying `items`. */
1131
+ open: (x: number, y: number, items: T) => void;
1132
+ /** Close the menu. */
1133
+ close: () => void;
1134
+ }
1135
+ /**
1136
+ * Headless open/close + position state for a right-click context menu, with the
1137
+ * dismissal lifecycle baked in: while a menu is open, an outside `pointerdown`
1138
+ * or `Escape` closes it.
1139
+ *
1140
+ * Pairs with `<ContextMenuBehaviour onContextMenu={…}>` (which supplies the
1141
+ * target + `screen` position) and `<ContextMenuOverlay>` (which renders the
1142
+ * menu). Feed `e.screen.x / e.screen.y` straight into {@link open}; because the
1143
+ * `<Canvas>` host is `position: relative`, those coordinates place the overlay
1144
+ * correctly when it's rendered as a `<Canvas>` descendant.
1145
+ *
1146
+ * The opening right-click's `pointerdown` fires *before* this effect's listener
1147
+ * attaches, so the menu never self-closes. `<ContextMenuOverlay>` stops
1148
+ * `pointerdown` propagation, so clicks *inside* the menu don't dismiss it —
1149
+ * leaf `onClick`s call {@link close} explicitly.
1150
+ *
1151
+ * Generic over the payload `T` so it stays UI-kit-agnostic; the graph stories
1152
+ * parameterise it as `MenuItem[]` (from `@invana/ui`).
1153
+ *
1154
+ * @example
1155
+ * ```tsx
1156
+ * const { menu, open, close } = useContextMenu<MenuItem[]>();
1157
+ * const onContextMenu = (e: ContextMenuEvent) =>
1158
+ * open(e.screen.x, e.screen.y, buildItems(e, close));
1159
+ * // …
1160
+ * <ContextMenuBehaviour layerId="graph" onContextMenu={onContextMenu} />
1161
+ * {menu && <ContextMenuOverlay x={menu.x} y={menu.y} items={menu.items} />}
1162
+ * ```
1163
+ */
1164
+ declare function useContextMenu<T>(): UseContextMenuResult<T>;
1165
+
1166
+ /**
1167
+ * Icon component accepted by the UI controls. These components are
1168
+ * **icon-agnostic** — the consumer passes the icon (e.g. a `lucide-react`
1169
+ * glyph), so the package takes on no icon dependency. Any component that renders
1170
+ * from `size` / `className` satisfies this (lucide icons do).
1171
+ */
1172
+ type ToolbarIcon = ComponentType<{
1173
+ size?: number | string;
1174
+ className?: string;
1175
+ }>;
1176
+ /**
1177
+ * Side a tooltip is placed on relative to its trigger. Mirrors the Radix /
1178
+ * `@invana/ui` `TooltipContent` `side` prop. A vertical Nav typically wants
1179
+ * `'right'`; a horizontal Nav `'bottom'`.
1180
+ */
1181
+ type TooltipSide = 'top' | 'right' | 'bottom' | 'left';
1182
+ /** Anchor position for a {@link Panel} within its positioned ancestor. */
1183
+ type PanelPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
1184
+
1185
+ interface PanelProps {
1186
+ /** Corner / edge of the nearest positioned ancestor to pin to. Default `'top-left'`. */
1187
+ position?: PanelPosition;
1188
+ /** Stack direction for children. Default `'vertical'`. */
1189
+ orientation?: 'horizontal' | 'vertical';
1190
+ /** Distance from the pinned edges, in px. Default `8`. */
1191
+ offset?: number;
1192
+ /** Gap between children, in px. Default `4`. */
1193
+ gap?: number;
1194
+ /** Stacking order, so the overlay sits above canvas content. Default `5`. */
1195
+ zIndex?: number;
1196
+ className?: string;
1197
+ /** Extra inline styles, merged onto the content wrapper (not the positioner). */
1198
+ style?: CSSProperties;
1199
+ children?: ReactNode;
1200
+ }
1201
+ /**
1202
+ * A positioned overlay container — the canvas equivalent of React Flow's
1203
+ * `<Panel>`. Pins itself to a corner / edge-centre of its **nearest positioned
1204
+ * ancestor** (e.g. the `<Canvas>` host, which is `position: relative`), and
1205
+ * stacks its children horizontally or vertically.
1206
+ *
1207
+ * Engine-agnostic and reference-free: it needs no `Canvas` instance — with
1208
+ * multiple canvases on one page you simply render one `<Panel>` inside each
1209
+ * `<Canvas>` and each pins to its own host.
1210
+ *
1211
+ * **Pointer events:** the absolutely-positioned root is `pointerEvents: 'none'`
1212
+ * so it never creates a dead zone over the canvas (a wide `top-center` panel
1213
+ * would otherwise block pan/zoom along that strip). Only the inner content
1214
+ * wrapper re-enables `pointerEvents: 'auto'`, so drags that miss the actual
1215
+ * controls still reach the canvas underneath.
1216
+ */
1217
+ declare function Panel({ position, orientation, offset, gap, zIndex, className, style, children, }: PanelProps): react_jsx_runtime.JSX.Element;
1218
+
1219
+ interface TooltippedProps {
1220
+ /**
1221
+ * Tooltip content (typically the host control's `title` / `label`). When
1222
+ * `null` / `undefined` / `''` the child renders **unwrapped** — no tooltip,
1223
+ * no extra DOM — so callers can pass an optional label without branching.
1224
+ */
1225
+ label?: ReactNode;
1226
+ /** Side the tooltip is placed on relative to the trigger. Default `'top'`. */
1227
+ side?: TooltipSide;
1228
+ /** Hover-open delay in ms. Default `0` (instant — matches a toolbar feel). */
1229
+ delayDuration?: number;
1230
+ /** The single trigger element (a `Button`, a dropdown trigger, …). */
1231
+ children: ReactElement;
1232
+ }
1233
+ /**
1234
+ * Wraps a single interactive element with an `@invana/ui` (Radix) tooltip
1235
+ * driven by `label`. The building-block that lets the dumb control components
1236
+ * surface their `title` / `label` as a real hover tooltip — readable when the
1237
+ * controls are dropped into a compact `NavHorizontal` / `NavVertical` slot,
1238
+ * where the native `title` attribute is easy to miss.
1239
+ *
1240
+ * Self-contained: bundles its own `TooltipProvider` (like `@invana/ui`'s
1241
+ * `ButtonWithTooltip`), so a control works standalone without the host wiring a
1242
+ * provider. `asChild` forwards the trigger props onto the child, preserving its
1243
+ * variant / size / active styling.
1244
+ *
1245
+ * The content background is pinned to `--color-popover` (opaque): the design
1246
+ * kit's default tooltip is translucent (`bg-popover/85` + backdrop-blur), which
1247
+ * reads as see-through over a busy canvas — same reasoning as the dropdown
1248
+ * surfaces in {@link OptionPicker} / {@link ZoomPicker}.
1249
+ */
1250
+ declare function Tooltipped({ label, side, delayDuration, children }: TooltippedProps): react_jsx_runtime.JSX.Element;
1251
+
1252
+ interface ControlButtonProps {
1253
+ /** Icon component (e.g. a `lucide-react` glyph). Consumer-supplied — icon-agnostic. */
1254
+ icon: ToolbarIcon;
1255
+ onClick: () => void;
1256
+ /** Tooltip content + accessible label. */
1257
+ title: string;
1258
+ /** Side the tooltip is placed on. Default `'top'`. */
1259
+ tooltipSide?: TooltipSide;
1260
+ /** Active styling — `'default'` (filled) vs `'ghost'` Button variant. Default `false`. */
1261
+ active?: boolean;
1262
+ disabled?: boolean;
1263
+ className?: string;
1264
+ }
1265
+ /**
1266
+ * A single icon control button — the building block to drop into a {@link Panel}
1267
+ * (the canvas equivalent of React Flow's `<ControlButton>`). Thin wrapper over
1268
+ * the `@invana/ui` `Button`; active state uses Button variants, not Tailwind, so
1269
+ * it works without the host running Tailwind.
1270
+ *
1271
+ * `title` drives both a real hover tooltip (via {@link Tooltipped}) and the
1272
+ * `aria-label`, so the icon-only button stays usable and accessible inside a
1273
+ * compact `NavHorizontal` / `NavVertical`.
1274
+ */
1275
+ declare function ControlButton({ icon: Icon, onClick, title, tooltipSide, active, disabled, className, }: ControlButtonProps): react_jsx_runtime.JSX.Element;
1276
+
1277
+ interface OptionPickerProps {
1278
+ /**
1279
+ * Label shown on the trigger and as the menu heading (e.g. `'Layout'`). Also
1280
+ * the trigger tooltip content unless {@link OptionPickerProps.tooltip} overrides it.
1281
+ */
1282
+ label: string;
1283
+ /** Currently selected option key. */
1284
+ value: string;
1285
+ /** Option key → human label. */
1286
+ options: Record<string, string>;
1287
+ /**
1288
+ * Optional option key → icon. When present, the active option's icon shows on
1289
+ * the trigger and each option's icon shows beside its label in the menu.
1290
+ * Icon-agnostic — pass a {@link ToolbarIcon} (e.g. a `lucide-react` glyph).
1291
+ */
1292
+ icons?: Record<string, ToolbarIcon>;
1293
+ /** Fired with the newly selected key. */
1294
+ onChange: (value: string) => void;
1295
+ /** Menu alignment relative to the trigger. Default `'start'`. */
1296
+ align?: 'start' | 'center' | 'end';
1297
+ /** Trigger tooltip content. Defaults to {@link OptionPickerProps.label}. */
1298
+ tooltip?: string;
1299
+ /** Side the trigger tooltip is placed on. Default `'top'`. */
1300
+ tooltipSide?: TooltipSide;
1301
+ className?: string;
1302
+ }
1303
+ /**
1304
+ * A single-select dropdown (radio group). Engine-agnostic — drives a `value` +
1305
+ * `onChange`. Used as the **layout switcher** and **selection-mode** picker in
1306
+ * {@link GraphToolbar}, and standalone for any single-choice control.
1307
+ */
1308
+ declare function OptionPicker({ label, value, options, icons, onChange, align, tooltip, tooltipSide, className, }: OptionPickerProps): react_jsx_runtime.JSX.Element;
1309
+
1310
+ interface ZoomControlsProps {
1311
+ zoomInIcon: ToolbarIcon;
1312
+ zoomOutIcon: ToolbarIcon;
1313
+ /** Explicit canvas instance; defaults to the context canvas. */
1314
+ canvas?: Canvas$1 | null;
1315
+ /** Side the "Zoom in" / "Zoom out" tooltips are placed on. Default `'top'`. */
1316
+ tooltipSide?: TooltipSide;
1317
+ /**
1318
+ * Show a live `NN%` zoom readout between the two buttons, sourced from the
1319
+ * canvas via {@link useZoom}. Ignored when `zoomLevel` is also provided.
1320
+ * Default `false`.
1321
+ */
1322
+ showLevel?: boolean;
1323
+ /** Stack direction. Default `'horizontal'`. */
1324
+ orientation?: 'horizontal' | 'vertical';
1325
+ /**
1326
+ * Manual zoom readout override rendered **between** the two buttons (e.g.
1327
+ * `'46%'`). Takes precedence over `showLevel`. Omit for a plain button pair.
1328
+ */
1329
+ zoomLevel?: ReactNode;
1330
+ className?: string;
1331
+ }
1332
+ /**
1333
+ * A pair of zoom-in / zoom-out icon buttons, optionally with a live zoom
1334
+ * readout between them. Self-wiring: hooks into the canvas via {@link useZoom}
1335
+ * — drop inside a `<Canvas>` and it works without any callback wiring.
1336
+ * Pass `onZoomIn` / `onZoomOut` to override the default hook-driven actions.
1337
+ */
1338
+ declare function ZoomControls({ canvas, zoomInIcon: ZoomInIcon, zoomOutIcon: ZoomOutIcon, showLevel, orientation, zoomLevel, tooltipSide, className, }: ZoomControlsProps): react_jsx_runtime.JSX.Element;
1339
+
1340
+ interface LockToggleProps {
1341
+ /** Whether the view is locked (drives icon + active styling). */
1342
+ locked: boolean;
1343
+ onToggle: () => void;
1344
+ lockedIcon: ToolbarIcon;
1345
+ unlockedIcon: ToolbarIcon;
1346
+ /** Side the tooltip is placed on. Default `'top'`. */
1347
+ tooltipSide?: TooltipSide;
1348
+ className?: string;
1349
+ }
1350
+ /**
1351
+ * Toggle button for a "lock view" action (the consumer decides what locking
1352
+ * disables — e.g. pan + drag). Shows the locked icon and active styling while
1353
+ * locked. The tooltip + accessible label flips with state
1354
+ * ("Lock view" / "Unlock view").
1355
+ */
1356
+ declare function LockToggle({ locked, onToggle, lockedIcon: LockedIcon, unlockedIcon: UnlockedIcon, tooltipSide, className, }: LockToggleProps): react_jsx_runtime.JSX.Element;
1357
+
1358
+ interface ClearButtonProps {
1359
+ /** Optional leading icon (e.g. a trash glyph). */
1360
+ icon?: ToolbarIcon;
1361
+ /** Explicit canvas instance; defaults to the context canvas. */
1362
+ canvas?: Canvas$1 | null;
1363
+ /**
1364
+ * Layer id to clear. Default `'graph'`. Forwarded to {@link useClearGraph}.
1365
+ */
1366
+ layerId?: string;
1367
+ /** Button text + tooltip content. Default `'Clear'`. */
1368
+ label?: string;
1369
+ /** Side the tooltip is placed on. Default `'top'`. */
1370
+ tooltipSide?: TooltipSide;
1371
+ className?: string;
1372
+ }
1373
+ /**
1374
+ * Labelled action button that clears all nodes and edges from the target layer.
1375
+ * Self-wiring: hooks into the canvas via {@link useClearGraph} — drop inside a
1376
+ * `<Canvas>` and it works without any callback wiring.
1377
+ */
1378
+ declare function ClearButton({ icon: Icon, canvas, layerId, label, tooltipSide, className, }: ClearButtonProps): react_jsx_runtime.JSX.Element;
1379
+
1380
+ interface FitContentButtonProps {
1381
+ /** Leading icon (e.g. a maximize / frame glyph). */
1382
+ icon: ToolbarIcon;
1383
+ /** Explicit canvas instance; defaults to the context canvas. */
1384
+ canvas?: Canvas$1 | null;
1385
+ /**
1386
+ * Layer id to fit to. Default `'graph'`. Forwarded to {@link useFitContent}.
1387
+ */
1388
+ layerId?: string;
1389
+ /** Tooltip text + accessible label. Default `'Fit to content'`. */
1390
+ title?: string;
1391
+ /** Side the tooltip is placed on. Default `'top'`. */
1392
+ tooltipSide?: TooltipSide;
1393
+ className?: string;
1394
+ }
1395
+ /**
1396
+ * Icon button that fits the viewport to the graph's content (zoom-to-extent).
1397
+ * Self-wiring: hooks into the canvas via {@link useFitContent} — drop inside a
1398
+ * `<Canvas>` and it works without any callback wiring. Pass `onFitContent` to
1399
+ * override the default hook-driven action.
1400
+ */
1401
+ declare function FitContentButton({ icon: Icon, canvas, layerId, title, tooltipSide, className, }: FitContentButtonProps): react_jsx_runtime.JSX.Element;
1402
+
1403
+ interface ZoomPickerProps {
1404
+ /** Explicit canvas instance; defaults to the context canvas. */
1405
+ canvas?: Canvas$1 | null;
1406
+ /**
1407
+ * Layer id used for the fit-to-content action. Default `'graph'`.
1408
+ */
1409
+ layerId?: string;
1410
+ /**
1411
+ * Preset zoom percentages shown in the dropdown. Default
1412
+ * `[25, 50, 75, 100, 125, 150, 200, 300, 400]`.
1413
+ */
1414
+ presets?: number[];
1415
+ /**
1416
+ * Show the "Fit / Reset View" action at the top of the dropdown.
1417
+ * Default `true`.
1418
+ */
1419
+ showFit?: boolean;
1420
+ /** Label for the fit action. Default `'Fit / Reset View'`. */
1421
+ fitLabel?: string;
1422
+ /** Trigger tooltip content + accessible label. Default `'Zoom level'`. */
1423
+ title?: string;
1424
+ /** Side the trigger tooltip is placed on. Default `'top'`. */
1425
+ tooltipSide?: TooltipSide;
1426
+ className?: string;
1427
+ }
1428
+ /**
1429
+ * A zoom-level picker: a trigger button showing the current zoom percentage
1430
+ * that opens a dropdown with preset zoom levels and an optional fit-to-content
1431
+ * action. Self-wiring via {@link useZoom} and {@link useFitContent} — drop
1432
+ * inside a `<Canvas>` and it works without any callback wiring.
1433
+ *
1434
+ * The active preset is highlighted automatically based on the live zoom state.
1435
+ *
1436
+ * @example
1437
+ * // In any toolbar — vertical or horizontal:
1438
+ * <ZoomPicker layerId="graph" />
1439
+ *
1440
+ * @example
1441
+ * // Custom presets, no fit action:
1442
+ * <ZoomPicker presets={[50, 100, 200]} showFit={false} />
1443
+ */
1444
+ declare function ZoomPicker({ canvas, layerId, presets, showFit, fitLabel, title, tooltipSide, className, }: ZoomPickerProps): react_jsx_runtime.JSX.Element;
1445
+
1446
+ interface UndoButtonProps {
1447
+ icon: ToolbarIcon;
1448
+ /** Tooltip / accessible label. Default `'Undo'`. */
1449
+ title?: string;
1450
+ /** Side the tooltip is placed on. Default `'top'`. */
1451
+ tooltipSide?: TooltipSide;
1452
+ /** Explicit canvas instance; defaults to the context canvas. */
1453
+ canvas?: Canvas$1 | null;
1454
+ className?: string;
1455
+ }
1456
+ /**
1457
+ * Self-wiring undo button. Disabled when there is nothing to undo. Requires a
1458
+ * `<GraphHistoryProvider>` ancestor (see {@link useHistory}).
1459
+ */
1460
+ declare function UndoButton({ icon, title, tooltipSide, canvas, className }: UndoButtonProps): react_jsx_runtime.JSX.Element;
1461
+
1462
+ interface RedoButtonProps {
1463
+ icon: ToolbarIcon;
1464
+ /** Tooltip / accessible label. Default `'Redo'`. */
1465
+ title?: string;
1466
+ /** Side the tooltip is placed on. Default `'top'`. */
1467
+ tooltipSide?: TooltipSide;
1468
+ /** Explicit canvas instance; defaults to the context canvas. */
1469
+ canvas?: Canvas$1 | null;
1470
+ className?: string;
1471
+ }
1472
+ /**
1473
+ * Self-wiring redo button. Disabled when there is nothing to redo. Requires a
1474
+ * `<GraphHistoryProvider>` ancestor (see {@link useHistory}).
1475
+ */
1476
+ declare function RedoButton({ icon, title, tooltipSide, canvas, className }: RedoButtonProps): react_jsx_runtime.JSX.Element;
1477
+
1478
+ interface RedrawButtonProps {
1479
+ icon: ToolbarIcon;
1480
+ /** Tooltip / accessible label. Default `'Redraw'`. */
1481
+ title?: string;
1482
+ /** Side the tooltip is placed on. Default `'top'`. */
1483
+ tooltipSide?: TooltipSide;
1484
+ /** Layer to redraw. Default `'graph'`. */
1485
+ layerId?: string;
1486
+ /** Explicit canvas instance; defaults to the context canvas. */
1487
+ canvas?: Canvas$1 | null;
1488
+ className?: string;
1489
+ }
1490
+ /**
1491
+ * Self-wiring redraw button — forces a full re-render of the target layer. A
1492
+ * pure render pass (not undoable); works without a history provider.
1493
+ */
1494
+ declare function RedrawButton({ icon, title, tooltipSide, layerId, canvas, className, }: RedrawButtonProps): react_jsx_runtime.JSX.Element;
1495
+
1496
+ interface CutButtonProps {
1497
+ icon: ToolbarIcon;
1498
+ /** Tooltip / accessible label. Default `'Cut'`. */
1499
+ title?: string;
1500
+ /** Side the tooltip is placed on. Default `'top'`. */
1501
+ tooltipSide?: TooltipSide;
1502
+ /** Id of the `ClickSelectBehaviour` to read selection from. Default `'click-select'`. */
1503
+ clickSelectId?: string;
1504
+ /** Explicit canvas instance; defaults to the context canvas. */
1505
+ canvas?: Canvas$1 | null;
1506
+ className?: string;
1507
+ }
1508
+ /**
1509
+ * Self-wiring cut button — copies the selection to the clipboard, then deletes
1510
+ * it (undoable when a `<GraphHistoryProvider>` is present). Disabled when
1511
+ * nothing is selected. Requires a `<GraphClipboardProvider>` + a
1512
+ * `ClickSelectBehaviour`.
1513
+ */
1514
+ declare function CutButton({ icon, title, tooltipSide, clickSelectId, canvas, className, }: CutButtonProps): react_jsx_runtime.JSX.Element;
1515
+
1516
+ interface CopyButtonProps {
1517
+ icon: ToolbarIcon;
1518
+ /** Tooltip / accessible label. Default `'Copy'`. */
1519
+ title?: string;
1520
+ /** Side the tooltip is placed on. Default `'top'`. */
1521
+ tooltipSide?: TooltipSide;
1522
+ /** Id of the `ClickSelectBehaviour` to read selection from. Default `'click-select'`. */
1523
+ clickSelectId?: string;
1524
+ /** Explicit canvas instance; defaults to the context canvas. */
1525
+ canvas?: Canvas$1 | null;
1526
+ className?: string;
1527
+ }
1528
+ /**
1529
+ * Self-wiring copy button — copies the selection to the clipboard. Disabled when
1530
+ * nothing is selected. Requires a `<GraphClipboardProvider>` + a
1531
+ * `ClickSelectBehaviour`.
1532
+ */
1533
+ declare function CopyButton({ icon, title, tooltipSide, clickSelectId, canvas, className, }: CopyButtonProps): react_jsx_runtime.JSX.Element;
1534
+
1535
+ interface PasteButtonProps {
1536
+ icon: ToolbarIcon;
1537
+ /** Tooltip / accessible label. Default `'Paste'`. */
1538
+ title?: string;
1539
+ /** Side the tooltip is placed on. Default `'top'`. */
1540
+ tooltipSide?: TooltipSide;
1541
+ /** Id of the `ClickSelectBehaviour` the pasted items are re-selected on. Default `'click-select'`. */
1542
+ clickSelectId?: string;
1543
+ /** Explicit canvas instance; defaults to the context canvas. */
1544
+ canvas?: Canvas$1 | null;
1545
+ className?: string;
1546
+ }
1547
+ /**
1548
+ * Self-wiring paste button — inserts the clipboard buffer (offset + re-id'd) and
1549
+ * selects the pasted items. Disabled when the buffer is empty. Requires a
1550
+ * `<GraphClipboardProvider>`; undoable when a `<GraphHistoryProvider>` is present.
1551
+ */
1552
+ declare function PasteButton({ icon, title, tooltipSide, clickSelectId, canvas, className, }: PasteButtonProps): react_jsx_runtime.JSX.Element;
1553
+
1554
+ interface DeleteSelectionButtonProps {
1555
+ icon: ToolbarIcon;
1556
+ /** Tooltip / accessible label. Default `'Delete selection'`. */
1557
+ title?: string;
1558
+ /** Side the tooltip is placed on. Default `'top'`. */
1559
+ tooltipSide?: TooltipSide;
1560
+ /** Id of the `ClickSelectBehaviour` to read selection from. Default `'click-select'`. */
1561
+ clickSelectId?: string;
1562
+ /** Explicit canvas instance; defaults to the context canvas. */
1563
+ canvas?: Canvas$1 | null;
1564
+ className?: string;
1565
+ }
1566
+ /**
1567
+ * Self-wiring delete button — removes the selected nodes/edges (undoable when a
1568
+ * `<GraphHistoryProvider>` is present). Disabled when nothing is selected.
1569
+ * Requires a `<GraphClipboardProvider>` + a `ClickSelectBehaviour`.
1570
+ */
1571
+ declare function DeleteSelectionButton({ icon, title, tooltipSide, clickSelectId, canvas, className, }: DeleteSelectionButtonProps): react_jsx_runtime.JSX.Element;
1572
+
1573
+ type PatternType$1 = NonNullable<BackgroundLayerOptions['patternType']>;
1574
+ interface GridToggleProps {
1575
+ icon: ToolbarIcon;
1576
+ /** Tooltip / accessible label. Default `'Toggle grid'`. */
1577
+ title?: string;
1578
+ /** Side the tooltip is placed on. Default `'top'`. */
1579
+ tooltipSide?: TooltipSide;
1580
+ /** Id of the `BackgroundLayer` to toggle. Default `'background'`. */
1581
+ backgroundLayerId?: string;
1582
+ /** Pattern to switch to when shown (e.g. `'grid'`); preserves existing if omitted. */
1583
+ patternType?: PatternType$1;
1584
+ /** Explicit canvas instance; defaults to the context canvas. */
1585
+ canvas?: Canvas$1 | null;
1586
+ className?: string;
1587
+ }
1588
+ /**
1589
+ * Self-wiring grid toggle. Shows the button as active while the background
1590
+ * pattern is visible. Wraps {@link useGrid}.
1591
+ */
1592
+ declare function GridToggle({ icon, title, tooltipSide, backgroundLayerId, patternType, canvas, className, }: GridToggleProps): react_jsx_runtime.JSX.Element;
1593
+
1594
+ interface ThemeToggleProps {
1595
+ /** Icon shown while the resolved theme is light. */
1596
+ lightIcon: ToolbarIcon;
1597
+ /** Icon shown while the resolved theme is dark. */
1598
+ darkIcon: ToolbarIcon;
1599
+ /** Tooltip / accessible label. Defaults describe the switch target. */
1600
+ title?: string;
1601
+ /** Side the tooltip is placed on. Default `'top'`. */
1602
+ tooltipSide?: TooltipSide;
1603
+ /** Id of the `ResponsiveThemeBehaviour` to drive. Default `'responsive-theme'`. */
1604
+ behaviourId?: string;
1605
+ /**
1606
+ * Optional id of a `BackgroundLayer` to flip in lockstep, so the background
1607
+ * switches with the graph content instead of following the OS independently.
1608
+ */
1609
+ backgroundLayerId?: string;
1610
+ /**
1611
+ * Called after the theme switches. Use it to flip app chrome that lives
1612
+ * outside the canvas (e.g. a design-system `data-theme` attribute) so the
1613
+ * floating controls stay legible against the canvas.
1614
+ */
1615
+ onChange?: (kind: ThemeKind, mode: ThemeMode) => void;
1616
+ /** Explicit canvas instance; defaults to the context canvas. */
1617
+ canvas?: Canvas$1 | null;
1618
+ className?: string;
1619
+ }
1620
+ /**
1621
+ * Self-wiring theme toggle. Flips a registered `ResponsiveThemeBehaviour` between
1622
+ * pinned light and dark, showing the current theme's icon and active styling
1623
+ * while dark. Wraps {@link useTheme}.
1624
+ */
1625
+ declare function ThemeToggle({ lightIcon, darkIcon, title, tooltipSide, behaviourId, backgroundLayerId, onChange, canvas, className, }: ThemeToggleProps): react_jsx_runtime.JSX.Element;
1626
+
1627
+ interface LockButtonProps {
1628
+ lockedIcon: ToolbarIcon;
1629
+ unlockedIcon: ToolbarIcon;
1630
+ /** Behaviour ids disabled while locked. Default `['pan', 'drag-node']`. */
1631
+ behaviourIds?: string[];
1632
+ /** Initial locked state. Default `false`. */
1633
+ initialLocked?: boolean;
1634
+ /** Side the tooltip is placed on. Default `'top'`. */
1635
+ tooltipSide?: TooltipSide;
1636
+ /** Explicit canvas instance; defaults to the context canvas. */
1637
+ canvas?: Canvas$1 | null;
1638
+ className?: string;
1639
+ }
1640
+ /**
1641
+ * Self-wiring lock toggle — disables pan + node drag (by default) while locked,
1642
+ * leaving zoom available. Wraps the dumb {@link LockToggle} with {@link useLock}.
1643
+ */
1644
+ declare function LockButton({ lockedIcon, unlockedIcon, behaviourIds, initialLocked, tooltipSide, canvas, className, }: LockButtonProps): react_jsx_runtime.JSX.Element;
1645
+
1646
+ interface LayoutPickerProps {
1647
+ /** Map of layout key → factory producing a fresh layout instance. Memoize it. */
1648
+ layouts: Record<string, LayoutFactory>;
1649
+ /** Trigger label. Default `'Layout'`. */
1650
+ label?: string;
1651
+ /** Target `GraphLayer` id. Default `'graph'`. */
1652
+ layerId?: string;
1653
+ /** Padding for the post-layout fit. Default `80`. */
1654
+ fitPadding?: number;
1655
+ /** Initially-selected key. Default: first key. */
1656
+ initial?: string;
1657
+ /** Optional key → human label map. Default: identity. */
1658
+ labels?: Record<string, string>;
1659
+ /** Dropdown alignment. */
1660
+ align?: 'start' | 'center' | 'end';
1661
+ /** Side the trigger tooltip is placed on. Default `'top'`. */
1662
+ tooltipSide?: TooltipSide;
1663
+ /** Explicit canvas instance; defaults to the context canvas. */
1664
+ canvas?: Canvas$1 | null;
1665
+ className?: string;
1666
+ }
1667
+ /**
1668
+ * Self-wiring layout selector: a dropdown that applies the chosen layout via
1669
+ * {@link useLayout}. Layouts come from separate packages, so the consumer
1670
+ * supplies the factory map.
1671
+ */
1672
+ declare function LayoutPicker({ layouts, label, layerId, fitPadding, initial, labels, align, tooltipSide, canvas, className, }: LayoutPickerProps): react_jsx_runtime.JSX.Element;
1673
+
1674
+ interface SelectModePickerProps {
1675
+ /** Map of mode key → behaviour id (e.g. `{ click: 'click-select', ... }`). Memoize it. */
1676
+ behaviourIds: Record<string, string>;
1677
+ /** Trigger label. Default `'Select'`. */
1678
+ label?: string;
1679
+ /** Initially-active mode key. Default: first key. */
1680
+ initial?: string;
1681
+ /** Optional key → human label map. Default: identity. */
1682
+ labels?: Record<string, string>;
1683
+ /** Optional mode key → icon map. Shown on the trigger and beside each option. */
1684
+ icons?: Record<string, ToolbarIcon>;
1685
+ /** Dropdown alignment. */
1686
+ align?: 'start' | 'center' | 'end';
1687
+ /** Side the trigger tooltip is placed on. Default `'top'`. */
1688
+ tooltipSide?: TooltipSide;
1689
+ /** Explicit canvas instance; defaults to the context canvas. */
1690
+ canvas?: Canvas$1 | null;
1691
+ className?: string;
1692
+ }
1693
+ /**
1694
+ * Self-wiring selection-mode selector: a dropdown that enables exactly one of
1695
+ * the mapped behaviours via {@link useSelectMode}. The consumer must have
1696
+ * registered those behaviours.
1697
+ */
1698
+ declare function SelectModePicker({ behaviourIds, label, initial, labels, icons, align, tooltipSide, canvas, className, }: SelectModePickerProps): react_jsx_runtime.JSX.Element;
1699
+
1700
+ interface EdgeTypePickerProps {
1701
+ /** Target `GraphLayer` id. Default `'graph'`. */
1702
+ layerId?: string;
1703
+ /** Trigger label. Default `'Edge'`. */
1704
+ label?: string;
1705
+ /** Initially-selected path type. Default: the layer's current edge default. */
1706
+ initial?: EdgePathType;
1707
+ /** Path types to expose, in order. Default: straight / orth / bezier / rounded / smooth. */
1708
+ types?: readonly EdgePathType[];
1709
+ /** Optional key → human label map. Default: the built-in path-type labels. */
1710
+ labels?: Record<string, string>;
1711
+ /** Per-option icons (key → icon component), surfaced on the trigger + items. */
1712
+ icons?: Record<string, ToolbarIcon>;
1713
+ /** Dropdown alignment. */
1714
+ align?: 'start' | 'center' | 'end';
1715
+ /** Side the trigger tooltip is placed on. */
1716
+ tooltipSide?: TooltipSide;
1717
+ /** Explicit canvas instance; defaults to the context canvas. */
1718
+ canvas?: Canvas$1 | null;
1719
+ className?: string;
1720
+ }
1721
+ /**
1722
+ * Self-wiring edge-routing selector: a dropdown that re-routes **every** edge in
1723
+ * the layer via {@link useEdgeType} (`GraphLayer.setEdgeDefaults`). Mirrors
1724
+ * {@link SelectModePicker} / {@link LayoutPicker} — consume the hook, render an
1725
+ * {@link OptionPicker}. Per-option icons are supported via `icons`.
1726
+ */
1727
+ declare function EdgeTypePicker({ layerId, label, initial, types, labels, icons, align, tooltipSide, canvas, className, }: EdgeTypePickerProps): react_jsx_runtime.JSX.Element;
1728
+
1729
+ interface ContextMenuOverlayProps {
1730
+ /** Left offset in px, relative to the positioned ancestor (the `<Canvas>` host). */
1731
+ x: number;
1732
+ /** Top offset in px, relative to the positioned ancestor. */
1733
+ y: number;
1734
+ /** Menu tree to render (per-target; leaves carry their own `onClick`). */
1735
+ items: MenuItem[];
1736
+ /** Stacking order; default `1000` so the menu floats over canvas chrome. */
1737
+ zIndex?: number;
1738
+ /** Extra inline style merged onto the positioned wrapper. */
1739
+ style?: CSSProperties;
1740
+ }
1741
+ /**
1742
+ * Dumb overlay for a right-click context menu: an absolutely-positioned
1743
+ * `@invana/ui` `<NestedMenu>` anchored at `(x, y)` within its positioned
1744
+ * ancestor. Engine-agnostic, props-in only — the open/close state and the
1745
+ * action wiring live in the consumer (`useContextMenu` + the menu items).
1746
+ *
1747
+ * Render it as a `<Canvas>` descendant: the host `<div>` is `position: relative`,
1748
+ * so `(x, y)` taken from `ContextMenuEvent.screen` lands the menu at the cursor.
1749
+ *
1750
+ * It **stops `pointerdown` propagation** so a click *inside* the menu doesn't
1751
+ * reach the window-level dismiss listener `useContextMenu` attaches, and
1752
+ * **prevents the native context menu** on a right-click over itself. Leaf items
1753
+ * close the menu via their own `onClick`.
1754
+ */
1755
+ declare function ContextMenuOverlay({ x, y, items, zIndex, style }: ContextMenuOverlayProps): react_jsx_runtime.JSX.Element;
1756
+
1757
+ interface CanvasControlsToolbarIconSet {
1758
+ zoomIn: ToolbarIcon;
1759
+ zoomOut: ToolbarIcon;
1760
+ fit: ToolbarIcon;
1761
+ /** Required only when using the controlled `locked` toggle. */
1762
+ locked?: ToolbarIcon;
1763
+ unlocked?: ToolbarIcon;
1764
+ }
1765
+ interface CanvasControlsToolbarProps {
1766
+ /** Where the controls pin within the canvas host. Default `'bottom-left'`. */
1767
+ position?: PanelPosition;
1768
+ /** Stack direction. Default `'vertical'`. */
1769
+ orientation?: 'horizontal' | 'vertical';
1770
+ /** Layer id the fit-to-content button targets. Default `'graph'`. */
1771
+ fitLayerId?: string;
1772
+ /** Show zoom +/- buttons. Default `true`. */
1773
+ showZoom?: boolean;
1774
+ /**
1775
+ * Show a live `NN%` zoom readout between the +/- buttons. Sourced from the
1776
+ * canvas via the self-wired {@link ZoomControls}. Default `false`.
1777
+ */
1778
+ showZoomLevel?: boolean;
1779
+ /** Show the fit-to-content button. Default `true`. */
1780
+ showFit?: boolean;
1781
+ /** Icon components (consumer-supplied — the package stays icon-agnostic). */
1782
+ icons: CanvasControlsToolbarIconSet;
1783
+ /**
1784
+ * Controlled lock state. Lock is **not** auto-wired (what "locked" disables —
1785
+ * pan, node-drag, … — is app policy). Provide both `locked` and
1786
+ * `onToggleLock` (plus `icons.locked`/`icons.unlocked`) to render the toggle.
1787
+ */
1788
+ locked?: boolean;
1789
+ onToggleLock?: () => void;
1790
+ /**
1791
+ * Render **without** the self-positioning `<Panel>` — just the bare nav
1792
+ * component — so it composes into consumer chrome. Default `false`.
1793
+ */
1794
+ bare?: boolean;
1795
+ /** Explicit canvas instance; forwarded to each smart component. Defaults to context canvas. */
1796
+ canvas?: Canvas$1 | null;
1797
+ /** Extra controls appended after the presets — e.g. `<ControlButton>`s. */
1798
+ children?: ReactNode;
1799
+ className?: string;
1800
+ }
1801
+ /**
1802
+ * Turnkey controls overlay — the canvas equivalent of React Flow's `<Controls>`.
1803
+ * Assembled from self-wiring smart components ({@link ZoomControls},
1804
+ * {@link FitContentButton}) arranged in a {@link NavVertical} or
1805
+ * {@link NavHorizontal} from `@invana/ui`. No hook wiring needed — drop inside
1806
+ * a `<Canvas>` with an `icons` prop and it works.
1807
+ *
1808
+ * Lock stays **controlled** — pass `locked` + `onToggleLock` to surface it.
1809
+ * Append extra controls as `children`.
1810
+ *
1811
+ * @example
1812
+ * // Pattern A — drop inside a <Canvas>, self-wires via context:
1813
+ * <Canvas>
1814
+ * <GraphLayer id="graph" data={data} />
1815
+ * <CanvasControlsToolbar icons={{ zoomIn: ZoomIn, zoomOut: ZoomOut, fit: Maximize }} />
1816
+ * </Canvas>
1817
+ *
1818
+ * @example
1819
+ * // Pattern B — one external controller driving the active canvas:
1820
+ * <div className="my-toolbar">
1821
+ * <CanvasControlsToolbar bare canvas={activeCanvas} icons={…} />
1822
+ * </div>
1823
+ */
1824
+ declare function CanvasControlsToolbar({ position, orientation, fitLayerId, showZoom, showZoomLevel, showFit, icons, locked, onToggleLock, bare, canvas, children, className, }: CanvasControlsToolbarProps): react_jsx_runtime.JSX.Element;
1825
+
1826
+ interface GraphToolbarProps {
1827
+ /** Layout switcher. */
1828
+ layout: string;
1829
+ layoutOptions: Record<string, string>;
1830
+ onLayoutChange: (value: string) => void;
1831
+ /** Selection-mode switcher (e.g. click / brush / lasso). */
1832
+ selectMode: string;
1833
+ selectModeOptions: Record<string, string>;
1834
+ onSelectModeChange: (value: string) => void;
1835
+ /**
1836
+ * Self-wiring edge-routing picker (straight / orthogonal / curved …) targeting
1837
+ * this `GraphLayer` id. Default `'graph'`; pass `null` to hide the picker.
1838
+ */
1839
+ edgeTypeLayerId?: string | null;
1840
+ /** Path types the edge picker exposes, in order. Default: straight / orth / bezier / rounded / smooth. */
1841
+ edgeTypes?: readonly EdgePathType[];
1842
+ /** Optional key → label map for the edge picker. */
1843
+ edgeTypeLabels?: Record<string, string>;
1844
+ /** Per-option icons for the edge picker (key → icon component). */
1845
+ edgeTypeIcons?: Record<string, ToolbarIcon>;
1846
+ /** Clear button — layer to clear. Default `'graph'`. */
1847
+ clearLayerId?: string;
1848
+ clearIcon?: ToolbarIcon;
1849
+ /** Explicit canvas instance; forwarded to the self-wiring {@link ClearButton}. Defaults to context canvas. */
1850
+ canvas?: Canvas$1 | null;
1851
+ /** Where the toolbar pins within the canvas host. Default `'top-center'`. */
1852
+ position?: PanelPosition;
1853
+ className?: string;
1854
+ }
1855
+ /**
1856
+ * Turnkey **horizontal** graph toolbar: a layout picker + selection-mode picker
1857
+ * + a self-wiring {@link EdgeTypePicker} (edge routing) + clear action, grouped
1858
+ * in a `@invana/ui` `NavHorizontal`. The layout / select pickers are
1859
+ * callback-driven (the consumer wires them to the engine); the edge-type and
1860
+ * clear actions self-wire from their layer id. Compose the underlying
1861
+ * {@link OptionPicker} / {@link EdgeTypePicker} / {@link ClearButton} primitives
1862
+ * directly for a custom arrangement.
1863
+ *
1864
+ * Self-positioning: it wraps itself in a {@link Panel}, so it overlays the
1865
+ * canvas host directly — render it as a child of `<Canvas>` (no hand-rolled
1866
+ * absolute wrapper needed). Positioning is the Panel's job (`position`); there
1867
+ * is no internal `align` knob.
1868
+ */
1869
+ declare function GraphToolbar({ layout, layoutOptions, onLayoutChange, selectMode, selectModeOptions, onSelectModeChange, edgeTypeLayerId, edgeTypes, edgeTypeLabels, edgeTypeIcons, clearLayerId, clearIcon, canvas, position, className, }: GraphToolbarProps): react_jsx_runtime.JSX.Element;
1870
+
1871
+ interface HistoryToolbarIconSet {
1872
+ undo: ToolbarIcon;
1873
+ redo: ToolbarIcon;
1874
+ /** Required only when `showRedraw` is left on. */
1875
+ redraw?: ToolbarIcon;
1876
+ }
1877
+ interface HistoryToolbarProps {
1878
+ icons: HistoryToolbarIconSet;
1879
+ /** Where the toolbar pins. Default `'top-left'`. */
1880
+ position?: PanelPosition;
1881
+ /** Stack direction. Default `'horizontal'`. */
1882
+ orientation?: 'horizontal' | 'vertical';
1883
+ /** Show the redraw button (needs `icons.redraw`). Default `true`. */
1884
+ showRedraw?: boolean;
1885
+ /** Layer the redraw button targets. Default `'graph'`. */
1886
+ layerId?: string;
1887
+ /** Render without the `<Panel>` wrapper (embed in external chrome). Default `false`. */
1888
+ bare?: boolean;
1889
+ /** Explicit canvas instance; defaults to the context canvas. */
1890
+ canvas?: Canvas$1 | null;
1891
+ className?: string;
1892
+ }
1893
+ /**
1894
+ * Undo / redo / redraw bar. Self-wires through {@link useHistory}; requires a
1895
+ * `<GraphHistoryProvider>` ancestor for undo/redo (redraw works regardless).
1896
+ */
1897
+ declare function HistoryToolbar({ icons, position, orientation, showRedraw, layerId, bare, canvas, className, }: HistoryToolbarProps): react_jsx_runtime.JSX.Element;
1898
+
1899
+ interface EditToolbarIconSet {
1900
+ cut: ToolbarIcon;
1901
+ copy: ToolbarIcon;
1902
+ paste: ToolbarIcon;
1903
+ delete: ToolbarIcon;
1904
+ /** Optional leading icon for the (labelled) Clear button. */
1905
+ clear?: ToolbarIcon;
1906
+ }
1907
+ interface EditToolbarProps {
1908
+ icons: EditToolbarIconSet;
1909
+ /** Where the toolbar pins. Default `'top-left'`. */
1910
+ position?: PanelPosition;
1911
+ /** Stack direction. Default `'horizontal'`. */
1912
+ orientation?: 'horizontal' | 'vertical';
1913
+ /** Show the clear-canvas button. Default `true`. */
1914
+ showClear?: boolean;
1915
+ /** Id of the `ClickSelectBehaviour` selection is read from. Default `'click-select'`. */
1916
+ clickSelectId?: string;
1917
+ /** Layer that clear / clipboard target. Default `'graph'`. */
1918
+ layerId?: string;
1919
+ /** Render without the `<Panel>` wrapper. Default `false`. */
1920
+ bare?: boolean;
1921
+ /** Explicit canvas instance; defaults to the context canvas. */
1922
+ canvas?: Canvas$1 | null;
1923
+ className?: string;
1924
+ }
1925
+ /**
1926
+ * Clipboard / edit bar — cut, copy, paste, delete selection, clear canvas. The
1927
+ * clipboard actions self-wire through {@link useClipboard} (require a
1928
+ * `<GraphClipboardProvider>` + a `ClickSelectBehaviour`); clear self-wires
1929
+ * through {@link useClearGraph}. All edits are undoable when a
1930
+ * `<GraphHistoryProvider>` is present.
1931
+ */
1932
+ declare function EditToolbar({ icons, position, orientation, showClear, clickSelectId, layerId, bare, canvas, className, }: EditToolbarProps): react_jsx_runtime.JSX.Element;
1933
+
1934
+ interface ViewToolbarIconSet {
1935
+ zoomIn: ToolbarIcon;
1936
+ zoomOut: ToolbarIcon;
1937
+ fit: ToolbarIcon;
1938
+ /** Required only when the lock toggle is shown. */
1939
+ locked?: ToolbarIcon;
1940
+ unlocked?: ToolbarIcon;
1941
+ }
1942
+ interface ViewToolbarProps {
1943
+ icons: ViewToolbarIconSet;
1944
+ /** Where the toolbar pins. Default `'bottom-left'`. */
1945
+ position?: PanelPosition;
1946
+ /** Stack direction. Default `'vertical'`. */
1947
+ orientation?: 'horizontal' | 'vertical';
1948
+ /** Show zoom in/out buttons. Default `true`. */
1949
+ showZoom?: boolean;
1950
+ /** Show the live NN% readout between the zoom buttons. Default `false`. */
1951
+ showZoomLevel?: boolean;
1952
+ /** Show the zoom-level preset picker. Default `true`. */
1953
+ showZoomPicker?: boolean;
1954
+ /** Show the fit-to-content button. Default `true`. */
1955
+ showFit?: boolean;
1956
+ /** Show the lock toggle (needs `icons.locked` + `icons.unlocked`). Default `true`. */
1957
+ showLock?: boolean;
1958
+ /** Layer that fit + zoom-picker target. Default `'graph'`. */
1959
+ layerId?: string;
1960
+ /** Behaviour ids disabled while locked. Default `['pan', 'drag-node']`. */
1961
+ lockBehaviourIds?: string[];
1962
+ /** Render without the `<Panel>` wrapper. Default `false`. */
1963
+ bare?: boolean;
1964
+ /** Explicit canvas instance; defaults to the context canvas. */
1965
+ canvas?: Canvas$1 | null;
1966
+ className?: string;
1967
+ }
1968
+ /**
1969
+ * View controls — zoom in/out, zoom-level picker, fit-to-content, lock view.
1970
+ * Zoom + fit self-wire through the camera hooks; lock self-wires through
1971
+ * {@link useLock} (disables pan + node drag by default, leaving zoom available).
1972
+ */
1973
+ declare function ViewToolbar({ icons, position, orientation, showZoom, showZoomLevel, showZoomPicker, showFit, showLock, layerId, lockBehaviourIds, bare, canvas, className, }: ViewToolbarProps): react_jsx_runtime.JSX.Element;
1974
+
1975
+ type PatternType = NonNullable<BackgroundLayerOptions['patternType']>;
1976
+ interface GridToolbarIconSet {
1977
+ grid: ToolbarIcon;
1978
+ }
1979
+ interface GridToolbarProps {
1980
+ icons: GridToolbarIconSet;
1981
+ /** Where the toolbar pins. Default `'bottom-right'`. */
1982
+ position?: PanelPosition;
1983
+ /** Stack direction. Default `'horizontal'`. */
1984
+ orientation?: 'horizontal' | 'vertical';
1985
+ /** Id of the `BackgroundLayer` to toggle. Default `'background'`. */
1986
+ backgroundLayerId?: string;
1987
+ /** Pattern to switch to when shown (e.g. `'grid'`); preserves existing if omitted. */
1988
+ patternType?: PatternType;
1989
+ /** Render without the `<Panel>` wrapper. Default `false`. */
1990
+ bare?: boolean;
1991
+ /** Explicit canvas instance; defaults to the context canvas. */
1992
+ canvas?: Canvas$1 | null;
1993
+ className?: string;
1994
+ }
1995
+ /**
1996
+ * Grid toggle bar — shows/hides a `BackgroundLayer`'s pattern. Self-wires
1997
+ * through {@link useGrid}.
1998
+ */
1999
+ declare function GridToolbar({ icons, position, orientation, backgroundLayerId, patternType, bare, canvas, className, }: GridToolbarProps): react_jsx_runtime.JSX.Element;
2000
+
2001
+ interface GraphLayoutToolbarProps {
2002
+ /** Map of layout key → factory producing a fresh layout instance. Memoize it. */
2003
+ layouts: Record<string, LayoutFactory>;
2004
+ /** Map of select-mode key → behaviour id (e.g. `{ click: 'click-select', ... }`). Memoize it. */
2005
+ selectModeBehaviourIds: Record<string, string>;
2006
+ /** Optional layout key → label map. Default: identity. */
2007
+ layoutLabels?: Record<string, string>;
2008
+ /** Optional select-mode key → label map. Default: identity. */
2009
+ selectModeLabels?: Record<string, string>;
2010
+ /** Optional select-mode key → icon map. Shown on the trigger and beside each option. */
2011
+ selectModeIcons?: Record<string, ToolbarIcon>;
2012
+ /** Initially-selected layout key. */
2013
+ initialLayout?: string;
2014
+ /** Initially-active select mode key. */
2015
+ initialSelectMode?: string;
2016
+ /** Target `GraphLayer` id. Default `'graph'`. */
2017
+ layerId?: string;
2018
+ /** Where the toolbar pins. Default `'top-center'`. */
2019
+ position?: PanelPosition;
2020
+ /** Render without the `<Panel>` wrapper (embed in external chrome). Default `false`. */
2021
+ bare?: boolean;
2022
+ /** Explicit canvas instance; defaults to the context canvas. */
2023
+ canvas?: Canvas$1 | null;
2024
+ className?: string;
2025
+ }
2026
+ /**
2027
+ * Graph controls — layout selector + selection-mode selector. Both self-wire
2028
+ * ({@link useLayout} / {@link useSelectMode}), but since layouts live in
2029
+ * separate packages and mode-switching toggles consumer-registered behaviours,
2030
+ * the consumer supplies the layout factory map and the mode→behaviour-id map.
2031
+ */
2032
+ declare function GraphLayoutToolbar({ layouts, selectModeBehaviourIds, layoutLabels, selectModeLabels, selectModeIcons, initialLayout, initialSelectMode, layerId, position, bare, canvas, className, }: GraphLayoutToolbarProps): react_jsx_runtime.JSX.Element;
2033
+
2034
+ /** Icons for the modeller toolbar. The four tool icons are required; the rest gate their controls. */
2035
+ interface ModellerToolbarIconSet {
2036
+ select: ToolbarIcon;
2037
+ add: ToolbarIcon;
2038
+ connect: ToolbarIcon;
2039
+ delete: ToolbarIcon;
2040
+ /** Required when `showHistory` is on (the default). */
2041
+ undo?: ToolbarIcon;
2042
+ redo?: ToolbarIcon;
2043
+ /** Optional leading icon for the Clear button. */
2044
+ clear?: ToolbarIcon;
2045
+ }
2046
+ interface ModellerToolbarProps {
2047
+ icons: ModellerToolbarIconSet;
2048
+ /** Which tool toggles to show, in order. Default `['select','add','connect','delete']`. */
2049
+ tools?: readonly GraphTool[];
2050
+ /** Override the tool tooltips / accessible labels. */
2051
+ labels?: Partial<Record<GraphTool, string>>;
2052
+ /**
2053
+ * Node-kind options for the **Add** tool's shape picker (key → label). The
2054
+ * picker shows only while the Add tool is active. Omit / leave empty to hide
2055
+ * it (e.g. when your `createNode` factory is fixed-shape).
2056
+ */
2057
+ nodeKinds?: Record<string, string>;
2058
+ /** Per-kind icons for the shape picker. */
2059
+ nodeKindIcons?: Record<string, ToolbarIcon>;
2060
+ /** Show undo / redo (needs `icons.undo` + `icons.redo`). Default `true`. */
2061
+ showHistory?: boolean;
2062
+ /** Show the clear-canvas button. Default `true`. */
2063
+ showClear?: boolean;
2064
+ /** Layer the clear button targets. Default `'graph'`. */
2065
+ layerId?: string;
2066
+ /** Where the toolbar pins. Default `'top-center'`. */
2067
+ position?: PanelPosition;
2068
+ /** Stack direction. Default `'horizontal'`. */
2069
+ orientation?: 'horizontal' | 'vertical';
2070
+ /** Render without the `<Panel>` wrapper (embed in external chrome). Default `false`. */
2071
+ bare?: boolean;
2072
+ /** Explicit canvas instance; defaults to the context canvas. */
2073
+ canvas?: Canvas$1 | null;
2074
+ className?: string;
2075
+ }
2076
+ /**
2077
+ * Turnkey **drawing / modeller** toolbar — tool toggles (Select / Add / Connect
2078
+ * / Delete) plus an optional Add-tool shape picker, undo/redo, and clear. The
2079
+ * canvas equivalent of a drawing app's tool palette.
2080
+ *
2081
+ * Self-wires the tool toggles through {@link useTool} (requires a
2082
+ * `<GraphToolProvider>` ancestor) and the undo/redo/clear actions through their
2083
+ * own hooks (a `<GraphHistoryProvider>` makes them live). The consumer still
2084
+ * declares the drawing behaviours, gating each one's `enabled` on the active
2085
+ * tool — this toolbar owns the *tool state*, not the behaviours.
2086
+ */
2087
+ declare function ModellerToolbar({ icons, tools, labels, nodeKinds, nodeKindIcons, showHistory, showClear, layerId, position, orientation, bare, canvas, className, }: ModellerToolbarProps): react_jsx_runtime.JSX.Element;
2088
+
2089
+ interface InspectorPanelProps {
2090
+ /** GraphLayer to read/write. Default `'graph'`. */
2091
+ layerId?: string;
2092
+ /** Id of the `ClickInspectBehaviour` the edit target is read from. Default `'click-inspect'`. */
2093
+ inspectId?: string;
2094
+ /** Where the panel pins. Default `'top-right'`. */
2095
+ position?: PanelPosition;
2096
+ /** Show the label field (nodes, non-`typeAsLabel` mode only). Default `true`. */
2097
+ showLabel?: boolean;
2098
+ /**
2099
+ * Modeller mode — edit a single `type` field on both nodes and edges that also
2100
+ * drives the drawn label. Hides the label field for both. Default `false`.
2101
+ */
2102
+ typeAsLabel?: boolean;
2103
+ /** Heading when a node is selected. Default `'Node'`. */
2104
+ nodeTitle?: string;
2105
+ /** Heading when an edge is selected. Default `'Edge'`. */
2106
+ edgeTitle?: string;
2107
+ /** Render the bare editor without the `<Panel>` wrapper. Default `false`. */
2108
+ bare?: boolean;
2109
+ /** Explicit canvas instance; defaults to the context canvas. */
2110
+ canvas?: Canvas$1 | null;
2111
+ className?: string;
2112
+ }
2113
+ /**
2114
+ * Self-wiring **inspector** — shows a {@link PropertiesEditor} for the single
2115
+ * node/edge the user clicked to edit and commits edits (label + `data`, plus
2116
+ * `type` + reverse for edges) back to the store undoably. The property-editing
2117
+ * analogue of `CanvasControlsToolbar`: drop it inside `<Canvas>` and it appears
2118
+ * whenever an element is clicked for editing, and renders nothing otherwise.
2119
+ *
2120
+ * Needs a `ClickInspectBehaviour` (for the click-to-edit target) and, for
2121
+ * undoable commits, a `<GraphHistoryProvider>` ancestor. Remounts the editor
2122
+ * (via `key`) when the targeted element changes, so the form reloads from it.
2123
+ */
2124
+ declare function InspectorPanel({ layerId, inspectId, position, showLabel, typeAsLabel, nodeTitle, edgeTitle, bare, canvas, className, }: InspectorPanelProps): react_jsx_runtime.JSX.Element | null;
2125
+
2126
+ /**
2127
+ * Context handed to a context-menu `items` builder for an empty-canvas
2128
+ * (background) right-click. Carries the pointer position, the live `Canvas`,
2129
+ * and a `close` callback for items that need to dismiss the menu explicitly
2130
+ * (auto-close already fires `close` after every leaf `onClick`).
2131
+ */
2132
+ interface GraphContextMenuContext {
2133
+ /** Pointer position in world (scene) coordinates — e.g. to place a new node. */
2134
+ readonly world: {
2135
+ readonly x: number;
2136
+ readonly y: number;
2137
+ };
2138
+ /** Pointer position in canvas-relative screen px (where the overlay sits). */
2139
+ readonly screen: {
2140
+ readonly x: number;
2141
+ readonly y: number;
2142
+ };
2143
+ /** The live engine instance, for reaching layers / behaviours / camera. */
2144
+ readonly canvas: Canvas$1;
2145
+ /** Dismiss the menu. Available for manual control; auto-close uses it too. */
2146
+ readonly close: () => void;
2147
+ }
2148
+ /**
2149
+ * Context handed to a node/edge context-menu `items` builder. Extends
2150
+ * {@link GraphContextMenuContext} with the right-clicked element's `id` and its
2151
+ * arbitrary `data` payload (`node.data` / `edge.data`).
2152
+ */
2153
+ interface GraphTargetMenuContext extends GraphContextMenuContext {
2154
+ /** Id of the right-clicked node / edge. */
2155
+ readonly id: string;
2156
+ /** Arbitrary user payload from `node.data` / `edge.data` (`undefined` if none). */
2157
+ readonly data: unknown;
2158
+ }
2159
+ /** Options shared by all three `Graph*ContextMenu` components. */
2160
+ interface GraphContextMenuCommonProps {
2161
+ /** GraphLayer id whose nodes/edges this menu watches; default `'graph'`. */
2162
+ layerId?: string;
2163
+ /** Whether the menu is active; reactive. Default `true`. */
2164
+ enabled?: boolean;
2165
+ /** Stacking order of the overlay; default `1000`. */
2166
+ zIndex?: number;
2167
+ /** Extra inline style merged onto the overlay wrapper. */
2168
+ style?: CSSProperties;
2169
+ /**
2170
+ * Auto-close the menu after any leaf item's `onClick`. Default `true`.
2171
+ * Set `false` to manage dismissal yourself via `ctx.close`.
2172
+ */
2173
+ autoClose?: boolean;
2174
+ }
2175
+
2176
+ /** Context handed to {@link GraphNodeContextMenuProps.items}. */
2177
+ type GraphNodeMenuContext = GraphTargetMenuContext;
2178
+ interface GraphNodeContextMenuProps extends GraphContextMenuCommonProps {
2179
+ /**
2180
+ * Build the menu shown when a **node** is right-clicked. Receives the node's
2181
+ * `id`, its `data`, the pointer position, the live `canvas`, and `close`.
2182
+ * Return the `@invana/ui` `MenuItem[]` to render.
2183
+ */
2184
+ items: (ctx: GraphNodeMenuContext) => MenuItem[];
2185
+ /** Behaviour id; default `'node-context-menu'`. */
2186
+ id?: string;
2187
+ /**
2188
+ * Transient state name applied to the right-clicked node while the menu is
2189
+ * open (e.g. `'context-open'`), cleared on the next open / dismiss. Default
2190
+ * `null` (no marker).
2191
+ */
2192
+ state?: string | null;
2193
+ }
2194
+ /**
2195
+ * Node-scoped right-click menu for a `GraphLayer`. Drop it inside `<Canvas>`
2196
+ * (alongside the layer) and pass an `items` builder — the behaviour wiring,
2197
+ * positioning, dismissal (outside-click / Escape), and auto-close are handled
2198
+ * internally.
2199
+ *
2200
+ * Pairs with {@link GraphEdgeContextMenu} and {@link GraphBackgroundContextMenu};
2201
+ * each owns a distinct behaviour scoped to its own target, so the three compose
2202
+ * without conflict.
2203
+ *
2204
+ * @example
2205
+ * ```tsx
2206
+ * <GraphNodeContextMenu
2207
+ * items={({ id, canvas, close }) => [
2208
+ * { id: 'edit', label: 'Edit', onClick: () => editNode(id) },
2209
+ * { id: 'delete', label: 'Delete', onClick: () => deleteNode(id) },
2210
+ * ]}
2211
+ * />
2212
+ * ```
2213
+ */
2214
+ declare function GraphNodeContextMenu({ items, id, ...common }: GraphNodeContextMenuProps): react_jsx_runtime.JSX.Element;
2215
+
2216
+ /** Context handed to {@link GraphEdgeContextMenuProps.items}. */
2217
+ type GraphEdgeMenuContext = GraphTargetMenuContext;
2218
+ interface GraphEdgeContextMenuProps extends GraphContextMenuCommonProps {
2219
+ /**
2220
+ * Build the menu shown when an **edge** is right-clicked. Receives the edge's
2221
+ * `id`, its `data`, the pointer position, the live `canvas`, and `close`.
2222
+ * Return the `@invana/ui` `MenuItem[]` to render.
2223
+ */
2224
+ items: (ctx: GraphEdgeMenuContext) => MenuItem[];
2225
+ /** Behaviour id; default `'edge-context-menu'`. */
2226
+ id?: string;
2227
+ /**
2228
+ * Transient state name applied to the right-clicked edge while the menu is
2229
+ * open (e.g. `'context-open'`), cleared on the next open / dismiss. Default
2230
+ * `null` (no marker).
2231
+ */
2232
+ state?: string | null;
2233
+ }
2234
+ /**
2235
+ * Edge-scoped right-click menu for a `GraphLayer`. Drop it inside `<Canvas>`
2236
+ * (alongside the layer) and pass an `items` builder — the behaviour wiring,
2237
+ * positioning, dismissal (outside-click / Escape), and auto-close are handled
2238
+ * internally.
2239
+ *
2240
+ * Pairs with {@link GraphNodeContextMenu} and {@link GraphBackgroundContextMenu};
2241
+ * each owns a distinct behaviour scoped to its own target, so the three compose
2242
+ * without conflict.
2243
+ *
2244
+ * @example
2245
+ * ```tsx
2246
+ * <GraphEdgeContextMenu
2247
+ * items={({ id, close }) => [
2248
+ * { id: 'reverse', label: 'Reverse direction', onClick: () => reverseEdge(id) },
2249
+ * { id: 'delete', label: 'Delete', onClick: () => deleteEdge(id) },
2250
+ * ]}
2251
+ * />
2252
+ * ```
2253
+ */
2254
+ declare function GraphEdgeContextMenu({ items, id, ...common }: GraphEdgeContextMenuProps): react_jsx_runtime.JSX.Element;
2255
+
2256
+ /** Context handed to {@link GraphBackgroundContextMenuProps.items}. */
2257
+ type GraphBackgroundMenuContext = GraphContextMenuContext;
2258
+ interface GraphBackgroundContextMenuProps extends GraphContextMenuCommonProps {
2259
+ /**
2260
+ * Build the menu shown when the **empty canvas** is right-clicked. Receives
2261
+ * the pointer position (`world` is handy for "add node here"), the live
2262
+ * `canvas`, and `close`. Return the `@invana/ui` `MenuItem[]` to render.
2263
+ */
2264
+ items: (ctx: GraphBackgroundMenuContext) => MenuItem[];
2265
+ /** Behaviour id; default `'background-context-menu'`. */
2266
+ id?: string;
2267
+ }
2268
+ /**
2269
+ * Background-scoped right-click menu for a `GraphLayer` — fires on a right-click
2270
+ * over the empty canvas (not on any node or edge). Drop it inside `<Canvas>`
2271
+ * (alongside the layer) and pass an `items` builder — the behaviour wiring,
2272
+ * positioning, dismissal (outside-click / Escape), and auto-close are handled
2273
+ * internally.
2274
+ *
2275
+ * Pairs with {@link GraphNodeContextMenu} and {@link GraphEdgeContextMenu}; each
2276
+ * owns a distinct behaviour scoped to its own target, so the three compose
2277
+ * without conflict.
2278
+ *
2279
+ * @example
2280
+ * ```tsx
2281
+ * <GraphBackgroundContextMenu
2282
+ * items={({ world, canvas }) => [
2283
+ * { id: 'add', label: 'Add node here', onClick: () => addNodeAt(world) },
2284
+ * { id: 'fit', label: 'Fit to content', onClick: () => fit(canvas) },
2285
+ * ]}
2286
+ * />
2287
+ * ```
2288
+ */
2289
+ declare function GraphBackgroundContextMenu({ items, id, ...common }: GraphBackgroundContextMenuProps): react_jsx_runtime.JSX.Element;
2290
+
2291
+ export { type ApplicableLayout, BackgroundLayer, type BackgroundLayerProps, BrushSelectBehaviour, type BrushSelectBehaviourProps, Canvas, CanvasContext, CanvasControlsToolbar, type CanvasControlsToolbarIconSet, type CanvasControlsToolbarProps, type CanvasProps, ClearButton, type ClearButtonProps, ClickInspectBehaviour, type ClickInspectBehaviourProps, ClickSelectBehaviour, type ClickSelectBehaviourProps, ClipboardContext, CollapseExpandBehaviour, type CollapseExpandBehaviourProps, ContextMenuBehaviour, type ContextMenuBehaviourProps, ContextMenuOverlay, type ContextMenuOverlayProps, type ContextMenuState, ControlButton, type ControlButtonProps, CopyButton, type CopyButtonProps, CreateNodeBehaviour, type CreateNodeBehaviourProps, CutButton, type CutButtonProps, D3ForceLayout, type D3ForceLayoutProps, DEFAULT_EDGE_TYPES, DEFAULT_EDGE_TYPE_LABELS, DegreeSizeBehaviour, type DegreeSizeBehaviourProps, DeleteSelectionButton, type DeleteSelectionButtonProps, DragNodeBehaviour, type DragNodeBehaviourProps, DragPanBehaviour, type DragPanBehaviourProps, DrawEdgeBehaviour, type DrawEdgeBehaviourProps, EdgeSizeLODBehaviour, type EdgeSizeLODBehaviourProps, EdgeTypePicker, type EdgeTypePickerProps, EditToolbar, type EditToolbarIconSet, type EditToolbarProps, type EntityEditorTarget, EraseBehaviour, type EraseBehaviourProps, FitContentButton, type FitContentButtonProps, GraphBackgroundContextMenu, type GraphBackgroundContextMenuProps, type GraphBackgroundMenuContext, GraphClipboardProvider, type GraphClipboardProviderProps, type GraphContextMenuCommonProps, type GraphContextMenuContext, GraphEdgeContextMenu, type GraphEdgeContextMenuProps, type GraphEdgeMenuContext, GraphHistoryProvider, type GraphHistoryProviderProps, GraphLayer, type GraphLayerProps, GraphLayoutToolbar, type GraphLayoutToolbarProps, GraphNodeContextMenu, type GraphNodeContextMenuProps, type GraphNodeMenuContext, type GraphTargetMenuContext, type GraphTool, GraphToolProvider, type GraphToolProviderProps, GraphToolbar, type GraphToolbarProps, GridToggle, type GridToggleProps, GridToolbar, type GridToolbarIconSet, type GridToolbarProps, HistoryContext, HistoryToolbar, type HistoryToolbarIconSet, type HistoryToolbarProps, HoverActivateBehaviour, type HoverActivateBehaviourProps, InspectorPanel, type InspectorPanelProps, KeyboardCameraInputBehaviour, type KeyboardCameraInputBehaviourProps, LabelCollisionBehaviour, type LabelCollisionBehaviourProps, LabelResolutionLODBehaviour, type LabelResolutionLODBehaviourProps, LassoSelectBehaviour, type LassoSelectBehaviourProps, type LayoutFactory, LayoutPicker, type LayoutPickerProps, LockButton, type LockButtonProps, LockToggle, type LockToggleProps, MiniMapLayer, type MiniMapLayerProps, ModellerToolbar, type ModellerToolbarIconSet, type ModellerToolbarProps, NodeResizeBehaviour, type NodeResizeBehaviourProps, NodeSizeLODBehaviour, type NodeSizeLODBehaviourProps, OptionPicker, type OptionPickerProps, Panel, type PanelPosition, type PanelProps, ParallelEdgeBehaviour, type ParallelEdgeBehaviourProps, PasteButton, type PasteButtonProps, PinchZoomBehaviour, type PinchZoomBehaviourProps, PropertiesEditor, type PropertiesEditorProps, type PropertiesEditorValues, RedoButton, type RedoButtonProps, RedrawButton, type RedrawButtonProps, ResponsiveThemeBehaviour, type ResponsiveThemeBehaviourProps, SelectModePicker, type SelectModePickerProps, ThemeToggle, type ThemeToggleProps, ToolContext, type ToolContextValue, type ToolbarIcon, type TooltipSide, Tooltipped, type TooltippedProps, UndoButton, type UndoButtonProps, type UseCameraResult, type UseClearGraphResult, type UseClipboardOptions, type UseClipboardResult, type UseContextMenuResult, type UseDrawHistoryResult, type UseEdgeTypeOptions, type UseEdgeTypeResult, type UseEntityEditorOptions, type UseFitContentResult, type UseGridOptions, type UseGridResult, type UseHistoryOptions, type UseHistoryResult, type UseInspectTargetOptions, type UseLayoutOptions, type UseLayoutResult, type UseLockOptions, type UseLockResult, type UseSelectModeOptions, type UseSelectModeResult, type UseSelectionOptions, type UseSelectionResult, type UseThemeOptions, type UseThemeResult, type UseZoomResult, ViewToolbar, type ViewToolbarIconSet, type ViewToolbarProps, WheelZoomBehaviour, type WheelZoomBehaviourProps, ZoomControls, type ZoomControlsProps, ZoomPicker, type ZoomPickerProps, useCamera, useCanvas, useCanvasEvent, useClearGraph, useClipboard, useContextMenu, useDrawHistory, useEdgeType, useEntityEditor, useFitContent, useGrid, useHistory, useInspectTarget, useLayout, useLock, useSelectMode, useSelection, useTheme, useTool, useZoom };