@linkurious/ogma-annotations 1.1.27 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,41 +1,71 @@
1
1
  import { BBox } from 'geojson';
2
2
  import { default as default_2 } from 'eventemitter3';
3
- import { default as default_3 } from '@linkurious/ogma';
4
3
  import { Feature } from 'geojson';
5
4
  import { FeatureCollection } from 'geojson';
6
5
  import { Geometry } from 'geojson';
7
6
  import { GeometryObject } from 'geojson';
8
7
  import { LineString } from 'geojson';
9
- import { Options } from '@linkurious/ogma';
10
- import { Overlay } from '@linkurious/ogma';
11
- import { Point as Point_2 } from '@linkurious/ogma';
12
- import { Polygon } from 'geojson';
8
+ import { Node as Node_2 } from '@linkurious/ogma';
9
+ import { Ogma } from '@linkurious/ogma';
10
+ import { Point as Point_2 } from 'geojson';
11
+ import { Point as Point_3 } from '@linkurious/ogma';
12
+ import { Polygon as Polygon_2 } from 'geojson';
13
13
  import { Position } from 'geojson';
14
- import { SVGLayer } from '@linkurious/ogma';
14
+ import { Size } from '@linkurious/ogma';
15
15
 
16
- export declare type Annotation = Arrow | Text_2;
16
+ /**
17
+ * Automatically lightens or darkens a color (hex or rgba) for highlight purposes.
18
+ * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
19
+ * @param amount - Amount to lighten/darken (default 20 for lighter and -10 for darker)
20
+ * @returns Highlighted color in rgba format
21
+ */
22
+ export declare function adjustColorBrightness(color: Color, amount: number): RgbaColor;
23
+
24
+ /** Union type of all Annotation features */
25
+ export declare type Annotation = Arrow | Box | Text_2 | Comment_2 | Polygon;
17
26
 
27
+ /** Collection of Annotations, GeoJSON FeatureCollection */
18
28
  export declare interface AnnotationCollection extends FeatureCollection {
19
- features: (Arrow | Text_2)[];
29
+ features: Annotation[];
20
30
  }
21
31
 
32
+ /**
33
+ * Base interface for all annotation features.
34
+ * @template G - Geometry type
35
+ * @template P - Properties type
36
+ */
22
37
  export declare interface AnnotationFeature<G extends GeometryObject = GeometryObject, P = AnnotationProps> extends Feature<G, P> {
23
- id: string | number;
38
+ /** Unique identifier for the annotation */
39
+ id: Id;
24
40
  }
25
41
 
42
+ /** Function type to get an Annotation by its id */
43
+ export declare type AnnotationGetter = (id: Id) => Annotation | undefined;
44
+
26
45
  export declare type AnnotationOptions = {
27
46
  handleSize: number;
28
- placeholder: string;
47
+ placeholder?: string;
29
48
  };
30
49
 
50
+ /**
51
+ * Base properties for all annotations.
52
+ */
31
53
  export declare interface AnnotationProps {
54
+ /** Type of annotation */
32
55
  type: AnnotationType;
56
+ /** Optional style configuration */
33
57
  style?: unknown;
34
58
  }
35
59
 
36
- declare type AnnotationType = "arrow" | "text";
60
+ /** Types of annotations supported */
61
+ export declare type AnnotationType = "arrow" | "text" | "box" | "comment" | "polygon";
37
62
 
38
- export declare type Arrow = AnnotationFeature<LineString, ArrowProperties>;
63
+ /**
64
+ * Arrow annotation feature. Represents a directed line between two points,
65
+ * can connect a textbox to a shape.
66
+ */
67
+ export declare interface Arrow extends AnnotationFeature<LineString, ArrowProperties> {
68
+ }
39
69
 
