@tumaet/apollon 4.2.8 → 4.2.10

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.
Files changed (42) hide show
  1. package/dist/assets/style.css +1 -1
  2. package/dist/components/DraggableGhost.d.ts +1 -1
  3. package/dist/components/ScrollOverlay.d.ts +1 -1
  4. package/dist/components/svgs/edges/InlineMarker.d.ts +62 -0
  5. package/dist/components/svgs/edges/index.d.ts +1 -1
  6. package/dist/components/svgs/nodes/classDiagram/ClassSVG.d.ts +1 -1
  7. package/dist/components/svgs/nodes/classDiagram/ColorDescriptionSVG.d.ts +2 -2
  8. package/dist/components/svgs/nodes/classDiagram/TitleAndDescriptionSVG.d.ts +1 -1
  9. package/dist/components/svgs/nodes/communicationDiagram/CommunicationObjectNameSVG.d.ts +1 -1
  10. package/dist/components/svgs/nodes/objectDiagram/ObjectNameSVG.d.ts +1 -1
  11. package/dist/constants.d.ts +176 -0
  12. package/dist/edges/Connection.d.ts +6 -1
  13. package/dist/edges/GenericEdge.d.ts +2 -1
  14. package/dist/edges/edgeTypes/ActivityDiagramEdge.d.ts +1 -1
  15. package/dist/edges/edgeTypes/BPMNDiagramEdge.d.ts +1 -1
  16. package/dist/edges/edgeTypes/ClassDiagramEdge.d.ts +1 -1
  17. package/dist/edges/edgeTypes/CommunicationDiagramEdge.d.ts +1 -1
  18. package/dist/edges/edgeTypes/ComponentDiagramEdge.d.ts +1 -1
  19. package/dist/edges/edgeTypes/DeploymentDiagramEdge.d.ts +1 -1
  20. package/dist/edges/edgeTypes/FlowChartEdge.d.ts +1 -1
  21. package/dist/edges/edgeTypes/ObjectDiagramEdge.d.ts +1 -1
  22. package/dist/edges/edgeTypes/PetriNetEdge.d.ts +1 -1
  23. package/dist/edges/edgeTypes/ReachabilityGraphArc.d.ts +1 -1
  24. package/dist/edges/types.d.ts +28 -28
  25. package/dist/hooks/useStraightPathEdge.d.ts +1 -3
  26. package/dist/index.js +35090 -32800
  27. package/dist/types/SVG.d.ts +1 -1
  28. package/dist/typings.d.ts +7 -0
  29. package/dist/utils/edgeUtils.d.ts +1 -1
  30. package/dist/utils/exportUtils.d.ts +102 -2
  31. package/dist/utils/flatSvgExporter.d.ts +8 -0
  32. package/dist/utils/index.d.ts +1 -0
  33. package/dist/utils/pathParsing.d.ts +54 -0
  34. package/package.json +14 -5
  35. package/dist/components/svgs/edges/markers/SvgMarkers.d.ts +0 -1
  36. package/dist/components/svgs/edges/markers/index.d.ts +0 -1
  37. package/dist/constants/canvasConstants.d.ts +0 -6
  38. package/dist/constants/dropElementConfig.d.ts +0 -14
  39. package/dist/constants/edgeConstants.d.ts +0 -13
  40. package/dist/constants/index.d.ts +0 -4
  41. package/dist/constants/layoutConstants.d.ts +0 -9
  42. package/dist/constants/zindexConstants.d.ts +0 -9
@@ -2,7 +2,7 @@ export interface SVGComponentProps {
2
2
  id: string;
3
3
  width: number;
4
4
  height: number;
5
- transformScale?: number;
5
+ SIDEBAR_PREVIEW_SCALE?: number;
6
6
  svgAttributes?: React.SVGAttributes<SVGElement>;
7
7
  showAssessmentResults?: boolean;
8
8
  }
package/dist/typings.d.ts CHANGED
@@ -65,6 +65,7 @@ export declare enum ApollonView {
65
65
  Exporting = "Exporting",
66
66
  Highlight = "Highlight"
67
67
  }
