@linkurious/ogma-annotations 2.1.0 → 2.1.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,1423 @@
1
+ import { default as default_2 } from 'eventemitter3';
2
+ import { Feature } from 'geojson';
3
+ import { FeatureCollection } from 'geojson';
4
+ import { GeometryObject } from 'geojson';
5
+ import { LineString } from 'geojson';
6
+ import { Node as Node_2 } from '@linkurious/ogma';
7
+ import { Ogma } from '@linkurious/ogma';
8
+ import { Point as Point_2 } from 'geojson';
9
+ import { Polygon as Polygon_2 } from 'geojson';
10
+
11
+ /** Union type of all Annotation features */
12
+ declare type Annotation = Arrow | Box | Text_2 | Comment_2 | Polygon;
13
+
14
+ /** Collection of Annotations, GeoJSON FeatureCollection */
15
+ declare interface AnnotationCollection extends FeatureCollection {
16
+ features: Annotation[];
17
+ }
18
+
19
+ /**
20
+ * Base interface for all annotation features.
21
+ * @template G - Geometry type
22
+ * @template P - Properties type
23
+ */
24
+ declare interface AnnotationFeature<G extends GeometryObject = GeometryObject, P = AnnotationProps> extends Feature<G, P> {
25
+ /** Unique identifier for the annotation */
26
+ id: Id;
27
+ }
28
+
29
+ export declare class AnnotationPanel {
30
+ private control;
31
+ private panel;
32
+ private panelBody;
33
+ private mode;
34
+ private currentAnnotation;
35
+ private currentColor;
36
+ private recent;
37
+ private colorCircles;
38
+ private colorPickerOverlay;
39
+ private colorPicker;
40
+ private detachVisibility;
41
+ private documentClickHandler;
42
+ constructor(options: AnnotationPanelOptions);
43
+ private setAnnotation;
44
+ private renderArrow;
45
+ private renderText;
46
+ private renderPolygon;
47
+ private section;
48
+ private icon;
49
+ private colorSelector;
50
+ private backgroundSelector;
51
+ private fontSelector;
52
+ private extremitySelector;
53
+ private dropdown;
54
+ private slider;
55
+ private lineTypeButtons;
56
+ private bind;
57
+ private updateColorFromAnnotation;
58
+ private updateColorCircles;
59
+ private toggleColorPicker;
60
+ private closeColorPicker;
61
+ private updateStyle;
62
+ setPlacement(placement: PanelPlacement): void;
63
+ setOrientation(orientation: PanelOrientation): void;
64
+ show(): void;
65
+ hide: () => void;
66
+ destroy(): void;
67
+ }
68
+
69
+ export declare interface AnnotationPanelOptions {
70
+ control: Control;
71
+ /**
72
+ * Element the panel mounts into. The panel creates and manages its own root
73
+ * `<div class="annotation-panel">` inside it. Defaults to `document.body`.
74
+ */
75
+ container?: HTMLElement;
76
+ /**
77
+ * Which screen edge/corner the panel docks to. Defaults to `"right"`
78
+ * (vertically centered on the right edge — the original look). Change at
79
+ * runtime with {@link AnnotationPanel.setPlacement}.
80
+ */
81
+ placement?: PanelPlacement;
82
+ /**
83
+ * Whether panel sections stack vertically or run horizontally as a
84
+ * toolbar. Defaults to `"vertical"`. Change at runtime with
85
+ * {@link AnnotationPanel.setOrientation}.
86
+ */
87
+ orientation?: PanelOrientation;
88
+ }
89
+
90
+ /**
91
+ * Base properties for all annotations.
92
+ */
93
+ declare interface AnnotationProps {
94
+ /** Type of annotation */
95
+ type: AnnotationType;
96
+ /** Optional style configuration */
97
+ style?: unknown;
98
+ }
99
+
100
+ /**
101
+ * Styled drawing/undo-redo toolbar: add arrow, comment, box, text and
102
+ * polygon annotations, undo/redo, and delete the current selection. The
103
+ * React equivalent is `AddMenu` (`@linkurious/ogma-annotations-react/ui`) -
104
+ * this class mirrors its buttons and defaults for a vanilla consumer.
105
+ */
106
+ export declare class AnnotationToolbar {
107
+ private control;
108
+ private root;
109
+ private activeButton;
110
+ private undoButton;
111
+ private redoButton;
112
+ private handleDrawingEnd;
113
+ private handleHistory;
114
+ constructor(options: AnnotationToolbarOptions);
115
+ private drawingButton;
116
+ private button;
117
+ private separator;
118
+ private setActiveMode;
119
+ private updateUndoRedo;
120
+ setPlacement(placement: PanelPlacement): void;
121
+ setOrientation(orientation: PanelOrientation): void;
122
+ destroy(): void;
123
+ }
124
+
125
+ export declare interface AnnotationToolbarOptions {
126
+ control: Control;
127
+ /**
128
+ * Element the toolbar mounts into. The toolbar creates and manages its
129
+ * own root `<div class="annotation-toolbar">` inside it. Defaults to
130
+ * `document.body`.
131
+ */
132
+ container?: HTMLElement;
133
+ /**
134
+ * Which screen edge/corner the toolbar docks to. Defaults to `"bottom"`.
135
+ * Change at runtime with {@link AnnotationToolbar.setPlacement}.
136
+ */
137
+ placement?: PanelPlacement;
138
+ /**
139
+ * Whether buttons run left-to-right or stack top-to-bottom. Defaults to
140
+ * `"horizontal"`. Change at runtime with
141
+ * {@link AnnotationToolbar.setOrientation}.
142
+ */
143
+ orientation?: PanelOrientation;
144
+ /**
145
+ * Which drawing tools to show, and in what order. Defaults to all six:
146
+ * `["arrow", "comment", "sticky-note", "box", "text", "polygon"]`.
147
+ */
148
+ enabledTypes?: ToolbarDrawingType[];
149
+ /** Per-type default style overrides for the drawing tool buttons. */
150
+ styles?: AnnotationToolbarStyles;
151
+ /**
152
+ * Which deletion control(s) to show - the erase tool, the
153
+ * select-then-trash button, or both. Defaults to `"erase"`.
154
+ */
155
+ deleteMode?: DeleteMode;
156
+ /** Called when the SVG export button is clicked. Omit to hide the button. */
157
+ onSvgExport?: () => void;
158
+ /** Called when the JSON export button is clicked. Omit to hide the button. */
159
+ onJsonExport?: () => void;
160
+ }
161
+
162
+ /**
163
+ * Per-type default style overrides, merged over the toolbar's own built-in
164
+ * defaults (which stay in effect for anything you don't override). See
165
+ * `Control.enableArrowDrawing` etc. for what each shape configures.
166
+ */
167
+ export declare interface AnnotationToolbarStyles {
168
+ arrow?: Partial<Arrow["properties"]["style"]>;
169
+ box?: Partial<Box["properties"]["style"]>;
170
+ text?: Partial<Text_2["properties"]["style"]>;
171
+ polygon?: Partial<Polygon["properties"]["style"]>;
172
+ comment?: {
173
+ offsetX?: number;
174
+ offsetY?: number;
175
+ commentStyle?: Partial<CommentProps>;
176
+ arrowStyle?: Partial<ArrowProperties>;
177
+ };
178
+ stickyNote?: Partial<Text_2["properties"]["style"]>;
179
+ }
180
+
181
+ /** Types of annotations supported */
182
+ declare type AnnotationType = "arrow" | "text" | "box" | "comment" | "polygon";
183
+
184
+ /**
185
+ * Arrow annotation feature. Represents a directed line between two points,
186
+ * can connect a textbox to a shape.
187
+ */
188
+ declare interface Arrow extends AnnotationFeature<LineString, ArrowProperties> {
189
+ }
190
+
191
+ declare interface ArrowProperties extends AnnotationProps {
192
+ type: "arrow";
193
+ style?: ArrowStyles;
194
+ link?: Partial<Record<Side, ExportedLink>>;
195
+ }
196
+
197
+ /**
198
+ * Styles specific to arrow annotations.
199
+ */
200
+ declare interface ArrowStyles extends StrokeOptions {
201
+ /** Tail extremity style */
202
+ tail?: Extremity;
203
+ /** Head extremity style */
204
+ head?: Extremity;
205
+ }
206
+
207
+ /**
208
+ * Wires `control` events to show/hide callbacks. Returns a `detach` function
209
+ * that removes every listener it registered.
210
+ */
211
+ export declare function attachPanelVisibility(control: PanelVisibilityControl, { onShow, onHide }: PanelVisibilityHandlers): () => void;
212
+
213
+ export declare interface BackgroundOption {
214
+ value: string;
215
+ /** Inline style for the swatch's color circle. */
216
+ style: string;
217
+ }
218
+
219
+ export declare const BACKGROUNDS: BackgroundOption[];
220
+
221
+ /**
222
+ * Box annotation feature
223
+ */
224
+ declare interface Box extends AnnotationFeature<Point_2, BoxProperties> {
225
+ }
226
+
227
+ /**
228
+ * Arrow snapped to a rectangular annotation (text, box, comment).
229
+ * nx/ny are center-relative fractions multiplied by width/height:
230
+ * left-center = { nx: -0.5, ny: 0 }
231
+ * right-center = { nx: 0.5, ny: 0 }
232
+ * center = { nx: 0, ny: 0 }
233
+ */
234
+ declare type BoxMagnet = {
235
+ type: "box";
236
+ nx: number;
237
+ ny: number;
238
+ };
239
+
240
+ /** Properties specific to box annotations. */
241
+ declare interface BoxProperties extends AnnotationProps {
242
+ type: "box";
243
+ /** Width of the box */
244
+ width: number;
245
+ /** Height of the box */
246
+ height: number;
247
+ /** Style options for the box */
248
+ style?: BoxStyle;
249
+ }
250
+
251
+ /** Styles specific to box annotations. */
252
+ declare interface BoxStyle extends StrokeOptions {
253
+ /** background color: empty for transparent #f00, yellow...*/
254
+ background?: Color;
255
+ /** padding around the box */
256
+ padding?: number;
257
+ /** border radius */
258
+ borderRadius?: number;
259
+ /** if true, the box scales with zoom. Default is true */
260
+ scaled?: boolean;
261
+ /** box shadow in CSS format, e.g. "0px 4px 6px rgba(0, 0, 0, 0.1)" */
262
+ boxShadow?: string;
263
+ }
264
+
265
+ /** Event related to a single annotation feature */
266
+ declare interface ClickEvent {
267
+ /** Annotation ID involved in the event */
268
+ id?: Id;
269
+ /** Mouse position in pixel coordinates */
270
+ position: {
271
+ x: number;
272
+ y: number;
273
+ };
274
+ }
275
+
276
+ /**
277
+ * Any valid color format
278
+ */
279
+ declare type Color = HexColor | RgbColor | RgbaColor_2 | "transparent" | "none" | string;
280
+
281
+ /**
282
+ * Comment annotation type
283
+ * Geometry: Point (center position of comment box/icon)
284
+ *
285
+ * Note: Arrows are stored separately in Arrow features.
286
+ * Arrows reference comments via their link.start or link.end properties.
287
+ */
288
+ declare interface Comment_2 extends AnnotationFeature<Point_2, CommentProps> {
289
+ }
290
+
291
+ declare const COMMENT_MODE_COLLAPSED = "collapsed";
292
+
293
+ declare const COMMENT_MODE_EXPANDED = "expanded";
294
+
295
+ /**
296
+ * Properties for Comment annotations
297
+ *
298
+ * Comments are specialized annotations that:
299
+ * - Always maintain fixed screen-space size
300
+ * - Always have at least one arrow pointing TO them
301
+ * - Can be collapsed (icon) or expanded (text box)
302
+ * - Support multiple arrows pointing to them
303
+ */
304
+ declare interface CommentProps extends AnnotationProps {
305
+ type: "comment";
306
+ /** Text content (similar to text annotation) */
307
+ content: string;
308
+ /** Display mode: collapsed (icon) or expanded (text box) */
309
+ mode: typeof COMMENT_MODE_COLLAPSED | typeof COMMENT_MODE_EXPANDED;
310
+ /** Width in expanded mode (pixels) */
311
+ width: number;
312
+ /** Height (auto-grows with content, pixels) */
313
+ height: number;
314
+ /** Optional metadata */
315
+ author?: string;
316
+ timestamp?: Date;
317
+ /** Styling */
318
+ style?: CommentStyle;
319
+ }
320
+
321
+ /**
322
+ * Style configuration for Comment annotations
323
+ */
324
+ declare interface CommentStyle extends TextStyle {
325
+ /** Background color for collapsed icon (default: "#FFD700") */
326
+ iconColor?: Color;
327
+ /** Icon to display when collapsed (default: "💬") */
328
+ iconSymbol?: string;
329
+ /** Border color for collapsed icon */
330
+ iconBorderColor?: Color;
331
+ /** Border width for collapsed icon */
332
+ iconBorderWidth?: number;
333
+ /** Minimum height (default: 60px) */
334
+ minHeight?: number;
335
+ /** Maximum height before scrolling (default: 480px, undefined = no limit) */
336
+ maxHeight?: number;
337
+ /** Size when collapsed (default: 32px) */
338
+ iconSize?: number;
339
+ /** Zoom threshold below which comment auto-collapses (default: 0.5) */
340
+ collapseZoomThreshold?: number;
341
+ /** Show "send" button in edit mode (default: true) */
342
+ showSendButton?: boolean;
343
+ /** Auto-grow height with content (default: true) */
344
+ autoGrow?: boolean;
345
+ /** Show drop shadow on comment box (default: true) */
346
+ shadow?: boolean;
347
+ /** Expand to full width when selected (default: false) */
348
+ expandOnSelect?: boolean;
349
+ /**
350
+ * Connector-line behavior when the attachment point moves (default: "rigid").
351
+ * - "rigid": the comment translates by the same offset as the moved
352
+ * attachment point — the arrow keeps its length/angle, whole callout moves.
353
+ * - "elastic": the comment stays put; the arrow re-anchors to the nearest
354
+ * point on the comment box, so the line can stretch/rotate.
355
+ */
356
+ connectorMode?: "rigid" | "elastic";
357
+ }
358
+
359
+ /**
360
+ * Main controller class for managing annotations.
361
+ * It manages rendering and editing of annotations.
362
+ */
363
+ declare class Control extends default_2<FeatureEvents> {
364
+ private ogma;
365
+ private store;
366
+ private renderers;
367
+ private interactions;
368
+ private editor;
369
+ private links;
370
+ private index;
371
+ private drawing;
372
+ private snapping;
373
+ private selectionManager;
374
+ private historyManager;
375
+ private updateManager;
376
+ private commentManager;
377
+ constructor(ogma: Ogma, options?: Partial<ControllerOptions>);
378
+ private initializeRenderers;
379
+ private setupEvents;
380
+ private onRotate;
381
+ private onZoom;
382
+ private onLayout;
383
+ /**
384
+ * Set the options for the controller
385
+ * @param options new Options
386
+ * @returns the updated options
387
+ */
388
+ setOptions(options?: Partial<ControllerOptions>): {
389
+ showSendButton: boolean;
390
+ showEditButton: boolean;
391
+ sendButtonIcon: string;
392
+ editButtonIcon: string;
393
+ minArrowHeight: number;
394
+ maxArrowHeight: number;
395
+ detectMargin: number;
396
+ magnetRadius: number;
397
+ magnetHandleRadius: number;
398
+ textPlaceholder: string;
399
+ };
400
+ /**
401
+ * Add an annotation to the controller
402
+ * @param annotation The annotation to add
403
+ */
404
+ add(annotation: Annotation | AnnotationCollection): this;
405
+ /**
406
+ * Remove an annotation or an array of annotations from the controller
407
+ * @param annotation The annotation(s) to remove
408
+ */
409
+ remove(annotation: Annotation | AnnotationCollection): this;
410
+ /**
411
+ * Undo the last change
412
+ * @returns true if undo was successful, false if no changes to undo
413
+ */
414
+ undo(): boolean;
415
+ /**
416
+ * Redo the last undone change
417
+ * @returns true if redo was successful, false if no changes to redo
418
+ */
419
+ redo(): boolean;
420
+ /**
421
+ * Check if there are changes to undo
422
+ * @returns true if undo is possible
423
+ */
424
+ canUndo(): boolean;
425
+ /**
426
+ * Check if there are changes to redo
427
+ * @returns true if redo is possible
428
+ */
429
+ canRedo(): boolean;
430
+ /**
431
+ * Clear the undo/redo history
432
+ */
433
+ clearHistory(): void;
434
+ /**
435
+ * Get all annotations in the controller
436
+ * @returns A FeatureCollection containing all annotations
437
+ */
438
+ getAnnotations(): AnnotationCollection;
439
+ /**
440
+ * Select one or more annotations by id
441
+ * @param annotations The id(s) of the annotation(s) to select
442
+ * @returns this for chaining
443
+ */
444
+ select(annotations: Id | Id[]): this;
445
+ /**
446
+ * Unselect one or more annotations, or all if no ids provided
447
+ * @param annotations The id(s) of the annotation(s) to unselect, or undefined to unselect all
448
+ * @returns this for chaining
449
+ */
450
+ unselect(annotations?: Id | Id[]): this;
451
+ /**
452
+ * Cancel the current drawing operation
453
+ * @returns this for chaining
454
+ */
455
+ cancelDrawing(): this;
456
+ /**
457
+ * Enable arrow drawing mode - the recommended way to add arrows.
458
+ *
459
+ * Call this method when the user clicks an "Add Arrow" button. The control will:
460
+ * 1. Wait for the next mousedown event
461
+ * 2. Create an arrow at that position with the specified style
462
+ * 3. Start the interactive drawing process
463
+ * 4. Clean up automatically when done
464
+ *
465
+ * **This is the recommended API for 99% of use cases.** Only use `startArrow()`
466
+ * if you need to implement custom mouse handling or positioning logic.
467
+ *
468
+ * @example
469
+ * ```ts
470
+ * addArrowButton.addEventListener('click', () => {
471
+ * control.enableArrowDrawing({ strokeColor: '#3A03CF', strokeWidth: 2 });
472
+ * });
473
+ * ```
474
+ *
475
+ * @param style Arrow style options
476
+ * @returns this for chaining
477
+ * @see startArrow for low-level programmatic control
478
+ */
479
+ enableArrowDrawing(style?: Partial<Arrow["properties"]["style"]>): this;
480
+ /**
481
+ * Enable text drawing mode - the recommended way to add text annotations.
482
+ *
483
+ * Call this method when the user clicks an "Add Text" button. The control will:
484
+ * 1. Wait for the next mousedown event
485
+ * 2. Create a text box at that position with the specified style
486
+ * 3. Start the interactive drawing/editing process
487
+ * 4. Clean up automatically when done
488
+ *
489
+ * **This is the recommended API for 99% of use cases.** Only use `startText()`
490
+ * if you need to implement custom mouse handling or positioning logic.
491
+ *
492
+ * @example
493
+ * ```ts
494
+ * addTextButton.addEventListener('click', () => {
495
+ * control.enableTextDrawing({ color: '#3A03CF', fontSize: 24 });
496
+ * });
497
+ * ```
498
+ *
499
+ * @param style Text style options
500
+ * @returns this for chaining
501
+ * @see startText for low-level programmatic control
502
+ */
503
+ enableTextDrawing(style?: Partial<Text_2["properties"]["style"]>): this;
504
+ /**
505
+ * Enable box drawing mode - the recommended way to add boxes.
506
+ *
507
+ * Call this method when the user clicks an "Add Box" button. The control will:
508
+ * 1. Wait for the next mousedown event
509
+ * 2. Create a box at that position with the specified style
510
+ * 3. Start the interactive drawing process (drag to size)
511
+ * 4. Clean up automatically when done
512
+ *
513
+ * **This is the recommended API for 99% of use cases.** Only use `startBox()`
514
+ * if you need to implement custom mouse handling or positioning logic.
515
+ *
516
+ * @example
517
+ * ```ts
518
+ * addBoxButton.addEventListener('click', () => {
519
+ * control.enableBoxDrawing({ background: '#EDE6FF', borderRadius: 8 });
520
+ * });
521
+ * ```
522
+ *
523
+ * @param style Box style options
524
+ * @returns this for chaining
525
+ * @see startBox for low-level programmatic control
526
+ */
527
+ enableBoxDrawing(style?: Partial<Box["properties"]["style"]>): this;
528
+ /**
529
+ * Enable polygon drawing mode - the recommended way to add polygons.
530
+ *
531
+ * Call this method when the user clicks an "Add Polygon" button. The control will:
532
+ * 1. Wait for the next mousedown event
533
+ * 2. Create a polygon starting at that position with the specified style
534
+ * 3. Start the interactive drawing process (click points to draw shape)
535
+ * 4. Clean up automatically when done
536
+ *
537
+ * **This is the recommended API for 99% of use cases.** Only use `startPolygon()`
538
+ * if you need to implement custom mouse handling or positioning logic.
539
+ *
540
+ * @example
541
+ * ```ts
542
+ * addPolygonButton.addEventListener('click', () => {
543
+ * control.enablePolygonDrawing({ strokeColor: '#3A03CF', background: 'rgba(58, 3, 207, 0.15)' });
544
+ * });
545
+ * ```
546
+ *
547
+ * @param style Polygon style options
548
+ * @returns this for chaining
549
+ * @see startPolygon for low-level programmatic control
550
+ */
551
+ enablePolygonDrawing(style?: Partial<Polygon["properties"]["style"]>): this;
552
+ /**
553
+ * Enable comment drawing mode - the recommended way to add comments.
554
+ *
555
+ * Call this method when the user clicks an "Add Comment" button. The control will:
556
+ * 1. Wait for the next mousedown event
557
+ * 2. Create a comment with an arrow pointing to that position
558
+ * 3. Smart positioning: automatically finds the best placement for the comment box
559
+ * 4. Start the interactive editing process
560
+ * 5. Clean up automatically when done
561
+ *
562
+ * **This is the recommended API for 99% of use cases.** Only use `startComment()`
563
+ * if you need to implement custom mouse handling or positioning logic.
564
+ *
565
+ * @example
566
+ * ```ts
567
+ * addCommentButton.addEventListener('click', () => {
568
+ * control.enableCommentDrawing({
569
+ * commentStyle: { color: '#3A03CF', background: '#EDE6FF' },
570
+ * arrowStyle: { strokeColor: '#3A03CF', head: 'halo-dot' }
571
+ * });
572
+ * });
573
+ * ```
574
+ *
575
+ * @param options Drawing options including offsets and styles
576
+ * @param options.offsetX Manual X offset for comment placement (overrides smart positioning)
577
+ * @param options.offsetY Manual Y offset for comment placement (overrides smart positioning)
578
+ * @param options.commentStyle Style options for the comment box
579
+ * @param options.arrowStyle Style options for the arrow
580
+ * @returns this for chaining
581
+ * @see startComment for low-level programmatic control
582
+ */
583
+ enableCommentDrawing(options?: {
584
+ offsetX?: number;
585
+ offsetY?: number;
586
+ commentStyle?: Partial<CommentProps>;
587
+ arrowStyle?: Partial<ArrowProperties>;
588
+ }): this;
589
+ /**
590
+ * Enable sticky note drawing mode - drops a plain, resizable text box
591
+ * (empty content, "Quick note…" ghost placeholder, no connector arrow)
592
+ * like a Miro sticky note, unlike `enableCommentDrawing`. It's a regular
593
+ * `text` annotation, so it's placed the same interactive way as
594
+ * `enableBoxDrawing`/`enableTextDrawing`: click for a default-size square,
595
+ * or drag to size it - either way it keeps the usual corner/edge drag
596
+ * handles to resize it afterward.
597
+ *
598
+ * Call this method when the user clicks an "Add sticky note" button. The
599
+ * control will:
600
+ * 1. Wait for the next mousedown event
601
+ * 2. Create the note at that position and start the interactive
602
+ * corner-drag, already selected
603
+ * 3. On release: a plain click (no drag) gets a default square size, a
604
+ * drag gets sized to match instead - either way it drops straight
605
+ * into editing (the placeholder is just ghost text, so typing
606
+ * immediately replaces it)
607
+ * 4. Clean up automatically when done
608
+ *
609
+ * @example
610
+ * ```ts
611
+ * addStickyNoteButton.addEventListener('click', () => {
612
+ * control.enableStickyNoteDrawing({ background: '#FFEB99' });
613
+ * });
614
+ * ```
615
+ *
616
+ * @param style Sticky note style options (merged over the sticky note defaults)
617
+ * @returns this for chaining
618
+ * @see startStickyNote for low-level programmatic control
619
+ */
620
+ enableStickyNoteDrawing(style?: Partial<Text_2["properties"]["style"]>): this;
621
+ /**
622
+ * Enable erase mode: every click on an annotation deletes it immediately.
623
+ * Stays armed across multiple clicks until `disableEraseMode()` is called,
624
+ * or another drawing tool is enabled / `cancelDrawing()` is called.
625
+ *
626
+ * @returns this for chaining
627
+ * @see disableEraseMode to turn erase mode off
628
+ */
629
+ enableEraseMode(): this;
630
+ /** Turn erase mode off. No-op if it isn't active. */
631
+ disableEraseMode(): this;
632
+ /** Whether erase mode is currently active. */
633
+ isEraseModeActive(): boolean;
634
+ /**
635
+ * Place a pre-created annotation by moving it with the cursor.
636
+ * The annotation follows the mouse until the user clicks to place it.
637
+ * Press Escape to cancel.
638
+ *
639
+ * @param annotation The text or box annotation to place
640
+ * @returns this for chaining
641
+ */
642
+ enablePlacement(annotation: Text_2 | Box): this;
643
+ /**
644
+ * **Advanced API:** Programmatically start drawing a comment at specific coordinates.
645
+ *
646
+ * This is a low-level method that gives you full control over the drawing process.
647
+ * You must handle mouse events and create the comment object yourself.
648
+ *
649
+ * **For most use cases, use `enableCommentDrawing()` instead** - it handles all
650
+ * mouse events and annotation creation automatically.
651
+ *
652
+ * Use this method only when you need:
653
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
654
+ * - Programmatic placement without user interaction
655
+ * - Integration with custom UI frameworks
656
+ *
657
+ * @example
658
+ * ```ts
659
+ * // Custom cursor example
660
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
661
+ * ogma.events.once('mousedown', (evt) => {
662
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
663
+ * const comment = createComment(x, y, 'My comment', { color: '#3A03CF' });
664
+ * control.startComment(x, y, comment);
665
+ * });
666
+ * ```
667
+ *
668
+ * @param x X coordinate to start drawing
669
+ * @param y Y coordinate to start drawing
670
+ * @param comment The comment annotation to add
671
+ * @param options Drawing options including offsets and styles
672
+ * @returns this for chaining
673
+ * @see enableCommentDrawing for the recommended high-level API
674
+ */
675
+ startComment(x: number, y: number, comment: Comment_2, options?: {
676
+ offsetX?: number;
677
+ offsetY?: number;
678
+ commentStyle?: Partial<CommentProps>;
679
+ arrowStyle?: Partial<ArrowProperties>;
680
+ }): this;
681
+ /**
682
+ * **Advanced API:** Programmatically start drawing a sticky note at
683
+ * specific coordinates - same interactive corner-drag as `startBox`.
684
+ * You must handle mouse events yourself (or immediately release/complete
685
+ * it via the same events `enableStickyNoteDrawing` would).
686
+ *
687
+ * **For most use cases, use `enableStickyNoteDrawing()` instead.**
688
+ *
689
+ * @param x X coordinate for the note's top-left corner
690
+ * @param y Y coordinate for the note's top-left corner
691
+ * @param style Sticky note style options
692
+ * @returns this for chaining
693
+ * @see enableStickyNoteDrawing for the recommended high-level API
694
+ */
695
+ startStickyNote(x: number, y: number, style?: Partial<Text_2["properties"]["style"]>): this;
696
+ /**
697
+ * **Advanced API:** Programmatically start drawing a box at specific coordinates.
698
+ *
699
+ * This is a low-level method that gives you full control over the drawing process.
700
+ * You must handle mouse events and optionally create the box object yourself.
701
+ *
702
+ * **For most use cases, use `enableBoxDrawing()` instead** - it handles all
703
+ * mouse events and annotation creation automatically.
704
+ *
705
+ * Use this method only when you need:
706
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
707
+ * - Programmatic placement without user interaction
708
+ * - Integration with custom UI frameworks
709
+ *
710
+ * @example
711
+ * ```ts
712
+ * // Custom cursor example
713
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
714
+ * ogma.events.once('mousedown', (evt) => {
715
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
716
+ * const box = createBox(x, y, 100, 50, { background: '#EDE6FF' });
717
+ * control.startBox(x, y, box);
718
+ * });
719
+ * ```
720
+ *
721
+ * @param x X coordinate for the box origin
722
+ * @param y Y coordinate for the box origin
723
+ * @param box The box annotation to add (optional, will be created if not provided)
724
+ * @returns this for chaining
725
+ * @see enableBoxDrawing for the recommended high-level API
726
+ */
727
+ startBox(x: number, y: number, box?: Box): this;
728
+ /**
729
+ * **Advanced API:** Programmatically start drawing an arrow at specific coordinates.
730
+ *
731
+ * This is a low-level method that gives you full control over the drawing process.
732
+ * You must handle mouse events and optionally create the arrow object yourself.
733
+ *
734
+ * **For most use cases, use `enableArrowDrawing()` instead** - it handles all
735
+ * mouse events and annotation creation automatically.
736
+ *
737
+ * Use this method only when you need:
738
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
739
+ * - Programmatic placement without user interaction
740
+ * - Integration with custom UI frameworks
741
+ *
742
+ * @example
743
+ * ```ts
744
+ * // Custom cursor example
745
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
746
+ * ogma.events.once('mousedown', (evt) => {
747
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
748
+ * const arrow = createArrow(x, y, x, y, { strokeColor: '#3A03CF' });
749
+ * control.startArrow(x, y, arrow);
750
+ * });
751
+ * ```
752
+ *
753
+ * @param x X coordinate for the arrow start
754
+ * @param y Y coordinate for the arrow start
755
+ * @param arrow The arrow annotation to add (optional, will be created if not provided)
756
+ * @returns this for chaining
757
+ * @see enableArrowDrawing for the recommended high-level API
758
+ */
759
+ startArrow(x: number, y: number, arrow?: Arrow): this;
760
+ /**
761
+ * **Advanced API:** Programmatically start drawing a text annotation at specific coordinates.
762
+ *
763
+ * This is a low-level method that gives you full control over the drawing process.
764
+ * You must handle mouse events and optionally create the text object yourself.
765
+ *
766
+ * **For most use cases, use `enableTextDrawing()` instead** - it handles all
767
+ * mouse events and annotation creation automatically.
768
+ *
769
+ * Use this method only when you need:
770
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
771
+ * - Programmatic placement without user interaction
772
+ * - Integration with custom UI frameworks
773
+ *
774
+ * @example
775
+ * ```ts
776
+ * // Custom cursor example
777
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
778
+ * ogma.events.once('mousedown', (evt) => {
779
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
780
+ * const text = createText(x, y, 0, 0, 'Hello', { color: '#3A03CF' });
781
+ * control.startText(x, y, text);
782
+ * });
783
+ * ```
784
+ *
785
+ * @param x X coordinate for the text
786
+ * @param y Y coordinate for the text
787
+ * @param text The text annotation to add (optional, will be created if not provided)
788
+ * @returns this for chaining
789
+ * @see enableTextDrawing for the recommended high-level API
790
+ */
791
+ startText(x: number, y: number, text?: Text_2): this;
792
+ /**
793
+ * **Advanced API:** Programmatically start drawing a polygon at specific coordinates.
794
+ *
795
+ * This is a low-level method that gives you full control over the drawing process.
796
+ * You must handle mouse events and create the polygon object yourself.
797
+ *
798
+ * **For most use cases, use `enablePolygonDrawing()` instead** - it handles all
799
+ * mouse events and annotation creation automatically.
800
+ *
801
+ * Use this method only when you need:
802
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
803
+ * - Programmatic placement without user interaction
804
+ * - Integration with custom UI frameworks
805
+ *
806
+ * @example
807
+ * ```ts
808
+ * // Custom cursor example
809
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
810
+ * ogma.events.once('mousedown', (evt) => {
811
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
812
+ * const polygon = createPolygon([[[x, y]]], { strokeColor: '#3A03CF' });
813
+ * control.startPolygon(x, y, polygon);
814
+ * });
815
+ * ```
816
+ *
817
+ * @param x X coordinate to start drawing
818
+ * @param y Y coordinate to start drawing
819
+ * @param polygon The polygon annotation to add
820
+ * @returns this for chaining
821
+ * @see enablePolygonDrawing for the recommended high-level API
822
+ */
823
+ startPolygon(x: number, y: number, polygon: Polygon): this;
824
+ /**
825
+ * Get the currently selected annotations as a collection
826
+ * @returns A FeatureCollection of selected annotations
827
+ */
828
+ getSelectedAnnotations(): AnnotationCollection;
829
+ /**
830
+ * Get the first selected annotation (for backwards compatibility)
831
+ * @returns The currently selected annotation, or null if none selected
832
+ */
833
+ getSelected(): Annotation | null;
834
+ /**
835
+ * Get a specific annotation by id
836
+ * @param id The id of the annotation to retrieve
837
+ * @returns The annotation with the given id, or undefined if not found
838
+ */
839
+ getAnnotation<T = Annotation>(id: Id): T | undefined;
840
+ /**
841
+ * Scale an annotation by a given factor around an origin point
842
+ * @param id The id of the annotation to scale
843
+ * @param scale The scale factor
844
+ * @param ox Origin x coordinate
845
+ * @param oy Origin y coordinate
846
+ * @returns this for chaining
847
+ */
848
+ setScale(id: Id, scale: number, ox: number, oy: number): this;
849
+ /**
850
+ * Toggle a comment between collapsed and expanded mode
851
+ * @param id The id of the comment to toggle
852
+ * @returns this for chaining
853
+ */
854
+ toggleComment(id: Id): this;
855
+ /**
856
+ * Destroy the controller and its elements
857
+ */
858
+ destroy(): void;
859
+ /**
860
+ * Update the style of the annotation with the given id
861
+ * @param id The id of the annotation to update
862
+ * @param style The new style
863
+ */
864
+ updateStyle<A extends Annotation>(id: Id, style: A["properties"]["style"]): this;
865
+ /**
866
+ * Update an annotation with partial updates
867
+ *
868
+ * This method allows you to update any properties of an annotation, including
869
+ * geometry, properties, and style. Updates are merged with existing data.
870
+ *
871
+ * @param annotation Partial annotation object with id and properties to update
872
+ * @returns this for chaining
873
+ *
874
+ * @example
875
+ * ```ts
876
+ * // Update arrow geometry
877
+ * controller.update({
878
+ * id: arrowId,
879
+ * geometry: {
880
+ * type: 'LineString',
881
+ * coordinates: [[0, 0], [200, 200]]
882
+ * }
883
+ * });
884
+ *
885
+ * // Update text content and position
886
+ * controller.update({
887
+ * id: textId,
888
+ * geometry: {
889
+ * type: 'Point',
890
+ * coordinates: [100, 100]
891
+ * },
892
+ * properties: {
893
+ * content: 'Updated text'
894
+ * }
895
+ * });
896
+ *
897
+ * // Update style only (prefer updateStyle for style-only updates)
898
+ * controller.update({
899
+ * id: boxId,
900
+ * properties: {
901
+ * style: {
902
+ * background: '#ff0000'
903
+ * }
904
+ * }
905
+ * });
906
+ * ```
907
+ */
908
+ update<A extends Annotation>(annotation: DeepPartial<A> & {
909
+ id: Id;
910
+ }): this;
911
+ /**
912
+ * Attach an arrow to a node at the specified side
913
+ * @param arrowId
914
+ * @param targetNode
915
+ * @param side
916
+ */
917
+ link(arrowId: Id, targetNode: Node_2, side: Side): this;
918
+ /**
919
+ * Attach an arrow to an annotation at the specified side
920
+ * @param arrowId
921
+ * @param target
922
+ * @param side
923
+ */
924
+ link(arrowId: Id, target: Id, side: Side): this;
925
+ isDrawing(): boolean;
926
+ }
927
+
928
+ /**
929
+ * Options for the annotations control
930
+ */
931
+ declare type ControllerOptions = {
932
+ /**
933
+ * The radius in which arrows are attracted
934
+ */
935
+ magnetRadius: number;
936
+ /**
937
+ * The margin in which the Texts are detected when looking for magnet points
938
+ */
939
+ detectMargin: number;
940
+ /**
941
+ * Display size of the magnet point
942
+ */
943
+ magnetHandleRadius: number;
944
+ /**
945
+ * Placeholder for the text input
946
+ */
947
+ textPlaceholder: string;
948
+ /**
949
+ * Show send button in text editor
950
+ */
951
+ showSendButton: boolean;
952
+ /**
953
+ * Show edit button in text editor
954
+ */
955
+ showEditButton: boolean;
956
+ /**
957
+ * SVG icon for the send button in text editor
958
+ * Should be a complete SVG string (e.g., '<svg>...</svg>')
959
+ */
960
+ sendButtonIcon: string;
961
+ /**
962
+ * SVG icon for the edit button in text editor
963
+ * Should be a complete SVG string (e.g., '<svg>...</svg>')
964
+ */
965
+ editButtonIcon: string;
966
+ /**
967
+ * Minimum height of the arrow in units
968
+ */
969
+ minArrowHeight: number;
970
+ /**
971
+ * Maximum height of the arrow in units
972
+ */
973
+ maxArrowHeight: number;
974
+ };
975
+
976
+ /**
977
+ * Registers `<rgba-color-picker>` if it isn't already, then returns a fresh
978
+ * instance. Safe to call repeatedly and from multiple module copies.
979
+ */
980
+ export declare function createRgbaColorPicker(): RgbaColorPicker;
981
+
982
+ declare type DeepPartial<T> = {
983
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
984
+ };
985
+
986
+ export declare const DEFAULT_PANEL_ORIENTATION: PanelOrientation;
987
+
988
+ /** Preserves the panel's original vertically-centered, right-docked look. */
989
+ export declare const DEFAULT_PANEL_PLACEMENT: PanelPlacement;
990
+
991
+ /** Default palette used to seed the recent-colors strip. */
992
+ export declare const DEFAULT_RECENT_COLORS: string[];
993
+
994
+ /**
995
+ * Which deletion control(s) the toolbar shows - `"erase"` (default) deletes
996
+ * on click via the erase tool; `"select"` selects an annotation then deletes
997
+ * it with the trash button; `"both"` shows both, since they serve slightly
998
+ * different workflows.
999
+ */
1000
+ export declare type DeleteMode = "select" | "erase" | "both";
1001
+
1002
+ /** Event related to a single annotation feature */
1003
+ declare interface DragEvent_2 {
1004
+ /** Annotation ID involved in the event */
1005
+ id: Id;
1006
+ /** Current mouse position in pixel coordinates during the drag */
1007
+ position: {
1008
+ x: number;
1009
+ y: number;
1010
+ };
1011
+ }
1012
+
1013
+ /** Arrow snapped at parametric position t (0–1) along an edge path. */
1014
+ declare type EdgeMagnet = {
1015
+ type: "edge";
1016
+ t: number;
1017
+ };
1018
+
1019
+ declare const EVT_ADD = "add";
1020
+
1021
+ declare const EVT_CANCEL_DRAWING = "cancelDrawing";
1022
+
1023
+ declare const EVT_CLICK = "click";
1024
+
1025
+ declare const EVT_COMPLETE_DRAWING = "completeDrawing";
1026
+
1027
+ declare const EVT_DRAG_END = "dragend";
1028
+
1029
+ declare const EVT_DRAG_START = "dragstart";
1030
+
1031
+ declare const EVT_HISTORY = "history";
1032
+
1033
+ declare const EVT_LINK = "link";
1034
+
1035
+ declare const EVT_REMOVE = "remove";
1036
+
1037
+ declare const EVT_SELECT = "select";
1038
+
1039
+ declare const EVT_UNSELECT = "unselect";
1040
+
1041
+ declare const EVT_UPDATE = "update";
1042
+
1043
+ /**
1044
+ * Serialized link stored inside arrow.properties.link.
1045
+ * Uses plain { x, y } for backward compatibility with saved annotations.
1046
+ * Converted to the internal Magnet type by Links.add().
1047
+ */
1048
+ declare type ExportedLink = {
1049
+ id: Id;
1050
+ side: Side;
1051
+ type: TargetType;
1052
+ magnet?: Point;
1053
+ };
1054
+
1055
+ /** Extremity types for arrow annotations. */
1056
+ declare type Extremity = "none" | "arrow" | "arrow-plain" | "dot" | "halo-dot";
1057
+
1058
+ export declare const EXTREMITY_OPTIONS: ExtremityOption[];
1059
+
1060
+ export declare interface ExtremityOption {
1061
+ value: string;
1062
+ label: string;
1063
+ icon: IconName;
1064
+ }
1065
+
1066
+ /** Event related to a single annotation feature */
1067
+ declare interface FeatureEvent {
1068
+ /** Annotation ID involved in the event */
1069
+ id: Id;
1070
+ }
1071
+
1072
+ declare type FeatureEvents = {
1073
+ /**
1074
+ * Event trigerred when selecting an annotation
1075
+ * @param evt The annotation selected
1076
+ */
1077
+ [EVT_SELECT]: (evt: FeaturesEvent) => void;
1078
+ /**
1079
+ * Event trigerred when unselecting an annotation
1080
+ * @param evt The annotation unselected
1081
+ */
1082
+ [EVT_UNSELECT]: (evt: FeaturesEvent) => void;
1083
+ /**
1084
+ * Event trigerred when removing an annotation
1085
+ * @param evt The annotation removed
1086
+ */
1087
+ [EVT_REMOVE]: (evt: FeatureEvent) => void;
1088
+ /**
1089
+ * Event trigerred when adding an annotation
1090
+ * @param evt The annotation added
1091
+ */
1092
+ [EVT_ADD]: (evt: FeatureEvent) => void;
1093
+ /**
1094
+ * Event trigerred when canceling drawing mode
1095
+ */
1096
+ [EVT_CANCEL_DRAWING]: () => void;
1097
+ /**
1098
+ * Event trigerred when completing a drawing operation
1099
+ * @param evt Contains the ID of the completed annotation
1100
+ */
1101
+ [EVT_COMPLETE_DRAWING]: (evt: FeatureEvent) => void;
1102
+ /**
1103
+ * Event trigerred when updating an annotation.
1104
+ * This fires after any modification including drag operations, style changes, scaling, etc.
1105
+ * @param evt The updated annotation with all changes applied
1106
+ */
1107
+ [EVT_UPDATE]: (evt: Annotation) => void;
1108
+ /**
1109
+ * Event trigerred when linking an arrow to a node or annotation
1110
+ * @param evt Contains the arrow and link details
1111
+ */
1112
+ [EVT_LINK]: (evt: {
1113
+ arrow: Arrow;
1114
+ link: Link;
1115
+ }) => void;
1116
+ /**
1117
+ * Event trigerred when history state changes (after undo/redo operations)
1118
+ * @param evt Contains boolean flags for undo/redo availability
1119
+ */
1120
+ [EVT_HISTORY]: (evt: HistoryEvent) => void;
1121
+ /**
1122
+ * Event triggered when a drag operation starts on an annotation
1123
+ */
1124
+ [EVT_DRAG_START]: (evt: DragEvent_2) => void;
1125
+ /**
1126
+ * Event triggered when a drag operation ends on an annotation
1127
+ */
1128
+ [EVT_DRAG_END]: (evt: DragEvent_2) => void;
1129
+ /**
1130
+ * Event triggered when a click completes on an annotation (mouseup without drag)
1131
+ */
1132
+ [EVT_CLICK]: (evt: ClickEvent) => void;
1133
+ };
1134
+
1135
+ /** Event related to multiple annotation features */
1136
+ declare interface FeaturesEvent {
1137
+ /** Annotation IDs involved in the event */
1138
+ ids: Id[];
1139
+ }
1140
+
1141
+ export declare interface FontOption {
1142
+ value: string;
1143
+ label: string;
1144
+ /** Icon name from the shared icon set (see `ui/icons`). */
1145
+ icon: IconName;
1146
+ }
1147
+
1148
+ export declare const FONTS: FontOption[];
1149
+
1150
+ /**
1151
+ * Hex color string in format #RGB or #RRGGBB
1152
+ * @example "#fff" | "#ffffff" | "#F0A" | "#FF00AA"
1153
+ */
1154
+ declare type HexColor = `#${string}`;
1155
+
1156
+ /** History stack change event */
1157
+ declare interface HistoryEvent {
1158
+ /** Indicates if undo operation is available */
1159
+ canUndo: boolean;
1160
+ /** Indicates if redo operation is available */
1161
+ canRedo: boolean;
1162
+ }
1163
+
1164
+ /** Inner SVG markup for each icon (paths only; no <svg> wrapper). */
1165
+ export declare const ICON_PATHS: Record<IconName, string>;
1166
+
1167
+ /**
1168
+ * Inline SVG icon set shared by the vanilla and React UI.
1169
+ *
1170
+ * Each entry is the *inner* markup of a 24x24 lucide icon (stroke-based,
1171
+ * `currentColor`). The vanilla panel wraps these with `svgIcon()`; the React
1172
+ * package wraps the same paths in a small `<Icon>` component. Keeping the path
1173
+ * data here means consumers need no icon font and no `lucide-react` runtime
1174
+ * dependency.
1175
+ *
1176
+ * Source: lucide.dev (ISC license).
1177
+ */
1178
+ export declare type IconName = "chevron-down" | "x" | "arrow-left" | "arrow-right" | "play" | "circle-dot" | "dot" | "circle" | "circle-dashed" | "type" | "italic" | "code" | "trash" | "undo" | "redo" | "pentagon" | "rectangle-horizontal" | "message-square" | "sticky-note" | "eraser" | "download" | "camera" | "rotate-cw" | "rotate-ccw" | "minimize";
1179
+
1180
+ /** Unique identifier type for annotations */
1181
+ declare type Id = string | number;
1182
+
1183
+ export declare function initialRecentColors(): RecentColorsState;
1184
+
1185
+ export declare const LINE_TYPES: LineTypeOption[];
1186
+
1187
+ export declare interface LineTypeOption {
1188
+ value: string;
1189
+ icon: IconName;
1190
+ }
1191
+
1192
+ /** Link between an arrow and a text or node */
1193
+ declare interface Link {
1194
+ /** arrow attached to the text or node */
1195
+ arrow: Id;
1196
+ /** id of the text the arrow is attached to */
1197
+ id: Id;
1198
+ /** On which end the arrow is tighten to the text */
1199
+ side: Side;
1200
+ /** id of the text or node the arrow is attached to */
1201
+ target: Id;
1202
+ /** Text or node */
1203
+ targetType: TargetType;
1204
+ /** Typed snap point — semantics depend on targetType, see Magnet union. */
1205
+ magnet: Magnet;
1206
+ }
1207
+
1208
+ declare type Magnet = NodeMagnet | EdgeMagnet | BoxMagnet | PolygonMagnet;
1209
+
1210
+ export declare const MAX_RECENT_COLORS = 3;
1211
+
1212
+ /** Arrow snapped to the center or perimeter of a node. */
1213
+ declare type NodeMagnet = {
1214
+ type: "node";
1215
+ center: boolean;
1216
+ };
1217
+
1218
+ /** Whether panel sections stack top-to-bottom or run left-to-right. */
1219
+ export declare type PanelOrientation = "vertical" | "horizontal";
1220
+
1221
+ /**
1222
+ * Placement and orientation options shared by the vanilla `AnnotationPanel`
1223
+ * and the React panel/controller. Both are applied as `data-placement` /
1224
+ * `data-orientation` attributes on the panel root, consumed by the rules in
1225
+ * `ui/styles.css` — no inline layout styles are set from JS.
1226
+ */
1227
+ /** Which screen edge/corner the panel docks to. */
1228
+ export declare type PanelPlacement = "left" | "right" | "top" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right";
1229
+
1230
+ /**
1231
+ * The slice of `Control` this state machine relies on. Declared structurally so
1232
+ * the function does not pull the full `Control` type into the `/ui` entry's
1233
+ * rolled declarations (which would otherwise create a duplicate, incompatible
1234
+ * `Control` identity for consumers).
1235
+ */
1236
+ export declare interface PanelVisibilityControl {
1237
+ on(event: string, handler: (...args: any[]) => void): unknown;
1238
+ off(event: string, handler: (...args: any[]) => void): unknown;
1239
+ once(event: string, handler: (...args: any[]) => void): unknown;
1240
+ getAnnotation(id: string | number): Annotation | undefined;
1241
+ isDrawing(): boolean;
1242
+ }
1243
+
1244
+ export declare interface PanelVisibilityHandlers {
1245
+ /** Called when the panel should be shown for `annotation`. */
1246
+ onShow: (annotation: Annotation) => void;
1247
+ /** Called when the panel should be hidden. */
1248
+ onHide: () => void;
1249
+ }
1250
+
1251
+ /** 2D coordinate */
1252
+ declare type Point = {
1253
+ x: number;
1254
+ y: number;
1255
+ };
1256
+
1257
+ /**
1258
+ * Polygon placed on the graph, use it to highlight areas
1259
+ */
1260
+ declare interface Polygon extends AnnotationFeature<Polygon_2, PolygonProperties> {
1261
+ }
1262
+
1263
+ /**
1264
+ * Arrow snapped to a polygon annotation.
1265
+ * rx/ry are 0–1 fractions of the polygon's bounding box from its top-left corner.
1266
+ */
1267
+ declare type PolygonMagnet = {
1268
+ type: "polygon";
1269
+ rx: number;
1270
+ ry: number;
1271
+ };
1272
+
1273
+ declare interface PolygonProperties extends AnnotationProps {
1274
+ type: "polygon";
1275
+ style?: PolygonStyle;
1276
+ }
1277
+
1278
+ declare interface PolygonStyle extends BoxStyle {
1279
+ }
1280
+
1281
+ export declare interface RecentColorsState {
1282
+ colors: string[];
1283
+ /** Index of the currently active swatch. */
1284
+ activeIndex: number;
1285
+ }
1286
+
1287
+ /** Channel-wise rgba, matching the shape emitted by `vanilla-colorful`. */
1288
+ export declare interface RgbaChannels {
1289
+ r: number;
1290
+ g: number;
1291
+ b: number;
1292
+ a: number;
1293
+ }
1294
+
1295
+ /** Channel-wise rgba color, as read/written by the picker's `color` property. */
1296
+ export declare interface RgbaColor {
1297
+ r: number;
1298
+ g: number;
1299
+ b: number;
1300
+ a: number;
1301
+ }
1302
+
1303
+ /**
1304
+ * RGBA color string in format rgba(r, g, b, a)
1305
+ * @example "rgba(255, 0, 0, 1)" | "rgba(128, 128, 128, 0.5)"
1306
+ */
1307
+ declare type RgbaColor_2 = `rgba(${number}, ${number}, ${number}, ${number})` | `rgba(${number},${number},${number},${number})`;
1308
+
1309
+ /**
1310
+ * The public surface of the `<rgba-color-picker>` element we rely on. Declared
1311
+ * locally (rather than re-exporting `vanilla-colorful`'s class type) so that
1312
+ * consumers don't have to resolve the package's deep `lib/entrypoints` types,
1313
+ * which it does not expose via its `exports` map.
1314
+ */
1315
+ export declare interface RgbaColorPicker extends HTMLElement {
1316
+ color: RgbaColor;
1317
+ addEventListener(type: "color-changed", listener: (event: CustomEvent<{
1318
+ value: RgbaColor;
1319
+ }>) => void): void;
1320
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
1321
+ }
1322
+
1323
+ /** Serializes an rgba object (as emitted by the color picker) to a CSS string. */
1324
+ export declare function rgbaToString(color: RgbaChannels): string;
1325
+
1326
+ /**
1327
+ * RGB color string in format rgb(r, g, b)
1328
+ * @example "rgb(255, 0, 0)" | "rgb(128, 128, 128)"
1329
+ */
1330
+ declare type RgbColor = `rgb(${number}, ${number}, ${number})` | `rgb(${number},${number},${number})`;
1331
+
1332
+ declare type Side = typeof SIDE_START | typeof SIDE_END;
1333
+
1334
+ declare const SIDE_END: "end";
1335
+
1336
+ declare const SIDE_START: "start";
1337
+
1338
+ /** Stroke style options for annotations */
1339
+ declare type StrokeOptions = {
1340
+ /** Type of stroke: plain, dashed, or none */
1341
+ strokeType?: StrokeType;
1342
+ /** Stroke color: #f00, yellow... */
1343
+ strokeColor?: Color;
1344
+ /** Stroke width */
1345
+ strokeWidth?: number;
1346
+ };
1347
+
1348
+ /** Stroke types available for annotations */
1349
+ declare type StrokeType = "plain" | "dashed" | "none";
1350
+
1351
+ /**
1352
+ * Returns a complete `<svg>` string for the named icon, ready to drop into
1353
+ * `innerHTML`. Used by the vanilla panel.
1354
+ */
1355
+ export declare function svgIcon(name: IconName, size?: number): string;
1356
+
1357
+ /** @private */
1358
+ declare const TARGET_TYPES: {
1359
+ TEXT: "text";
1360
+ NODE: "node";
1361
+ BOX: "box";
1362
+ COMMENT: "comment";
1363
+ POLYGON: "polygon";
1364
+ ANNOTATION: "annotation";
1365
+ EDGE: "edge";
1366
+ };
1367
+
1368
+ declare type TargetType = (typeof TARGET_TYPES)[keyof typeof TARGET_TYPES];
1369
+
1370
+ /**
1371
+ * Text annotation feature, represents a text box at a specific position
1372
+ */
1373
+ declare interface Text_2 extends AnnotationFeature<Point_2, TextProperties> {
1374
+ }
1375
+
1376
+ declare interface TextProperties extends Omit<BoxProperties, "type"> {
1377
+ type: "text";
1378
+ /**text to display*/
1379
+ content: string;
1380
+ /** Width of the text box */
1381
+ width: number;
1382
+ /** Height of the text box */
1383
+ height: number;
1384
+ style?: TextStyle;
1385
+ }
1386
+
1387
+ declare interface TextStyle extends BoxStyle {
1388
+ /** Helvetica, sans-serif... */
1389
+ font?: string;
1390
+ /** Font size, in pixels */
1391
+ fontSize?: number | string;
1392
+ /** text color: #f00, yellow...*/
1393
+ color?: Color;
1394
+ /** background color: empty for transparent #f00, yellow...*/
1395
+ background?: Color;
1396
+ /** padding around the text */
1397
+ padding?: number;
1398
+ /** Text box border radius */
1399
+ borderRadius?: number;
1400
+ /** When true, text maintains constant size regardless of zoom level */
1401
+ fixedSize?: boolean;
1402
+ /**
1403
+ * Ghost text shown (via the textarea's native `placeholder` attribute)
1404
+ * while `content` is empty - disappears the instant the user types, no
1405
+ * selection/focus tricks needed. Overrides the global
1406
+ * `ControllerOptions.textPlaceholder` for this annotation.
1407
+ */
1408
+ placeholder?: string;
1409
+ }
1410
+
1411
+ /** One of the toolbar's drawing tools - see `enabledTypes`. */
1412
+ export declare type ToolbarDrawingType = "arrow" | "comment" | "sticky-note" | "box" | "text" | "polygon";
1413
+
1414
+ /**
1415
+ * Given the current recent-colors state and a color coming from the selected
1416
+ * annotation, returns the next state: if the color is already known it becomes
1417
+ * active, otherwise it is unshifted to the front (capped at MAX_RECENT_COLORS).
1418
+ *
1419
+ * Pure — callers (React/vanilla) hold the state and apply the result.
1420
+ */
1421
+ export declare function withColorFromAnnotation(state: RecentColorsState, color: string): RecentColorsState;
1422
+
1423
+ export { }