40
70
  export declare interface ArrowProperties extends AnnotationProps {
41
71
  type: "arrow";
@@ -44,45 +74,39 @@ export declare interface ArrowProperties extends AnnotationProps {
44
74
  }
45
75
 
46
76
  /**
47
- * @class Arrows
48
- * Draw and edit arrows
49
- */
50
- export declare class Arrows extends Editor<Arrow> {
51
- private draggedHandle;
52
- private start;
53
- private end;
54
- private arrow;
55
- private startX;
56
- private startY;
57
- private minArrowHeight;
58
- private maxArrowHeight;
59
- private handles;
60
- constructor(ogma: default_3, options?: Pick<Partial<ControllerOptions>, "arrowHandleSize" | "maxArrowHeight" | "minArrowHeight">);
61
- private onHandleMouseDown;
62
- /**
63
- * Start drawing a new arrow, it will also be added as a new annotation
64
- * @param x
65
- * @param y
66
- * @param arrow
67
- */
68
- startDrawing(x: number, y: number, arrow?: Arrow): void;
69
- cancelDrawing(): void;
70
- private startDragging;
71
- private onMouseUp;
72
- private onMouseMove;
73
- detect(point: Point_2, margin?: number): Arrow | undefined;
74
- refreshEditor(): void;
75
- getDefaultOptions(): Arrow;
76
- draw(svg: SVGSVGElement): void;
77
- refreshDrawing(): void;
78
- destroy(): void;
79
- }
80
-
77
+ * Styles specific to arrow annotations.
78
+ */
81
79
  export declare interface ArrowStyles extends StrokeOptions {
80
+ /** Tail extremity style */
82
81
  tail?: Extremity;
82
+ /** Head extremity style */
83
83
  head?: Extremity;
84
84
  }
85
85
 
86
+ /**
87
+ * Safely cast a string to a Color type with runtime validation
88
+ * @throws {Error} if the color format is invalid
89
+ */
90
+ export declare function asColor(color: string): Color;
91
+
92
+ /**
93
+ * Safely cast a string to a HexColor type with runtime validation
94
+ * @throws {Error} if the color format is invalid
95
+ */
96
+ export declare function asHexColor(color: string): HexColor;
97
+
98
+ /**
99
+ * Safely cast a string to an RgbaColor type with runtime validation
100
+ * @throws {Error} if the color format is invalid
101
+ */
102
+ export declare function asRgbaColor(color: string): RgbaColor;
103
+
104
+ /**
105
+ * Safely cast a string to an RgbColor type with runtime validation
106
+ * @throws {Error} if the color format is invalid
107
+ */
108
+ export declare function asRgbColor(color: string): RgbColor;
109
+
86
110
  /**
87
111
  * Bounding box object, with the following properties:
88
112
  * - [0]: min x
@@ -92,130 +116,681 @@ export declare interface ArrowStyles extends StrokeOptions {
92
116
  */
93
117
  export declare type Bounds = [number, number, number, number];
94
118
 
95
- export declare function clientToContainerPosition(evt: {
119
+ /**
120
+ * Box annotation feature
121
+ */
122
+ export declare interface Box extends AnnotationFeature<Point_2, BoxProperties> {
123
+ }
124
+
125
+ /** Properties specific to box annotations. */
126
+ export declare interface BoxProperties extends AnnotationProps {
127
+ type: "box";
128
+ /** Width of the box */
129
+ width: number;
130
+ /** Height of the box */
131
+ height: number;
132
+ /** Style options for the box */
133
+ style?: BoxStyle;
134
+ }
135
+
136
+ /** Styles specific to box annotations. */
137
+ export declare interface BoxStyle extends StrokeOptions {
138
+ /** background color: empty for transparent #f00, yellow...*/
139
+ background?: Color;
140
+ /** padding around the box */
141
+ padding?: number;
142
+ /** border radius */
143
+ borderRadius?: number;
144
+ /** if true, the box scales with zoom. Default is true */
145
+ scaled?: boolean;
146
+ }
147
+
148
+ /**
149
+ * Brighten a color for highlight purposes.
150
+ * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
151
+ * @returns
152
+ */
153
+ export declare const brighten: (color: Color) => RgbaColor;
154
+
155
+ /**
156
+ * Calculate optimal zoom threshold for auto-collapse based on comment dimensions
157
+ *
158
+ * The threshold is computed so that the comment collapses when its screen-space
159
+ * size would be smaller than a minimum readable size.
160
+ *
161
+ * @param comment - Comment annotation
162
+ * @param minReadableWidth - Minimum readable width in pixels (default: 80)
163
+ * @returns Zoom threshold below which comment should collapse
164
+ *
165
+ * @example
166
+ * // A 200px wide comment with minReadable=80 will collapse at zoom < 0.4
167
+ * // because 200 * 0.4 = 80
168
+ */
169
+ export declare function calculateCommentZoomThreshold(comment: Comment_2, minReadableWidth?: number): number;
170
+
171
+ /**
172
+ * Check if arrow endpoint can be detached from its target
173
+ *
174
+ * Always returns true since arrow endpoints can be freely retargeted,
175
+ * even for comment arrows. The comment is typically on the start side.
176
+ *
177
+ * @param _arrow - The arrow feature (unused, kept for API consistency)
178
+ * @returns Always true - arrow ends can be detached
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * if (canDetachArrowEnd(arrow)) {
183
+ * // Allow user to drag arrow end point
184
+ * }
185
+ * ```
186
+ */
187
+ export declare function canDetachArrowEnd(_arrow: Arrow): boolean;
188
+
189
+ /**
190
+ * Check if arrow start point can be detached from its source
191
+ *
192
+ * Returns false for arrows originating FROM comments, since comment arrows
193
+ * must always remain attached to the comment on their start side.
194
+ *
195
+ * @param arrow - The arrow feature
196
+ * @returns True if arrow start can be detached
197
+ *
198
+ * @example
199
+ * ```typescript
200
+ * if (canDetachArrowStart(arrow)) {
201
+ * // Allow user to drag arrow start point
202
+ * } else {
203
+ * // Keep arrow start locked to comment
204
+ * }
205
+ * ```
206
+ */
207
+ export declare function canDetachArrowStart(arrow: Arrow): boolean;
208
+
209
+ export declare type ClientMouseEvent = {
96
210
  clientX: number;
97
211
  clientY: number;
98
- }, container?: HTMLElement | null): {
212
+ };
213
+
214
+ export declare function clientToContainerPosition(evt: ClientMouseEvent, container?: HTMLElement | null): {
99
215
  x: number;
100
216
  y: number;
101
217
  };
102
218
 
103
- export declare function colorToRgba(color: string, alpha: number): string;
219
+ /**
220
+ * Any valid color format
221
+ */
222
+ export declare type Color = HexColor | RgbColor | RgbaColor | "transparent" | "none" | string;
223
+
224
+ export declare function colorToRgba(color: Color, alpha: number): RgbaColor;
225
+
226
+ /**
227
+ * Comment annotation type
228
+ * Geometry: Point (center position of comment box/icon)
229
+ *
230
+ * Note: Arrows are stored separately in Arrow features.
231
+ * Arrows reference comments via their link.start or link.end properties.
232
+ */
233
+ declare interface Comment_2 extends AnnotationFeature<Point_2, CommentProps> {
234
+ }
235
+ export { Comment_2 as Comment }
104
236
 
237
+ export declare const COMMENT_MODE_COLLAPSED = "collapsed";
238
+
239
+ export declare const COMMENT_MODE_EXPANDED = "expanded";
240
+
241
+ /**
242
+ * Properties for Comment annotations
243
+ *
244
+ * Comments are specialized annotations that:
245
+ * - Always maintain fixed screen-space size
246
+ * - Always have at least one arrow pointing TO them
247
+ * - Can be collapsed (icon) or expanded (text box)
248
+ * - Support multiple arrows pointing to them
249
+ */
250
+ export declare interface CommentProps extends AnnotationProps {
251
+ type: "comment";
252
+ /** Text content (similar to text annotation) */
253
+ content: string;
254
+ /** Display mode: collapsed (icon) or expanded (text box) */
255
+ mode: typeof COMMENT_MODE_COLLAPSED | typeof COMMENT_MODE_EXPANDED;
256
+ /** Width in expanded mode (pixels) */
257
+ width: number;
258
+ /** Height (auto-grows with content, pixels) */
259
+ height: number;
260
+ /** Optional metadata */
261
+ author?: string;
262
+ timestamp?: Date;
263
+ /** Styling */
264
+ style?: CommentStyle;
265
+ }
266
+
267
+ /**
268
+ * Style configuration for Comment annotations
269
+ */
270
+ export declare interface CommentStyle extends TextStyle {
271
+ /** Background color for collapsed icon (default: "#FFD700") */
272
+ iconColor?: Color;
273
+ /** Icon to display when collapsed (default: "💬") */
274
+ iconSymbol?: string;
275
+ /** Border color for collapsed icon */
276
+ iconBorderColor?: Color;
277
+ /** Border width for collapsed icon */
278
+ iconBorderWidth?: number;
279
+ /** Minimum height (default: 60px) */
280
+ minHeight?: number;
281
+ /** Maximum height before scrolling (default: 480px, undefined = no limit) */
282
+ maxHeight?: number;
283
+ /** Size when collapsed (default: 32px) */
284
+ iconSize?: number;
285
+ /** Zoom threshold below which comment auto-collapses (default: 0.5) */
286
+ collapseZoomThreshold?: number;
287
+ /** Show "send" button in edit mode (default: true) */
288
+ showSendButton?: boolean;
289
+ /** Auto-grow height with content (default: true) */
290
+ autoGrow?: boolean;
291
+ }
292
+
293
+ /**
294
+ * Main controller class for managing annotations.
295
+ * It manages rendering and editing of annotations.
296
+ */
105
297
  export declare class Control extends default_2<FeatureEvents> {
106
- private arrows;
107
- private texts;
108
- private links;
109
- private layer;
110
- private annotations;
111
298
  private ogma;
112
- private options;
113
- private selected;
114
- private updateTimeout;
115
- private hoveredNode;
116
- private dragged;
117
- private textToMagnet;
118
- private activeLinks;
119
- constructor(ogma: default_3, options?: Partial<ControllerOptions>);
120
- private _render;
121
- private _onFeatureDrag;
122
- private _onFeatureDragEnd;
123
- private _onFeatureDragStart;
124
- private _onNodesDragStart;
125
- private _onNodesDrag;
126
- private _onLayoutEnd;
127
- private _moveNodes;
128
- private _snapToText;
129
- private _findAndSnapToNode;
130
- private _snapToNode;
131
- private _onAdded;
132
- private _onRemoved;
133
- private _onUnselect;
134
- private _onSelect;
135
- private refreshTextLinks;
136
- /**
137
- * @returns the currently selected annotation
138
- */
139
- getSelected(): Annotation | null;
140
- private findMagnetPoint;
299
+ private store;
300
+ private renderers;
301
+ private interactions;
302
+ private editor;
303
+ private links;
304
+ private index;
305
+ private drawing;
306
+ private selectionManager;
307
+ private historyManager;
308
+ private updateManager;
309
+ private commentManager;
310
+ constructor(ogma: Ogma, options?: Partial<ControllerOptions>);
311
+ private initializeRenderers;
312
+ private setupEvents;
313
+ private onRotate;
314
+ private onZoom;
315
+ private onLayout;
141
316
  /**
142
317
  * Set the options for the controller
143
318
  * @param options new Options
144
319
  * @returns the updated options
145
320
  */
146
- setOptions(options?: Partial<ControllerOptions>): ControllerOptions;
147
- /**
148
- * Selects the annotation with the given id
149
- * @param id the id of the annotation to select
150
- */
151
- select(id: Id): this;
152
- /**
153
- * Unselects the currently selected annotation
154
- */
155
- unselect(): this;
321
+ setOptions(options?: Partial<ControllerOptions>): {
322
+ showSendButton: boolean;
323
+ sendButtonIcon: string;
324
+ minArrowHeight: number;
325
+ maxArrowHeight: number;
326
+ detectMargin: number;
327
+ magnetRadius: number;
328
+ magnetHandleRadius: number;
329
+ textPlaceholder: string;
330
+ };
156
331
  /**
157
332
  * Add an annotation to the controller
158
333
  * @param annotation The annotation to add
159
334
  */
160
- add(annotation: Arrow | Text_2 | AnnotationCollection): this;
335
+ add(annotation: Annotation | AnnotationCollection): this;
161
336
  /**
162
337
  * Remove an annotation or an array of annotations from the controller
163
338
  * @param annotation The annotation(s) to remove
164
339
  */
165
- remove(annotation: Arrow | Text_2 | AnnotationCollection): this;
166
- private loadLink;
340
+ remove(annotation: Annotation | AnnotationCollection): this;
341
+ /**
342
+ * Undo the last change
343
+ * @returns true if undo was successful, false if no changes to undo
344
+ */
345
+ undo(): boolean;
346
+ /**
347
+ * Redo the last undone change
348
+ * @returns true if redo was successful, false if no changes to redo
349
+ */
350
+ redo(): boolean;
351
+ /**
352
+ * Check if there are changes to undo
353
+ * @returns true if undo is possible
354
+ */
355
+ canUndo(): boolean;
356
+ /**
357
+ * Check if there are changes to redo
358
+ * @returns true if redo is possible
359
+ */
360
+ canRedo(): boolean;
361
+ /**
362
+ * Clear the undo/redo history
363
+ */
364
+ clearHistory(): void;
365
+ /**
366
+ * Get all annotations in the controller
367
+ * @returns A FeatureCollection containing all annotations
368
+ */
369
+ getAnnotations(): AnnotationCollection;
370
+ /**
371
+ * Select one or more annotations by id
372
+ * @param annotations The id(s) of the annotation(s) to select
373
+ * @returns this for chaining
374
+ */
375
+ select(annotations: Id | Id[]): this;
376
+ /**
377
+ * Unselect one or more annotations, or all if no ids provided
378
+ * @param annotations The id(s) of the annotation(s) to unselect, or undefined to unselect all
379
+ * @returns this for chaining
380
+ */
381
+ unselect(annotations?: Id | Id[]): this;
167
382
  /**
168
- * Start adding an arrow (add it, and give control to the user)
169
- * @param x coord of the first point
170
- * @param y coord of the first point
171
- * @param arrow The arrow to add
383
+ * Cancel the current drawing operation
384
+ * @returns this for chaining
172
385
  */
173
- startArrow(x: number, y: number, arrow?: Arrow): void;
386
+ cancelDrawing(): this;
174
387
  /**
175
- * Start adding a text (add it, and give control to the user)
176
- * @param x coord of the top left point
177
- * @param y coord of the top left point
178
- * @param text The text to add
388
+ * Enable arrow drawing mode - the recommended way to add arrows.
389
+ *
390
+ * Call this method when the user clicks an "Add Arrow" button. The control will:
391
+ * 1. Wait for the next mousedown event
392
+ * 2. Create an arrow at that position with the specified style
393
+ * 3. Start the interactive drawing process
394
+ * 4. Clean up automatically when done
395
+ *
396
+ * **This is the recommended API for 99% of use cases.** Only use `startArrow()`
397
+ * if you need to implement custom mouse handling or positioning logic.
398
+ *
399
+ * @example
400
+ * ```ts
401
+ * addArrowButton.addEventListener('click', () => {
402
+ * control.enableArrowDrawing({ strokeColor: '#3A03CF', strokeWidth: 2 });
403
+ * });
404
+ * ```
405
+ *
406
+ * @param style Arrow style options
407
+ * @returns this for chaining
408
+ * @see startArrow for low-level programmatic control
179
409
  */
180
- startText(x: number, y: number, text?: Text_2): void;
410
+ enableArrowDrawing(style?: Partial<Arrow["properties"]["style"]>): this;
181
411
  /**
182
- * Cancel drawing on the current frame
412
+ * Enable text drawing mode - the recommended way to add text annotations.
413
+ *
414
+ * Call this method when the user clicks an "Add Text" button. The control will:
415
+ * 1. Wait for the next mousedown event
416
+ * 2. Create a text box at that position with the specified style
417
+ * 3. Start the interactive drawing/editing process
418
+ * 4. Clean up automatically when done
419
+ *
420
+ * **This is the recommended API for 99% of use cases.** Only use `startText()`
421
+ * if you need to implement custom mouse handling or positioning logic.
422
+ *
423
+ * @example
424
+ * ```ts
425
+ * addTextButton.addEventListener('click', () => {
426
+ * control.enableTextDrawing({ color: '#3A03CF', fontSize: 24 });
427
+ * });
428
+ * ```
429
+ *
430
+ * @param style Text style options
431
+ * @returns this for chaining
432
+ * @see startText for low-level programmatic control
183
433
  */
184
- cancelDrawing(): void;
434
+ enableTextDrawing(style?: Partial<Text_2["properties"]["style"]>): this;
185
435
  /**
186
- * Triggers the update event on the annotation
187
- * @param annotation The annotation updated
436
+ * Enable box drawing mode - the recommended way to add boxes.
437
+ *
438
+ * Call this method when the user clicks an "Add Box" button. The control will:
439
+ * 1. Wait for the next mousedown event
440
+ * 2. Create a box at that position with the specified style
441
+ * 3. Start the interactive drawing process (drag to size)
442
+ * 4. Clean up automatically when done
443
+ *
444
+ * **This is the recommended API for 99% of use cases.** Only use `startBox()`
445
+ * if you need to implement custom mouse handling or positioning logic.
446
+ *
447
+ * @example
448
+ * ```ts
449
+ * addBoxButton.addEventListener('click', () => {
450
+ * control.enableBoxDrawing({ background: '#EDE6FF', borderRadius: 8 });
451
+ * });
452
+ * ```
453
+ *
454
+ * @param style Box style options
455
+ * @returns this for chaining
456
+ * @see startBox for low-level programmatic control
188
457
  */
189
- onUpdate: (annotation: Annotation) => void;
190
- private _onUpdate;
458
+ enableBoxDrawing(style?: Partial<Box["properties"]["style"]>): this;
459
+ /**
460
+ * Enable polygon drawing mode - the recommended way to add polygons.
461
+ *
462
+ * Call this method when the user clicks an "Add Polygon" button. The control will:
463
+ * 1. Wait for the next mousedown event
464
+ * 2. Create a polygon starting at that position with the specified style
465
+ * 3. Start the interactive drawing process (click points to draw shape)
466
+ * 4. Clean up automatically when done
467
+ *
468
+ * **This is the recommended API for 99% of use cases.** Only use `startPolygon()`
469
+ * if you need to implement custom mouse handling or positioning logic.
470
+ *
471
+ * @example
472
+ * ```ts
473
+ * addPolygonButton.addEventListener('click', () => {
474
+ * control.enablePolygonDrawing({ strokeColor: '#3A03CF', background: 'rgba(58, 3, 207, 0.15)' });
475
+ * });
476
+ * ```
477
+ *
478
+ * @param style Polygon style options
479
+ * @returns this for chaining
480
+ * @see startPolygon for low-level programmatic control
481
+ */
482
+ enablePolygonDrawing(style?: Partial<Polygon["properties"]["style"]>): this;
483
+ /**
484
+ * Enable comment drawing mode - the recommended way to add comments.
485
+ *
486
+ * Call this method when the user clicks an "Add Comment" button. The control will:
487
+ * 1. Wait for the next mousedown event
488
+ * 2. Create a comment with an arrow pointing to that position
489
+ * 3. Smart positioning: automatically finds the best placement for the comment box
490
+ * 4. Start the interactive editing process
491
+ * 5. Clean up automatically when done
492
+ *
493
+ * **This is the recommended API for 99% of use cases.** Only use `startComment()`
494
+ * if you need to implement custom mouse handling or positioning logic.
495
+ *
496
+ * @example
497
+ * ```ts
498
+ * addCommentButton.addEventListener('click', () => {
499
+ * control.enableCommentDrawing({
500
+ * commentStyle: { color: '#3A03CF', background: '#EDE6FF' },
501
+ * arrowStyle: { strokeColor: '#3A03CF', head: 'halo-dot' }
502
+ * });
503
+ * });
504
+ * ```
505
+ *
506
+ * @param options Drawing options including offsets and styles
507
+ * @param options.offsetX Manual X offset for comment placement (overrides smart positioning)
508
+ * @param options.offsetY Manual Y offset for comment placement (overrides smart positioning)
509
+ * @param options.commentStyle Style options for the comment box
510
+ * @param options.arrowStyle Style options for the arrow
511
+ * @returns this for chaining
512
+ * @see startComment for low-level programmatic control
513
+ */
514
+ enableCommentDrawing(options?: {
515
+ offsetX?: number;
516
+ offsetY?: number;
517
+ commentStyle?: Partial<CommentProps>;
518
+ arrowStyle?: Partial<ArrowProperties>;
519
+ }): this;
520
+ /**
521
+ * **Advanced API:** Programmatically start drawing a comment at specific coordinates.
522
+ *
523
+ * This is a low-level method that gives you full control over the drawing process.
524
+ * You must handle mouse events and create the comment object yourself.
525
+ *
526
+ * **For most use cases, use `enableCommentDrawing()` instead** - it handles all
527
+ * mouse events and annotation creation automatically.
528
+ *
529
+ * Use this method only when you need:
530
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
531
+ * - Programmatic placement without user interaction
532
+ * - Integration with custom UI frameworks
533
+ *
534
+ * @example
535
+ * ```ts
536
+ * // Custom cursor example
537
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
538
+ * ogma.events.once('mousedown', (evt) => {
539
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
540
+ * const comment = createComment(x, y, 'My comment', { color: '#3A03CF' });
541
+ * control.startComment(x, y, comment);
542
+ * });
543
+ * ```
544
+ *
545
+ * @param x X coordinate to start drawing
546
+ * @param y Y coordinate to start drawing
547
+ * @param comment The comment annotation to add
548
+ * @param options Drawing options including offsets and styles
549
+ * @returns this for chaining
550
+ * @see enableCommentDrawing for the recommended high-level API
551
+ */
552
+ startComment(x: number, y: number, comment: Comment_2, options?: {
553
+ offsetX?: number;
554
+ offsetY?: number;
555
+ commentStyle?: Partial<CommentProps>;
556
+ arrowStyle?: Partial<ArrowProperties>;
557
+ }): this;
558
+ /**
559
+ * **Advanced API:** Programmatically start drawing a box at specific coordinates.
560
+ *
561
+ * This is a low-level method that gives you full control over the drawing process.
562
+ * You must handle mouse events and optionally create the box object yourself.
563
+ *
564
+ * **For most use cases, use `enableBoxDrawing()` instead** - it handles all
565
+ * mouse events and annotation creation automatically.
566
+ *
567
+ * Use this method only when you need:
568
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
569
+ * - Programmatic placement without user interaction
570
+ * - Integration with custom UI frameworks
571
+ *
572
+ * @example
573
+ * ```ts
574
+ * // Custom cursor example
575
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
576
+ * ogma.events.once('mousedown', (evt) => {
577
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
578
+ * const box = createBox(x, y, 100, 50, { background: '#EDE6FF' });
579
+ * control.startBox(x, y, box);
580
+ * });
581
+ * ```
582
+ *
583
+ * @param x X coordinate for the box origin
584
+ * @param y Y coordinate for the box origin
585
+ * @param box The box annotation to add (optional, will be created if not provided)
586
+ * @returns this for chaining
587
+ * @see enableBoxDrawing for the recommended high-level API
588
+ */
589
+ startBox(x: number, y: number, box?: Box): this;
590
+ /**
591
+ * **Advanced API:** Programmatically start drawing an arrow at specific coordinates.
592
+ *
593
+ * This is a low-level method that gives you full control over the drawing process.
594
+ * You must handle mouse events and optionally create the arrow object yourself.
595
+ *
596
+ * **For most use cases, use `enableArrowDrawing()` instead** - it handles all
597
+ * mouse events and annotation creation automatically.
598
+ *
599
+ * Use this method only when you need:
600
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
601
+ * - Programmatic placement without user interaction
602
+ * - Integration with custom UI frameworks
603
+ *
604
+ * @example
605
+ * ```ts
606
+ * // Custom cursor example
607
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
608
+ * ogma.events.once('mousedown', (evt) => {
609
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
610
+ * const arrow = createArrow(x, y, x, y, { strokeColor: '#3A03CF' });
611
+ * control.startArrow(x, y, arrow);
612
+ * });
613
+ * ```
614
+ *
615
+ * @param x X coordinate for the arrow start
616
+ * @param y Y coordinate for the arrow start
617
+ * @param arrow The arrow annotation to add (optional, will be created if not provided)
618
+ * @returns this for chaining
619
+ * @see enableArrowDrawing for the recommended high-level API
620
+ */
621
+ startArrow(x: number, y: number, arrow?: Arrow): this;
622
+ /**
623
+ * **Advanced API:** Programmatically start drawing a text annotation at specific coordinates.
624
+ *
625
+ * This is a low-level method that gives you full control over the drawing process.
626
+ * You must handle mouse events and optionally create the text object yourself.
627
+ *
628
+ * **For most use cases, use `enableTextDrawing()` instead** - it handles all
629
+ * mouse events and annotation creation automatically.
630
+ *
631
+ * Use this method only when you need:
632
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
633
+ * - Programmatic placement without user interaction
634
+ * - Integration with custom UI frameworks
635
+ *
636
+ * @example
637
+ * ```ts
638
+ * // Custom cursor example
639
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
640
+ * ogma.events.once('mousedown', (evt) => {
641
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
642
+ * const text = createText(x, y, 0, 0, 'Hello', { color: '#3A03CF' });
643
+ * control.startText(x, y, text);
644
+ * });
645
+ * ```
646
+ *
647
+ * @param x X coordinate for the text
648
+ * @param y Y coordinate for the text
649
+ * @param text The text annotation to add (optional, will be created if not provided)
650
+ * @returns this for chaining
651
+ * @see enableTextDrawing for the recommended high-level API
652
+ */
653
+ startText(x: number, y: number, text?: Text_2): this;
654
+ /**
655
+ * **Advanced API:** Programmatically start drawing a polygon at specific coordinates.
656
+ *
657
+ * This is a low-level method that gives you full control over the drawing process.
658
+ * You must handle mouse events and create the polygon object yourself.
659
+ *
660
+ * **For most use cases, use `enablePolygonDrawing()` instead** - it handles all
661
+ * mouse events and annotation creation automatically.
662
+ *
663
+ * Use this method only when you need:
664
+ * - Custom mouse event handling (e.g., custom cursors, right-click menus)
665
+ * - Programmatic placement without user interaction
666
+ * - Integration with custom UI frameworks
667
+ *
668
+ * @example
669
+ * ```ts
670
+ * // Custom cursor example
671
+ * ogma.setOptions({ cursor: { default: 'crosshair' } });
672
+ * ogma.events.once('mousedown', (evt) => {
673
+ * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
674
+ * const polygon = createPolygon([[[x, y]]], { strokeColor: '#3A03CF' });
675
+ * control.startPolygon(x, y, polygon);
676
+ * });
677
+ * ```
678
+ *
679
+ * @param x X coordinate to start drawing
680
+ * @param y Y coordinate to start drawing
681
+ * @param polygon The polygon annotation to add
682
+ * @returns this for chaining
683
+ * @see enablePolygonDrawing for the recommended high-level API
684
+ */
685
+ startPolygon(x: number, y: number, polygon: Polygon): this;
686
+ /**
687
+ * Get the currently selected annotations as a collection
688
+ * @returns A FeatureCollection of selected annotations
689
+ */
690
+ getSelectedAnnotations(): AnnotationCollection;
691
+ /**
692
+ * Get the first selected annotation (for backwards compatibility)
693
+ * @returns The currently selected annotation, or null if none selected
694
+ */
695
+ getSelected(): Annotation | null;
696
+ /**
697
+ * Get a specific annotation by id
698
+ * @param id The id of the annotation to retrieve
699
+ * @returns The annotation with the given id, or undefined if not found
700
+ */
701
+ getAnnotation<T = Annotation>(id: Id): T | undefined;
702
+ /**
703
+ * Scale an annotation by a given factor around an origin point
704
+ * @param id The id of the annotation to scale
705
+ * @param scale The scale factor
706
+ * @param ox Origin x coordinate
707
+ * @param oy Origin y coordinate
708
+ * @returns this for chaining
709
+ */
710
+ setScale(id: Id, scale: number, ox: number, oy: number): this;
711
+ /**
712
+ * Toggle a comment between collapsed and expanded mode
713
+ * @param id The id of the comment to toggle
714
+ * @returns this for chaining
715
+ */
716
+ toggleComment(id: Id): this;
717
+ /**
718
+ * Destroy the controller and its elements
719
+ */
720
+ destroy(): void;
191
721
  /**
192
722
  * Update the style of the annotation with the given id
193
723
  * @param id The id of the annotation to update
194
724
  * @param style The new style
195
725
  */
196
726
  updateStyle<A extends Annotation>(id: Id, style: A["properties"]["style"]): this;
197
- setScale(id: Id, scale: number, ox: number, oy: number): this;
198
727
  /**
199
- * @returns the annotations in the controller
728
+ * Update an annotation with partial updates
729
+ *
730
+ * This method allows you to update any properties of an annotation, including
731
+ * geometry, properties, and style. Updates are merged with existing data.
732
+ *
733
+ * @param annotation Partial annotation object with id and properties to update
734
+ * @returns this for chaining
735
+ *
736
+ * @example
737
+ * ```ts
738
+ * // Update arrow geometry
739
+ * controller.update({
740
+ * id: arrowId,
741
+ * geometry: {
742
+ * type: 'LineString',
743
+ * coordinates: [[0, 0], [200, 200]]
744
+ * }
745
+ * });
746
+ *
747
+ * // Update text content and position
748
+ * controller.update({
749
+ * id: textId,
750
+ * geometry: {
751
+ * type: 'Point',
752
+ * coordinates: [100, 100]
753
+ * },
754
+ * properties: {
755
+ * content: 'Updated text'
756
+ * }
757
+ * });
758
+ *
759
+ * // Update style only (prefer updateStyle for style-only updates)
760
+ * controller.update({
761
+ * id: boxId,
762
+ * properties: {
763
+ * style: {
764
+ * background: '#ff0000'
765
+ * }
766
+ * }
767
+ * });
768
+ * ```
200
769
  */
201
- getAnnotations(): AnnotationCollection;
770
+ update<A extends Annotation>(annotation: DeepPartial<A> & {
771
+ id: Id;
772
+ }): this;
202
773
  /**
203
- * Retrieve the annotation with the given id
204
- * @param id the id of the annotation to get
205
- * @returns The annotation with the given id
774
+ * Attach an arrow to a node at the specified side
775
+ * @param arrowId
776
+ * @param targetNode
777
+ * @param side
206
778
  */
207
- getAnnotation(id: Id): Arrow | Text_2 | undefined;
779
+ link(arrowId: Id, targetNode: Node_2, side: Side): this;
208
780
  /**
209
- * Destroy the controller and its elements
781
+ * Attach an arrow to an annotation at the specified side
782
+ * @param arrowId
783
+ * @param target
784
+ * @param side
210
785
  */
211
- destroy(): void;
786
+ link(arrowId: Id, target: Id, side: Side): this;
787
+ isDrawing(): boolean;
212
788
  }
213
789
 
790
+ /**
791
+ * Options for the annotations control
792
+ */
214
793
  export declare type ControllerOptions = {
215
- /**
216
- * The color of the magnet points
217
- */
218
- magnetColor: string;
219
794
  /**
220
795
  * The radius in which arrows are attracted
221
796
  */
@@ -233,13 +808,14 @@ export declare type ControllerOptions = {
233
808
  */
234
809
  textPlaceholder: string;
235
810
  /**
236
- * Size of the text handle
811
+ * Show send button in text editor
237
812
  */
238
- textHandleSize: number;
813
+ showSendButton: boolean;
239
814
  /**
240
- * Size of the arrow handle
815
+ * SVG icon for the send button in text editor
816
+ * Should be a complete SVG string (e.g., '<svg>...</svg>')
241
817
  */
242
- arrowHandleSize: number;
818
+ sendButtonIcon: string;
243
819
  /**
244
820
  * Minimum height of the arrow in units
245
821
  */
@@ -251,132 +827,342 @@ export declare type ControllerOptions = {
251
827
  };
252
828
 
253
829
  export declare const createArrow: (x0?: number, y0?: number, x1?: number, y1?: number, styles?: {
830
+ /** Tail extremity style */
254
831
  tail?: Extremity | undefined;
832
+ /** Head extremity style */
255
833
  head?: Extremity | undefined;
256
- strokeType?: "none" | "plain" | "dashed" | undefined;
834
+ strokeType?: StrokeType | undefined;
257
835
  strokeColor?: string | undefined;
258
836
  strokeWidth?: number | undefined;
259
837
  }) => Arrow;
260
838
 
839
+ export declare const createBox: (x?: number, y?: number, width?: number, height?: number, styles?: Partial<BoxStyle>) => Box;
840
+
841
+ /**
842
+ * Create a new Comment annotation
843
+ *
844
+ * @param x - X coordinate of the comment box/icon center
845
+ * @param y - Y coordinate of the comment box/icon center
846
+ * @param content - Text content
847
+ * @param options - Optional configuration
848
+ * @returns New Comment feature
849
+ *
850
+ * @important This creates ONLY the comment box without an arrow. Since comments
851
+ * require at least one arrow, you should use {@link createCommentWithArrow}
852
+ * instead for programmatic creation. This function is primarily used internally
853
+ * by the interactive drawing handlers.
854
+ *
855
+ * @see createCommentWithArrow for creating comments programmatically
856
+ */
857
+ export declare function createComment(x: number, y: number, content: string, options?: Partial<CommentProps>): Comment_2;
858
+
859
+ /**
860
+ * Create a comment with an arrow pointing to a target location
861
+ *
862
+ * This is the recommended way to create comments programmatically, as it ensures
863
+ * that the comment always has at least one arrow (which is required).
864
+ *
865
+ * @param targetX - X coordinate where the arrow points to
866
+ * @param targetY - Y coordinate where the arrow points to
867
+ * @param commentX - X coordinate of the comment box center
868
+ * @param commentY - Y coordinate of the comment box center
869
+ * @param content - Text content of the comment
870
+ * @param options - Optional configuration
871
+ * @param options.commentStyle - Style options for the comment
872
+ * @param options.arrowStyle - Style options for the arrow
873
+ * @returns Object containing the comment and arrow features
874
+ *
875
+ * @example
876
+ * ```typescript
877
+ * import { createCommentWithArrow } from '@linkurious/ogma-annotations';
878
+ *
879
+ * // Create a comment pointing to a node at (100, 100)
880
+ * const { comment, arrow } = createCommentWithArrow(
881
+ * 100, 100, // Target position (where arrow points)
882
+ * 300, 50, // Comment position
883
+ * "Important node!", // Comment text
884
+ * {
885
+ * commentStyle: {
886
+ * style: {
887
+ * background: "#FFFACD",
888
+ * color: "#333"
889
+ * }
890
+ * },
891
+ * arrowStyle: {
892
+ * strokeColor: "#3498db",
893
+ * strokeWidth: 2,
894
+ * head: "arrow"
895
+ * }
896
+ * }
897
+ * );
898
+ *
899
+ * // Add both to the controller
900
+ * controller.add(comment);
901
+ * controller.add(arrow);
902
+ *
903
+ * // The arrow is automatically linked to the comment
904
+ * ```
905
+ */
906
+ export declare function createCommentWithArrow(targetX: number, targetY: number, commentX: number, commentY: number, content?: string, options?: {
907
+ commentStyle?: Partial<CommentProps>;
908
+ arrowStyle?: Partial<ArrowStyles>;
909
+ }): {
910
+ comment: Comment_2;
911
+ arrow: Arrow;
912
+ };
913
+
914
+ /**
915
+ * Create a polygon annotation
916
+ */
917
+ export declare function createPolygon(coordinates: [number, number][][], properties?: Partial<Omit<PolygonProperties, "type">> & {
918
+ id?: Id;
919
+ }): Polygon;
920
+
921
+ /** @private */
261
922
  export declare function createSVGElement<T extends SVGElement>(tag: string): T;
262
923
 
263
924
  export declare const createText: (x?: number, y?: number, width?: number, height?: number, content?: string, styles?: Partial<TextStyle>) => Text_2;
264
925
 
926
+ /** @private */
927
+ export declare type Cursor = "default" | "pointer" | "move" | "grab" | "grabbing" | "auto" | "resize" | "col-resize" | "row-resize" | "all-scroll" | "n-resize" | "e-resize" | "s-resize" | "w-resize" | "ne-resize" | "nw-resize" | "se-resize" | "sw-resize" | "ew-resize" | "ns-resize" | "nesw-resize" | "nwse-resize" | "alias" | "crosshair";
928
+
929
+ /** @private */
930
+ export declare const cursors: Record<string, Cursor>;
931
+
932
+ /**
933
+ * Darken a color for highlight purposes.
934
+ * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
935
+ * @returns
936
+ */
937
+ export declare const darken: (color: Color) => RgbaColor;
938
+
939
+ export declare const DATA_ATTR = "data-annotation";
940
+
941
+ /** @private */
942
+ export declare const debounce: <F extends (...args: Parameters<F>) => ReturnType<F>>(func: F, waitFor: number) => (...args: Parameters<F>) => void;
943
+
944
+ /** @private */
945
+ export declare function debounceTail<T, A extends unknown[]>(fn: (this: T, ...args: A) => void, delay: number): (this: T, ...args: A) => void;
946
+
947
+ export declare type DeepPartial<T> = {
948
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
949
+ };
950
+
951
+ /** Default send button icon (paper plane) */
952
+ export declare const DEFAULT_SEND_ICON = "<svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>";
953
+
954
+ /**
955
+ * Default options for creating new Arrow annotations.
956
+ * Contains the default arrow structure with {@link defaultArrowStyle}.
957
+ */
265
958
  export declare const defaultArrowOptions: Arrow;
266
959
 
960
+ /**
961
+ * Default style configuration for arrow annotations.
962
+ *
963
+ * @example
964
+ * ```typescript
965
+ * {
966
+ * strokeType: "plain",
967
+ * strokeColor: "#202020",
968
+ * strokeWidth: 1,
969
+ * head: "none",
970
+ * tail: "none"
971
+ * }
972
+ * ```
973
+ */
267
974
  export declare const defaultArrowStyle: ArrowStyles;
268
975
 
269
- export declare const defaultControllerOptions: AnnotationOptions;
976
+ /**
977
+ * Default options for creating new Box annotations.
978
+ * Contains the default box structure with {@link defaultBoxStyle}.
979
+ */
980
+ export declare const defaultBoxOptions: Box;
981
+
982
+ /**
983
+ * Default style configuration for box annotations.
984
+ *
985
+ * @example
986
+ * ```typescript
987
+ * {
988
+ * background: "#f5f5f5",
989
+ * strokeWidth: 0,
990
+ * borderRadius: 8,
991
+ * padding: 16,
992
+ * strokeType: "plain"
993
+ * }
994
+ * ```
995
+ */
996
+ export declare const defaultBoxStyle: BoxStyle;
997
+
998
+ /**
999
+ * Default options for creating new Comments.
1000
+ * Contains the default comment configuration with {@link defaultCommentStyle}.
1001
+ *
1002
+ * @example
1003
+ * ```typescript
1004
+ * {
1005
+ * mode: "expanded",
1006
+ * width: 200,
1007
+ * height: 120,
1008
+ * content: "",
1009
+ * style: defaultCommentStyle
1010
+ * }
1011
+ * ```
1012
+ */
1013
+ export declare const defaultCommentOptions: Partial<CommentProps>;
1014
+
1015
+ /**
1016
+ * Default style for Comment annotations
1017
+ *
1018
+ * @example
1019
+ * ```typescript
1020
+ * {
1021
+ * // Box styling
1022
+ * background: "#FFFACD", // Light yellow (sticky note color)
1023
+ * padding: 8,
1024
+ * borderRadius: 4,
1025
+ * strokeColor: "#DDD",
1026
+ * strokeWidth: 1,
1027
+ * strokeType: "plain",
1028
+ *
1029
+ * // Icon styling (collapsed mode)
1030
+ * iconColor: "#FFCB2F", // Gold
1031
+ * iconSymbol: "💬",
1032
+ * iconBorderColor: "#aaa",
1033
+ * iconBorderWidth: 2,
1034
+ *
1035
+ * // Size properties
1036
+ * minHeight: 60,
1037
+ * iconSize: 32,
1038
+ *
1039
+ * // Text styling
1040
+ * color: "#333",
1041
+ * font: "Arial, sans-serif",
1042
+ * fontSize: 12,
1043
+ *
1044
+ * // Editing UI
1045
+ * showSendButton: true,
1046
+ * autoGrow: true,
1047
+ *
1048
+ * // Fixed size (always screen-aligned)
1049
+ * fixedSize: true
1050
+ * }
1051
+ * ```
1052
+ */
1053
+ export declare const defaultCommentStyle: CommentStyle;
1054
+
1055
+ /**
1056
+ * Default polygon properties for creating new Polygon annotations.
1057
+ * Contains the default polygon configuration with {@link defaultPolygonStyle}.
1058
+ */
1059
+ export declare const defaultPolygonProperties: PolygonProperties;
1060
+
1061
+ /**
1062
+ * Default style configuration for polygon annotations.
1063
+ *
1064
+ * @example
1065
+ * ```typescript
1066
+ * {
1067
+ * background: "transparent",
1068
+ * strokeWidth: 2,
1069
+ * borderRadius: 8,
1070
+ * padding: 16,
1071
+ * strokeType: "plain",
1072
+ * strokeColor: "#000000"
1073
+ * }
1074
+ * ```
1075
+ */
1076
+ export declare const defaultPolygonStyle: PolygonStyle;
270
1077
 
1078
+ /**
1079
+ * Default options for creating new Text annotations.
1080
+ * Contains the default text structure with {@link defaultTextStyle}.
1081
+ */
271
1082
  export declare const defaultTextOptions: Text_2;
272
1083
 
1084
+ /**
1085
+ * Default style configuration for text annotations.
1086
+ *
1087
+ * @example
1088
+ * ```typescript
1089
+ * {
1090
+ * font: "sans-serif",
1091
+ * fontSize: 18,
1092
+ * color: "#505050",
1093
+ * background: "#f5f5f5",
1094
+ * strokeWidth: 0,
1095
+ * borderRadius: 8,
1096
+ * padding: 16,
1097
+ * strokeType: "plain",
1098
+ * fixedSize: false
1099
+ * }
1100
+ * ```
1101
+ */
273
1102
  export declare const defaultTextStyle: TextStyle;
274
1103
 
275
1104
  /**
276
- * @class Annotations
277
- * Abstract class to display Texts and Arrows, provide add/remove/update and mouse events
278
- * Modifying annotation is handled by the child classes, it is too specific
279
- */
280
- declare abstract class Editor<T extends Annotation> extends default_2<Events<T>> {
281
- protected ogma: default_3;
282
- protected elements: T[];
283
- protected layer: SVGLayer;
284
- protected editor: Overlay;
285
- protected selectedId: Id;
286
- protected hoveredId: Id;
287
- protected ogmaOptions: Options;
288
- protected shouldDetect: boolean;
289
- protected isDragging: boolean;
290
- protected showeditorOnHover: boolean;
291
- constructor(ogma: default_3, editorHtml: string);
292
- private _onKeyUp;
293
- protected _canRemove(): boolean;
294
- private _onClickMouseMove;
295
- /**
296
- * @method add
297
- * @param options Params for the annotation (merged with default)
298
- * @returns the added annotation
299
- */
300
- add(options: T): T;
301
- updateStyle(annotation: T, style: Partial<T["properties"]["style"]>): void;
302
- updateGeometry(annotation: T, geometry: Partial<T["geometry"]>): void;
303
- scale(annotation: T, scale: number, ox: number, oy: number): void;
304
- /**
305
- * @method update
306
- * Updates an annotation (position, color etc)
307
- * @param id Id of the annotation to update
308
- * @param element params of the annotation
309
- */
310
- update(id: Id, element: Partial<T>): void;
311
- updateAnnotation(target: T, element: Partial<T>): void;
312
- getById(id: Id): T;
313
- /**
314
- * @method select
315
- * @param id id of the element to select
316
- * Select element, show editor, disable Ogma dragging and fire event
317
- */
318
- select(id: Id): void;
319
- hover(id: Id): void;
320
- getSelectedFeature(): T | null;
321
- unselect(): this;
322
- unhover(): this;
323
- /**
324
- * @method remove
325
- * @param id Id of the annotation to remove
326
- * Removes annotation with the given id
327
- */
328
- remove(id: Id): void;
329
- /**
330
- * @method disableDragging
331
- * Prevents Ogma from dragging elements or moving the view while dragging an annotation
332
- */
333
- disableDragging(): void;
334
- /**
335
- * @method restoreDragging
336
- * restore ogma options as they were before we start dragging an annotation
337
- */
338
- restoreDragging(): void;
339
- enableDetection(): void;
340
- /**
341
- * @method disableDetection
342
- * Disables the hover behaviour, used by controller to avoid hovering
343
- * arrows while dragging texts and vice versa
344
- */
345
- disableDetection(): void;
346
- refreshLayer(): void;
347
- refreshDrawing(): void;
348
- getElements(): T[];
349
- abstract refreshEditor(): void;
350
- abstract draw(svg: SVGSVGElement): void;
351
- abstract cancelDrawing(): void;
352
- abstract getDefaultOptions(): T;
353
- abstract detect(point: Point_2, margin: number): T | undefined;
354
- destroy(): void;
355
- }
1105
+ * @private
1106
+ * @param a Arrow annotation
1107
+ * @param point Point to test
1108
+ * @param threshold Detection threshold
1109
+ * @returns True if the point is on the arrow line within the given threshold
1110
+ */
1111
+ export declare function detectArrow(a: Arrow, point: Point_3, threshold: number): boolean;
356
1112
 
357
- export declare type Events<T> = {
358
- [EVT_HOVER]: (evt: T) => void;
359
- [EVT_UNHOVER]: (evt: T) => void;
360
- [EVT_SELECT]: (evt: T) => void;
361
- [EVT_UNSELECT]: (evt: T) => void;
362
- [EVT_DRAG_START]: (evt: T) => void;
363
- [EVT_DRAG]: (evt: T, key: "line" | "start" | "end" | "text") => void;
364
- [EVT_DRAG_END]: (evt: T) => void;
365
- [EVT_REMOVE]: (evt: T) => void;
366
- [EVT_ADD]: (evt: T) => void;
367
- [EVT_UPDATE]: (evt: T) => void;
368
- };
1113
+ /** @private */
1114
+ export declare function detectBox(a: Box, p: Point, sin?: number, cos?: number, threshold?: number): boolean;
1115
+
1116
+ /**
1117
+ * Detect if a point is within a comment's bounds
1118
+ * @private
1119
+ * @param comment - Comment to test
1120
+ * @param point - Point to test
1121
+ * @param threshold - Detection threshold in pixels
1122
+ * @param zoom - Current zoom level
1123
+ * @returns True if point is within comment bounds
1124
+ */
1125
+ export declare function detectComment(comment: Comment_2, point: Point, threshold: number | undefined, sin: number, cos: number, zoom?: number): boolean;
1126
+
1127
+ /**
1128
+ * Point-in-polygon detection using ray casting algorithm
1129
+ * @private
1130
+ * @param polygon The polygon annotation
1131
+ * @param point The point to test
1132
+ * @param threshold Detection threshold in pixels
1133
+ * @return True if the point is inside the polygon or within the threshold distance from its edges
1134
+ */
1135
+ export declare function detectPolygon(polygon: Polygon, point: Point, threshold?: number): boolean;
1136
+
1137
+ /**
1138
+ * Detects whether a point is within a text annotation's bounds.
1139
+ * @private
1140
+ * @param a Text annotation
1141
+ * @param p Point to test
1142
+ * @param threshold Detection threshold
1143
+ * @param sin Rotation sine
1144
+ * @param cos Rotation cosine
1145
+ * @param zoom Current zoom level
1146
+ * @returns True if the point is within the text bounds, false otherwise
1147
+ */
1148
+ export declare function detectText(a: Text_2, p: Point, threshold?: number, sin?: number, cos?: number, zoom?: number): boolean;
369
1149
 
370
1150
  export declare const EVT_ADD = "add";
371
1151
 
372
1152
  export declare const EVT_CANCEL_DRAWING = "cancelDrawing";
373
1153
 
1154
+ export declare const EVT_CLICK = "click";
1155
+
1156
+ export declare const EVT_COMPLETE_DRAWING = "completeDrawing";
1157
+
374
1158
  export declare const EVT_DRAG = "dragging";
375
1159
 
376
1160
  export declare const EVT_DRAG_END = "dragend";
377
1161
 
378
1162
  export declare const EVT_DRAG_START = "dragstart";
379
1163
 
1164
+ export declare const EVT_HISTORY = "history";
1165
+
380
1166
  export declare const EVT_HOVER = "hover";
381
1167
 
382
1168
  export declare const EVT_LINK = "link";
@@ -391,66 +1177,95 @@ export declare const EVT_UNSELECT = "unselect";
391
1177
 
392
1178
  export declare const EVT_UPDATE = "update";
393
1179
 
394
- declare type ExportedLink = {
1180
+ export declare type ExportedLink = {
395
1181
  id: Id;
396
- side: "start" | "end";
397
- type: "node" | "text";
1182
+ side: Side;
1183
+ type: TargetType;
398
1184
  magnet?: Point;
399
1185
  };
400
1186
 
1187
+ /** Extremity types for arrow annotations. */
401
1188
  export declare type Extremity = "none" | "arrow" | "arrow-plain" | "dot" | "halo-dot";
402
1189
 
1190
+ /** Event related to a single annotation feature */
1191
+ export declare interface FeatureEvent {
1192
+ /** Annotation ID involved in the event */
1193
+ id: Id;
1194
+ }
1195
+
403
1196
  export declare type FeatureEvents = {
404
1197
  /**
405
1198
  * Event trigerred when selecting an annotation
406
1199
  * @param evt The annotation selected
407
1200
  */
408
- [EVT_SELECT]: (evt: Annotation) => void;
1201
+ [EVT_SELECT]: (evt: FeaturesEvent) => void;
409
1202
  /**
410
1203
  * Event trigerred when unselecting an annotation
411
1204
  * @param evt The annotation unselected
412
1205
  */
413
- [EVT_UNSELECT]: (evt: Annotation) => void;
1206
+ [EVT_UNSELECT]: (evt: FeaturesEvent) => void;
414
1207
  /**
415
1208
  * Event trigerred when removing an annotation
416
1209
  * @param evt The annotation removed
417
1210
  */
418
- [EVT_REMOVE]: (evt: Annotation) => void;
1211
+ [EVT_REMOVE]: (evt: FeatureEvent) => void;
419
1212
  /**
420
1213
  * Event trigerred when adding an annotation
421
1214
  * @param evt The annotation added
422
1215
  */
423
- [EVT_ADD]: (evt: Annotation) => void;
1216
+ [EVT_ADD]: (evt: FeatureEvent) => void;
1217
+ /**
1218
+ * Event trigerred when canceling drawing mode
1219
+ */
424
1220
  [EVT_CANCEL_DRAWING]: () => void;
425
1221
  /**
426
- * Event trigerred when updating an annotation
427
- * @returns The annotation updated
1222
+ * Event trigerred when completing a drawing operation
1223
+ * @param evt Contains the ID of the completed annotation
1224
+ */
1225
+ [EVT_COMPLETE_DRAWING]: (evt: FeatureEvent) => void;
1226
+ /**
1227
+ * Event trigerred when updating an annotation.
1228
+ * This fires after any modification including drag operations, style changes, scaling, etc.
1229
+ * @param evt The updated annotation with all changes applied
428
1230
  */
429
1231
  [EVT_UPDATE]: (evt: Annotation) => void;
430
1232
  /**
431
- * Event trigerred when linking an arrow to a text or node
1233
+ * Event trigerred when linking an arrow to a node or annotation
1234
+ * @param evt Contains the arrow and link details
432
1235
  */
433
1236
  [EVT_LINK]: (evt: {
434
1237
  arrow: Arrow;
435
1238
  link: Link;
436
1239
  }) => void;
437
1240
  /**
438
- * Event trigerred when starting to drag an arrow or a text
1241
+ * Event trigerred when history state changes (after undo/redo operations)
1242
+ * @param evt Contains boolean flags for undo/redo availability
439
1243
  */
440
- [EVT_DRAG_START]: (evt: Arrow | Text_2) => void;
1244
+ [EVT_HISTORY]: (evt: HistoryEvent) => void;
441
1245
  /**
442
- * Event trigerred when dragging an arrow or a text
1246
+ * Event triggered when a drag operation starts on an annotation
443
1247
  */
444
- [EVT_DRAG]: (evt: Arrow | Text_2, key: "line" | "start" | "end" | "text") => void;
1248
+ [EVT_DRAG_START]: () => void;
445
1249
  /**
446
- * Event trigerred when stopped dragging an arrow or a text
1250
+ * Event triggered when a drag operation ends on an annotation
447
1251
  */
448
- [EVT_DRAG_END]: (evt: Arrow | Text_2) => void;
1252
+ [EVT_DRAG_END]: () => void;
1253
+ /**
1254
+ * Event triggered when a click completes on an annotation (mouseup without drag)
1255
+ */
1256
+ [EVT_CLICK]: () => void;
449
1257
  };
450
1258
 
1259
+ /** Event related to multiple annotation features */
1260
+ export declare interface FeaturesEvent {
1261
+ /** Annotation IDs involved in the event */
1262
+ ids: Id[];
1263
+ }
1264
+
451
1265
  /**
452
1266
  * Calculate the bounds of a collection of annotations
453
1267
  * @param annotations
1268
+ * @returns Bounds [minX, minY, maxX, maxY]
454
1269
  */
455
1270
  export declare function getAnnotationsBounds(annotations: AnnotationCollection): Bounds;
456
1271
 
@@ -470,7 +1285,7 @@ export declare function getArrowEndPoints(a: Arrow): {
470
1285
  };
471
1286
  };
472
1287
 
473
- export declare function getArrowSide(a: Arrow, side: "start" | "end"): {
1288
+ export declare function getArrowSide(a: Arrow, side: Side): {
474
1289
  x: number;
475
1290
  y: number;
476
1291
  };
@@ -480,40 +1295,179 @@ export declare function getArrowStart(a: Arrow): {
480
1295
  y: number;
481
1296
  };
482
1297
 
483
- export declare function getAttachmentPointOnNode(start: Point_2, nodeCenter: Point_2, nodeRadius: number): {
1298
+ export declare function getAttachmentPointOnNode(start: Point_3, nodeCenter: Point_3, nodeRadius: number): {
484
1299
  x: number;
485
1300
  y: number;
486
1301
  };
487
1302
 
488
- export declare function getCoordinates(gj: Feature | FeatureCollection | Geometry): Position[];
489
-
490
- export declare const getHandleId: (handle: HTMLDivElement) => number;
1303
+ declare function getBbox<T extends Annotation>(b: T): BBox;
1304
+ export { getBbox }
1305
+ export { getBbox as getTextBbox }
491
1306
 
492
- export declare function getTextBbox(t: Text_2): BBox;
1307
+ export declare function getBoxCenter<T extends Annotation>(t: T): {
1308
+ x: number;
1309
+ y: number;
1310
+ };
493
1311
 
494
- export declare function getTextPosition(t: Text_2): {
1312
+ declare function getBoxPosition<T extends Annotation>(t: T, fixedSize?: boolean, zoom?: number): {
495
1313
  x: number;
496
1314
  y: number;
497
1315
  };
1316
+ export { getBoxPosition }
1317
+ export { getBoxPosition as getTextPosition }
498
1318
 
499
- export declare function getTextSize(t: Text_2): {
1319
+ declare function getBoxSize<T extends Annotation>(t: T): {
500
1320
  width: number;
501
1321
  height: number;
502
1322
  };
1323
+ export { getBoxSize }
1324
+ export { getBoxSize as getTextSize }
503
1325
 
504
- export declare function hexShortToLong(color: string): string;
1326
+ /** @private */
1327
+ export declare function getBrowserWindow(): HTMLElement | undefined;
505
1328
 
506
- export declare function hexToRgba(color: string, alpha: number): string;
1329
+ /**
1330
+ * Get the position (center) of a comment
1331
+ *
1332
+ * @param comment - Comment annotation
1333
+ * @returns Center position
1334
+ */
1335
+ export declare function getCommentPosition(comment: Comment_2): Point;
507
1336
 
1337
+ /**
1338
+ * Get the dimensions of a comment based on its mode
1339
+ *
1340
+ * @param comment - Comment annotation
1341
+ * @returns Width and height
1342
+ */
1343
+ export declare function getCommentSize(comment: Comment_2): Size;
1344
+
1345
+ /**
1346
+ * Get the effective zoom threshold for a comment
1347
+ * Uses explicit threshold if set, otherwise calculates from dimensions
1348
+ *
1349
+ * @param comment - Comment annotation
1350
+ * @returns Effective zoom threshold
1351
+ */
1352
+ export declare function getCommentZoomThreshold(comment: Comment_2): number;
1353
+
1354
+ export declare function getCoordinates(geojson: Feature | FeatureCollection | Geometry): Position[];
1355
+
1356
+ export declare const getHandleId: (handle: HTMLDivElement) => number;
1357
+
1358
+ /**
1359
+ * Get bounding box of a polygon
1360
+ */
1361
+ export declare function getPolygonBounds(polygon: Polygon): Bounds;
1362
+
1363
+ /**
1364
+ * Get centroid (geometric center) of a polygon
1365
+ */
1366
+ export declare function getPolygonCenter(polygon: Polygon): Point;
1367
+
1368
+ export declare const handleDetectionThreshold = 5;
1369
+
1370
+ export declare const handleRadius = 3;
1371
+
1372
+ /**
1373
+ * Hex color string in format #RGB or #RRGGBB
1374
+ * @example "#fff" | "#ffffff" | "#F0A" | "#FF00AA"
1375
+ */
1376
+ export declare type HexColor = `#${string}`;
1377
+
1378
+ export declare function hexShortToLong(color: HexColor): HexColor;
1379
+
1380
+ /**
1381
+ * Adds alpha channel to a hex color
1382
+ * @param color
1383
+ * @param alpha
1384
+ * @returns rgba color string
1385
+ */
1386
+ export declare function hexToRgba(color: HexColor, alpha: number): RgbaColor;
1387
+
1388
+ /** History stack change event */
1389
+ export declare interface HistoryEvent {
1390
+ /** Indicates if undo operation is available */
1391
+ canUndo: boolean;
1392
+ /** Indicates if redo operation is available */
1393
+ canRedo: boolean;
1394
+ }
1395
+
1396
+ export declare const HL_BRIGHTEN = 0.2;
1397
+
1398
+ /** Unique identifier type for annotations */
508
1399
  export declare type Id = string | number;
509
1400
 
1401
+ /** Helper to check if a feature collection is an annotation collection */
510
1402
  export declare const isAnnotationCollection: (a: AnnotationFeature<Geometry, AnnotationProps> | FeatureCollection) => a is AnnotationCollection;
511
1403
 
512
1404
  export declare const isArrow: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Arrow;
513
1405
 
1406
+ export declare const isBox: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Box;
1407
+
1408
+ /**
1409
+ * Type guard to check if a string is a valid color
1410
+ */
1411
+ export declare function isColor(color: string): color is Color;
1412
+
1413
+ /**
1414
+ * Type guard to check if an annotation is a Comment
1415
+ */
1416
+ export declare const isComment: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Comment_2;
1417
+
1418
+ /**
1419
+ * Helper functions for managing comment-arrow relationships
1420
+ *
1421
+ * These functions provide utilities for:
1422
+ * - Checking if an arrow is connected to a comment
1423
+ * - Determining if arrow endpoints can be detached from comments
1424
+ *
1425
+ * Note: The core rule "comments must have at least one arrow" is enforced
1426
+ * in store/index.ts removeFeature() method, not here.
1427
+ */
1428
+ /**
1429
+ * Check if an arrow is connected to a comment
1430
+ *
1431
+ * @param arrow - The arrow feature to check
1432
+ * @returns True if the arrow has a comment on either end
1433
+ *
1434
+ * @example
1435
+ * ```typescript
1436
+ * if (isCommentArrow(arrow)) {
1437
+ * // Handle comment arrow specially
1438
+ * }
1439
+ * ```
1440
+ */
1441
+ export declare function isCommentArrow(arrow: Arrow): boolean;
1442
+
1443
+ /**
1444
+ * Type guard to check if a string is a valid hex color
1445
+ */
1446
+ export declare function isHexColor(color: string): color is HexColor;
1447
+
1448
+ export declare const isPolygon: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Polygon;
1449
+
1450
+ /**
1451
+ * Type guard to check if a string is a valid RGBA color
1452
+ */
1453
+ export declare function isRgbaColor(color: string): color is RgbaColor;
1454
+
1455
+ /**
1456
+ * Type guard to check if a string is a valid RGB color
1457
+ */
1458
+ export declare function isRgbColor(color: string): color is RgbColor;
1459
+
514
1460
  export declare const isText: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Text_2;
515
1461
 
516
- export declare type Link = {
1462
+ /** @private */
1463
+ export declare const LAYERS: {
1464
+ SHAPES: number;
1465
+ EDITOR: number;
1466
+ HANDLES: number;
1467
+ };
1468
+
1469
+ /** Link between an arrow and a text or node */
1470
+ export declare interface Link {
517
1471
  /** arrow attached to the text or node */
518
1472
  arrow: Id;
519
1473
  /** id of the text the arrow is attached to */
@@ -526,113 +1480,204 @@ export declare type Link = {
526
1480
  targetType: TargetType;
527
1481
  /**
528
1482
  * On which point relative to topleft corner the arrow is tighten, in case of
529
- * node, it can be deduced from the arrow itself
1483
+ * node, a 0 vector represents the center, otherwise it can be deduced from the arrow itself
530
1484
  */
531
- connectionPoint: Point;
532
- };
1485
+ magnet: Point;
1486
+ }
1487
+
1488
+ /**
1489
+ * Migrates old Polygon-based Box/Text to new Point-based format
1490
+ * Called only when annotations are added/loaded
1491
+ * @private
1492
+ */
1493
+ export declare function migrateBoxOrTextIfNeeded<T extends Annotation>(annotation: T): T;
533
1494
 
534
1495
  export declare const NONE = -1;
535
1496
 
1497
+ export declare function parseColor(color: Color): {
1498
+ r: number;
1499
+ g: number;
1500
+ b: number;
1501
+ a: number;
1502
+ };
1503
+
1504
+ /** 2D coordinate */
536
1505
  export declare type Point = {
537
1506
  x: number;
538
1507
  y: number;
539
1508
  };
540
1509
 
541
- export declare function rgbToRgba(color: string, alpha: number): string;
1510
+ /**
1511
+ * Polygon placed on the graph, use it to highlight areas
1512
+ */
1513
+ export declare interface Polygon extends AnnotationFeature<Polygon_2, PolygonProperties> {
1514
+ }
1515
+
1516
+ export declare interface PolygonProperties extends AnnotationProps {
1517
+ type: "polygon";
1518
+ style?: PolygonStyle;
1519
+ }
542
1520
 
543
- export declare function scaleGeometry(geometry: LineString | Polygon, scale: number, ox: number, oy: number): LineString | Polygon;
1521
+ export declare interface PolygonStyle extends BoxStyle {
1522
+ }
1523
+
1524
+ /**
1525
+ * RGBA color string in format rgba(r, g, b, a)
1526
+ * @example "rgba(255, 0, 0, 1)" | "rgba(128, 128, 128, 0.5)"
1527
+ */
1528
+ export declare type RgbaColor = `rgba(${number}, ${number}, ${number}, ${number})` | `rgba(${number},${number},${number},${number})`;
1529
+
1530
+ /**
1531
+ * RGB color string in format rgb(r, g, b)
1532
+ * @example "rgb(255, 0, 0)" | "rgb(128, 128, 128)"
1533
+ */
1534
+ export declare type RgbColor = `rgb(${number}, ${number}, ${number})` | `rgb(${number},${number},${number})`;
1535
+
1536
+ /**
1537
+ * Adds alpha channel to an rgb color
1538
+ * @param color
1539
+ * @param alpha
1540
+ * @returns rgba color string
1541
+ */
1542
+ export declare function rgbToRgba(color: RgbColor, alpha: number): RgbaColor;
1543
+
1544
+ export declare function scaleGeometry(geometry: LineString | Polygon_2, scale: number, ox: number, oy: number): LineString | Polygon_2;
1545
+
1546
+ /**
1547
+ * Scale polygon around an origin point
1548
+ */
1549
+ export declare function scalePolygon(polygon: Polygon, scale: number, originX: number, originY: number): Polygon;
544
1550
 
545
1551
  export declare function setArrowEnd(a: Arrow, x: number, y: number): void;
546
1552
 
547
- export declare function setArrowEndPoint(a: Arrow, side: "start" | "end", x: number, y: number): void;
1553
+ export declare function setArrowEndPoint(a: Arrow, side: Side, x: number, y: number): void;
548
1554
 
549
1555
  export declare function setArrowStart(a: Arrow, x: number, y: number): void;
550
1556
 
551
- export declare function setTextBbox(t: Text_2, x: number, y: number, width: number, height: number): void;
1557
+ declare function setBbox(t: Box | Text_2, x: number, y: number, width: number, height: number): void;
1558
+ export { setBbox }
1559
+ export { setBbox as setTextBbox }
1560
+
1561
+ export declare type Side = typeof SIDE_START | typeof SIDE_END;
1562
+
1563
+ export declare const SIDE_END: "end";
552
1564
 
553
- export declare type Side = "start" | "end";
1565
+ export declare const SIDE_START: "start";
554
1566
 
1567
+ /**
1568
+ * Polyline simplification using a combination of
1569
+ * the Radial Distance and
1570
+ * the Douglas-Peucker algorithms
1571
+ * See https://github.com/mourner/simplify-js for more details
1572
+ *
1573
+ * @param points Points to simplify
1574
+ * @param tolerance Tolerance in pixels
1575
+ * @param highestQuality Whether to skip radial distance simplification
1576
+ * @returns Simplified points
1577
+ */
1578
+ export declare function simplifyPolygon(points: Position[], tolerance: number, highestQuality: boolean): Position[];
1579
+
1580
+ /** Stroke style for arrow annotations */
555
1581
  export declare type Stroke = {
556
- type: "plain" | "dashed" | "none";
557
- color: string;
1582
+ /** Stroke type */
1583
+ type: StrokeType;
1584
+ /** Stroke color */
1585
+ color: Color;
1586
+ /** Stroke width */
558
1587
  width: number;
559
1588
  };
560
1589
 
1590
+ /** Stroke style options for annotations */
561
1591
  export declare type StrokeOptions = {
562
- strokeType?: "plain" | "dashed" | "none";
563
- strokeColor?: string;
1592
+ /** Type of stroke: plain, dashed, or none */
1593
+ strokeType?: StrokeType;
1594
+ /** Stroke color: #f00, yellow... */
1595
+ strokeColor?: Color;
1596
+ /** Stroke width */
564
1597
  strokeWidth?: number;
565
1598
  };
566
1599
 
567
1600
  export declare type StrokeStyle = Stroke;
568
1601
 
569
- export declare type TargetType = "text" | "node";
1602
+ /** Stroke types available for annotations */
1603
+ export declare type StrokeType = "plain" | "dashed" | "none";
1604
+
1605
+ /** @private */
1606
+ export declare const TARGET_TYPES: {
1607
+ TEXT: "text";
1608
+ NODE: "node";
1609
+ BOX: "box";
1610
+ COMMENT: "comment";
1611
+ POLYGON: "polygon";
1612
+ ANNOTATION: "annotation";
1613
+ EDGE: "edge";
1614
+ };
1615
+
1616
+ export declare type TargetType = (typeof TARGET_TYPES)[keyof typeof TARGET_TYPES];
570
1617
 
571
- declare type Text_2 = AnnotationFeature<Polygon, TextProperties>;
1618
+ /**
1619
+ * Text annotation feature, represents a text box at a specific position
1620
+ */
1621
+ declare interface Text_2 extends AnnotationFeature<Point_2, TextProperties> {
1622
+ }
572
1623
  export { Text_2 as Text }
573
1624
 
574
- export declare interface TextProperties extends AnnotationProps {
1625
+ export declare const TEXT_LINE_HEIGHT = 1.2;
1626
+
1627
+ export declare interface TextProperties extends Omit<BoxProperties, "type"> {
575
1628
  type: "text";
576
1629
  /**text to display*/
577
1630
  content: string;
1631
+ /** Width of the text box */
1632
+ width: number;
1633
+ /** Height of the text box */
1634
+ height: number;
578
1635
  style?: TextStyle;
579
1636
  }
580
1637
 
581
- /**
582
- * @class Texts
583
- * Draw, update, edit texts
584
- */
585
- export declare class Texts extends Editor<Text_2> {
586
- private textArea;
587
- private handleSize;
588
- private rect;
589
- private annotation;
590
- private startX;
591
- private startY;
592
- private handles;
593
- private draggedHandle;
594
- private isFocused;
595
- private placeholder;
596
- constructor(ogma: default_3, options?: Pick<Partial<ControllerOptions>, "textHandleSize" | "textPlaceholder">);
597
- private _onFocus;
598
- private _onBlur;
599
- protected _canRemove(): boolean;
600
- startDrawing: (x: number, y: number, text?: Text_2) => void;
601
- cancelDrawing: () => void;
602
- private startDragging;
603
- private onHandleMouseDown;
604
- private onMouseMove;
605
- private _onMouseMove;
606
- private onMouseUp;
607
- private _onMousedown;
608
- private onViewChanged;
609
- private _onInput;
610
- detect({ x, y }: Point_2, margin?: number): Text_2 | undefined;
611
- draw(svg: SVGSVGElement): void;
612
- refreshDrawing(): void;
613
- getDefaultOptions(): Text_2;
614
- refreshEditor(): void;
615
- select(id: Id): void;
616
- destroy(): void;
617
- }
618
-
619
- export declare interface TextStyle extends StrokeOptions {
1638
+ export declare interface TextStyle extends BoxStyle {
620
1639
  /** Helvetica, sans-serif... */
621
1640
  font?: string;
622
1641
  /** Font size, in pixels */
623
1642
  fontSize?: number | string;
624
1643
  /** text color: #f00, yellow...*/
625
- color?: string;
1644
+ color?: Color;
626
1645
  /** background color: empty for transparent #f00, yellow...*/
627
- background?: string;
1646
+ background?: Color;
628
1647
  /** padding around the text */
629
1648
  padding?: number;
630
1649
  /** Text box border radius */
631
1650
  borderRadius?: number;
1651
+ /** When true, text maintains constant size regardless of zoom level */
1652
+ fixedSize?: boolean;
632
1653
  }
633
1654
 
634
- export declare function updateTextBbox(t: Text_2): void;
1655
+ /** @private */
1656
+ export declare const throttle: <T extends unknown[]>(callback: (...args: T) => void, delay?: number) => (...args: T) => void;
1657
+
1658
+ /**
1659
+ * Toggle comment mode between collapsed and expanded
1660
+ *
1661
+ * @param comment - Comment to toggle
1662
+ * @returns Updated comment with toggled mode
1663
+ */
1664
+ export declare function toggleCommentMode(comment: Comment_2): Comment_2;
1665
+
1666
+ /**
1667
+ * Translate (move) a polygon by dx, dy
1668
+ */
1669
+ export declare function translatePolygon(polygon: Polygon, dx: number, dy: number): Polygon;
1670
+
1671
+ declare function updateBbox<T extends Annotation>(t: T): void;
1672
+ export { updateBbox }
1673
+ export { updateBbox as updateTextBbox }
1674
+
1675
+ /**
1676
+ * Update bbox for a polygon
1677
+ */
1678
+ export declare function updatePolygonBbox(polygon: Polygon): void;
635
1679
 
1680
+ /** @private */
636
1681
  export declare type Vector = Point;
637
1682
 
638
1683
  export { }