@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.
Files changed (73) hide show
  1. package/README.md +45 -20
  2. package/dist/assets/style.css +1 -1
  3. package/dist/export.d.ts +73 -0
  4. package/dist/export.js +219 -0
  5. package/dist/exportStyles-Co-WBqTa.js +5 -0
  6. package/dist/external/LICENSE-InterFont +92 -0
  7. package/dist/external/exportFonts-DxO9jrR1.js +19 -0
  8. package/dist/external/exportStyles-Co-WBqTa.js +5 -0
  9. package/dist/external/index.js +22191 -0
  10. package/dist/fontStack-DOtVH2j8.js +5 -0
  11. package/dist/index.d.ts +150 -3
  12. package/dist/index.js +19993 -19219
  13. package/dist/internals.d.ts +65 -1
  14. package/dist/internals.js +14 -12
  15. package/dist/react/apollon-editor.d.ts +56 -3
  16. package/dist/react/components/AlignmentGuides.d.ts +1 -1
  17. package/dist/react/components/CustomControls.d.ts +7 -0
  18. package/dist/react/components/DraggableGhost.d.ts +5 -0
  19. package/dist/react/components/popovers/PopoverManager.d.ts +1 -1
  20. package/dist/react/components/popovers/activityDiagram/ActivitySwimlaneEditPopover.d.ts +2 -0
  21. package/dist/react/components/popovers/activityDiagram/index.d.ts +1 -0
  22. package/dist/react/components/react/ApollonControl.d.ts +18 -0
  23. package/dist/react/components/svgs/nodes/InterfaceLabel.d.ts +26 -0
  24. package/dist/react/components/svgs/nodes/activityDiagram/ActivitySwimlaneSVG.d.ts +9 -0
  25. package/dist/react/components/svgs/nodes/activityDiagram/index.d.ts +1 -0
  26. package/dist/react/components/svgs/nodes/componentDiagram/ComponentInterfaceNodeSVG.d.ts +2 -0
  27. package/dist/react/components/svgs/nodes/deploymentDiagram/DeploymentInterfaceSVG.d.ts +2 -0
  28. package/dist/react/constants.d.ts +28 -0
  29. package/dist/react/edges/labelTypes/EdgeIncludeExtendLabel.d.ts +1 -4
  30. package/dist/react/edges/labelTypes/EdgeMiddleLabels.d.ts +7 -4
  31. package/dist/react/edges/labelTypes/EdgeMultipleLabels.d.ts +2 -3
  32. package/dist/react/edges/labelTypes/messageLayout.d.ts +51 -0
  33. package/dist/react/export/exportErrors.d.ts +10 -0
  34. package/dist/react/export/index.d.ts +13 -0
  35. package/dist/react/export/normalizeExportSvg.d.ts +16 -0
  36. package/dist/react/export/preProcessSvgForPdf.d.ts +20 -0
  37. package/dist/react/export/svgToPdf.d.ts +17 -0
  38. package/dist/react/export/svgToPng.d.ts +38 -0
  39. package/dist/react/exportStyles-yVX7Dykt.js +6 -0
  40. package/dist/react/hooks/index.d.ts +0 -1
  41. package/dist/react/hooks/useRemoteDraggingNodes.d.ts +20 -0
  42. package/dist/react/hooks/useStepPathEdge.d.ts +11 -0
  43. package/dist/react/index.d.ts +1 -0
  44. package/dist/react/nodes/activityDiagram/ActivitySwimlane.d.ts +3 -0
  45. package/dist/react/nodes/activityDiagram/index.d.ts +1 -0
  46. package/dist/react/nodes/types.d.ts +2 -1
  47. package/dist/react/overlay/OverlayLayer.d.ts +8 -0
  48. package/dist/react/overlay/RegionMount.d.ts +10 -0
  49. package/dist/react/overlay/overlayStore.d.ts +20 -0
  50. package/dist/react/overlay/types.d.ts +48 -0
  51. package/dist/react/react.d.ts +1 -0
  52. package/dist/react/react.js +13625 -18669
  53. package/dist/react/store/context.d.ts +3 -0
  54. package/dist/react/store/diagramStore.d.ts +17 -1
  55. package/dist/react/sync/perfCounters.d.ts +6 -0
  56. package/dist/react/sync/ydoc.d.ts +2 -0
  57. package/dist/react/sync/yjsSync.d.ts +3 -2
  58. package/dist/react/types/nodes/NodeProps.d.ts +24 -0
  59. package/dist/react/typings.d.ts +17 -0
  60. package/dist/react/utils/collaboration.d.ts +10 -1
  61. package/dist/react/utils/exportUtils.d.ts +0 -130
  62. package/dist/react/utils/geometry/edgeLabelLayout.d.ts +123 -0
  63. package/dist/react/utils/geometry/interfaceLabelLayout.d.ts +44 -0
  64. package/dist/react/utils/index.d.ts +1 -0
  65. package/dist/react/utils/paletteLayout.d.ts +70 -0
  66. package/dist/react/utils/swimlaneUtils.d.ts +58 -0
  67. package/dist/yjsSync-BCNFF_EI.js +45418 -0
  68. package/package.json +33 -8
  69. package/schema/uml-model-4.schema.json +1 -0
  70. package/dist/exportStyles-Xk-Vm7Ul.js +0 -5
  71. package/dist/react/exportStyles-DZCHk5mK.js +0 -6
  72. package/dist/react/hooks/useMessagePositioning.d.ts +0 -30
  73. package/dist/yjsSync-aPxjWNdZ.js +0 -50939
