@tumaet/apollon 4.7.0 → 4.9.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.
- package/README.md +45 -20
- package/dist/assets/style.css +1 -1
- package/dist/export.d.ts +73 -0
- package/dist/export.js +219 -0
- package/dist/exportStyles-Co-WBqTa.js +5 -0
- package/dist/external/LICENSE-InterFont +92 -0
- package/dist/external/exportFonts-DxO9jrR1.js +19 -0
- package/dist/external/exportStyles-Co-WBqTa.js +5 -0
- package/dist/external/index.js +22191 -0
- package/dist/fontStack-DOtVH2j8.js +5 -0
- package/dist/index.d.ts +150 -3
- package/dist/index.js +19993 -19219
- package/dist/internals.d.ts +65 -1
- package/dist/internals.js +14 -12
- package/dist/react/apollon-editor.d.ts +56 -3
- package/dist/react/components/AlignmentGuides.d.ts +1 -1
- package/dist/react/components/CustomControls.d.ts +7 -0
- package/dist/react/components/DraggableGhost.d.ts +5 -0
- package/dist/react/components/popovers/PopoverManager.d.ts +1 -1
- package/dist/react/components/popovers/activityDiagram/ActivitySwimlaneEditPopover.d.ts +2 -0
- package/dist/react/components/popovers/activityDiagram/index.d.ts +1 -0
- package/dist/react/components/react/ApollonControl.d.ts +18 -0
- package/dist/react/components/svgs/nodes/InterfaceLabel.d.ts +26 -0
- package/dist/react/components/svgs/nodes/activityDiagram/ActivitySwimlaneSVG.d.ts +9 -0
- package/dist/react/components/svgs/nodes/activityDiagram/index.d.ts +1 -0
- package/dist/react/components/svgs/nodes/componentDiagram/ComponentInterfaceNodeSVG.d.ts +2 -0
- package/dist/react/components/svgs/nodes/deploymentDiagram/DeploymentInterfaceSVG.d.ts +2 -0
- package/dist/react/constants.d.ts +28 -0
- package/dist/react/edges/labelTypes/EdgeIncludeExtendLabel.d.ts +1 -4
- package/dist/react/edges/labelTypes/EdgeMiddleLabels.d.ts +7 -4
- package/dist/react/edges/labelTypes/EdgeMultipleLabels.d.ts +2 -3
- package/dist/react/edges/labelTypes/messageLayout.d.ts +51 -0
- package/dist/react/export/exportErrors.d.ts +10 -0
- package/dist/react/export/index.d.ts +13 -0
- package/dist/react/export/normalizeExportSvg.d.ts +16 -0
- package/dist/react/export/preProcessSvgForPdf.d.ts +20 -0
- package/dist/react/export/svgToPdf.d.ts +17 -0
- package/dist/react/export/svgToPng.d.ts +38 -0
- package/dist/react/exportStyles-yVX7Dykt.js +6 -0
- package/dist/react/hooks/index.d.ts +0 -1
- package/dist/react/hooks/useRemoteDraggingNodes.d.ts +20 -0
- package/dist/react/hooks/useStepPathEdge.d.ts +11 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/nodes/activityDiagram/ActivitySwimlane.d.ts +3 -0
- package/dist/react/nodes/activityDiagram/index.d.ts +1 -0
- package/dist/react/nodes/types.d.ts +2 -1
- package/dist/react/overlay/OverlayLayer.d.ts +8 -0
- package/dist/react/overlay/RegionMount.d.ts +10 -0
- package/dist/react/overlay/overlayStore.d.ts +20 -0
- package/dist/react/overlay/types.d.ts +48 -0
- package/dist/react/react.d.ts +1 -0
- package/dist/react/react.js +13625 -18669
- package/dist/react/store/context.d.ts +3 -0
- package/dist/react/store/diagramStore.d.ts +17 -1
- package/dist/react/sync/perfCounters.d.ts +6 -0
- package/dist/react/sync/ydoc.d.ts +2 -0
- package/dist/react/sync/yjsSync.d.ts +3 -2
- package/dist/react/types/nodes/NodeProps.d.ts +24 -0
- package/dist/react/typings.d.ts +17 -0
- package/dist/react/utils/collaboration.d.ts +10 -1
- package/dist/react/utils/exportUtils.d.ts +0 -130
- package/dist/react/utils/geometry/edgeLabelLayout.d.ts +123 -0
- package/dist/react/utils/geometry/interfaceLabelLayout.d.ts +44 -0
- package/dist/react/utils/index.d.ts +1 -0
- package/dist/react/utils/paletteLayout.d.ts +70 -0
- package/dist/react/utils/swimlaneUtils.d.ts +58 -0
- package/dist/yjsSync-BCNFF_EI.js +45418 -0
- package/package.json +33 -8
- package/schema/uml-model-4.schema.json +1 -0
- package/dist/exportStyles-Xk-Vm7Ul.js +0 -5
- package/dist/react/exportStyles-DZCHk5mK.js +0 -6
- package/dist/react/hooks/useMessagePositioning.d.ts +0 -30
- package/dist/yjsSync-aPxjWNdZ.js +0 -50939
package/dist/internals.d.ts
CHANGED
|
@@ -24,6 +24,21 @@ declare function ActivityMergeNode({ id, width, height, data, parentId, }: NodeP
|
|
|
24
24
|
|
|
25
25
|
declare function ActivityObjectNode({ id, width, height, data, parentId, }: NodeProps<Node_2<DefaultNodeProps>>): JSX.Element | null;
|
|
26
26
|
|
|
27
|
+
declare function ActivitySwimlane({ id, width, height, data, parentId, }: NodeProps<Node_2<ActivitySwimlaneProps>>): JSX.Element | null;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Activity-partition (swimlane) container. Lanes are equal divisions along the
|
|
31
|
+
* primary axis (columns when vertical, rows when horizontal). Elements dropped
|
|
32
|
+
* into the swimlane become its children and move with it; which lane an element
|
|
33
|
+
* belongs to is expressed by where the modeller places it, matching the UML
|
|
34
|
+
* activity-partition notation where partition membership is positional rather
|
|
35
|
+
* than stored per element.
|
|
36
|
+
*/
|
|
37
|
+
declare type ActivitySwimlaneProps = DefaultNodeProps & {
|
|
38
|
+
orientation: "vertical" | "horizontal";
|
|
39
|
+
lanes: SwimlaneLane[];
|
|
40
|
+
};
|
|
41
|
+
|
|
27
42
|
declare type ApollonEdge = {
|
|
28
43
|
id: string;
|
|
29
44
|
source: string;
|
|
@@ -174,6 +189,7 @@ declare type CollaborationState = {
|
|
|
174
189
|
viewport?: CollaborationViewport | null;
|
|
175
190
|
followingClientId?: number | null;
|
|
176
191
|
selectedElementId?: string | null;
|
|
192
|
+
draggingNodes?: DraggingNode[] | null;
|
|
177
193
|
};
|
|
178
194
|
|
|
179
195
|
declare type CollaborationUser = {
|
|
@@ -359,6 +375,7 @@ declare const diagramNodeTypes: {
|
|
|
359
375
|
activityMergeNode: typeof ActivityMergeNode;
|
|
360
376
|
activityForkNode: typeof ActivityForkNode;
|
|
361
377
|
activityForkNodeHorizontal: typeof ActivityForkNodeHorizontal;
|
|
378
|
+
activitySwimlane: typeof ActivitySwimlane;
|
|
362
379
|
useCase: typeof UseCase;
|
|
363
380
|
useCaseActor: typeof UseCaseActor;
|
|
364
381
|
useCaseSystem: typeof UseCaseSystem;
|
|
@@ -411,8 +428,24 @@ declare type DiagramStore = {
|
|
|
411
428
|
canUndo: boolean;
|
|
412
429
|
canRedo: boolean;
|
|
413
430
|
undoManager: Y.UndoManager | null;
|
|
431
|
+
collaborationEnabled: boolean;
|
|
414
432
|
previewMode: boolean;
|
|
415
433
|
setDiagramId: (diagramId: string) => void;
|
|
434
|
+
setCollaborationEnabled: (enabled: boolean) => void;
|
|
435
|
+
/**
|
|
436
|
+
* Inject the sink that forwards transient drag/resize frames onto the
|
|
437
|
+
* ephemeral awareness channel (wired by `YjsSync` for every editor). Kept as
|
|
438
|
+
* runtime wiring rather than diagram state so a `reset()` never clears it.
|
|
439
|
+
* The broadcast itself is gated by `collaborationEnabled`, not by this sink;
|
|
440
|
+
* `null` (headless, where no `YjsSync` runs) just leaves it unwired.
|
|
441
|
+
*/
|
|
442
|
+
setDraggingNodesPublisher: (publisher: ((draggingNodes: DraggingNode[] | null) => void) | null) => void;
|
|
443
|
+
/**
|
|
444
|
+
* Clear the peers' live-drag overlay once a gesture's settled value is
|
|
445
|
+
* committed. Called from `onNodeDragStop` (after the doc write) and on
|
|
446
|
+
* collaboration teardown; a no-op when nothing is being broadcast.
|
|
447
|
+
*/
|
|
448
|
+
endTransientNodeBroadcast: () => void;
|
|
416
449
|
setNodes: (payload: Node_2[] | ((nodes: Node_2[]) => Node_2[])) => void;
|
|
417
450
|
setEdges: (payload: Edge[] | ((edges: Edge[]) => Edge[])) => void;
|
|
418
451
|
setNodesAndEdges: (nodes: Node_2[], edges: Edge[]) => void;
|
|
@@ -445,6 +478,23 @@ declare type DiagramStore = {
|
|
|
445
478
|
setPreviewMode: (active: boolean) => void;
|
|
446
479
|
};
|
|
447
480
|
|
|
481
|
+
/**
|
|
482
|
+
* One node a peer is actively dragging or resizing. Broadcast over the
|
|
483
|
+
* ephemeral awareness channel — never written to the Yjs document — so peers
|
|
484
|
+
* can render the in-progress gesture live without growing the CRDT or entering
|
|
485
|
+
* anyone's undo history. The settled position/size is committed once on
|
|
486
|
+
* drop/release through the document like any other edit.
|
|
487
|
+
*/
|
|
488
|
+
declare type DraggingNode = {
|
|
489
|
+
id: string;
|
|
490
|
+
position: {
|
|
491
|
+
x: number;
|
|
492
|
+
y: number;
|
|
493
|
+
};
|
|
494
|
+
width?: number | null;
|
|
495
|
+
height?: number | null;
|
|
496
|
+
};
|
|
497
|
+
|
|
448
498
|
declare type ExtendedEdgeProps = EdgeProps<Edge<CustomEdgeProps>> & {
|
|
449
499
|
markerEnd?: string;
|
|
450
500
|
markerPadding?: number;
|
|
@@ -607,6 +657,19 @@ declare type SfcTransitionBranchNodeProps = DefaultNodeProps & {
|
|
|
607
657
|
showHint?: boolean;
|
|
608
658
|
};
|
|
609
659
|
|
|
660
|
+
/** A single partition (lane) inside an activity swimlane. */
|
|
661
|
+
declare type SwimlaneLane = {
|
|
662
|
+
id: string;
|
|
663
|
+
name: string;
|
|
664
|
+
/**
|
|
665
|
+
* Lane's extent along the swimlane's primary axis, in absolute flow px. The
|
|
666
|
+
* last lane is elastic (fills the remainder), so resizing the swimlane only
|
|
667
|
+
* changes the last lane. Optional: lanes without it divide the space equally,
|
|
668
|
+
* so existing saved swimlanes render as equal lanes until a separator moves.
|
|
669
|
+
*/
|
|
670
|
+
size?: number;
|
|
671
|
+
};
|
|
672
|
+
|
|
610
673
|
declare function SyntaxTreeNonterminal({ id, width, height, data, parentId, }: NodeProps<Node_2<DefaultNodeProps>>): JSX.Element | null;
|
|
611
674
|
|
|
612
675
|
declare function SyntaxTreeTerminal({ id, width, height, data, parentId, }: NodeProps<Node_2<DefaultNodeProps>>): JSX.Element | null;
|
|
@@ -849,6 +912,7 @@ export declare class YjsSync {
|
|
|
849
912
|
setLocalAwarenessViewport: (viewport: CollaborationViewport | null) => void;
|
|
850
913
|
setLocalAwarenessFollowing: (followingClientId: number | null) => void;
|
|
851
914
|
setLocalAwarenessSelectedElement: (selectedElementId: string | null) => void;
|
|
915
|
+
setLocalAwarenessDraggingNodes: (draggingNodes: DraggingNode[] | null) => void;
|
|
852
916
|
setLocalAwarenessState: (state: Partial<CollaborationState>) => void;
|
|
853
917
|
subscribeToAwarenessChanges: (callback: (states: Map<number, CollaborationState>) => void) => () => void;
|
|
854
918
|
getAwarenessStates: () => Map<number, CollaborationState>;
|
|
@@ -870,7 +934,7 @@ export declare class YjsSync {
|
|
|
870
934
|
/**
|
|
871
935
|
* Convert Base64 string to Uint8Array
|
|
872
936
|
*/
|
|
873
|
-
|
|
937
|
+
static base64ToUint8(base64: string): Uint8Array;
|
|
874
938
|
}
|
|
875
939
|
|
|
876
940
|
export { }
|
package/dist/internals.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { aD as r } from "./yjsSync-BCNFF_EI.js";
|
|
2
|
+
import { a8 as m, aT as p, aU as g, aV as u, aW as S, aX as T, aY as b, bo as l, bp as F, bq as Y } from "./yjsSync-BCNFF_EI.js";
|
|
3
|
+
import * as n from "yjs";
|
|
4
|
+
function d(t = new n.Doc()) {
|
|
4
5
|
const e = () => {
|
|
5
6
|
}, a = {
|
|
6
7
|
getState: () => ({
|
|
@@ -8,6 +9,7 @@ function V(t = new n()) {
|
|
|
8
9
|
updateEdgesFromYjs: e,
|
|
9
10
|
updateAssessmentFromYjs: e,
|
|
10
11
|
updateUndoRedoState: e,
|
|
12
|
+
setDraggingNodesPublisher: e,
|
|
11
13
|
undoManager: null
|
|
12
14
|
// Other DiagramStore fields are typed but never accessed by
|
|
13
15
|
// YjsSync; cast through `unknown` keeps the helper from
|
|
@@ -30,16 +32,16 @@ function V(t = new n()) {
|
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
34
|
export {
|
|
33
|
-
|
|
35
|
+
m as MessageType,
|
|
34
36
|
r as YjsSync,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
p as convertV2ToV4,
|
|
38
|
+
g as convertV3EdgeTypeToV4,
|
|
39
|
+
u as convertV3HandleToV4,
|
|
40
|
+
S as convertV3MessagesToV4,
|
|
39
41
|
T as convertV3NodeTypeToV4,
|
|
40
42
|
b as convertV3ToV4,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
d as createHeadlessSync,
|
|
44
|
+
l as isV2Format,
|
|
45
|
+
F as isV3Format,
|
|
46
|
+
Y as isV4Format
|
|
45
47
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Node, Edge } from '@xyflow/react';
|
|
2
2
|
import { UMLDiagramType } from './types';
|
|
3
|
+
import { OverlayControlInput, OverlayRegion, OverlaySide } from './overlay/types';
|
|
3
4
|
import { SendBroadcastMessage } from './sync/yjsSync';
|
|
4
5
|
import * as Apollon from "./typings";
|
|
5
6
|
export declare class ApollonEditor {
|
|
@@ -11,8 +12,8 @@ export declare class ApollonEditor {
|
|
|
11
12
|
private readonly metadataStore;
|
|
12
13
|
private readonly popoverStore;
|
|
13
14
|
private readonly assessmentSelectionStore;
|
|
14
|
-
private readonly
|
|
15
|
-
private readonly
|
|
15
|
+
private readonly overlayStore;
|
|
16
|
+
private readonly hostRegionEls;
|
|
16
17
|
private subscribers;
|
|
17
18
|
constructor(element: HTMLElement, options?: Apollon.ApollonOptions);
|
|
18
19
|
private setReactFlowInstance;
|
|
@@ -31,10 +32,62 @@ export declare class ApollonEditor {
|
|
|
31
32
|
x: number;
|
|
32
33
|
y: number;
|
|
33
34
|
}): import('@xyflow/react').XYPosition | null;
|
|
35
|
+
/**
|
|
36
|
+
* Zoom/pan so the whole diagram fits, capped at `maxZoom: 1.0`. Retries up to
|
|
37
|
+
* 10 animation frames until every node is measured.
|
|
38
|
+
* @param options.padding - Scalar fraction (default `0.15`), or per-side px
|
|
39
|
+
* that adds to a 16px gutter. A per-side object forces the inset-aware path.
|
|
40
|
+
* @param options.duration - Animation duration in ms (default `200`).
|
|
41
|
+
* @param options.respectInsets - Pad the fit by reserved overlay insets
|
|
42
|
+
* (header, rails, …). Default `true`.
|
|
43
|
+
*/
|
|
34
44
|
fitView(options?: {
|
|
35
|
-
padding?: number
|
|
45
|
+
padding?: number | Partial<Record<OverlaySide, number>>;
|
|
36
46
|
duration?: number;
|
|
47
|
+
/** Pad the fit by the reserved overlay insets (header, rails, …). */
|
|
48
|
+
respectInsets?: boolean;
|
|
37
49
|
}): void;
|
|
50
|
+
/**
|
|
51
|
+
* Register a floating control, returning a disposer. Re-using an id replaces
|
|
52
|
+
* (idempotent / StrictMode-safe). Pick a façade: a React host →
|
|
53
|
+
* `<ApollonControl>`; a non-React host (or one that needs its own React
|
|
54
|
+
* root/context) → `getRegionElement` + `createPortal`; a one-off imperative
|
|
55
|
+
* widget → `addControl`.
|
|
56
|
+
* @param control - id, target region, a `render` thunk, and optional layout
|
|
57
|
+
* options ({@link OverlayControlInput}).
|
|
58
|
+
* @returns A disposer that unregisters this control; safe to call twice.
|
|
59
|
+
* @throws If `id` is empty or `region` is not a known region — mistakes fail
|
|
60
|
+
* loudly at the edge, not silently in the renderer.
|
|
61
|
+
*/
|
|
62
|
+
addControl(control: OverlayControlInput): () => void;
|
|
63
|
+
/**
|
|
64
|
+
* Patch a registered control's options/renderer (a no-op if absent).
|
|
65
|
+
* @param id - The control's immutable id (an `id` in `patch` is ignored).
|
|
66
|
+
* @param patch - Partial options/renderer merged over the existing control.
|
|
67
|
+
*/
|
|
68
|
+
updateControl(id: string, patch: Partial<OverlayControlInput>): void;
|
|
69
|
+
/**
|
|
70
|
+
* @param id - A control id.
|
|
71
|
+
* @returns `true` if a control with this id is currently registered.
|
|
72
|
+
*/
|
|
73
|
+
hasControl(id: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* A stable DOM node anchored in `region`, for hosts that render their own
|
|
76
|
+
* React into it (via `createPortal`) to keep host context. Auto-measured, so
|
|
77
|
+
* the diagram makes room for whatever the host mounts. Lifetime = the editor;
|
|
78
|
+
* `releaseRegionElement` unregisters it. Reserved id: `apollon:host:<region>`.
|
|
79
|
+
* @param region - The region to anchor the node in.
|
|
80
|
+
* @returns The same node for the lifetime of one acquire; `releaseRegionElement`
|
|
81
|
+
* drops it and the next call returns a fresh node.
|
|
82
|
+
* @throws If `region` is not a known region.
|
|
83
|
+
*/
|
|
84
|
+
getRegionElement(region: OverlayRegion): HTMLElement;
|
|
85
|
+
/**
|
|
86
|
+
* Release a region acquired via {@link getRegionElement} (unregister + drop
|
|
87
|
+
* the cached node); a later `getRegionElement(region)` creates a fresh node.
|
|
88
|
+
* @param region - The region whose host node to release.
|
|
89
|
+
*/
|
|
90
|
+
releaseRegionElement(region: OverlayRegion): void;
|
|
38
91
|
set diagramType(type: UMLDiagramType);
|
|
39
92
|
destroy(): void;
|
|
40
93
|
/** Renders a model to SVG via a hidden, off-screen mount. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AlignmentGuides: () => import("react").JSX.Element
|
|
1
|
+
export declare const AlignmentGuides: () => import("react").JSX.Element;
|
|
@@ -1 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bottom-left control cluster. Every button shares one idiom
|
|
3
|
+
* (`apollon-chrome-iconbtn`): borderless on the glass pane, state shown as a
|
|
4
|
+
* surface-layer fill. Reads left→right as view (zoom-out/in, fit, a clickable
|
|
5
|
+
* %-reset) then, past a hairline, history (undo/redo). React Flow renders its
|
|
6
|
+
* built-in zoom/fit buttons first; our children follow.
|
|
7
|
+
*/
|
|
1
8
|
export declare const CustomControls: () => import("react").JSX.Element;
|
|
@@ -3,6 +3,11 @@ import { DropElementConfig } from '../constants';
|
|
|
3
3
|
interface DraggableGhostProps {
|
|
4
4
|
children: React.ReactNode;
|
|
5
5
|
dropElementConfig: DropElementConfig;
|
|
6
|
+
/**
|
|
7
|
+
* Visual scale of the palette preview.
|
|
8
|
+
* Used to convert pointer offsets into node-placement offsets.
|
|
9
|
+
*/
|
|
10
|
+
previewScale?: number;
|
|
6
11
|
}
|
|
7
12
|
export declare const DraggableGhost: React.FC<DraggableGhostProps>;
|
|
8
13
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type NodePopoverType = "class" | "objectName" | "communicationObjectName" | "default" | "Component" | "ComponentSubsystem" | "FlowchartTerminal" | "FlowchartProcess" | "FlowchartDecision" | "FlowchartInputOutput" | "FlowchartFunctionCall" | "DeploymentComponent" | "DeploymentNode" | "SyntaxTreeNonterminal" | "SyntaxTreeTerminal" | "PetriNetPlace" | "BPMNTask" | "BPMNStartEvent" | "BPMNIntermediateEvent" | "BPMNEndEvent" | "BPMNGateway" | "BPMNSubprocess" | "BPMNTransaction" | "BPMNCallActivity" | "BPMNAnnotation" | "BPMNDataObject" | "BPMNDataStore" | "BPMNPool" | "BPMNGroup" | "ReachabilityGraphMarking" | "Sfc" | "SfcActionTable";
|
|
1
|
+
type NodePopoverType = "class" | "objectName" | "communicationObjectName" | "default" | "Component" | "ComponentSubsystem" | "FlowchartTerminal" | "FlowchartProcess" | "FlowchartDecision" | "FlowchartInputOutput" | "FlowchartFunctionCall" | "DeploymentComponent" | "DeploymentNode" | "SyntaxTreeNonterminal" | "SyntaxTreeTerminal" | "PetriNetPlace" | "BPMNTask" | "BPMNStartEvent" | "BPMNIntermediateEvent" | "BPMNEndEvent" | "BPMNGateway" | "BPMNSubprocess" | "BPMNTransaction" | "BPMNCallActivity" | "BPMNAnnotation" | "BPMNDataObject" | "BPMNDataStore" | "BPMNPool" | "BPMNGroup" | "ReachabilityGraphMarking" | "Sfc" | "SfcActionTable" | "ActivitySwimlane";
|
|
2
2
|
type EdgePopoverType = "ClassAggregation" | "ClassInheritance" | "ClassRealization" | "ClassComposition" | "ClassBidirectional" | "ClassUnidirectional" | "ClassDependency" | "ActivityControlFlow" | "ObjectLink" | "CommunicationLink" | "UseCaseAssociation" | "UseCaseInclude" | "UseCaseExtend" | "UseCaseGeneralization" | "ComponentDependency" | "ComponentProvidedInterface" | "ComponentRequiredInterface" | "ComponentRequiredThreeQuarterInterface" | "ComponentRequiredQuarterInterface" | "BPMNSequenceFlow" | "BPMNMessageFlow" | "BPMNAssociationFlow" | "BPMNDataAssociationFlow" | "DeploymentAssociation" | "DeploymentDependency" | "DeploymentProvidedInterface" | "DeploymentRequiredInterface" | "DeploymentRequiredThreeQuarterInterface" | "DeploymentRequiredQuarterInterface" | "FlowChartFlowline" | "SyntaxTreeLink" | "SfcDiagramEdge" | "ReachabilityGraphArc" | "PetriNetArc";
|
|
3
3
|
type PopoverType = NodePopoverType | EdgePopoverType;
|
|
4
4
|
interface PopoverManagerProps {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ActivitySwimlaneEditPopover } from './ActivitySwimlaneEditPopover';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { OverlayControlOptions } from '../../overlay/types';
|
|
3
|
+
/** Props for {@link ApollonControl}: every {@link OverlayControlOptions} field
|
|
4
|
+
* (id, region, inset, order, …) plus the children to render in-canvas. */
|
|
5
|
+
export type ApollonControlProps = OverlayControlOptions & {
|
|
6
|
+
/** Portaled into the control's host node inside the chosen region. Children
|
|
7
|
+
* changes never re-register the control; only real option changes do. */
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Declarative façade over `editor.addControl`. Registers a control that renders
|
|
12
|
+
* a stable host node into the chosen region, and portals `children` into that
|
|
13
|
+
* node — so children render INSIDE the canvas while React owns their
|
|
14
|
+
* reconciliation. Children changes therefore never touch the overlay store; only
|
|
15
|
+
* real option changes (region/inset/order/…) push an update. Returns null in the
|
|
16
|
+
* host tree.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ApollonControl({ children, ...options }: ApollonControlProps): ReactNode;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { InterfaceLabelSide } from '../../../utils/geometry/interfaceLabelLayout';
|
|
3
|
+
interface Props {
|
|
4
|
+
name?: string | null;
|
|
5
|
+
/** Interface circle bounds (always square — INTERFACE.SIZE). */
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
fill?: string;
|
|
9
|
+
/** Which side of the circle the name sits on. Defaults to "bottom"; the node
|
|
10
|
+
* component flips it away from sides a connecting edge attaches to (including
|
|
11
|
+
* a diagonal corner when every side is taken). */
|
|
12
|
+
side?: InterfaceLabelSide;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The provided/required interface name. Sits centered below the ball/socket by
|
|
16
|
+
* default; the node component moves it to whichever side — or, when all four
|
|
17
|
+
* sides have an edge, whichever diagonal corner — is clear of connecting edges.
|
|
18
|
+
* The name is rendered as real multi-line text (honouring line breaks) and is
|
|
19
|
+
* never auto-wrapped.
|
|
20
|
+
*
|
|
21
|
+
* Renders as SVG <text>/<tspan> in the node's overflow:visible region. The
|
|
22
|
+
* PNG/PDF/SVG export pipeline captures it via its node-text bbox scan
|
|
23
|
+
* (utils/exportUtils.ts), so it exports correctly without enlarging the viewBox.
|
|
24
|
+
*/
|
|
25
|
+
export declare const InterfaceLabel: FC<Props>;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SVGComponentProps } from '../../../../types/SVG';
|
|
2
|
+
import { ActivitySwimlaneProps } from '../../../../types';
|
|
3
|
+
/** Thickness of the band that holds the lane name labels. */
|
|
4
|
+
export declare const SWIMLANE_HEADER_SIZE = 30;
|
|
5
|
+
interface ActivitySwimlaneSVGProps extends SVGComponentProps {
|
|
6
|
+
data: ActivitySwimlaneProps;
|
|
7
|
+
}
|
|
8
|
+
export declare const ActivitySwimlaneSVG: React.FC<ActivitySwimlaneSVGProps>;
|
|
9
|
+
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { SVGComponentProps } from '../../../../types/SVG';
|
|
2
2
|
import { DefaultNodeProps } from '../../../../types';
|
|
3
|
+
import { InterfaceLabelSide } from '../../../../utils/geometry/interfaceLabelLayout';
|
|
3
4
|
interface Props extends SVGComponentProps {
|
|
4
5
|
data: DefaultNodeProps;
|
|
6
|
+
labelSide?: InterfaceLabelSide;
|
|
5
7
|
}
|
|
6
8
|
export declare const ComponentInterfaceNodeSVG: React.FC<Props>;
|
|
7
9
|
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { SVGComponentProps } from '../../../../types/SVG';
|
|
2
2
|
import { DefaultNodeProps } from '../../../../types';
|
|
3
|
+
import { InterfaceLabelSide } from '../../../../utils/geometry/interfaceLabelLayout';
|
|
3
4
|
interface Props extends SVGComponentProps {
|
|
4
5
|
data: DefaultNodeProps;
|
|
6
|
+
labelSide?: InterfaceLabelSide;
|
|
5
7
|
}
|
|
6
8
|
export declare const DeploymentInterfaceSVG: React.FC<Props>;
|
|
7
9
|
export {};
|
|
@@ -39,6 +39,16 @@ export declare const LAYOUT: Readonly<{
|
|
|
39
39
|
readonly STEREOTYPE_LINE_HEIGHT: 15;
|
|
40
40
|
readonly STEREOTYPE_NAME_GAP: 4;
|
|
41
41
|
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Treat narrow portrait viewports and short phone-landscape viewports as
|
|
44
|
+
* mobile. The portrait bound stops just below 768px so iPads (768px portrait)
|
|
45
|
+
* keep the regular desktop layout; the second clause catches phones in
|
|
46
|
+
* landscape, where the short height distinguishes them from tablets.
|
|
47
|
+
*
|
|
48
|
+
* NOTE: mirrored in standalone/webapp/src/constants/responsive.ts (the webapp
|
|
49
|
+
* can't import the library's curated public surface). Keep both in sync.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MOBILE_VIEW_QUERY = "(max-width: 767.95px), (max-width: 950px) and (max-height: 500px)";
|
|
42
52
|
export declare const INTERFACE: Readonly<{
|
|
43
53
|
readonly SIZE: 30;
|
|
44
54
|
readonly RADIUS: number;
|
|
@@ -97,6 +107,19 @@ export declare const EDGES: Readonly<{
|
|
|
97
107
|
* U-turn is never a deliberate edit, so this stays at the visual-merge
|
|
98
108
|
* threshold rather than the per-step threshold. */
|
|
99
109
|
readonly ORTHOGONAL_ARM_OVERLAP_PX: 10;
|
|
110
|
+
/** Perpendicular gap (flow px) between an edge's mid-segment line and the
|
|
111
|
+
* near edge of its relationship/stereotype label. The label sits this far
|
|
112
|
+
* off the line on whichever side is clearer. */
|
|
113
|
+
readonly LABEL_GAP: 14;
|
|
114
|
+
/** Nominal label line height (flow px) used as the across-text depth of the
|
|
115
|
+
* candidate box when scoring which side a label sits on. Constant by
|
|
116
|
+
* construction — placement never measures the rendered text (mirrors the
|
|
117
|
+
* messageLayout.ts invariant). */
|
|
118
|
+
readonly LABEL_LINE_HEIGHT: 14;
|
|
119
|
+
/** Nominal half-width (flow px) of a label along its text axis, used only to
|
|
120
|
+
* build the candidate box for side scoring. Coarse on purpose: we choose a
|
|
121
|
+
* side, not a pixel-perfect fit. */
|
|
122
|
+
readonly LABEL_NOMINAL_HALF_EXTENT: 40;
|
|
100
123
|
}>;
|
|
101
124
|
export declare const ZINDEX: Readonly<{
|
|
102
125
|
readonly BASE: 0;
|
|
@@ -225,6 +248,11 @@ export type DropElementConfig = {
|
|
|
225
248
|
readonly type: DiagramNodeType;
|
|
226
249
|
readonly width: number;
|
|
227
250
|
readonly height: number;
|
|
251
|
+
/** Size of the node when dropped on the canvas, if it should differ from the
|
|
252
|
+
* sidebar preview size (`width`/`height`). Lets a large element preview small
|
|
253
|
+
* in the palette without shrinking the rest of the picker. */
|
|
254
|
+
readonly dropWidth?: number;
|
|
255
|
+
readonly dropHeight?: number;
|
|
228
256
|
readonly defaultData?: Record<string, unknown>;
|
|
229
257
|
readonly svg: React.FC<any>;
|
|
230
258
|
readonly marginTop?: number;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { IPoint } from '../Connection';
|
|
2
2
|
interface EdgeIncludeExtendLabelsProps {
|
|
3
|
-
label?: string | null;
|
|
4
|
-
pathMiddlePosition: IPoint;
|
|
5
3
|
sourcePoint?: IPoint;
|
|
6
4
|
targetPoint?: IPoint;
|
|
7
|
-
isUseCasePath?: boolean;
|
|
8
5
|
showRelationshipLabels?: boolean;
|
|
9
6
|
relationshipType?: "include" | "extend";
|
|
10
7
|
textColor?: string;
|
|
11
8
|
}
|
|
12
|
-
export declare const EdgeIncludeExtendLabel: ({ sourcePoint, targetPoint, showRelationshipLabels, relationshipType, textColor, }: EdgeIncludeExtendLabelsProps) => import("react").JSX.Element;
|
|
9
|
+
export declare const EdgeIncludeExtendLabel: ({ sourcePoint, targetPoint, showRelationshipLabels, relationshipType, textColor, }: EdgeIncludeExtendLabelsProps) => import("react").JSX.Element | null;
|
|
13
10
|
export {};
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { IPoint } from '../Connection';
|
|
2
|
+
import { Rect } from '../../utils/geometry/edgeLabelLayout';
|
|
2
3
|
interface EdgeMiddleLabelsProps {
|
|
3
4
|
label?: string | null;
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
/** The edge's full rendered polyline (orthogonal edges). */
|
|
6
|
+
activePoints?: IPoint[];
|
|
6
7
|
sourcePoint?: IPoint;
|
|
7
8
|
targetPoint?: IPoint;
|
|
9
|
+
/** Every node the edge routes near, so the label avoids all of them. */
|
|
10
|
+
nodeRects?: Rect[];
|
|
11
|
+
neighborGeometry?: IPoint[][];
|
|
8
12
|
showRelationshipLabels?: boolean;
|
|
9
13
|
isUseCasePath?: boolean;
|
|
10
14
|
isPetriNet?: boolean;
|
|
11
|
-
avoidToolbarOverlap?: boolean;
|
|
12
15
|
textColor: string;
|
|
13
16
|
}
|
|
14
|
-
export declare const EdgeMiddleLabels: ({ label,
|
|
17
|
+
export declare const EdgeMiddleLabels: ({ label, activePoints, sourcePoint, targetPoint, nodeRects, neighborGeometry, showRelationshipLabels, isUseCasePath, isPetriNet, textColor, }: EdgeMiddleLabelsProps) => import("react").JSX.Element | null;
|
|
15
18
|
export {};
|
|
@@ -7,9 +7,8 @@ interface EdgeMultipleLabelsProps {
|
|
|
7
7
|
isReconnecting?: boolean;
|
|
8
8
|
sourcePosition: IPoint;
|
|
9
9
|
targetPosition: IPoint;
|
|
10
|
-
|
|
11
|
-
isHorizontalEdge?: boolean;
|
|
10
|
+
isHorizontalEdge: boolean;
|
|
12
11
|
textColor: string;
|
|
13
12
|
}
|
|
14
|
-
export declare const EdgeMultipleLabels: ({ messages, pathMiddlePosition, showRelationshipLabels, isReconnecting, sourcePosition, targetPosition,
|
|
13
|
+
export declare const EdgeMultipleLabels: ({ messages, pathMiddlePosition, showRelationshipLabels, isReconnecting, sourcePosition, targetPosition, isHorizontalEdge, textColor, }: EdgeMultipleLabelsProps) => import("react").JSX.Element | null;
|
|
15
14
|
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { MessageData } from '../EdgeProps';
|
|
2
|
+
import { IPoint } from '../Connection';
|
|
3
|
+
/**
|
|
4
|
+
* Geometry for communication-edge message labels, relative to the middle-segment
|
|
5
|
+
* midpoint (position-independent, hence unit-testable on its own).
|
|
6
|
+
*
|
|
7
|
+
* Invariant: a group's SIDE is fixed by the segment orientation; flow direction
|
|
8
|
+
* is encoded ONLY by the arrow rotation, never by the side. Gaps are constant by
|
|
9
|
+
* construction — nothing measures text width.
|
|
10
|
+
*/
|
|
11
|
+
export interface MessageHostSegment {
|
|
12
|
+
/** Rounded midpoint of the chosen arm (flow space). */
|
|
13
|
+
point: IPoint;
|
|
14
|
+
/** Orientation of the chosen arm. */
|
|
15
|
+
isHorizontal: boolean;
|
|
16
|
+
/** The arm's endpoints in source->target order (for arrow direction). */
|
|
17
|
+
start: IPoint;
|
|
18
|
+
end: IPoint;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The arm of a (possibly stepped) communication edge that should HOST the
|
|
22
|
+
* message stack. The naive mid-segment can land on a tiny jog between two long
|
|
23
|
+
* arms — classifying a dominantly-vertical edge as "horizontal" so the labels
|
|
24
|
+
* centre on the jog and straddle BOTH neighbouring arms. Instead we host on the
|
|
25
|
+
* LONGEST arm (tie-broken toward the edge's middle), so the stack sits beside a
|
|
26
|
+
* long straight run: it never crosses the line and, in vertical mode, all
|
|
27
|
+
* same-direction messages share a leading edge. Pure geometry — identical in the
|
|
28
|
+
* editor and in headless export.
|
|
29
|
+
*/
|
|
30
|
+
export declare const getMessageHostSegment: (renderPoints: IPoint[], fallbackSource: IPoint, fallbackTarget: IPoint) => MessageHostSegment;
|
|
31
|
+
export type LabelTextAnchor = "start" | "middle" | "end";
|
|
32
|
+
export declare const ARROW_SIZE = 16;
|
|
33
|
+
export declare const ARROW_TEXT_GAP = 4;
|
|
34
|
+
export declare const LINE_GAP = 8;
|
|
35
|
+
export declare const STACK_SPACING = 22;
|
|
36
|
+
export interface MessageGroupLayout {
|
|
37
|
+
messages: MessageData[];
|
|
38
|
+
arrowRotation: number;
|
|
39
|
+
textAnchor: LabelTextAnchor;
|
|
40
|
+
/** Top-left of the arrow icon for the first message, relative to the segment midpoint. */
|
|
41
|
+
arrowOrigin: IPoint;
|
|
42
|
+
/** Text anchor point for the first message, relative to the segment midpoint. */
|
|
43
|
+
textOrigin: IPoint;
|
|
44
|
+
/** Offset added per stacked message (multiplied by the message index). */
|
|
45
|
+
stackStep: IPoint;
|
|
46
|
+
}
|
|
47
|
+
export interface MessageLayout {
|
|
48
|
+
forward: MessageGroupLayout;
|
|
49
|
+
backward: MessageGroupLayout;
|
|
50
|
+
}
|
|
51
|
+
export declare const computeMessageLayout: (messages: MessageData[], sourcePosition: IPoint, targetPosition: IPoint, isHorizontalEdge: boolean) => MessageLayout;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error for the raster (PNG) export path so callers can show an
|
|
3
|
+
* actionable "diagram too large" message instead of the silent 0-byte file the
|
|
4
|
+
* old canvas path produced (#667).
|
|
5
|
+
*/
|
|
6
|
+
export declare class RasterTooLargeError extends Error {
|
|
7
|
+
readonly canvasWidth: number;
|
|
8
|
+
readonly canvasHeight: number;
|
|
9
|
+
constructor(message: string, canvasWidth: number, canvasHeight: number);
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@tumaet/apollon/export` — reliable browser raster/vector export of a
|
|
3
|
+
* compat-mode Apollon SVG. PNG via resvg (wasm); PDF via svg2pdf.js on jsPDF.
|
|
4
|
+
* Both fix the canvas-area-cap silent failure of the old client path (#667).
|
|
5
|
+
*
|
|
6
|
+
* The heavy renderers (`@resvg/resvg-wasm`, `jspdf`, `svg2pdf.js`) are optional
|
|
7
|
+
* dependencies, loaded lazily, so importing the editor never pulls them in.
|
|
8
|
+
*/
|
|
9
|
+
export { svgToPng, computeAppliedScale } from './svgToPng';
|
|
10
|
+
export type { SvgToPngOptions, SvgToPngResult } from './svgToPng';
|
|
11
|
+
export { svgToPdf } from './svgToPdf';
|
|
12
|
+
export type { SvgToPdfOptions } from './svgToPdf';
|
|
13
|
+
export { RasterTooLargeError } from './exportErrors';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drop `font-style="italic"` from every element of an export SVG.
|
|
3
|
+
*
|
|
4
|
+
* Apollon emits italic for abstract-class headers, but the editor itself ships
|
|
5
|
+
* only upright Inter (Regular + Bold) — on screen the slant is the browser's
|
|
6
|
+
* *synthetic* oblique, and text width is measured with the upright metrics.
|
|
7
|
+
* The raster (resvg) and PDF (jsPDF) paths carry the same two upright faces, so
|
|
8
|
+
* a real italic face would change advance widths and break the editor↔export
|
|
9
|
+
* determinism guarantee (and risk overflowing label boxes). We therefore render
|
|
10
|
+
* abstract names upright by design — matching the server export — and strip the
|
|
11
|
+
* attribute so the SVG no longer *claims* an italic it doesn't deliver. Abstract
|
|
12
|
+
* classes stay distinguishable by their «Abstract» stereotype label.
|
|
13
|
+
*
|
|
14
|
+
* Mutates `root` in place.
|
|
15
|
+
*/
|
|
16
|
+
export declare function normalizeExportSvg(root: Element): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapt a compat-mode Apollon SVG to the three svg2pdf.js limitations that the
|
|
3
|
+
* library's own compat passes (in exportUtils.ts) do NOT already cover.
|
|
4
|
+
* Relative font-sizes, `tspan` `dy` and `dominant-baseline` are resolved
|
|
5
|
+
* upstream by `getSVG`, so they are intentionally absent here.
|
|
6
|
+
*
|
|
7
|
+
* 1. Nested `<svg>` clips its content despite `overflow="visible"` — svg2pdf
|
|
8
|
+
* treats the intrinsic size as a clip rect. Apollon wraps each node in
|
|
9
|
+
* `<svg width viewBox>`; replace those with `<g>` (layout-equivalent since
|
|
10
|
+
* the viewBox is always `0 0 w h`), translating any non-zero origin.
|
|
11
|
+
* 2. A `<text>` with 2+ `<tspan>` children renders with wrong glyph widths in
|
|
12
|
+
* svg2pdf; split it into independent `<text>` elements. Each tspan already
|
|
13
|
+
* carries an absolute `y` (resolved by `resolveTspanDy`).
|
|
14
|
+
* 3. svg2pdf looks up `font-family` as a literal string, so the CSS list
|
|
15
|
+
* `"Inter, system-ui, …"` misses the registered "Inter" and falls back to a
|
|
16
|
+
* standard font; collapse any Inter-led list to plain `"Inter"`.
|
|
17
|
+
*
|
|
18
|
+
* Mutates `root` in place and returns it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function preProcessSvgForPdf(root: Element): Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type SvgToPdfOptions = {
|
|
2
|
+
/** Document title metadata; does not affect layout. */
|
|
3
|
+
title?: string;
|
|
4
|
+
/**
|
|
5
|
+
* Inter Regular + Bold as ttf/otf bytes, for hosts without `fetch` of the
|
|
6
|
+
* bundled `?url` font asset (e.g. tests, headless Node). Defaults to the
|
|
7
|
+
* bundled Inter.
|
|
8
|
+
*/
|
|
9
|
+
fonts?: {
|
|
10
|
+
regular: Uint8Array;
|
|
11
|
+
bold: Uint8Array;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export declare function svgToPdf(svg: string, clip: {
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
}, opts?: SvgToPdfOptions): Promise<Blob>;
|