68
+ export type SvgExportMode = "web" | "compat";
68
69
  export type ApollonOptions = {
69
70
  type?: UMLDiagramType;
70
71
  mode?: ApollonMode;
@@ -104,6 +105,12 @@ export type ExportOptions = {
104
105
  keepOriginalSize?: boolean;
105
106
  include?: string[];
106
107
  exclude?: string[];
108
+ /**
109
+ * Controls how SVG output is post-processed.
110
+ * - "web": keep CSS variables for theme-adaptive rendering in browsers
111
+ * - "compat": resolve CSS variables + inline attributes for PowerPoint/Inkscape
112
+ */
113
+ svgMode?: SvgExportMode;
107
114
  };
108
115
  export type SVG = {
109
116
  svg: string;
@@ -74,7 +74,7 @@ export declare function getEllipseHandlePosition(centerX: number, centerY: numbe
74
74
  };
75
75
  export declare function calculateOverlayPath(sourceX: number, sourceY: number, targetX: number, targetY: number, type: string): string;
76
76
  export declare function calculateStraightPath(sourceX: number, sourceY: number, targetX: number, targetY: number, type: string): string;
77
- export declare function simplifySvgPath(path: string, decimals?: number): string;
77
+ export declare function simplifySvgPath(path: string): string;
78
78
  export declare function simplifyPoints(points: IPoint[]): IPoint[];
79
79
  export declare function parseSvgPath(path: string): IPoint[];
80
80
  export declare function calculateInnerMidpoints(points: IPoint[], decimals?: number): IPoint[];
@@ -1,3 +1,103 @@
1
1
  import { ReactFlowInstance, Node, Edge, Rect } from '@xyflow/react';
2
- export declare const getSVG: (container: HTMLElement, clip: Rect) => string;
3
- export declare function getDiagramBounds(reactFlow: ReactFlowInstance<Node, Edge>): Rect;
2
+ import { Point } from './pathParsing';
3
+ type SvgExportMode = "web" | "compat";
4
+ export declare const getSVG: (container: HTMLElement, clip: Rect, options?: {
5
+ svgMode?: SvgExportMode;
6
+ }) => string;
7
+ /**
8
+ * Extract all coordinate points from an SVG path string.
9
+ * This includes endpoints AND control points for bezier curves,
10
+ * which is important because bezier curves are bounded by the
11
+ * convex hull of all their control points.
12
+ *
13
+ * For S (smooth cubic) and T (smooth quadratic) commands, we also
14
+ * include the reflected control point which may extend the bounds.
15
+ */
16
+ declare function extractPathPoints(pathD: string): Point[];
17
+ /**
18
+ * Calculate bounds for node SVG overflow content.
19
+ *
20
+ * Some nodes render elements outside their viewBox (e.g., the initial marking
21
+ * arrow in Reachability Graphs extends to negative coordinates). These elements
22
+ * are visible because the node SVGs use overflow="visible", but they are NOT
23
+ * included in reactFlow.getNodesBounds() which only considers node position
24
+ * and dimensions.
25
+ *
26
+ * This function scans node SVGs for <line>, <path>, and <circle> elements
27
+ * that extend outside the node's local coordinate system (viewBox), converts
28
+ * them to global coordinates, and returns the bounding box of all such content.
29
+ */
30
+ declare function getNodeOverflowBoundsFromDOM(container: HTMLElement): Rect | undefined;
31
+ declare function mergeBounds(a: Rect, b: Rect): Rect;
32
+ export declare function getDiagramBounds(reactFlow: ReactFlowInstance<Node, Edge>, container?: HTMLElement | null): Rect;
33
+ declare function extractStyles(styleString: string): {
34
+ transform: {
35
+ x: number;
36
+ y: number;
37
+ };
38
+ width: string | null;
39
+ height: string | null;
40
+ };
41
+ type CSSVariableMap = Readonly<Record<string, string>>;
42
+ /**
43
+ * Resolve a single CSS variable reference to its final value.
44
+ * Handles recursive var() resolution and fallback values.
45
+ */
46
+ declare function resolveCSSVariable(value: string, cssVarMap?: CSSVariableMap): string;
47
+ /**
48
+ * Replace CSS variables and currentColor in all attributes of an element tree.
49
+ *
50
+ * @param node - The DOM node to process
51
+ * @param inheritedColor - The inherited 'currentColor' value from parent elements
52
+ */
53
+ declare function replaceCSSVariables(node: Element | ChildNode, inheritedColor?: string, cssVarMap?: CSSVariableMap): void;
54
+ /**
55
+ * Convert inline style properties to direct SVG attributes for better compatibility.
56
+ * PowerPoint and some other applications don't properly parse CSS in style attributes.
57
+ */
58
+ declare function convertStyleToAttributes(node: Element | ChildNode): void;
59
+ /**
60
+ * Ensure all <text> elements have explicit font-size, font-weight, and font-family.
61
+ *
62
+ * In the browser, text inherits these from CSS (:root font-family, default font-size).
63
+ * In exported SVGs opened in non-browser renderers, missing attributes cause text to
64
+ * render with the renderer's own defaults (often Times New Roman at an arbitrary size).
65
+ *
66
+ * This pass runs AFTER convertStyleToAttributes so any font props already extracted
67
+ * from inline styles are present as attributes.
68
+ */
69
+ declare function ensureTextFontDefaults(svg: Element): void;
70
+ /**
71
+ * Replace `text-decoration="underline"` on `<text>` elements with manual
72
+ * `<line>` siblings so the underline is visible in non-browser renderers.
73
+ *
74
+ * resvg 2.6.2 has a rendering bug where 3+ `text-decoration="underline"`
75
+ * attributes across nested `<svg>` elements cause unrelated paths (particularly
76
+ * vertical lines) to disappear. This workaround removes the problematic
77
+ * attribute and draws explicit underline lines using `getBBox()` for accurate
78
+ * text measurements.
79
+ *
80
+ * The SVG must be temporarily attached to the DOM for `getBBox()` to work.
81
+ */
82
+ declare function replaceTextDecorationWithManualUnderline(svg: SVGSVGElement): void;
83
+ /**
84
+ * Final safety pass: strip any legacy <marker> references that could sneak in
85
+ * from third-party content. Keeps exports clean for PowerPoint/Keynote.
86
+ */
87
+ declare function removeMarkerElements(svg: Element): void;
88
+ /**
89
+ * @internal — Exported for unit testing only. Not part of the public API.
90
+ */
91
+ export declare const __testing: {
92
+ readonly extractPathPoints: typeof extractPathPoints;
93
+ readonly extractStyles: typeof extractStyles;
94
+ readonly resolveCSSVariable: typeof resolveCSSVariable;
95
+ readonly replaceCSSVariables: typeof replaceCSSVariables;
96
+ readonly convertStyleToAttributes: typeof convertStyleToAttributes;
97
+ readonly ensureTextFontDefaults: typeof ensureTextFontDefaults;
98
+ readonly removeMarkerElements: typeof removeMarkerElements;
99
+ readonly replaceTextDecorationWithManualUnderline: typeof replaceTextDecorationWithManualUnderline;
100
+ readonly mergeBounds: typeof mergeBounds;
101
+ readonly getNodeOverflowBoundsFromDOM: typeof getNodeOverflowBoundsFromDOM;
102
+ };
103
+ export {};
@@ -0,0 +1,8 @@
1
+ import { SVG, UMLModel } from '../typings';
2
+ export type FlatSvgExportOptions = {
3
+ margin?: number;
4
+ background?: "white" | "transparent";
5
+ fontFamily?: string;
6
+ fontSize?: number;
7
+ };
8
+ export declare const exportClassDiagramAsFlatSvg: (model: UMLModel, options?: FlatSvgExportOptions) => SVG;
@@ -13,3 +13,4 @@ export * from './bpmnConstraints';
13
13
  export * from './versionConverter';
14
14
  export * from './labelUtils';
15
15
  export * from './alignmentUtils';
16
+ export * from './flatSvgExporter';
@@ -0,0 +1,54 @@
1
+ /**
2
+ * SVG Path Parsing Utilities
3
+ *
4
+ * Parses SVG path commands to extract endpoint positions and directions.
5
+ * Used by InlineMarker to correctly position and orient edge markers.
6
+ *
7
+ * Supports all SVG path commands including relative coordinates.
8
+ */
9
+ export interface Point {
10
+ readonly x: number;
11
+ readonly y: number;
12
+ }
13
+ export interface PathEndInfo {
14
+ /** The endpoint coordinates */
15
+ readonly endPoint: Point;
16
+ /** Direction angle in radians (from previous point to endpoint) */
17
+ readonly direction: number;
18
+ }
19
+ export interface PathStartInfo {
20
+ /** The start point coordinates */
21
+ readonly startPoint: Point;
22
+ /** Direction angle in radians (pointing into the start, away from second point) */
23
+ readonly direction: number;
24
+ }
25
+ /**
26
+ * Calculate the direction angle from point A to point B.
27
+ */
28
+ export declare function calculateDirection(from: Point, to: Point): number;
29
+ /**
30
+ * Extract endpoint information from an SVG path.
31
+ *
32
+ * Parses the path to find the final position and the direction of approach.
33
+ * The direction is calculated from the control point (or previous point) to the endpoint.
34
+ *
35
+ * @param pathD - SVG path data string (e.g., "M0,0 L100,100")
36
+ * @returns Endpoint info or null if path is invalid
37
+ */
38
+ export declare function getPathEndInfo(pathD: string): PathEndInfo | null;
39
+ /**
40
+ * Extract start point information from an SVG path.
41
+ *
42
+ * @param pathD - SVG path data string
43
+ * @returns Start point info or null if path is invalid
44
+ */
45
+ export declare function getPathStartInfo(pathD: string): PathStartInfo | null;
46
+ /**
47
+ * Extract marker ID from a url() reference.
48
+ *
49
+ * @example
50
+ * extractMarkerId("url(#black-arrow)") // "black-arrow"
51
+ * extractMarkerId("url('#my-marker')") // "my-marker"
52
+ * extractMarkerId(undefined) // null
53
+ */
54
+ export declare function extractMarkerId(markerUrl: string | undefined): string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tumaet/apollon",
3
- "version": "4.2.8",
3
+ "version": "4.2.10",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,7 +20,10 @@
20
20
  "build:watch": "tsc -b --watch & vite build --watch",
21
21
  "preview": "vite preview",
22
22
  "lint": "eslint .",
23
- "lint:fix": "eslint --fix ."
23
+ "lint:fix": "eslint --fix .",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "test:coverage": "vitest run --coverage"
24
27
  },
25
28
  "dependencies": {
26
29
  "@emotion/react": "11.11.1",
@@ -31,18 +34,24 @@
31
34
  "react": "18.3.1",
32
35
  "react-dom": "18.3.1",
33
36
  "uuid": "11.0.3",
34
- "zustand": "5.0.3",
35
- "yjs": "13.6.20"
37
+ "yjs": "13.6.20",
38
+ "zustand": "5.0.3"
36
39
  },
37
40
  "devDependencies": {
38
41
  "@eslint/js": "9.17.0",
42
+ "@testing-library/jest-dom": "^6.9.1",
43
+ "@testing-library/react": "^16.3.2",
44
+ "@testing-library/user-event": "^14.6.1",
39
45
  "@vitejs/plugin-react": "4.3.4",
46
+ "@vitest/coverage-v8": "^4.0.18",
40
47
  "eslint": "9.17.0",
41
48
  "eslint-plugin-react": "7.37.2",
42
49
  "globals": "15.13.0",
50
+ "jsdom": "^28.1.0",
43
51
  "typescript": "5.7.2",
44
52
  "typescript-eslint": "8.18.1",
45
53
  "vite": "6.3.4",
46
- "vite-plugin-dts": "4.3.0"
54
+ "vite-plugin-dts": "4.3.0",
55
+ "vitest": "^4.0.18"
47
56
  }
48
57
  }