@@ -0,0 +1,38 @@
1
+ export type SvgToPngOptions = {
2
+ /** Multiplier applied to the diagram clip dimensions. Default 1.5. */
3
+ scale?: number;
4
+ /** CSS colour (e.g. "#ffffff") or null for transparent. Default null. */
5
+ background?: string | null;
6
+ /** Override the 75 MP area budget. */
7
+ maxAreaPx?: number;
8
+ /** Override the 16,384 px per-side cap. */
9
+ maxDimensionPx?: number;
10
+ /**
11
+ * The `@resvg/resvg-wasm` binary, as anything resvg's `initWasm` accepts.
12
+ * Required: where the wasm lives is the host bundler's concern, not the
13
+ * library's (resvg-wasm doesn't export it under a portable URL specifier).
14
+ * In Vite:
15
+ * `import url from "@resvg/resvg-wasm/index_bg.wasm?url"`
16
+ * `svgToPng(svg, clip, { wasmInput: fetch(url) })`
17
+ */
18
+ wasmInput?: WebAssembly.Module | BufferSource | Response | Promise<Response>;
19
+ /** Font buffers (ttf/otf) to use instead of the bundled Inter. */
20
+ fontBuffers?: Uint8Array[];
21
+ };
22
+ export type SvgToPngResult = {
23
+ blob: Blob;
24
+ /** The scale actually used — below the requested one when clamped. */
25
+ appliedScale: number;
26
+ clamped: boolean;
27
+ width: number;
28
+ height: number;
29
+ };
30
+ /**
31
+ * Largest scale that fits both the area budget and the per-side cap. Pure, so
32
+ * the clamp can be unit-tested without booting wasm.
33
+ */
34
+ export declare function computeAppliedScale(width: number, height: number, requestedScale: number, maxAreaPx: number, maxDimensionPx: number): number;
35
+ export declare function svgToPng(svg: string, clip: {
36
+ width: number;
37
+ height: number;
38
+ }, opts?: SvgToPngOptions): Promise<SvgToPngResult>;
@@ -0,0 +1,6 @@
1
+ "use client";
2
+ const o = ".react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-border-default: 1px solid #bbb;--xy-node-border-selected-default: 1px solid #555;--xy-handle-background-color-default: #333;--xy-selection-background-color-default: rgba(150, 150, 180, .1);--xy-selection-border-default: 1px dotted rgba(155, 155, 155, .8);--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #777;--xy-background-pattern-lines-color-default: #777;--xy-background-pattern-cross-color-default: #777;--xy-node-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default))}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{border:var(--xy-node-border, var(--xy-node-border-default));color:var(--xy-node-color, var(--xy-node-color-default))}.react-flow__node-input.selected,.react-flow__node-input:focus,.react-flow__node-input:focus-visible,.react-flow__node-default.selected,.react-flow__node-default:focus,.react-flow__node-default:focus-visible,.react-flow__node-output.selected,.react-flow__node-output:focus,.react-flow__node-output:focus-visible,.react-flow__node-group.selected,.react-flow__node-group:focus,.react-flow__node-group:focus-visible{outline:none;border:var(--xy-node-border-selected, var(--xy-node-border-selected-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}", e = ':root{--safe-area-inset-top: env(safe-area-inset-top, 0px);--safe-area-inset-right: env(safe-area-inset-right, 0px);--safe-area-inset-bottom: env(safe-area-inset-bottom, 0px);--safe-area-inset-left: env(safe-area-inset-left, 0px)}:root{--apollon-chrome-surface: var(--apollon-background, #fff);--apollon-chrome-surface-hover: color-mix( in srgb, var(--apollon-primary-contrast, #000) 8%, var(--apollon-background, #fff) );--apollon-chrome-surface-active: color-mix( in srgb, var(--apollon-primary-contrast, #000) 14%, var(--apollon-background, #fff) );--apollon-chrome-border: color-mix( in srgb, var(--apollon-primary-contrast, #000) 12%, var(--apollon-background, #fff) );--apollon-chrome-border-strong: color-mix( in srgb, var(--apollon-primary-contrast, #000) 28%, var(--apollon-background, #fff) );--apollon-chrome-text: var(--apollon-primary-contrast, #212529);--apollon-chrome-text-muted: color-mix( in srgb, var(--apollon-primary-contrast, #000) 58%, var(--apollon-background, #fff) );--apollon-chrome-accent: var(--apollon-primary, #3e8acc);--apollon-chrome-accent-contrast: #fff;--apollon-chrome-radius-sm: 6px;--apollon-chrome-radius-md: 8px;--apollon-chrome-radius-lg: 12px;--apollon-chrome-edge: 10px;--apollon-chrome-gap: 8px;--apollon-chrome-btn: 32px;--apollon-chrome-pad: 6px;--apollon-chrome-hit: 44px;--apollon-chrome-edge-safe-left: max( var(--apollon-chrome-edge), var(--safe-area-inset-left, 0px) );--apollon-chrome-edge-safe-right: max( var(--apollon-chrome-edge), var(--safe-area-inset-right, 0px) );--apollon-chrome-edge-safe-bottom: max( var(--apollon-chrome-edge), var(--safe-area-inset-bottom, 0px) );--apollon-chrome-island-h: calc( var(--apollon-chrome-btn) + 2 * var(--apollon-chrome-pad) + 2px );--apollon-chrome-shadow-docked: 0 1px 2px rgb(15 23 42 / 8%);--apollon-chrome-shadow-floating: 0 0 1px 0 rgb(15 23 42 / 20%), 0 2px 8px 0 rgb(15 23 42 / 12%);--apollon-chrome-inset-hairline: 0 0 0 0 transparent;--apollon-chrome-glass: color-mix( in srgb, var(--apollon-background, #fff) 80%, transparent );--apollon-chrome-glass-solid: color-mix( in srgb, var(--apollon-background, #fff) 92%, transparent );--apollon-chrome-glass-blur: saturate(180%) blur(20px);--apollon-chrome-duration-hover: .12s;--apollon-chrome-duration-enter: .22s;--apollon-chrome-ease-standard: cubic-bezier(.2, 0, 0, 1);--apollon-chrome-ease-decelerate: cubic-bezier(.05, .7, .1, 1)}:root[data-theme=dark],.apollon-editor[data-theme=dark]{--apollon-chrome-shadow-docked: 0 1px 2px rgb(0 0 0 / 40%);--apollon-chrome-shadow-floating: 0 2px 12px 0 rgb(0 0 0 / 50%);--apollon-chrome-inset-hairline: inset 0 0 0 1px rgb(255 255 255 / 8%)}@media(pointer:coarse){:root{--apollon-chrome-pad: 4px}}.react-flow{--panel-background: var(--apollon-background, #fff);--panel-shadow: 0 0 4px 0 var(--apollon-background-variant, #f8f9fa);--text: var(--apollon-primary-contrast, #000);--xy-edge-stroke: var(--apollon-primary-contrast, #000);--xy-edge-stroke-width: 2px;--xy-controls-button-background-color: var(--apollon-background, #fff);--xy-controls-button-border-color: transparent}.apollon-editor{background-color:var(--apollon-background, #fff);color:var(--apollon-primary-contrast, #000);isolation:isolate;--apollon-z-chrome: 10005}.apollon-overlay-panel,.apollon-overlay-band{z-index:var(--apollon-z-chrome)}.apollon-canvas{position:relative;flex:1;min-width:0;height:100%;overflow:hidden}.apollon-collaboration-presence-bar{position:absolute;top:calc(10px + var(--apollon-inset-top, 0px));right:calc(10px + var(--apollon-inset-right, 0px));display:flex;align-items:center;z-index:10002;pointer-events:auto}.apollon-collaboration-presence-bar [role=button]:focus-visible{outline:2px solid var(--apollon-primary, #3e8acc);outline-offset:2px}.apollon-collaboration-follower-badge{position:absolute;bottom:-4px;left:-4px;min-width:14px;height:14px;padding:0 3px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;border-radius:10px;border:2px solid;background-color:var(--apollon-background, #fff);color:var(--apollon-primary-contrast, #000);font-size:8px;font-weight:700}.apollon-collaboration-follow-frame{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;z-index:10001}.apollon-collaboration-follow-banner{position:absolute;top:16px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:8px;max-width:min(calc(100% - 32px),420px);padding:6px 6px 6px 14px;border-radius:999px;border:1px solid;background-color:var(--apollon-background, #fff);color:var(--apollon-primary-contrast, #000);box-shadow:0 2px 12px color-mix(in srgb,var(--apollon-primary-contrast, #000) 22%,transparent);font-size:13px;font-weight:500;white-space:nowrap;z-index:10004;pointer-events:auto;animation:apollon-collaboration-follow-banner-in .16s ease-out}@keyframes apollon-collaboration-follow-banner-in{0%{opacity:0;transform:translate(-50%,-8px)}to{opacity:1;transform:translate(-50%)}}@media(prefers-reduced-motion:reduce){.apollon-collaboration-follow-banner{animation:none}}.apollon-collaboration-follow-banner-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}.apollon-collaboration-follow-banner-text{overflow:hidden;text-overflow:ellipsis}.apollon-collaboration-follow-banner-stop{flex-shrink:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;cursor:pointer;border-radius:999px;padding:3px 12px;font:inherit;font-weight:600;background-color:var(--apollon-primary-contrast, #000);color:var(--apollon-background, #fff)}.apollon-collaboration-follow-banner-stop:hover{opacity:.85}.apollon-collaboration-follow-banner-stop:focus-visible{outline:2px solid var(--apollon-primary, #3e8acc);outline-offset:2px}.apollon-collaboration-cursors{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;pointer-events:none;z-index:10003}.apollon-collaboration-cursor{position:absolute}.apollon-collaboration-cursor-label{margin-top:4px;padding:2px 6px;font-size:12px;border-radius:6px;color:#fff;white-space:nowrap}.react-flow__node.apollon-collaboration-highlighted{box-shadow:0 0 0 4px var(--apollon-collaboration-highlight-color),0 0 16px 3px var(--apollon-collaboration-highlight-color)!important;border-color:var(--apollon-collaboration-highlight-color)!important}.react-flow__edge.apollon-collaboration-highlighted path{stroke:var(--apollon-collaboration-highlight-color)!important;stroke-width:4.5px!important;filter:drop-shadow(0 0 4px var(--apollon-collaboration-highlight-color))}.apollon-palette{box-sizing:border-box;position:absolute;top:calc(var(--safe-area-inset-top, 0px) + var(--apollon-chrome-gap) + var( --apollon-inset-top, calc(var(--apollon-chrome-edge) + var(--apollon-chrome-island-h)) ));left:calc(var(--apollon-chrome-edge-safe-left) + var(--apollon-inset-left, 0px));z-index:10000;max-height:calc(100% - var(--safe-area-inset-top, 0px) - var(--apollon-chrome-gap) - var( --apollon-inset-top, calc(var(--apollon-chrome-edge) + var(--apollon-chrome-island-h)) ) - var(--apollon-chrome-edge-safe-bottom) - var(--apollon-chrome-island-h) - var(--apollon-chrome-gap) - var(--apollon-inset-bottom, 0px));display:flex;flex-direction:column;gap:var(--apollon-chrome-gap);align-items:center;padding:var(--apollon-chrome-pad);overflow-y:auto;overscroll-behavior:contain;background:var(--apollon-chrome-glass);backdrop-filter:var(--apollon-chrome-glass-blur);-webkit-backdrop-filter:var(--apollon-chrome-glass-blur);color:var(--apollon-chrome-text);border:1px solid var(--apollon-chrome-border);border-radius:var(--apollon-chrome-radius-lg);box-shadow:var(--apollon-chrome-shadow-floating),var(--apollon-chrome-inset-hairline)}.apollon-palette__entries{display:grid;justify-content:center}.apollon-palette__entry{display:flex;align-items:center;justify-content:center;cursor:grab;border-radius:var(--apollon-chrome-radius-sm);transition:background-color .12s ease}.apollon-palette__entry:hover{background:var(--apollon-chrome-surface-hover)}.apollon-palette__entry:active{cursor:grabbing}.apollon-palette__view-switch{width:100%;display:flex;flex-direction:column;gap:4px}.apollon-palette__view-button{border-radius:var(--apollon-chrome-radius-md);border:1px solid var(--apollon-chrome-border-strong);background:transparent;color:var(--apollon-chrome-text);padding:6px 8px;cursor:pointer;font-weight:600;white-space:nowrap;font-size:12px}.apollon-palette__view-button:hover{background:var(--apollon-chrome-surface-hover)}.apollon-palette__view-button--active,.apollon-palette__view-button--active:hover{background:var(--apollon-chrome-accent);color:var(--apollon-chrome-accent-contrast);border-color:var(--apollon-chrome-accent)}.apollon-palette__hint{box-sizing:border-box;width:100%;max-width:160px;padding:4px;font-size:11px;line-height:1.4}.react-flow__panel.top.left,.react-flow__panel.top.right{margin-top:calc(var(--apollon-chrome-edge) + var(--safe-area-inset-top, 0px))}.react-flow__panel.bottom.left,.react-flow__panel.bottom.right{margin-bottom:var(--apollon-chrome-edge-safe-bottom)}.react-flow__panel.top.left,.react-flow__panel.bottom.left{margin-left:var(--apollon-chrome-edge-safe-left)}.react-flow__panel.top.right,.react-flow__panel.bottom.right{margin-right:var(--apollon-chrome-edge-safe-right)}.apollon-chrome-header-row{display:flex;align-items:flex-start;gap:var(--apollon-chrome-gap);width:100%;box-sizing:border-box;padding-top:var(--apollon-chrome-edge);padding-left:var(--apollon-chrome-edge-safe-left);padding-right:var(--apollon-chrome-edge-safe-right);pointer-events:none}.apollon-chrome-header-row>:not(.apollon-chrome-header-spacer){flex-shrink:0}.apollon-chrome-header-spacer{display:flex;flex:1 1 auto;min-width:0;justify-content:flex-start}@media(max-width:950px)and (max-height:500px){:root{--apollon-chrome-island-h: 36px;--apollon-chrome-pad: 2px}.apollon-collaboration-presence-bar{right:var(--apollon-chrome-edge-safe-right)}}.apollon-chrome-iconbtn{box-sizing:border-box;position:relative;display:inline-flex;align-items:center;justify-content:center;width:var(--apollon-chrome-btn);height:var(--apollon-chrome-btn);padding:0;border:0;border-radius:var(--apollon-chrome-radius-sm);background:transparent;color:var(--apollon-chrome-text);cursor:pointer;transition:background-color var(--apollon-chrome-duration-hover) var(--apollon-chrome-ease-standard)}.apollon-chrome-iconbtn>svg{fill:currentColor}.apollon-chrome-iconbtn:before{content:"";position:absolute;inset:calc((var(--apollon-chrome-btn) - var(--apollon-chrome-hit)) / 2)}.apollon-chrome-iconbtn:disabled{opacity:.4;cursor:not-allowed}.apollon-chrome-iconbtn:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--apollon-chrome-accent) 45%,transparent)}.apollon-chrome-iconbtn:hover:not(:disabled){background:var(--apollon-chrome-surface-hover)}.apollon-chrome-iconbtn:active:not(:disabled){background:var(--apollon-chrome-surface-active)}.apollon-chrome-iconbtn--readout{width:auto;min-width:48px;padding:0 8px;font-size:13px;font-weight:600;font-variant-numeric:tabular-nums}.react-flow__minimap.apollon-minimap{padding:0;overflow:hidden;border-radius:var(--apollon-chrome-radius-lg)}.react-flow__minimap.apollon-minimap .react-flow__minimap-svg{display:block;border-radius:inherit}.apollon-chrome-cluster-divider{align-self:stretch;width:1px;margin:4px 2px;background:var(--apollon-chrome-border)}.react-flow__controls-button{position:relative;width:var(--apollon-chrome-btn);height:var(--apollon-chrome-btn);padding:0;border:0;border-radius:var(--apollon-chrome-radius-sm);background:transparent;color:var(--apollon-chrome-text);transition:background-color var(--apollon-chrome-duration-hover) var(--apollon-chrome-ease-standard)}.react-flow__controls-button:before{content:"";position:absolute;inset:calc((var(--apollon-chrome-btn) - var(--apollon-chrome-hit)) / 2)}.react-flow__controls-button:hover{background:var(--apollon-chrome-surface-hover)}.react-flow__controls-button>svg{max-width:18px;max-height:18px;fill:currentColor}.apollon-glass,.react-flow__panel,.react-flow__node-toolbar{background-color:var(--apollon-chrome-glass);backdrop-filter:var(--apollon-chrome-glass-blur);-webkit-backdrop-filter:var(--apollon-chrome-glass-blur);border:1px solid var(--apollon-chrome-border);box-shadow:var(--apollon-chrome-shadow-floating),var(--apollon-chrome-inset-hairline);border-radius:var(--apollon-chrome-radius-lg)}.react-flow__panel,.react-flow__node-toolbar{padding:var(--apollon-chrome-pad)}.apollon-history-panel{background-color:var(--apollon-chrome-glass-solid)}.apollon-overlay-band,.apollon-overlay-panel{background-color:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;border:0;box-shadow:none;border-radius:0;padding:0}.apollon-overlay-panel{margin:var(--apollon-chrome-edge)}@keyframes apollon-island-in{0%{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}.apollon-chrome-island{animation:apollon-island-in var(--apollon-chrome-duration-enter) var(--apollon-chrome-ease-decelerate) both}.apollon-chrome-title-island:focus-within{border-color:var(--apollon-chrome-accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--apollon-chrome-accent) 35%,transparent),var(--apollon-chrome-shadow-floating)}@media(prefers-reduced-motion:reduce){.apollon-chrome-island{animation:none}}@media(prefers-reduced-transparency:reduce){.apollon-glass,.react-flow__panel,.react-flow__node-toolbar,.apollon-palette{background-color:var(--apollon-chrome-surface);backdrop-filter:none;-webkit-backdrop-filter:none}}@media(prefers-contrast:more){.apollon-glass,.react-flow__panel,.react-flow__node-toolbar,.apollon-palette{border-color:var(--apollon-chrome-border-strong)}}.react-flow svg{display:block}.react-flow__node-toolbar{display:flex;gap:8px}.react-flow__handle{opacity:0;background-color:transparent}.react-flow__handle.apollon-arc-handle:before{content:"";position:absolute;background-color:var(--apollon-primary, #3e8acc);opacity:.4;box-sizing:border-box;pointer-events:all;cursor:crosshair;--arc-long: calc(28px * var(--arc-scale, 1));--arc-short: calc(14px * var(--arc-scale, 1));--arc-radius: calc(14px * var(--arc-scale, 1))}.react-flow__handle.apollon-arc-handle--top:before{width:var(--arc-long);height:var(--arc-short);left:50%;top:50%;transform:translate(-50%,-100%);border-radius:var(--arc-radius) var(--arc-radius) 0 0}.react-flow__handle.apollon-arc-handle--right:before{width:var(--arc-short);height:var(--arc-long);left:50%;top:50%;transform:translateY(-50%);border-radius:0 var(--arc-radius) var(--arc-radius) 0}.react-flow__handle.apollon-arc-handle--bottom:before{width:var(--arc-long);height:var(--arc-short);left:50%;top:50%;transform:translate(-50%);border-radius:0 0 var(--arc-radius) var(--arc-radius)}.react-flow__handle.apollon-arc-handle--left:before{width:var(--arc-short);height:var(--arc-long);left:50%;top:50%;transform:translate(-100%,-50%);border-radius:var(--arc-radius) 0 0 var(--arc-radius)}.react-flow__resize-control line{z-index:9}.react-flow__resize-control.handle{z-index:20}.react-flow__resize-control{opacity:0;pointer-events:none;transition:opacity .12s ease}.react-flow__node:hover .react-flow__resize-control,.react-flow__node.selected .react-flow__resize-control{opacity:1;pointer-events:all}.react-flow__node:hover .react-flow__handle,.react-flow__node.selected .react-flow__handle{opacity:1;background-color:transparent;pointer-events:all;cursor:crosshair}.apollon-editor--connection-guidance .react-flow__handle.apollon-arc-handle:before{opacity:0;pointer-events:none}.apollon-editor--connection-guidance .react-flow__node:has(.apollon-connection-guidance-source),.apollon-editor--connection-guidance .react-flow__node:has(.react-flow__handle.connectionindicator.connectingto){z-index:10001!important}.apollon-editor--connection-guidance .react-flow__handle.connectionindicator{opacity:1!important;width:10px!important;height:10px!important;border-radius:999px;border:2px solid var(--apollon-primary, #3e8acc);background-color:var(--apollon-background, #fff);box-sizing:border-box}.apollon-editor--connection-guidance .react-flow__handle.connectionindicator.connectingfrom,.apollon-editor--connection-guidance .react-flow__handle.apollon-connection-guidance-source{opacity:0!important;pointer-events:none!important;border-color:transparent!important;background-color:transparent!important}.apollon-editor--connection-guidance .react-flow__handle.connectionindicator.valid{background-color:var(--apollon-primary, #3e8acc)!important}.edge-bend-handle{opacity:0;stroke:none;fill:color-mix(in srgb,var(--apollon-primary, #3e8acc) 34%,var(--apollon-background, #fff));transition:fill .12s ease,opacity .12s ease;vector-effect:non-scaling-stroke}.edge-endpoint-handle{fill:transparent;stroke:transparent;stroke-width:0;cursor:move;vector-effect:non-scaling-stroke}.edge-endpoint-handle--disabled{cursor:default}.react-flow__edge:hover .edge-bend-handle,.react-flow__edge.selected .edge-bend-handle{opacity:1;fill:var(--apollon-primary, #3e8acc)}.react-flow__edge:hover .edge-bend-handle:hover,.react-flow__edge.selected .edge-bend-handle:hover{fill:color-mix(in srgb,var(--apollon-primary, #3e8acc) 70%,#000)}.react-flow__edge:hover .edge-overlay,.react-flow__edge:hover .edge-marker-highlight{opacity:0}.react-flow__edge.selected .edge-overlay{opacity:0;pointer-events:none}.react-flow__edge.selected .edge-marker-highlight{opacity:0}.react-flow__edge:hover .react-flow__edge-path,.react-flow__edge:hover [data-inline-marker]{stroke:color-mix(in srgb,var(--apollon-primary, #3e8acc) 70%,#000)!important}.react-flow__edge:hover [data-inline-marker-filled=true]{fill:color-mix(in srgb,var(--apollon-primary, #3e8acc) 70%,#000)!important}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selected [data-inline-marker]{stroke:var(--apollon-primary, #3e8acc)!important}.react-flow__edge.selected [data-inline-marker-filled=true]{fill:var(--apollon-primary, #3e8acc)!important}.react-flow__node:hover,.react-flow__node.selected{opacity:.9;box-shadow:0 0 0 2px var(--apollon-primary, #3e8acc);border-radius:4px}.apollon-interactive-selection{--apollon-interactive-selection-color: var( --apollon-interactive-selection, #f39c12 )}.apollon-interactive-selection--selected [stroke]:not([stroke=none]){stroke:var(--apollon-interactive-selection-color)}.apollon-interactive-selection--selected .react-flow__edge-path{stroke-width:3px}.apollon-interactive-selection--selected .edge-overlay,.apollon-interactive-selection--selected .edge-marker-highlight{opacity:.45;stroke:var(--apollon-interactive-selection-color);stroke-width:15px}.react-flow__edges{z-index:9999}.react-flow__node{z-index:9998}svg.react-flow__connectionline{z-index:10000}.react-flow__connection-path{stroke:var(--xy-edge-stroke);stroke-width:var(--xy-edge-stroke-width);opacity:.5}.react-flow__minimap-mask{fill:var(--apollon-chrome-text-muted);opacity:.15}.prevent-select{-webkit-user-select:none;-ms-user-select:none;user-select:none}.horizontally-not-resizable .react-flow__resize-control.top.line:hover,.horizontally-not-resizable .react-flow__resize-control.bottom.line:hover,.vertically-not-resizable .react-flow__resize-control.right.line:hover,.vertically-not-resizable .react-flow__resize-control.left.line:hover{cursor:grab}.apollon-editor .MuiSelect-select,.apollon-editor .MuiFormLabel-root{color:var(--apollon-primary-contrast, #000)!important}.apollon-editor .MuiOutlinedInput-notchedOutline{border-color:var(--apollon-primary-contrast, #000)!important}.apollon-editor .MuiSvgIcon-root{color:var(--apollon-primary-contrast, #000)!important}.scroll-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background-color:var(--apollon-grid, rgba(36, 39, 36, .1));-webkit-backdrop-filter:blur(.5px);backdrop-filter:blur(.5px);z-index:10;cursor:not-allowed;animation:fadeIn .2s ease-in-out;display:flex;align-items:center;justify-content:center;pointer-events:auto}.scroll-overlay-hint{position:absolute;bottom:40px;left:50%;transform:translate(-50%);z-index:11}.scroll-overlay-hint-content{background-color:var(--apollon-background, #fff);border:2px solid var(--apollon-primary, #3e8acc);border-radius:8px;padding:16px 24px;box-shadow:0 4px 12px var(--apollon-grid, rgba(36, 39, 36, .1));display:flex;align-items:center;justify-content:center}.scroll-overlay-hint-text{margin:0;color:var(--apollon-primary, #3e8acc);font-weight:600;font-size:14px;text-align:center}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}', r = `${o}
3
+ ${e}`;
4
+ export {
5
+ r as EXPORT_LAYOUT_CSS
6
+ };
@@ -14,6 +14,5 @@ export * from './useDragOver';
14
14
  export * from './useHandleFinder';
