@tumaet/apollon 4.7.0 → 4.8.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 +2 -2
- package/dist/assets/style.css +1 -1
- package/dist/export.d.ts +73 -0
- package/dist/export.js +219 -0
- package/dist/exportStyles-Wcc8N8Xj.js +5 -0
- package/dist/fontStack-DOtVH2j8.js +5 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +11295 -11167
- package/dist/internals.d.ts +36 -1
- package/dist/internals.js +12 -11
- package/dist/react/components/AlignmentGuides.d.ts +1 -1
- package/dist/react/components/DraggableGhost.d.ts +5 -0
- package/dist/react/constants.d.ts +10 -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-CH2hautV.js +6 -0
- package/dist/react/hooks/useRemoteDraggingNodes.d.ts +20 -0
- package/dist/react/react.js +7237 -7009
- 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/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/paletteLayout.d.ts +66 -0
- package/dist/{yjsSync-aPxjWNdZ.js → yjsSync-CqmgRwRE.js} +6800 -6701
- package/package.json +15 -1
- package/dist/exportStyles-Xk-Vm7Ul.js +0 -5
- package/dist/react/exportStyles-DZCHk5mK.js +0 -6
package/dist/internals.d.ts
CHANGED
|
@@ -174,6 +174,7 @@ declare type CollaborationState = {
|
|
|
174
174
|
viewport?: CollaborationViewport | null;
|
|
175
175
|
followingClientId?: number | null;
|
|
176
176
|
selectedElementId?: string | null;
|
|
177
|
+
draggingNodes?: DraggingNode[] | null;
|
|
177
178
|
};
|
|
178
179
|
|
|
179
180
|
declare type CollaborationUser = {
|
|
@@ -411,8 +412,24 @@ declare type DiagramStore = {
|
|
|
411
412
|
canUndo: boolean;
|
|
412
413
|
canRedo: boolean;
|
|
413
414
|
undoManager: Y.UndoManager | null;
|
|
415
|
+
collaborationEnabled: boolean;
|
|
414
416
|
previewMode: boolean;
|
|
415
417
|
setDiagramId: (diagramId: string) => void;
|
|
418
|
+
setCollaborationEnabled: (enabled: boolean) => void;
|
|
419
|
+
/**
|
|
420
|
+
* Inject the sink that forwards transient drag/resize frames onto the
|
|
421
|
+
* ephemeral awareness channel (wired by `YjsSync` for every editor). Kept as
|
|
422
|
+
* runtime wiring rather than diagram state so a `reset()` never clears it.
|
|
423
|
+
* The broadcast itself is gated by `collaborationEnabled`, not by this sink;
|
|
424
|
+
* `null` (headless, where no `YjsSync` runs) just leaves it unwired.
|
|
425
|
+
*/
|
|
426
|
+
setDraggingNodesPublisher: (publisher: ((draggingNodes: DraggingNode[] | null) => void) | null) => void;
|
|
427
|
+
/**
|
|
428
|
+
* Clear the peers' live-drag overlay once a gesture's settled value is
|
|
429
|
+
* committed. Called from `onNodeDragStop` (after the doc write) and on
|
|
430
|
+
* collaboration teardown; a no-op when nothing is being broadcast.
|
|
431
|
+
*/
|
|
432
|
+
endTransientNodeBroadcast: () => void;
|
|
416
433
|
setNodes: (payload: Node_2[] | ((nodes: Node_2[]) => Node_2[])) => void;
|
|
417
434
|
setEdges: (payload: Edge[] | ((edges: Edge[]) => Edge[])) => void;
|
|
418
435
|
setNodesAndEdges: (nodes: Node_2[], edges: Edge[]) => void;
|
|
@@ -445,6 +462,23 @@ declare type DiagramStore = {
|
|
|
445
462
|
setPreviewMode: (active: boolean) => void;
|
|
446
463
|
};
|
|
447
464
|
|
|
465
|
+
/**
|
|
466
|
+
* One node a peer is actively dragging or resizing. Broadcast over the
|
|
467
|
+
* ephemeral awareness channel — never written to the Yjs document — so peers
|
|
468
|
+
* can render the in-progress gesture live without growing the CRDT or entering
|
|
469
|
+
* anyone's undo history. The settled position/size is committed once on
|
|
470
|
+
* drop/release through the document like any other edit.
|
|
471
|
+
*/
|
|
472
|
+
declare type DraggingNode = {
|
|
473
|
+
id: string;
|
|
474
|
+
position: {
|
|
475
|
+
x: number;
|
|
476
|
+
y: number;
|
|
477
|
+
};
|
|
478
|
+
width?: number | null;
|
|
479
|
+
height?: number | null;
|
|
480
|
+
};
|
|
481
|
+
|
|
448
482
|
declare type ExtendedEdgeProps = EdgeProps<Edge<CustomEdgeProps>> & {
|
|
449
483
|
markerEnd?: string;
|
|
450
484
|
markerPadding?: number;
|
|
@@ -849,6 +883,7 @@ export declare class YjsSync {
|
|
|
849
883
|
setLocalAwarenessViewport: (viewport: CollaborationViewport | null) => void;
|
|
850
884
|
setLocalAwarenessFollowing: (followingClientId: number | null) => void;
|
|
851
885
|
setLocalAwarenessSelectedElement: (selectedElementId: string | null) => void;
|
|
886
|
+
setLocalAwarenessDraggingNodes: (draggingNodes: DraggingNode[] | null) => void;
|
|
852
887
|
setLocalAwarenessState: (state: Partial<CollaborationState>) => void;
|
|
853
888
|
subscribeToAwarenessChanges: (callback: (states: Map<number, CollaborationState>) => void) => () => void;
|
|
854
889
|
getAwarenessStates: () => Map<number, CollaborationState>;
|
|
@@ -870,7 +905,7 @@ export declare class YjsSync {
|
|
|
870
905
|
/**
|
|
871
906
|
* Convert Base64 string to Uint8Array
|
|
872
907
|
*/
|
|
873
|
-
|
|
908
|
+
static base64ToUint8(base64: string): Uint8Array;
|
|
874
909
|
}
|
|
875
910
|
|
|
876
911
|
export { }
|
package/dist/internals.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
function
|
|
1
|
+
import { U as n, aB as r } from "./yjsSync-CqmgRwRE.js";
|
|
2
|
+
import { a8 as m, aR as g, aS as p, aT as u, aU as S, aV as T, aW as b, bl as l, bm as F, bn as v } from "./yjsSync-CqmgRwRE.js";
|
|
3
|
+
function d(t = new n()) {
|
|
4
4
|
const e = () => {
|
|
5
5
|
}, a = {
|
|
6
6
|
getState: () => ({
|
|
@@ -8,6 +8,7 @@ function V(t = new n()) {
|
|
|
8
8
|
updateEdgesFromYjs: e,
|
|
9
9
|
updateAssessmentFromYjs: e,
|
|
10
10
|
updateUndoRedoState: e,
|
|
11
|
+
setDraggingNodesPublisher: e,
|
|
11
12
|
undoManager: null
|
|
12
13
|
// Other DiagramStore fields are typed but never accessed by
|
|
13
14
|
// YjsSync; cast through `unknown` keeps the helper from
|
|
@@ -30,16 +31,16 @@ function V(t = new n()) {
|
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
export {
|
|
33
|
-
|
|
34
|
+
m as MessageType,
|
|
34
35
|
r as YjsSync,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
g as convertV2ToV4,
|
|
37
|
+
p as convertV3EdgeTypeToV4,
|
|
38
|
+
u as convertV3HandleToV4,
|
|
39
|
+
S as convertV3MessagesToV4,
|
|
39
40
|
T as convertV3NodeTypeToV4,
|
|
40
41
|
b as convertV3ToV4,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
d as createHeadlessSync,
|
|
43
|
+
l as isV2Format,
|
|
44
|
+
F as isV3Format,
|
|
44
45
|
v as isV4Format
|
|
45
46
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AlignmentGuides: () => import("react").JSX.Element
|
|
1
|
+
export declare const AlignmentGuides: () => 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 {};
|
|
@@ -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;
|
|
@@ -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>;
|
|
@@ -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: rgb(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: rgb(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, var(--xy-background-color-props, 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__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__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;transform:translate(-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:4px;height:4px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));transform: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)}.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-minimap-mask-background-color-props: #00000020;--xy-controls-button-background-color: var(--apollon-background, #fff)}.apollon-editor{background-color:var(--apollon-background, #fff);color:var(--apollon-primary-contrast, #000);isolation:isolate}.apollon-canvas{position:relative;flex:1;min-width:0;height:100%;overflow:hidden}.apollon-collaboration-presence-bar{position:absolute;top:10px;right:10px;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:10px;left:calc(10px + var(--safe-area-inset-left, 0px));z-index:10000;max-height:calc(100% - 84px - var(--safe-area-inset-bottom, 0px));display:flex;flex-direction:column;gap:8px;align-items:center;padding:6px;overflow-y:auto;overscroll-behavior:contain;background:var(--apollon-background, #fff);color:var(--apollon-primary-contrast, #000);border:1px solid var(--apollon-gray, #e9ecef);border-radius:6px;box-shadow:0 2px 8px #0000002e}.apollon-palette__entries{display:grid;justify-content:center}.apollon-palette__entry{display:flex;align-items:center;justify-content:center;cursor:grab;border-radius:4px;transition:background-color .12s ease}.apollon-palette__entry:hover{background:var(--apollon-background-variant, #f8f9fa)}.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:6px;border:1px solid var(--apollon-primary-contrast, #000);background:transparent;color:var(--apollon-primary-contrast, #000);padding:6px 8px;cursor:pointer;font-weight:600;white-space:nowrap;font-size:12px}.apollon-palette__view-button--active{background:var(--apollon-primary, #3e8acc);color:var(--apollon-background, #fff)}.apollon-palette__hint{box-sizing:border-box;width:100%;max-width:160px;padding:4px;font-size:11px;line-height:1.4}@media(max-width:950px)and (max-height:500px){.react-flow__panel.bottom.left{margin-left:calc(10px + var(--safe-area-inset-left, 0px));margin-bottom:calc(10px + var(--safe-area-inset-bottom, 0px))}.react-flow__panel.bottom.right{margin-right:calc(10px + var(--safe-area-inset-right, 0px));margin-bottom:calc(10px + var(--safe-area-inset-bottom, 0px))}.apollon-collaboration-presence-bar{right:calc(10px + var(--safe-area-inset-right, 0px))}}.react-flow__controls-button{background:none;border-bottom:none}.react-flow__panel,.react-flow__node-toolbar{background-color:var(--panel-background);box-shadow:var(--panel-shadow);border-radius:8px;padding:8px}.react-flow svg{display:block}.react-flow__node-toolbar{display:flex;gap:8px}.react-flow__controls-button,.react-flow__controls-button:hover{background:var(--panel-background);border-bottom:none}.react-flow__controls-button>svg{fill:var(--text)}.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:"#f2f2f2";opacity:.6}.prevent-select{-webkit-user-select:none;-ms-user-select:none;user-select:none}.control-button{background-color:var(--apollon-background, #fff);border:1px solid var(--apollon-gray-variant, #495057);border-radius:8px;padding:6px 8px;cursor:pointer;opacity:1;display:flex;align-items:center;justify-content:center;min-width:32px;height:32px;font-size:14px;font-weight:700;transition:background-color .2s ease}.control-button:hover:not(.disabled){background-color:var(--apollon-background-variant, #f8f9fa)}.control-button.disabled{cursor:not-allowed;opacity:.5}.control-button.disabled:hover{background-color:var(--apollon-background, #fff)}.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
|
+
};
|
|
@@ -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[];
|