@@ -1 +0,0 @@
1
- export declare function SvgMarkers(): JSX.Element;
@@ -1 +0,0 @@
1
- export * from './SvgMarkers';
@@ -1,6 +0,0 @@
1
- export declare const MIN_SCALE_TO_ZOOM_OUT = 0.4;
2
- export declare const MAX_SCALE_TO_ZOOM_IN = 2.5;
3
- export declare const MOUSE_UP_OFFSET_IN_PIXELS = 5;
4
- export declare const SNAP_TO_GRID_PX = 10;
5
- export declare const EXTRA_SPACE_FOR_EXTENTION = 10;
6
- export declare const PASTE_OFFSET = 20;
@@ -1,14 +0,0 @@
1
- import { UMLDiagramType } from '../types';
2
- import { DiagramNodeType } from '../nodes';
3
- export * from './layoutConstants';
4
- export declare const transformScale = 0.8;
5
- export type DropElementConfig = {
6
- type: DiagramNodeType;
7
- width: number;
8
- height: number;
9
- defaultData?: Record<string, unknown>;
10
- svg: React.FC<any>;
11
- marginTop?: number;
12
- };
13
- export declare const dropElementConfigs: Record<UMLDiagramType, DropElementConfig[]>;
14
- export declare const ColorDescriptionConfig: DropElementConfig;
@@ -1,13 +0,0 @@
1
- export declare const ARROW_MARKER_PADDING = -3;
2
- export declare const DOTTED_ARROW_MARKER_PADDING = -3;
3
- export declare const TRIANGLE_MARKER_PADDING = -3;
4
- export declare const RHOMBUS_MARKER_PADDING = 12;
5
- export declare const MARKER_PADDING = -3;
6
- export declare const SOURCE_CONNECTION_POINT_PADDING = 3.5;
7
- export declare const STEP_BOARDER_RADIUS = 0;
8
- export declare const USECASE_PADDING = -3;
9
- export declare const NO_PADDING = 0;
10
- export declare const EDGE_HIGHTLIGHT_STROKE_WIDTH = 15;
11
- export declare const BPMN_SMALL_ARROW_PADDING = 4;
12
- export declare const BPMN_CIRCLE_PADDING = 5;
13
- export declare const BPMN_MESSAGE_ARROW_PADDING = 4.5;
@@ -1,4 +0,0 @@
1
- export * from './dropElementConfig';
2
- export * from './canvasConstants';
3
- export * from './edgeConstants';
4
- export * from './layoutConstants';
@@ -1,9 +0,0 @@
1
- export declare const DEFAULT_FONT = "400 16px Inter, system-ui, Avenir, Helvetica, Arial, sans-serif";
2
- export declare const DEFAULT_HEADER_HEIGHT = 40;
3
- export declare const DEFAULT_HEADER_HEIGHT_WITH_STREOTYPE = 50;
4
- export declare const DEFAULT_ATTRIBUTE_HEIGHT = 30;
5
- export declare const DEFAULT_METHOD_HEIGHT = 30;
6
- export declare const DEFAULT_PADDING = 10;
7
- export declare const LINE_WIDTH = 1;
8
- export declare const LINE_WIDTH_INTERFACE = 2;
9
- export declare const LINE_WIDTH_ON_EDGE: number;
@@ -1,9 +0,0 @@
1
- export declare const ZINDEX_BASE = 0;
2
- export declare const ZINDEX_HEADER_SWITCH = 1;
3
- export declare const ZINDEX_MODAL = 9998;
4
- export declare const ZINDEX_TOOLTIP = 10000;
5
- export declare const ZINDEX_LABEL = 9998;
6
- export declare const ZINDEX_PANEL = 10;
7
- export declare const ZINDEX_MINIMAP = 5;
8
- export declare const ZINDEX_DRAGGABLE_GHOST = 2;
9
- export declare const ZINDEX_DRAGGABLE_ELEMENT = 9999;