@tumaet/apollon 4.8.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/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/index.d.ts +131 -3
- package/dist/index.js +19744 -19098
- package/dist/internals.d.ts +29 -0
- package/dist/internals.js +7 -6
- package/dist/react/apollon-editor.d.ts +56 -3
- package/dist/react/components/CustomControls.d.ts +7 -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 +18 -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/exportStyles-yVX7Dykt.js +6 -0
- package/dist/react/hooks/index.d.ts +0 -1
- 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 +13264 -18536
- package/dist/react/store/context.d.ts +3 -0
- package/dist/react/types/nodes/NodeProps.d.ts +24 -0
- 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 +23 -19
- package/dist/react/utils/swimlaneUtils.d.ts +58 -0
- package/dist/yjsSync-BCNFF_EI.js +45418 -0
- package/package.json +19 -8
- package/schema/uml-model-4.schema.json +1 -0
- package/dist/exportStyles-Wcc8N8Xj.js +0 -5
- package/dist/react/exportStyles-CH2hautV.js +0 -6
- package/dist/react/hooks/useMessagePositioning.d.ts +0 -30
- package/dist/yjsSync-CqmgRwRE.js +0 -51038
|
@@ -5,15 +5,18 @@ import { PopoverStore } from './popoverStore';
|
|
|
5
5
|
import { AssessmentSelectionStore } from './assessmentSelectionStore';
|
|
6
6
|
import { AlignmentGuidesStore } from './alignmentGuidesStore';
|
|
7
7
|
import { EdgeGeometryStore } from './edgeGeometryStore';
|
|
8
|
+
import { OverlayStore } from '../overlay/overlayStore';
|
|
8
9
|
export declare const DiagramStoreContext: import('react').Context<StoreApi<DiagramStore> | null>;
|
|
9
10
|
export declare const MetadataStoreContext: import('react').Context<StoreApi<MetadataStore> | null>;
|
|
10
11
|
export declare const PopoverStoreContext: import('react').Context<StoreApi<PopoverStore> | null>;
|
|
11
12
|
export declare const AssessmentSelectionStoreContext: import('react').Context<StoreApi<AssessmentSelectionStore> | null>;
|
|
12
13
|
export declare const AlignmentGuidesStoreContext: import('react').Context<StoreApi<AlignmentGuidesStore> | null>;
|
|
13
14
|
export declare const EdgeGeometryStoreContext: import('react').Context<StoreApi<EdgeGeometryStore> | null>;
|
|
15
|
+
export declare const OverlayStoreContext: import('react').Context<StoreApi<OverlayStore> | null>;
|
|
14
16
|
export declare const useDiagramStore: <T>(selector: (state: DiagramStore) => T) => T;
|
|
15
17
|
export declare const useMetadataStore: <T>(selector: (state: MetadataStore) => T) => T;
|
|
16
18
|
export declare const usePopoverStore: <T>(selector: (state: PopoverStore) => T) => T;
|
|
17
19
|
export declare const useAssessmentSelectionStore: <T>(selector: (state: AssessmentSelectionStore) => T) => T;
|
|
18
20
|
export declare const useAlignmentGuidesStore: <T>(selector: (state: AlignmentGuidesStore) => T) => T;
|
|
19
21
|
export declare const useEdgeGeometryStore: <T>(selector: (state: EdgeGeometryStore) => T) => T;
|
|
22
|
+
export declare const useOverlayStore: <T>(selector: (state: OverlayStore) => T) => T;
|
|
@@ -8,6 +8,30 @@ export type DefaultNodeProps = {
|
|
|
8
8
|
export type ClassNodeElement = {
|
|
9
9
|
id: string;
|
|
10
10
|
} & DefaultNodeProps;
|
|
11
|
+
/** A single partition (lane) inside an activity swimlane. */
|
|
12
|
+
export type SwimlaneLane = {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
/**
|
|
16
|
+
* Lane's extent along the swimlane's primary axis, in absolute flow px. The
|
|
17
|
+
* last lane is elastic (fills the remainder), so resizing the swimlane only
|
|
18
|
+
* changes the last lane. Optional: lanes without it divide the space equally,
|
|
19
|
+
* so existing saved swimlanes render as equal lanes until a separator moves.
|
|
20
|
+
*/
|
|
21
|
+
size?: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Activity-partition (swimlane) container. Lanes are equal divisions along the
|
|
25
|
+
* primary axis (columns when vertical, rows when horizontal). Elements dropped
|
|
26
|
+
* into the swimlane become its children and move with it; which lane an element
|
|
27
|
+
* belongs to is expressed by where the modeller places it, matching the UML
|
|
28
|
+
* activity-partition notation where partition membership is positional rather
|
|
29
|
+
* than stored per element.
|
|
30
|
+
*/
|
|
31
|
+
export type ActivitySwimlaneProps = DefaultNodeProps & {
|
|
32
|
+
orientation: "vertical" | "horizontal";
|
|
33
|
+
lanes: SwimlaneLane[];
|
|
34
|
+
};
|
|
11
35
|
export type ClassNodeProps = {
|
|
12
36
|
methods: ClassNodeElement[];
|
|
13
37
|
attributes: ClassNodeElement[];
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { IPoint } from '../../edges/Connection';
|
|
2
|
+
/**
|
|
3
|
+
* Pure geometry for edge-label placement, in flow space. No React, no DOM —
|
|
4
|
+
* every output is derived synchronously from the edge's polyline so it is
|
|
5
|
+
* identical interactively and in headless (resvg) export, and unit-testable on
|
|
6
|
+
* its own (mirrors edges/labelTypes/messageLayout.ts, the #645 gold standard).
|
|
7
|
+
*
|
|
8
|
+
* The model follows the cross-tool consensus (yEd / ELK CENTER / mxGraph /
|
|
9
|
+
* JointJS): keep the text horizontal and offset it by a constant gap onto a
|
|
10
|
+
* perpendicular side. The label is hosted on whichever ARM of the (possibly
|
|
11
|
+
* stepped) edge has room — scored against the edge's own arms, nodes, and
|
|
12
|
+
* neighbour edges — defaulting to centered-on-top of the arc-mid segment when
|
|
13
|
+
* that is already clear. Deterministic scoring, not a continuous optimizer.
|
|
14
|
+
*/
|
|
15
|
+
export interface Rect {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
}
|
|
21
|
+
export interface MidSegment {
|
|
22
|
+
/** Rounded midpoint of the chosen mid-segment (flow space). */
|
|
23
|
+
point: IPoint;
|
|
24
|
+
/** Orientation of the chosen mid-segment. */
|
|
25
|
+
isHorizontal: boolean;
|
|
26
|
+
/** Index of the chosen segment in the collapsed polyline. */
|
|
27
|
+
segmentIndex: number;
|
|
28
|
+
/** The chosen segment's endpoints in source->target order. Useful to derive
|
|
29
|
+
* the LOCAL flow direction at the middle (e.g. communication arrows) instead
|
|
30
|
+
* of the raw node anchors, which can disagree on a bent edge. */
|
|
31
|
+
start: IPoint;
|
|
32
|
+
end: IPoint;
|
|
33
|
+
}
|
|
34
|
+
export type LabelSide = "above" | "below" | "left" | "right";
|
|
35
|
+
export interface PlacedLabel {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
textAnchor: "start" | "middle" | "end";
|
|
39
|
+
dominantBaseline: "auto" | "middle" | "hanging";
|
|
40
|
+
/** Exposed for unit assertions; not needed for rendering. */
|
|
41
|
+
side: LabelSide;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The mid-SEGMENT midpoint and orientation, computed purely from the polyline.
|
|
45
|
+
*
|
|
46
|
+
* Walks the collapsed polyline accumulating Manhattan segment length (exact
|
|
47
|
+
* because EDGES.STEP_BORDER_RADIUS === 0, so getSmoothStepPath emits no corner
|
|
48
|
+
* arcs and the rendered path equals the polyline). The "middle" is the first
|
|
49
|
+
* segment whose cumulative length reaches half the total; the midpoint is lerped
|
|
50
|
+
* strictly INSIDE that one segment, so it is corner-safe — unlike sampling the
|
|
51
|
+
* rendered path with getPointAtLength(total/2), which can land on a bend or, if
|
|
52
|
+
* line-jump bridges are present, on a bridge arc off the straight line.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getMidSegment(renderPoints: IPoint[], fallbackSource: IPoint, fallbackTarget: IPoint): MidSegment;
|
|
55
|
+
/**
|
|
56
|
+
* Rough single-line text width (flow px). Deterministic — a pure character-count
|
|
57
|
+
* estimate, never canvas measurement — so the chosen placement is identical
|
|
58
|
+
* interactively and in headless export, and SSR-safe. Slightly generous so the
|
|
59
|
+
* scoring box errs toward MORE clearance.
|
|
60
|
+
*/
|
|
61
|
+
export declare function estimateLabelWidth(text: string, fontSize: number): number;
|
|
62
|
+
/**
|
|
63
|
+
* The text box (flow space) for a label anchored at `point` on the chosen side,
|
|
64
|
+
* sized to the actual label (`w` × `h`). Used to score overlap against the
|
|
65
|
+
* edge's own arms, neighbour edges, and nodes.
|
|
66
|
+
*/
|
|
67
|
+
export declare function candidateBox(point: IPoint, side: LabelSide, w: number, h: number): Rect;
|
|
68
|
+
/**
|
|
69
|
+
* The other edges' polylines whose bounding box comes within `radius` of
|
|
70
|
+
* `center`, excluding `selfId`. Bounds the neighbour scan to edges actually near
|
|
71
|
+
* the label so placement stays O(nearby), not O(all edges) per label.
|
|
72
|
+
*/
|
|
73
|
+
export declare function collectNeighborPolylines(geometryById: Record<string, IPoint[]>, selfId: string, center: IPoint, radius: number): IPoint[][];
|
|
74
|
+
export interface MiddleLabelInput {
|
|
75
|
+
/** The edge's full rendered polyline (source → target). */
|
|
76
|
+
renderPoints: IPoint[];
|
|
77
|
+
/** The label text — used for a width fallback when measuredWidth is absent. */
|
|
78
|
+
labelText: string;
|
|
79
|
+
/** Render font size (px) of the label. */
|
|
80
|
+
fontSize: number;
|
|
81
|
+
/** Real measured label width (px), from the rendering context. Preferred over
|
|
82
|
+
* the character-count estimate so the scored box equals the rendered ink. */
|
|
83
|
+
measuredWidth?: number;
|
|
84
|
+
/** Node rects to avoid — NOT only source/target: every node the edge routes
|
|
85
|
+
* near, so the label never lands on an unrelated node's body. */
|
|
86
|
+
nodeRects?: Rect[];
|
|
87
|
+
/** Nearby other-edge polylines (see collectNeighborPolylines), collected over
|
|
88
|
+
* the WHOLE edge so they cover any arm the label may land on. */
|
|
89
|
+
neighborGeometry?: IPoint[][];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Places the relationship/stereotype middle label so it overlaps nothing it can
|
|
93
|
+
* avoid. The label is hosted on whichever arm of the edge — and on whichever
|
|
94
|
+
* perpendicular side — has room: each candidate (every segment × its two sides)
|
|
95
|
+
* is scored lexicographically by
|
|
96
|
+
* [ overlaps (own other arms + nodes + neighbour edges),
|
|
97
|
+
* does-not-fit-within-the-segment,
|
|
98
|
+
* distance from the arc-midpoint (keep it central),
|
|
99
|
+
* side preference (on top / right) ].
|
|
100
|
+
* For a simple edge the arc-mid segment wins with zero overlaps, so the label
|
|
101
|
+
* stays centered on top exactly as before; on a zig-zag/stepped edge it moves to
|
|
102
|
+
* a longer arm with clearance instead of crossing the short mid-segment's
|
|
103
|
+
* neighbouring arms. All inputs are static geometry, so the placement is stable
|
|
104
|
+
* across selection and identical in headless export.
|
|
105
|
+
*/
|
|
106
|
+
export declare function computeMiddleLabelLayout(input: MiddleLabelInput): PlacedLabel;
|
|
107
|
+
export interface RotatedLabelPlacement {
|
|
108
|
+
x: number;
|
|
109
|
+
y: number;
|
|
110
|
+
/** Degrees; the label is rotated to lie along the connector, flipped to stay
|
|
111
|
+
* upright. */
|
|
112
|
+
rotation: number;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Placement for a label that lies ALONG a straight (possibly diagonal)
|
|
116
|
+
* connector — use-case association names and the <<include>>/<<extend>>
|
|
117
|
+
* stereotype. The text is rotated to the line's slope (flipped to stay upright)
|
|
118
|
+
* and pushed `perpendicularOffset` px off the line on the upper-left normal.
|
|
119
|
+
* Pass 0 to center it on the line (e.g. include/extend, which sits in the gap
|
|
120
|
+
* carved by calculateStraightPath). Centralises the rotation math that was
|
|
121
|
+
* duplicated across the use-case label components.
|
|
122
|
+
*/
|
|
123
|
+
export declare function computeUseCaseLabelLayout(source: IPoint, target: IPoint, perpendicularOffset: number): RotatedLabelPlacement;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure side-selection for the provided/required interface node label. The
|
|
3
|
+
* interface is a small circle that connects only at its four directional
|
|
4
|
+
* handles ("top"/"right"/"bottom"/"left"). The name sits centered below by
|
|
5
|
+
* default (see InterfaceLabel), but must move off any side a connecting edge
|
|
6
|
+
* attaches to — otherwise the label overlaps that edge. Pure and unit-testable
|
|
7
|
+
* in the spirit of edgeLabelLayout.ts; no React, no DOM, no constants.
|
|
8
|
+
*/
|
|
9
|
+
/** A side an edge can attach to (the four directional interface handles). */
|
|
10
|
+
export type CardinalSide = "top" | "right" | "bottom" | "left";
|
|
11
|
+
/**
|
|
12
|
+
* Where the label sits relative to the circle: one of the four sides, or — when
|
|
13
|
+
* every side has a connecting edge — a diagonal quadrant (which no cardinal edge
|
|
14
|
+
* passes through).
|
|
15
|
+
*/
|
|
16
|
+
export type InterfaceLabelSide = CardinalSide | "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
17
|
+
/** Minimal structural view of a React Flow edge (the store's `Edge[]` fits). */
|
|
18
|
+
interface InterfaceEdgeLike {
|
|
19
|
+
source: string;
|
|
20
|
+
target: string;
|
|
21
|
+
sourceHandle?: string | null;
|
|
22
|
+
targetHandle?: string | null;
|
|
23
|
+
}
|
|
24
|
+
/** The sides of `nodeId` that a connecting edge attaches to. */
|
|
25
|
+
export declare function getOccupiedInterfaceSides(edges: ReadonlyArray<InterfaceEdgeLike>, nodeId: string): Set<CardinalSide>;
|
|
26
|
+
/**
|
|
27
|
+
* Picks where the label sits. Prefers a free cardinal side by priority — reads
|
|
28
|
+
* naturally under a small circle (bottom, then top, then a horizontal side).
|
|
29
|
+
* When the assessment badge occupies the top-right corner, "top" and "right"
|
|
30
|
+
* are demoted last so a label can't graze the badge.
|
|
31
|
+
*
|
|
32
|
+
* If every cardinal side has a connecting edge, the label moves into a DIAGONAL
|
|
33
|
+
* quadrant: each cardinal edge leaves along an axis, so a corner label sits in
|
|
34
|
+
* the gap between two of them and crosses none. Prefer a corner away from the
|
|
35
|
+
* top-right badge.
|
|
36
|
+
*/
|
|
37
|
+
export declare function pickInterfaceLabelSide(occupied: ReadonlySet<CardinalSide>, opts?: {
|
|
38
|
+
badgeTopRight?: boolean;
|
|
39
|
+
}): InterfaceLabelSide;
|
|
40
|
+
/** Convenience: the interface label side for `nodeId` given the current edges. */
|
|
41
|
+
export declare function computeInterfaceLabelSide(edges: ReadonlyArray<InterfaceEdgeLike>, nodeId: string, opts?: {
|
|
42
|
+
badgeTopRight?: boolean;
|
|
43
|
+
}): InterfaceLabelSide;
|
|
44
|
+
export {};
|
|
@@ -10,6 +10,7 @@ export * from './diagramTypeUtils';
|
|
|
10
10
|
export * from './storeUtils';
|
|
11
11
|
export * from './deepPartial';
|
|
12
12
|
export * from './bpmnConstraints';
|
|
13
|
+
export * from './swimlaneUtils';
|
|
13
14
|
export { importDiagram } from './versionConverter';
|
|
14
15
|
export * from './alignmentUtils';
|
|
15
16
|
export * from './requiredInterfaceUtils';
|
|
@@ -8,41 +8,45 @@
|
|
|
8
8
|
* space, which is what you actually draw in.
|
|
9
9
|
* 2. Fill the available VERTICAL space — a single column down the side reads
|
|
10
10
|
* like a classic palette and wastes no height.
|
|
11
|
-
* 3.
|
|
12
|
-
* column
|
|
11
|
+
* 3. Shrink the cells down to the `COMFORT_MIN_H` LEGIBILITY threshold BEFORE
|
|
12
|
+
* adding a column — but no smaller: below that, spill to another column so
|
|
13
|
+
* the node types stay distinguishable (rather than collapsing to an
|
|
14
|
+
* illegible sliver). Cap at `CELL_MAX_H` so they're never too large. The
|
|
15
|
+
* `CELL_MIN_H` touch floor is the last-resort fallback on a tiny canvas.
|
|
13
16
|
*
|
|
14
17
|
* So: walk column counts low→high and take the first one whose cells, sized to
|
|
15
|
-
* fill the height, are still
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
+
* fill the height (capped), are still at least the legibility threshold. One
|
|
19
|
+
* column of legible cells is preferred over two columns of bigger ones; cells
|
|
20
|
+
* shrink toward the legibility threshold first, and only spill to another column
|
|
21
|
+
* when staying legible in fewer columns no longer fits the height.
|
|
22
|
+
*
|
|
23
|
+
* `availH` is the palette's REAL available band (the caller measures the space
|
|
24
|
+
* between the palette's top and the bottom controls), so this math does NOT
|
|
25
|
+
* re-subtract any top/bottom chrome reserve — it fills the band it is given.
|
|
18
26
|
*
|
|
19
27
|
* Cells are rectangular (the dominant elements — class boxes, BPMN tasks — are
|
|
20
28
|
* ~1.6:1 wide); narrower/square elements letterbox centered inside. Sizing the
|
|
21
29
|
* cell, not the SVG, keeps the node components untouched.
|
|
22
30
|
*/
|
|
23
31
|
export declare const PALETTE: Readonly<{
|
|
24
|
-
/** HIG/WCAG touch
|
|
32
|
+
/** Absolute floor (HIG/WCAG touch) — only reached on a tiny canvas where even
|
|
33
|
+
* spilling to more columns can't keep cells legible; never shrink past it. */
|
|
25
34
|
readonly CELL_MIN_H: 44;
|
|
26
|
-
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
readonly CELL_MAX_H:
|
|
35
|
+
/** Legibility threshold: shrink a column's cells down to here BEFORE adding
|
|
36
|
+
* another column, but spill (rather than go smaller) so the node types stay
|
|
37
|
+
* distinguishable. ~a comfortably legible node-preview cell. */
|
|
38
|
+
readonly COMFORT_MIN_H: 64;
|
|
39
|
+
/** Upper bound so few-element palettes don't get absurdly tall cells;
|
|
40
|
+
* ~a 0.8-scale class-box preview. */
|
|
41
|
+
readonly CELL_MAX_H: 88;
|
|
33
42
|
/** cellW = round(CELL_RATIO * cellH); ~matches the 160×100 class box. */
|
|
34
43
|
readonly CELL_RATIO: 1.6;
|
|
35
44
|
readonly GAP: 8;
|
|
36
45
|
readonly PAD: 6;
|
|
37
|
-
/** Keep the palette horizontally narrow so the canvas keeps its width
|
|
46
|
+
/** Keep the palette horizontally narrow so the canvas keeps its width. */
|
|
38
47
|
readonly MAX_FRAC_W: 0.5;
|
|
39
|
-
/** … but let it use most of the height. */
|
|
40
|
-
readonly MAX_FRAC_H: 0.9;
|
|
41
48
|
/** Letterbox padding around the preview inside a cell. */
|
|
42
49
|
readonly CONTENT_INSET: 6;
|
|
43
|
-
/** Space kept clear above (top offset) and below (zoom controls) the palette. */
|
|
44
|
-
readonly TOP_RESERVE: 10;
|
|
45
|
-
readonly BOTTOM_RESERVE: 84;
|
|
46
50
|
}>;
|
|
47
51
|
export interface PaletteLayout {
|
|
48
52
|
cols: number;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { SwimlaneLane } from '../types';
|
|
2
|
+
/** Smallest a lane may be shrunk to (flow px) when dragging a separator. */
|
|
3
|
+
export declare const MIN_LANE_EXTENT = 40;
|
|
4
|
+
/**
|
|
5
|
+
* Pixel `start`/`extent` of every lane along the primary axis.
|
|
6
|
+
*
|
|
7
|
+
* Lane sizes are stored as absolute flow px. The **last** lane is elastic: it
|
|
8
|
+
* always fills the remaining space. That way resizing the whole swimlane only
|
|
9
|
+
* grows/shrinks the last lane — the interior separators stay put — instead of
|
|
10
|
+
* rescaling every lane (which would move every separator). Lanes with no size
|
|
11
|
+
* at all (a freshly dropped swimlane) divide the axis equally.
|
|
12
|
+
*/
|
|
13
|
+
export declare const getLaneOffsets: (lanes: {
|
|
14
|
+
size?: number;
|
|
15
|
+
}[], primaryExtent: number) => {
|
|
16
|
+
start: number;
|
|
17
|
+
extent: number;
|
|
18
|
+
}[];
|
|
19
|
+
/**
|
|
20
|
+
* Pin every lane's current rendered extent as its `size`, so the elastic last
|
|
21
|
+
* lane gets a concrete value before an operation (reorder/add/remove) that
|
|
22
|
+
* changes which lane is last.
|
|
23
|
+
*/
|
|
24
|
+
export declare const materializeLaneSizes: (lanes: SwimlaneLane[], primaryExtent: number) => SwimlaneLane[];
|
|
25
|
+
/** Index of the lane whose range contains the primary-axis coordinate `pos`. */
|
|
26
|
+
export declare const laneIndexAtOffset: (offsets: {
|
|
27
|
+
start: number;
|
|
28
|
+
extent: number;
|
|
29
|
+
}[], pos: number) => number;
|
|
30
|
+
/**
|
|
31
|
+
* Balanced resize of the divider between lane `index` and `index + 1`: move the
|
|
32
|
+
* shared boundary by `deltaPx`, growing one lane and shrinking the other by the
|
|
33
|
+
* same amount so the swimlane's outer size never changes. Neither lane drops
|
|
34
|
+
* below `MIN_LANE_EXTENT`. Returns lanes with an explicit `size` on every entry.
|
|
35
|
+
*
|
|
36
|
+
* When `snapGridPx > 0` the moved boundary is snapped to that grid, so a lane
|
|
37
|
+
* separator lands on the same grid that nodes and edge bends snap to. The lane
|
|
38
|
+
* offsets are measured from the swimlane's own origin, which React Flow already
|
|
39
|
+
* keeps grid-aligned, so the snapped boundary lines up with the absolute grid.
|
|
40
|
+
*/
|
|
41
|
+
export declare const resizeLaneDivider: (lanes: SwimlaneLane[], index: number, deltaPx: number, primaryExtent: number, snapGridPx?: number) => SwimlaneLane[];
|
|
42
|
+
/**
|
|
43
|
+
* Reposition a swimlane child when orientation flips and the swimlane's
|
|
44
|
+
* width/height swap: transpose the child's corner (x,y)->(y,x), then clamp it
|
|
45
|
+
* into the swapped frame by its own size so it can't be stranded off the new
|
|
46
|
+
* (shorter) cross-axis. `newWidth`/`newHeight` are the post-swap dimensions.
|
|
47
|
+
*/
|
|
48
|
+
export declare const flipSwimlaneChildPosition: (child: {
|
|
49
|
+
position: {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
};
|
|
53
|
+
width?: number;
|
|
54
|
+
height?: number;
|
|
55
|
+
}, newWidth: number, newHeight: number) => {
|
|
56
|
+
x: number;
|
|
57
|
+
y: number;
|
|
58
|
+
};
|