15
15
  export * from './useStepPathEdge';
16
16
  export * from './useStraightPathEdge';
17
- export * from './useMessagePositioning';
18
17
  export * from './useAssessmentSelection';
19
18
  export * from './usePaneClicked';
@@ -0,0 +1,20 @@
1
+ import { Node } from '@xyflow/react';
2
+ import { CollaborationAwarenessApi } from '../components/collaboration/CollaborationLayer';
3
+ import { DraggingNode } from '../typings';
4
+ /**
5
+ * Live positions/sizes of nodes that *remote* peers are currently dragging or
6
+ * resizing, keyed by node id. These travel over the ephemeral awareness channel
7
+ * (never the Yjs document — see `diagramStore.onNodesChange`), so this hook is
8
+ * the read side of the live remote drag: it mirrors awareness into React state
9
+ * that `applyDraggingOverlay` overlays onto the rendered nodes.
10
+ */
11
+ export type RemoteDraggingOverlay = Map<string, DraggingNode>;
12
+ export declare const useRemoteDraggingNodes: (awareness: CollaborationAwarenessApi, active: boolean) => RemoteDraggingOverlay;
13
+ /**
14
+ * Overlay remote live-drag positions/sizes onto the rendered nodes. Returns the
15
+ * same array reference when there is nothing to overlay so React Flow skips the
16
+ * update. Behaviourally identical to the old per-frame document write — it
17
+ * moves the node in the controlled `nodes` prop — so connected edges follow
18
+ * exactly as before; the difference is only the (ephemeral) source.
19
+ */
20
+ export declare const applyDraggingOverlay: (nodes: Node[], overlay: RemoteDraggingOverlay) => Node[];
@@ -1,6 +1,7 @@
1
1
  import { Position } from '@xyflow/react';
