@linkurious/ogma-annotations 2.0.3 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Polygon-DVFVmDbR.js +780 -0
- package/dist/index.js +8 -13
- package/dist/index.mjs +4352 -3732
- package/dist/ogma-annotations.css +1 -1
- package/dist/types/index.d.ts +111 -5
- package/dist/types/ui.d.ts +1415 -0
- package/dist/ui-styles.css +573 -0
- package/dist/ui.js +48 -0
- package/dist/ui.mjs +533 -0
- package/package.json +30 -11
- package/src/style.d.ts +2 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--handle-width: 2px;--point-handle-width: calc(3 * var(--handle-width));--point-handle-border: 2px;--point-handle-total: calc(var(--point-handle-width) + var(--point-handle-border));--handle-color: #38e;--handle-background: #fff;--active-color: #1a70e5;--disabled-color: #999;--hover-color: rgba(56, 136, 238, .2)}svg text{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.handle{position:absolute;background-color:var(--handle-color)}.handle.line{cursor:move}.ogma-annotation-text-editor{display:flex;flex-direction:column;align-items:flex-end;position:relative;width:100%;height:100%}.ogma-annotation-text-editor.animate-width{transition:width .2s ease-out,left .2s ease-out}.ogma-annotation-text-editor textarea{outline:none;padding:0;margin:0;border:0;width:100%;height:100%;cursor:text;z-index:1000;resize:none;white-space:break-spaces;background-color:transparent;overflow:hidden}.ogma-annotation-text-editor textarea::-webkit-scrollbar{width:6px}.ogma-annotation-text-editor textarea::-webkit-scrollbar-track{background:transparent}.ogma-annotation-text-editor textarea::-webkit-scrollbar-thumb{background:#0003;border-radius:3px}.ogma-annotation-text-editor textarea::-webkit-scrollbar-thumb:hover{background:#0000004d}.ogma-send-button{width:24px;height:24px;margin-left:auto;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:background-color .2s ease;z-index:1001}.ogma-send-button-icon{width:16px;height:16px;display:flex;align-items:center;justify-content:center;color:var(--handle-color, #38e)}.ogma-send-button-icon svg{width:100%;height:100%}.ogma-send-button:not(:disabled):hover{background-color:var(--hover-color);transform:scale(1.05)}.ogma-send-button:not(:disabled):hover .ogma-send-button-icon{color:var(--active-color)}.ogma-send-button:not(:disabled):active{background-color:var(--hover-color);transform:scale(.95)}.ogma-send-button:not(:disabled):active .ogma-send-button-icon{color:var(--active-color)}.ogma-send-button:disabled{cursor:not-allowed;opacity:.3}.ogma-send-button:disabled .ogma-send-button-icon{color:var(--disabled-color)}.annotation-text-handle .noevents{pointer-events:none;z-index:20}.line-handle,.point-handle{z-index:30}.line-handle.top{cursor:ns-resize;height:var(--handle-width);left:0;width:100%;top:calc(var(--handle-width) * -1)}.line-handle.bottom{cursor:ns-resize;height:var(--handle-width);width:100%;left:0;bottom:calc(var(--handle-width) * -1)}.line-handle.left{cursor:ew-resize;height:100%;top:0;left:calc(var(--handle-width) * -1);width:var(--handle-width)}.line-handle.right{cursor:ew-resize;height:100%;right:calc(var(--handle-width) * -1);top:0;width:var(--handle-width)}.line-handle.top,.line-handle.bottom,.line-handle.left,.line-handle.right{cursor:move}.point-handle{border-radius:50%;background-color:#fff;transform-origin:center;transform:translate(-50%,-50%);border:var(--point-handle-border) solid var(--handle-color);width:var(--point-handle-width);height:var(--point-handle-width)}.point-handle.top-left{transform:translate(-55%,-55%)}.point-handle.top-right{transform:translate(-45%,-55%)}.point-handle.bottom-left{transform:translate(-55%,-45%)}.point-handle.bottom-right{transform:translate(-45%,-45%)}.rotated .point-handle.bottom-left,.rotated .point-handle.top-right{display:none}.point-handle.top-left,.point-handle.bottom-right{cursor:nwse-resize}.point-handle.top-right,.point-handle.bottom-left{cursor:nesw-resize}.point-handle.bottom-left,.point-handle.bottom-right{top:100%}.point-handle.top-left,.point-handle.top-right{top:0}.point-handle.bottom-left,.point-handle.top-left{left:0}.point-handle.bottom-right,.point-handle.top-right{left:100%}.arrow-handle>.handle{height:var(--point-handle-width);width:var(--point-handle-width);border-radius:50%;cursor:move;transform:translate(-50%,-50%)}.arrow-handle>.line{height:var(--handle-width);border-radius:0;cursor:move}.arrow-handle>.point{background-color:var(--handle-background);border:2px solid var(--handle-color)}.annotations-hidden-input{position:absolute;bottom:0;left:0;visibility:hidden;display:block}.active{background-color:#38e}.annotation-text{cursor:pointer}.annotation-text:hover>rect{stroke:var(--handle-color)}.annotation-text a{fill:var(--handle-color)}.annotation-text a:hover{text-decoration:underline}.annotation-hovered,.annotation-selected{background:#f5f5f5;background-color:#f5f5f5}
|
|
1
|
+
:root{--handle-width: 2px;--point-handle-width: calc(3 * var(--handle-width));--point-handle-border: 2px;--point-handle-total: calc(var(--point-handle-width) + var(--point-handle-border));--handle-color: #38e;--annotation-link-color: var(--handle-color);--handle-background: #fff;--active-color: #1a70e5;--disabled-color: #999;--hover-color: rgba(56, 136, 238, .2)}svg text{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ogma-annotation-link{fill:var(--annotation-link-color, #38e);color:var(--annotation-link-color, #38e);text-decoration:none;pointer-events:auto;cursor:pointer}.handle{position:absolute;background-color:var(--handle-color)}.handle.line{cursor:move}.ogma-annotation-text-editor{display:flex;flex-direction:column;align-items:flex-end;position:relative;width:100%;height:100%}.ogma-annotation-text-editor.animate-width{transition:width .2s ease-out,left .2s ease-out}.ogma-annotation-text-editor textarea{outline:none;padding:0;margin:0;border:0;width:100%;height:100%;cursor:text;z-index:1000;resize:none;white-space:break-spaces;background-color:transparent;overflow:hidden}.ogma-annotation-text-editor textarea::-webkit-scrollbar{width:6px}.ogma-annotation-text-editor textarea::-webkit-scrollbar-track{background:transparent}.ogma-annotation-text-editor textarea::-webkit-scrollbar-thumb{background:#0003;border-radius:3px}.ogma-annotation-text-editor textarea::-webkit-scrollbar-thumb:hover{background:#0000004d}.ogma-send-button{width:24px;height:24px;margin-left:auto;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:background-color .2s ease;z-index:1001}.ogma-send-button-icon{width:16px;height:16px;display:flex;align-items:center;justify-content:center;color:var(--handle-color, #38e)}.ogma-send-button-icon svg{width:100%;height:100%}.ogma-send-button:not(:disabled):hover{background-color:var(--hover-color);transform:scale(1.05)}.ogma-send-button:not(:disabled):hover .ogma-send-button-icon{color:var(--active-color)}.ogma-send-button:not(:disabled):active{background-color:var(--hover-color);transform:scale(.95)}.ogma-send-button:not(:disabled):active .ogma-send-button-icon{color:var(--active-color)}.ogma-send-button:disabled{cursor:not-allowed;opacity:.3}.ogma-send-button:disabled .ogma-send-button-icon{color:var(--disabled-color)}.annotation-text-handle .noevents{pointer-events:none;z-index:20}.line-handle,.point-handle{z-index:30}.line-handle.top{cursor:ns-resize;height:var(--handle-width);left:0;width:100%;top:calc(var(--handle-width) * -1)}.line-handle.bottom{cursor:ns-resize;height:var(--handle-width);width:100%;left:0;bottom:calc(var(--handle-width) * -1)}.line-handle.left{cursor:ew-resize;height:100%;top:0;left:calc(var(--handle-width) * -1);width:var(--handle-width)}.line-handle.right{cursor:ew-resize;height:100%;right:calc(var(--handle-width) * -1);top:0;width:var(--handle-width)}.line-handle.top,.line-handle.bottom,.line-handle.left,.line-handle.right{cursor:move}.point-handle{border-radius:50%;background-color:#fff;transform-origin:center;transform:translate(-50%,-50%);border:var(--point-handle-border) solid var(--handle-color);width:var(--point-handle-width);height:var(--point-handle-width)}.point-handle.top-left{transform:translate(-55%,-55%)}.point-handle.top-right{transform:translate(-45%,-55%)}.point-handle.bottom-left{transform:translate(-55%,-45%)}.point-handle.bottom-right{transform:translate(-45%,-45%)}.rotated .point-handle.bottom-left,.rotated .point-handle.top-right{display:none}.point-handle.top-left,.point-handle.bottom-right{cursor:nwse-resize}.point-handle.top-right,.point-handle.bottom-left{cursor:nesw-resize}.point-handle.bottom-left,.point-handle.bottom-right{top:100%}.point-handle.top-left,.point-handle.top-right{top:0}.point-handle.bottom-left,.point-handle.top-left{left:0}.point-handle.bottom-right,.point-handle.top-right{left:100%}.arrow-handle>.handle{height:var(--point-handle-width);width:var(--point-handle-width);border-radius:50%;cursor:move;transform:translate(-50%,-50%)}.arrow-handle>.line{height:var(--handle-width);border-radius:0;cursor:move}.arrow-handle>.point{background-color:var(--handle-background);border:2px solid var(--handle-color)}.annotations-hidden-input{position:absolute;bottom:0;left:0;visibility:hidden;display:block}.active{background-color:#38e}.annotation-text{cursor:pointer}.annotation-text:hover>rect{stroke:var(--handle-color)}.annotation-text a{fill:var(--handle-color)}.annotation-text a:hover{text-decoration:underline}.annotation-hovered,.annotation-selected{background:#f5f5f5;background-color:#f5f5f5}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -128,6 +128,19 @@ export declare type Bounds = [number, number, number, number];
|
|
|
128
128
|
export declare interface Box extends AnnotationFeature<Point_2, BoxProperties> {
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Arrow snapped to a rectangular annotation (text, box, comment).
|
|
133
|
+
* nx/ny are center-relative fractions multiplied by width/height:
|
|
134
|
+
* left-center = { nx: -0.5, ny: 0 }
|
|
135
|
+
* right-center = { nx: 0.5, ny: 0 }
|
|
136
|
+
* center = { nx: 0, ny: 0 }
|
|
137
|
+
*/
|
|
138
|
+
export declare type BoxMagnet = {
|
|
139
|
+
type: "box";
|
|
140
|
+
nx: number;
|
|
141
|
+
ny: number;
|
|
142
|
+
};
|
|
143
|
+
|
|
131
144
|
/** Properties specific to box annotations. */
|
|
132
145
|
export declare interface BoxProperties extends AnnotationProps {
|
|
133
146
|
type: "box";
|
|
@@ -543,6 +556,51 @@ export declare class Control extends default_2<FeatureEvents> {
|
|
|
543
556
|
commentStyle?: Partial<CommentProps>;
|
|
544
557
|
arrowStyle?: Partial<ArrowProperties>;
|
|
545
558
|
}): this;
|
|
559
|
+
/**
|
|
560
|
+
* Enable sticky note drawing mode - drops a plain, resizable text box
|
|
561
|
+
* (empty content, "Quick note…" ghost placeholder, no connector arrow)
|
|
562
|
+
* like a Miro sticky note, unlike `enableCommentDrawing`. It's a regular
|
|
563
|
+
* `text` annotation, so it's placed the same interactive way as
|
|
564
|
+
* `enableBoxDrawing`/`enableTextDrawing`: click for a default-size square,
|
|
565
|
+
* or drag to size it - either way it keeps the usual corner/edge drag
|
|
566
|
+
* handles to resize it afterward.
|
|
567
|
+
*
|
|
568
|
+
* Call this method when the user clicks an "Add sticky note" button. The
|
|
569
|
+
* control will:
|
|
570
|
+
* 1. Wait for the next mousedown event
|
|
571
|
+
* 2. Create the note at that position and start the interactive
|
|
572
|
+
* corner-drag, already selected
|
|
573
|
+
* 3. On release: a plain click (no drag) gets a default square size, a
|
|
574
|
+
* drag gets sized to match instead - either way it drops straight
|
|
575
|
+
* into editing (the placeholder is just ghost text, so typing
|
|
576
|
+
* immediately replaces it)
|
|
577
|
+
* 4. Clean up automatically when done
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* ```ts
|
|
581
|
+
* addStickyNoteButton.addEventListener('click', () => {
|
|
582
|
+
* control.enableStickyNoteDrawing({ background: '#FFEB99' });
|
|
583
|
+
* });
|
|
584
|
+
* ```
|
|
585
|
+
*
|
|
586
|
+
* @param style Sticky note style options (merged over the sticky note defaults)
|
|
587
|
+
* @returns this for chaining
|
|
588
|
+
* @see startStickyNote for low-level programmatic control
|
|
589
|
+
*/
|
|
590
|
+
enableStickyNoteDrawing(style?: Partial<Text_2["properties"]["style"]>): this;
|
|
591
|
+
/**
|
|
592
|
+
* Enable erase mode: every click on an annotation deletes it immediately.
|
|
593
|
+
* Stays armed across multiple clicks until `disableEraseMode()` is called,
|
|
594
|
+
* or another drawing tool is enabled / `cancelDrawing()` is called.
|
|
595
|
+
*
|
|
596
|
+
* @returns this for chaining
|
|
597
|
+
* @see disableEraseMode to turn erase mode off
|
|
598
|
+
*/
|
|
599
|
+
enableEraseMode(): this;
|
|
600
|
+
/** Turn erase mode off. No-op if it isn't active. */
|
|
601
|
+
disableEraseMode(): this;
|
|
602
|
+
/** Whether erase mode is currently active. */
|
|
603
|
+
isEraseModeActive(): boolean;
|
|
546
604
|
/**
|
|
547
605
|
* Place a pre-created annotation by moving it with the cursor.
|
|
548
606
|
* The annotation follows the mouse until the user clicks to place it.
|
|
@@ -590,6 +648,21 @@ export declare class Control extends default_2<FeatureEvents> {
|
|
|
590
648
|
commentStyle?: Partial<CommentProps>;
|
|
591
649
|
arrowStyle?: Partial<ArrowProperties>;
|
|
592
650
|
}): this;
|
|
651
|
+
/**
|
|
652
|
+
* **Advanced API:** Programmatically start drawing a sticky note at
|
|
653
|
+
* specific coordinates - same interactive corner-drag as `startBox`.
|
|
654
|
+
* You must handle mouse events yourself (or immediately release/complete
|
|
655
|
+
* it via the same events `enableStickyNoteDrawing` would).
|
|
656
|
+
*
|
|
657
|
+
* **For most use cases, use `enableStickyNoteDrawing()` instead.**
|
|
658
|
+
*
|
|
659
|
+
* @param x X coordinate for the note's top-left corner
|
|
660
|
+
* @param y Y coordinate for the note's top-left corner
|
|
661
|
+
* @param style Sticky note style options
|
|
662
|
+
* @returns this for chaining
|
|
663
|
+
* @see enableStickyNoteDrawing for the recommended high-level API
|
|
664
|
+
*/
|
|
665
|
+
startStickyNote(x: number, y: number, style?: Partial<Text_2["properties"]["style"]>): this;
|
|
593
666
|
/**
|
|
594
667
|
* **Advanced API:** Programmatically start drawing a box at specific coordinates.
|
|
595
668
|
*
|
|
@@ -1209,6 +1282,12 @@ declare interface DragEvent_2 {
|
|
|
1209
1282
|
}
|
|
1210
1283
|
export { DragEvent_2 as DragEvent }
|
|
1211
1284
|
|
|
1285
|
+
/** Arrow snapped at parametric position t (0–1) along an edge path. */
|
|
1286
|
+
export declare type EdgeMagnet = {
|
|
1287
|
+
type: "edge";
|
|
1288
|
+
t: number;
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1212
1291
|
export declare const EVT_ADD = "add";
|
|
1213
1292
|
|
|
1214
1293
|
export declare const EVT_CANCEL_DRAWING = "cancelDrawing";
|
|
@@ -1239,6 +1318,11 @@ export declare const EVT_UNSELECT = "unselect";
|
|
|
1239
1318
|
|
|
1240
1319
|
export declare const EVT_UPDATE = "update";
|
|
1241
1320
|
|
|
1321
|
+
/**
|
|
1322
|
+
* Serialized link stored inside arrow.properties.link.
|
|
1323
|
+
* Uses plain { x, y } for backward compatibility with saved annotations.
|
|
1324
|
+
* Converted to the internal Magnet type by Links.add().
|
|
1325
|
+
*/
|
|
1242
1326
|
export declare type ExportedLink = {
|
|
1243
1327
|
id: Id;
|
|
1244
1328
|
side: Side;
|
|
@@ -1540,13 +1624,12 @@ export declare interface Link {
|
|
|
1540
1624
|
target: Id;
|
|
1541
1625
|
/** Text or node */
|
|
1542
1626
|
targetType: TargetType;
|
|
1543
|
-
/**
|
|
1544
|
-
|
|
1545
|
-
* node, a 0 vector represents the center, otherwise it can be deduced from the arrow itself
|
|
1546
|
-
*/
|
|
1547
|
-
magnet: Point;
|
|
1627
|
+
/** Typed snap point — semantics depend on targetType, see Magnet union. */
|
|
1628
|
+
magnet: Magnet;
|
|
1548
1629
|
}
|
|
1549
1630
|
|
|
1631
|
+
export declare type Magnet = NodeMagnet | EdgeMagnet | BoxMagnet | PolygonMagnet;
|
|
1632
|
+
|
|
1550
1633
|
/**
|
|
1551
1634
|
* Migrates old Polygon-based Box/Text to new Point-based format
|
|
1552
1635
|
* Called only when annotations are added/loaded
|
|
@@ -1554,6 +1637,12 @@ export declare interface Link {
|
|
|
1554
1637
|
*/
|
|
1555
1638
|
export declare function migrateBoxOrTextIfNeeded<T extends Annotation>(annotation: T): T;
|
|
1556
1639
|
|
|
1640
|
+
/** Arrow snapped to the center or perimeter of a node. */
|
|
1641
|
+
export declare type NodeMagnet = {
|
|
1642
|
+
type: "node";
|
|
1643
|
+
center: boolean;
|
|
1644
|
+
};
|
|
1645
|
+
|
|
1557
1646
|
export declare const NONE = -1;
|
|
1558
1647
|
|
|
1559
1648
|
export declare function parseColor(color: Color): {
|
|
@@ -1575,6 +1664,16 @@ export declare type Point = {
|
|
|
1575
1664
|
export declare interface Polygon extends AnnotationFeature<Polygon_2, PolygonProperties> {
|
|
1576
1665
|
}
|
|
1577
1666
|
|
|
1667
|
+
/**
|
|
1668
|
+
* Arrow snapped to a polygon annotation.
|
|
1669
|
+
* rx/ry are 0–1 fractions of the polygon's bounding box from its top-left corner.
|
|
1670
|
+
*/
|
|
1671
|
+
export declare type PolygonMagnet = {
|
|
1672
|
+
type: "polygon";
|
|
1673
|
+
rx: number;
|
|
1674
|
+
ry: number;
|
|
1675
|
+
};
|
|
1676
|
+
|
|
1578
1677
|
export declare interface PolygonProperties extends AnnotationProps {
|
|
1579
1678
|
type: "polygon";
|
|
1580
1679
|
style?: PolygonStyle;
|
|
@@ -1712,6 +1811,13 @@ export declare interface TextStyle extends BoxStyle {
|
|
|
1712
1811
|
borderRadius?: number;
|
|
1713
1812
|
/** When true, text maintains constant size regardless of zoom level */
|
|
1714
1813
|
fixedSize?: boolean;
|
|
1814
|
+
/**
|
|
1815
|
+
* Ghost text shown (via the textarea's native `placeholder` attribute)
|
|
1816
|
+
* while `content` is empty - disappears the instant the user types, no
|
|
1817
|
+
* selection/focus tricks needed. Overrides the global
|
|
1818
|
+
* `ControllerOptions.textPlaceholder` for this annotation.
|
|
1819
|
+
*/
|
|
1820
|
+
placeholder?: string;
|
|
1715
1821
|
}
|
|
1716
1822
|
|
|
1717
1823
|
/** @private */
|