2
2
  import { IPoint } from '../edges/Connection';
3
3
  import { BendHandle } from '../utils/geometry/bendHandles';
4
+ import { Rect } from '../utils/geometry/edgeLabelLayout';
4
5
  interface UseStepPathEdgeProps {
5
6
  id: string;
6
7
  type: string;
@@ -27,6 +28,16 @@ export interface StepPathEdgeData {
27
28
  isMiddlePathHorizontal: boolean;
28
29
  sourcePoint: IPoint;
29
30
  targetPoint: IPoint;
31
+ /** Bounds (flow space) of every node the edge routes near, so label placement
32
+ * keeps the label off any node's body, not just the source/target. */
33
+ nodeRects: Rect[];
34
+ /** Mid-segment endpoints in source->target order — the LOCAL flow direction
35
+ * at the middle (used for communication-message arrow direction). */
36
+ midSegmentStart: IPoint;
37
+ midSegmentEnd: IPoint;
38
+ /** Nearby other-edge polylines, so a middle label can break a side tie toward
39
+ * where fewer edges cross. */
40
+ neighborGeometry: IPoint[][];
30
41
  }
31
42
  export declare const useStepPathEdge: ({ id, type, source, target, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data, allowMidpointDragging, enableStraightPath, }: UseStepPathEdgeProps) => {
32
43
  pathRef: import('react').RefObject<SVGPathElement | null>;
@@ -1,5 +1,6 @@
1
1
  export * from './typings';
2
2
  export { ApollonEditor } from './apollon-editor';
3
+ export type { OverlayRegion, OverlaySide, InsetContribution, OverlayControlOptions, OverlayControlInput, } from './overlay/types';
3
4
  export { getAssessmentNameForArtemis, getEdgeAssessmentDataById, getNodeAssessmentDataByNodeElementId, type AssessmentViewData, } from './utils/helpers';
4
5
  export { importDiagram } from './utils/versionConverter';
5
6
  export { collabColorFromName, randomCollabName } from './utils/collaboration';
@@ -0,0 +1,3 @@
1
+ import { NodeProps, Node } from '@xyflow/react';
2
+ import { ActivitySwimlaneProps } from '../../types';
3
+ export declare function ActivitySwimlane({ id, width, height, data, parentId, }: NodeProps<Node<ActivitySwimlaneProps>>): import("react").JSX.Element | null;
@@ -6,3 +6,4 @@ export * from './ActivityObjectNode';
6
6
  export * from './ActivityMergeNode';
7
7
  export * from './ActivityForkNode';
8
8
  export * from './ActivityForkNodeHorizontal';
9
+ export * from './ActivitySwimlane';
@@ -3,7 +3,7 @@ import { ObjectName } from './objectDiagram';
3
3
  import { CommunicationObjectName } from './communicationDiagram';
4
4
  import { TitleAndDesctiption } from './TitleAndDescriptionNode';
5
5
  import { default as Package } from './classDiagram/Package';
6
- import { Activity, ActivityInitialNode, ActivityFinalNode, ActivityActionNode, ActivityObjectNode, ActivityMergeNode, ActivityForkNode, ActivityForkNodeHorizontal } from './activityDiagram';
6
+ import { Activity, ActivityInitialNode, ActivityFinalNode, ActivityActionNode, ActivityObjectNode, ActivityMergeNode, ActivityForkNode, ActivityForkNodeHorizontal, ActivitySwimlane } from './activityDiagram';
7
7
  import { UseCase, UseCaseActor, UseCaseSystem } from './useCaseDiagram';
8
8
  import { Component, ComponentInterface, ComponentSubsystem } from './componentDiagram';
9
9
  import { DeploymentNode, DeploymentComponent, DeploymentArtifact, DeploymentInterface } from './deploymentDiagram';
@@ -29,6 +29,7 @@ export declare const diagramNodeTypes: {
29
29
  activityMergeNode: typeof ActivityMergeNode;
30
30
  activityForkNode: typeof ActivityForkNode;
31
31
  activityForkNodeHorizontal: typeof ActivityForkNodeHorizontal;
32
+ activitySwimlane: typeof ActivitySwimlane;
32
33
  useCase: typeof UseCase;
33
34
  useCaseActor: typeof UseCaseActor;
34
35
  useCaseSystem: typeof UseCaseSystem;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The single in-canvas host layer. Renders every registered overlay control into
3
+ * its region (React Flow `<Panel>` for the six corners, library-owned bands for
4
+ * header/rails, `<ViewportPortal>` for on-canvas) and measures auto-inset
5
+ * controls with one shared ResizeObserver (the store derives the content-inset
6
+ * rect from those measurements — it is the single inset authority).
7
+ */
8
+ export declare function OverlayLayer(): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Mounts a host-owned DOM node (returned by `editor.getRegionElement`) into an
3
+ * overlay region. The node's lifetime is the editor instance, not this React
4
+ * subtree, so a host `createPortal` target stays valid across re-renders. The
5
+ * host renders into the node from its OWN React root, keeping host context
6
+ * (theme tokens, router) — see ApollonEditor.getRegionElement.
7
+ */
8
+ export declare function RegionMount({ el }: {
9
+ el: HTMLElement;
10
+ }): import("react").JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { StoreApi, UseBoundStore } from 'zustand';
2
+ import { Insets, OverlayControl, OverlaySide } from './types';
3
+ /**
4
+ * Content-inset rect: per side, the largest reservation among visible controls
5
+ * touching that side. `max` (not sum) avoids double-counting nested/stacked
6
+ * chrome. Controls hidden with `visible: false` reserve nothing. Recomputed on
7
+ * every mutation so the rect is reliable without a render.
8
+ */
9
+ export declare function computeInsets(controls: OverlayControl[], measured: Record<string, Partial<Record<OverlaySide, number>>>): Insets;
10
+ export type OverlayStore = {
11
+ controls: Record<string, OverlayControl>;
12
+ /** Measured rects per control id (written by the shared ResizeObserver). */
13
+ measured: Record<string, Partial<Record<OverlaySide, number>>>;
14
+ /** Derived content-inset rect — recomputed on every registry mutation. */
15
+ insets: Insets;
16
+ register: (control: OverlayControl) => void;
17
+ unregister: (id: string) => void;
18
+ setMeasured: (id: string, rect: Partial<Record<OverlaySide, number>>) => void;
19
+ };
20
+ export declare const createOverlayStore: () => UseBoundStore<StoreApi<OverlayStore>>;
@@ -0,0 +1,48 @@
1
+ import { ReactNode, CSSProperties } from 'react';
2
+ /**
3
+ * Where a control is anchored. The six React Flow `<Panel>` corners are
4
+ * screen-space and rendered through React Flow; `header`/`left-rail`/`right-rail`
5
+ * are library-owned bands; `on-canvas` pans/zooms with the diagram.
6
+ */
7
+ export type OverlayRegion = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right" | "header" | "left-rail" | "right-rail" | "on-canvas";
8
+ /** Regions that map directly onto a React Flow `<Panel position>`. */
9
+ export declare const PANEL_REGIONS: readonly ["top-left", "top-center", "top-right", "bottom-left", "bottom-center", "bottom-right"];
10
+ /** Every valid region — used to validate control registration at the API edge. */
11
+ export declare const OVERLAY_REGIONS: readonly OverlayRegion[];
12
+ /** One of the four edges a control can sit against / reserve room on. */
13
+ export type OverlaySide = "top" | "right" | "bottom" | "left";
14
+ /** Reserved room per side, in px. */
15
+ export type Insets = Record<OverlaySide, number>;
16
+ export declare const ZERO_INSETS: Insets;
17
+ /**
18
+ * How much room a control reserves so the diagram "makes way" (fed into
19
+ * `fitView` padding, MapLibre-style). `"auto"` measures the control via the
20
+ * shared ResizeObserver on the region's dominant axis; an object mixes explicit
21
+ * px with per-side `"auto"` (e.g. `{ top: "auto" }`).
22
+ */
23
+ export type InsetContribution = "auto" | Partial<Record<OverlaySide, number | "auto">>;
24
+ export interface OverlayControlOptions {
25
+ /** Stable id. Re-adding the same id REPLACES (idempotent, StrictMode-safe). */
26
+ id: string;
27
+ /** Which band/corner the control is anchored in. */
28
+ region: OverlayRegion;
29
+ /** Reserve viewport room. Default: reserves nothing (the control floats). */
30
+ inset?: InsetContribution;
31
+ /** Stacking within a region; lower renders toward the region's anchor edge. */
32
+ order?: number;
33
+ /** When false the region frame stays pointer-transparent here too. Default true. */
34
+ interactive?: boolean;
35
+ /** Wraps the control in a `role="group"` with this aria-label. No focus
36
+ * management is imposed. */
37
+ groupLabel?: string;
38
+ /** Hide without unregistering (reserves no inset while hidden). Default true. */
39
+ visible?: boolean;
40
+ /** Extra class on the control's wrapper element. */
41
+ className?: string;
42
+ /** Inline styles merged onto the control's wrapper element. */
43
+ style?: CSSProperties;
44
+ }
45
+ /** The public registration payload (options + renderer). */
46
+ export type OverlayControlInput = OverlayControlOptions & {
47
+ render: () => ReactNode;
48
+ };
@@ -2,3 +2,4 @@ export * from './index';
2
2
  export { Apollon, type ApollonProps } from './components/react/Apollon';
3
3
  export { ApollonProvider, useApollonEditor, useApollonEditorOrThrow, } from './components/react/context';
4
4
  export { useApollonSubscription } from './components/react/useApollonSubscription';
5
+ export { ApollonControl, type ApollonControlProps, } from './components/react/ApollonControl';