@pixerate/editor-react 0.40.0 → 0.42.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/dist/animation-editor/index.cjs +192 -0
- package/dist/animation-editor/index.cjs.map +1 -0
- package/dist/animation-editor/index.d.cts +61 -0
- package/dist/animation-editor/index.d.ts +61 -0
- package/dist/animation-editor/index.js +162 -0
- package/dist/animation-editor/index.js.map +1 -0
- package/dist/canvas/index.cjs +536 -313
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +155 -6
- package/dist/canvas/index.d.ts +155 -6
- package/dist/canvas/index.js +221 -0
- package/dist/canvas/index.js.map +1 -1
- package/dist/index.cjs +439 -412
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +52 -26
- package/dist/index.js.map +1 -1
- package/package.json +11 -3
package/dist/canvas/index.js
CHANGED
|
@@ -2532,6 +2532,217 @@ import {
|
|
|
2532
2532
|
angleToSvgLinearCoords,
|
|
2533
2533
|
gradientToSvgDef as gradientToSvgDef2
|
|
2534
2534
|
} from "@pixerate/editor/canvas";
|
|
2535
|
+
|
|
2536
|
+
// src/canvas/useMermaidDiagram.ts
|
|
2537
|
+
import { useEffect as useEffect10, useMemo as useMemo8, useRef as useRef15, useState as useState8, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
2538
|
+
import {
|
|
2539
|
+
DiagramController
|
|
2540
|
+
} from "@pixerate/editor/diagram";
|
|
2541
|
+
import {
|
|
2542
|
+
DiagramStream,
|
|
2543
|
+
blendDiagramLayout,
|
|
2544
|
+
easeDiagramTween,
|
|
2545
|
+
mermaidMovesFromCanvas,
|
|
2546
|
+
mermaidToCanvas
|
|
2547
|
+
} from "@pixerate/editor/canvas";
|
|
2548
|
+
function useDiagramState(controller) {
|
|
2549
|
+
return useSyncExternalStore4(controller.subscribe, controller.getState, controller.getState);
|
|
2550
|
+
}
|
|
2551
|
+
function useMermaidDiagram(controllerOrOptions = {}) {
|
|
2552
|
+
const own = useRef15(null);
|
|
2553
|
+
let controller;
|
|
2554
|
+
if (controllerOrOptions instanceof DiagramController) controller = controllerOrOptions;
|
|
2555
|
+
else {
|
|
2556
|
+
if (!own.current) own.current = new DiagramController(controllerOrOptions);
|
|
2557
|
+
controller = own.current;
|
|
2558
|
+
}
|
|
2559
|
+
const layoutOptions = controllerOrOptions instanceof DiagramController ? void 0 : controllerOrOptions.layoutOptions;
|
|
2560
|
+
const state = useDiagramState(controller);
|
|
2561
|
+
const canvas = useMemo8(
|
|
2562
|
+
() => mermaidToCanvas(state.document, { ...layoutOptions, editable: state.editable }),
|
|
2563
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2564
|
+
[state.document, state.editable]
|
|
2565
|
+
);
|
|
2566
|
+
const layoutRef = useRef15(canvas.layout);
|
|
2567
|
+
layoutRef.current = canvas.layout;
|
|
2568
|
+
const actions = useMemo8(
|
|
2569
|
+
() => ({
|
|
2570
|
+
apply: (ops, label) => controller.apply(ops, label),
|
|
2571
|
+
load: (source, options) => controller.load(source, options),
|
|
2572
|
+
moveNodes: (moved, all = moved) => {
|
|
2573
|
+
const op = mermaidMovesFromCanvas(layoutRef.current, moved, all, { stored: controller.getDocument().meta.layout ?? {} });
|
|
2574
|
+
return op ? controller.apply(op, "Move") : null;
|
|
2575
|
+
},
|
|
2576
|
+
connect: (source, target, label) => controller.apply({ type: "addEdge", edge: { source, target, ...label ? { label } : {} } }, "Connect"),
|
|
2577
|
+
remove: (ids) => {
|
|
2578
|
+
const graph = controller.getDocument().graph;
|
|
2579
|
+
const edgeIds = new Set(graph.edges.map((e) => e.id));
|
|
2580
|
+
const edges = ids.filter((id) => edgeIds.has(id));
|
|
2581
|
+
const nodes = ids.filter((id) => !edgeIds.has(id));
|
|
2582
|
+
const ops = [];
|
|
2583
|
+
if (edges.length) ops.push({ type: "removeEdges", ids: edges });
|
|
2584
|
+
if (nodes.length) ops.push({ type: "removeNodes", ids: nodes });
|
|
2585
|
+
return controller.apply(ops, "Delete");
|
|
2586
|
+
},
|
|
2587
|
+
rename: (id, label) => controller.apply(
|
|
2588
|
+
controller.getDocument().graph.groups.some((g) => g.id === id) ? { type: "renameGroup", id, label } : { type: "renameNode", id, label },
|
|
2589
|
+
"Rename"
|
|
2590
|
+
),
|
|
2591
|
+
select: (ids) => controller.select(ids),
|
|
2592
|
+
undo: () => void controller.undo(),
|
|
2593
|
+
redo: () => void controller.redo()
|
|
2594
|
+
}),
|
|
2595
|
+
[controller]
|
|
2596
|
+
);
|
|
2597
|
+
return { controller, state, document: state.document, source: state.source, ...canvas, ...actions };
|
|
2598
|
+
}
|
|
2599
|
+
function useMermaidStream(source, options = {}) {
|
|
2600
|
+
const { complete = false, duration = 300, ...layoutOptions } = options;
|
|
2601
|
+
const stream = useRef15(null);
|
|
2602
|
+
if (!stream.current) stream.current = new DiagramStream(layoutOptions);
|
|
2603
|
+
const result = useMemo8(() => stream.current.update(source, complete), [source, complete]);
|
|
2604
|
+
const [shown, setShown] = useState8({ layout: result.layout, settled: true });
|
|
2605
|
+
const shownRef = useRef15(shown.layout);
|
|
2606
|
+
shownRef.current = shown.layout;
|
|
2607
|
+
useEffect10(() => {
|
|
2608
|
+
const target = result.layout;
|
|
2609
|
+
if (!target) return setShown({ layout: null, settled: true });
|
|
2610
|
+
const from = shownRef.current;
|
|
2611
|
+
if (!from || duration <= 0 || typeof requestAnimationFrame !== "function") return setShown({ layout: target, settled: true });
|
|
2612
|
+
if (from === target) return;
|
|
2613
|
+
let frame = 0;
|
|
2614
|
+
const start = performance.now();
|
|
2615
|
+
const step = () => {
|
|
2616
|
+
const t = Math.min(1, (performance.now() - start) / duration);
|
|
2617
|
+
setShown({ layout: blendDiagramLayout(from, target, easeDiagramTween(t)), settled: t >= 1 });
|
|
2618
|
+
if (t < 1) frame = requestAnimationFrame(step);
|
|
2619
|
+
};
|
|
2620
|
+
frame = requestAnimationFrame(step);
|
|
2621
|
+
return () => cancelAnimationFrame(frame);
|
|
2622
|
+
}, [result.layout, duration]);
|
|
2623
|
+
const doc = result.document.tier === "editable" ? result.document : null;
|
|
2624
|
+
const canvas = useMemo8(() => {
|
|
2625
|
+
if (!doc || !shown.layout) return { nodes: [], edges: [] };
|
|
2626
|
+
const placed = new Set(Object.keys(shown.layout.positions));
|
|
2627
|
+
const graph = {
|
|
2628
|
+
...doc.graph,
|
|
2629
|
+
nodes: doc.graph.nodes.filter((n) => placed.has(n.id)),
|
|
2630
|
+
groups: doc.graph.groups.filter((g) => placed.has(g.id)),
|
|
2631
|
+
edges: doc.graph.edges.filter((e) => placed.has(e.source) && placed.has(e.target))
|
|
2632
|
+
};
|
|
2633
|
+
return mermaidToCanvas({ ...doc, graph }, { layout: shown.layout });
|
|
2634
|
+
}, [doc, shown.layout]);
|
|
2635
|
+
return { document: doc, ...canvas, layout: shown.layout, settled: shown.settled };
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
// src/canvas/MermaidDiagramNode.tsx
|
|
2639
|
+
import { MERMAID_SHAPE_PAINT, mermaidLabelLines, mermaidNodeMembers, mermaidNodePaint, mermaidShapePaths } from "@pixerate/editor/canvas";
|
|
2640
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2641
|
+
function mermaidNodeStyle(styles = {}, selected = false) {
|
|
2642
|
+
const paint = mermaidNodePaint(styles, selected);
|
|
2643
|
+
const { color, "stroke-width": strokeWidth, "stroke-dasharray": strokeDasharray, ...vars } = paint;
|
|
2644
|
+
return { ...vars, color, strokeWidth, strokeDasharray };
|
|
2645
|
+
}
|
|
2646
|
+
function MermaidDiagramNode({ data, width = 160, height = 56, selected, className = "", children }) {
|
|
2647
|
+
const node = data.node;
|
|
2648
|
+
if (!node) return null;
|
|
2649
|
+
const members = mermaidNodeMembers(node.data);
|
|
2650
|
+
return /* @__PURE__ */ jsxs8(
|
|
2651
|
+
"div",
|
|
2652
|
+
{
|
|
2653
|
+
className: `pixerate-diagram-node ${className}`.trim(),
|
|
2654
|
+
"data-shape": node.shape,
|
|
2655
|
+
"data-selected": selected ? "true" : void 0,
|
|
2656
|
+
style: { position: "relative", width: "100%", height: "100%", ...mermaidNodeStyle(data.resolvedStyles, selected) },
|
|
2657
|
+
children: [
|
|
2658
|
+
/* @__PURE__ */ jsx8("svg", { viewBox: `0 0 ${width} ${height}`, preserveAspectRatio: "none", width: "100%", height: "100%", style: { position: "absolute", inset: 0, overflow: "visible" }, "aria-hidden": "true", children: mermaidShapePaths(node.shape, width, height).map((path, i) => /* @__PURE__ */ jsx8("path", { d: path.d, style: { ...MERMAID_SHAPE_PAINT[path.paint], vectorEffect: "non-scaling-stroke" } }, i)) }),
|
|
2659
|
+
/* @__PURE__ */ jsxs8(
|
|
2660
|
+
"div",
|
|
2661
|
+
{
|
|
2662
|
+
style: { position: "relative", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: members.length ? "flex-start" : "center", height: "100%", padding: "6px 10px", boxSizing: "border-box", fontSize: 13, lineHeight: 1.3, textAlign: "center", pointerEvents: "none" },
|
|
2663
|
+
children: [
|
|
2664
|
+
mermaidLabelLines(node.label).map((line, i) => /* @__PURE__ */ jsx8("span", { style: { fontWeight: members.length ? 600 : void 0 }, children: line }, i)),
|
|
2665
|
+
members.length > 0 && /* @__PURE__ */ jsx8("div", { style: { alignSelf: "stretch", marginTop: 4, paddingTop: 4, borderTop: "1px solid var(--pixerate-diagram-node-border)", textAlign: "left", fontSize: 12 }, children: members.map((m, i) => /* @__PURE__ */ jsx8("div", { children: m }, i)) })
|
|
2666
|
+
]
|
|
2667
|
+
}
|
|
2668
|
+
),
|
|
2669
|
+
children
|
|
2670
|
+
]
|
|
2671
|
+
}
|
|
2672
|
+
);
|
|
2673
|
+
}
|
|
2674
|
+
function MermaidDiagramGroup({ data, selected, className = "", children }) {
|
|
2675
|
+
const group = data.group;
|
|
2676
|
+
if (!group) return null;
|
|
2677
|
+
return /* @__PURE__ */ jsxs8(
|
|
2678
|
+
"div",
|
|
2679
|
+
{
|
|
2680
|
+
className: `pixerate-diagram-group ${className}`.trim(),
|
|
2681
|
+
"data-selected": selected ? "true" : void 0,
|
|
2682
|
+
style: {
|
|
2683
|
+
width: "100%",
|
|
2684
|
+
height: "100%",
|
|
2685
|
+
boxSizing: "border-box",
|
|
2686
|
+
borderRadius: 8,
|
|
2687
|
+
border: `1px ${selected ? "solid" : "dashed"} ${selected ? "var(--primary, #2563eb)" : data.resolvedStyles?.stroke ?? "var(--border, #cbd5e1)"}`,
|
|
2688
|
+
background: data.resolvedStyles?.fill ?? "var(--muted, rgba(148, 163, 184, 0.08))",
|
|
2689
|
+
color: data.resolvedStyles?.color ?? "var(--muted-foreground, #475569)"
|
|
2690
|
+
},
|
|
2691
|
+
children: [
|
|
2692
|
+
/* @__PURE__ */ jsx8("div", { style: { padding: "6px 10px", fontSize: 12, fontWeight: 600 }, children: mermaidLabelLines(group.label).join(" ") }),
|
|
2693
|
+
children
|
|
2694
|
+
]
|
|
2695
|
+
}
|
|
2696
|
+
);
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
// src/canvas/MermaidThumbnail.tsx
|
|
2700
|
+
import { useMemo as useMemo9 } from "react";
|
|
2701
|
+
import { parseMermaid } from "@pixerate/editor/diagram";
|
|
2702
|
+
import { mermaidThumbnailSvg } from "@pixerate/editor/canvas";
|
|
2703
|
+
import { Fragment as Fragment2, jsx as jsx9 } from "react/jsx-runtime";
|
|
2704
|
+
function MermaidThumbnail({ source, className = "", fallback = null, ...options }) {
|
|
2705
|
+
const doc = useMemo9(() => typeof source === "string" ? parseMermaid(source) : source, [source]);
|
|
2706
|
+
const key = JSON.stringify(options);
|
|
2707
|
+
const drawn = useMemo9(
|
|
2708
|
+
() => doc.tier === "editable" && doc.graph.nodes.length ? mermaidThumbnailSvg(doc, options) : null,
|
|
2709
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2710
|
+
[doc, key]
|
|
2711
|
+
);
|
|
2712
|
+
if (!drawn) return /* @__PURE__ */ jsx9(Fragment2, { children: fallback });
|
|
2713
|
+
return /* @__PURE__ */ jsx9("span", { className: `pixerate-diagram-thumbnail ${className}`.trim(), style: { display: "inline-block", lineHeight: 0 }, dangerouslySetInnerHTML: { __html: drawn.svg } });
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
// src/canvas/useDiagramDirector.ts
|
|
2717
|
+
import { useRef as useRef16, useSyncExternalStore as useSyncExternalStore5 } from "react";
|
|
2718
|
+
import { DiagramDirector, PresenceStore } from "@pixerate/editor/diagram";
|
|
2719
|
+
function useDiagramDirector(controller, options) {
|
|
2720
|
+
const placement = useRef16(options.placement);
|
|
2721
|
+
placement.current = options.placement;
|
|
2722
|
+
const ref = useRef16(null);
|
|
2723
|
+
if (!ref.current) {
|
|
2724
|
+
const presence = new PresenceStore();
|
|
2725
|
+
ref.current = {
|
|
2726
|
+
presence,
|
|
2727
|
+
director: new DiagramDirector(controller, presence, { placement: () => placement.current(), speed: options.speed, clock: options.clock, linger: options.linger })
|
|
2728
|
+
};
|
|
2729
|
+
}
|
|
2730
|
+
return ref.current;
|
|
2731
|
+
}
|
|
2732
|
+
function usePresenceState(presence) {
|
|
2733
|
+
return useSyncExternalStore5(presence.subscribe, presence.getState, presence.getState);
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
// src/canvas/DiagramPresenceLayer.tsx
|
|
2737
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2738
|
+
function DiagramPresenceLayer({ presence, viewport, className = "" }) {
|
|
2739
|
+
const { actors } = usePresenceState(presence);
|
|
2740
|
+
if (!actors.length) return null;
|
|
2741
|
+
return /* @__PURE__ */ jsx10("div", { className: `pixerate-diagram-presence ${className}`.trim(), "aria-hidden": "true", style: { position: "absolute", inset: 0, pointerEvents: "none", overflow: "hidden", zIndex: 50 }, children: actors.map((a) => /* @__PURE__ */ jsxs9("div", { "data-actor": a.id, style: { position: "absolute", left: 0, top: 0, transform: `translate(${a.x * viewport.zoom + viewport.x}px, ${a.y * viewport.zoom + viewport.y}px)` }, children: [
|
|
2742
|
+
/* @__PURE__ */ jsx10("svg", { width: "18", height: "20", viewBox: "0 0 12 18", style: { display: "block", transform: a.pressed ? "scale(0.85)" : void 0, transformOrigin: "0 0" }, children: /* @__PURE__ */ jsx10("path", { d: "M0,0 L0,14 L4,10.5 L7,17 L9.5,16 L6.5,9.5 L11.5,9.5 Z", style: { fill: a.color, stroke: "#ffffff", strokeWidth: 1 } }) }),
|
|
2743
|
+
/* @__PURE__ */ jsx10("span", { style: { position: "absolute", left: 14, top: 16, whiteSpace: "nowrap", borderRadius: 4, padding: "1px 6px", fontSize: 11, fontWeight: 600, color: "#ffffff", background: a.color }, children: a.message ?? a.name })
|
|
2744
|
+
] }, a.id)) });
|
|
2745
|
+
}
|
|
2535
2746
|
export {
|
|
2536
2747
|
ANIMATABLE_PROPERTIES,
|
|
2537
2748
|
ANIMATION_DATA_KEY,
|
|
@@ -2556,8 +2767,12 @@ export {
|
|
|
2556
2767
|
CanvasInstanceInspector,
|
|
2557
2768
|
CanvasScenesStore2 as CanvasScenesStore,
|
|
2558
2769
|
DEFAULT_ARRANGE_SHORTCUTS,
|
|
2770
|
+
DiagramPresenceLayer,
|
|
2559
2771
|
MAX_KEYFRAME_REFS,
|
|
2560
2772
|
ManualClock,
|
|
2773
|
+
MermaidDiagramGroup,
|
|
2774
|
+
MermaidDiagramNode,
|
|
2775
|
+
MermaidThumbnail,
|
|
2561
2776
|
RESIZE_HANDLES,
|
|
2562
2777
|
SHAPE_DATA_KEY,
|
|
2563
2778
|
SHAPE_KINDS,
|
|
@@ -2738,6 +2953,7 @@ export {
|
|
|
2738
2953
|
measureSelection2 as measureSelection,
|
|
2739
2954
|
measureToLine,
|
|
2740
2955
|
mergeNodeUpdates,
|
|
2956
|
+
mermaidNodeStyle,
|
|
2741
2957
|
mixColorsOklab,
|
|
2742
2958
|
moveKeyframes,
|
|
2743
2959
|
moveLayoutChild,
|
|
@@ -2855,6 +3071,11 @@ export {
|
|
|
2855
3071
|
useCanvasScenes,
|
|
2856
3072
|
useCanvasShortcuts,
|
|
2857
3073
|
useCanvasTokens,
|
|
3074
|
+
useDiagramDirector,
|
|
3075
|
+
useDiagramState,
|
|
3076
|
+
useMermaidDiagram,
|
|
3077
|
+
useMermaidStream,
|
|
3078
|
+
usePresenceState,
|
|
2858
3079
|
useStreamingCanvas,
|
|
2859
3080
|
withNodeAnimation,
|
|
2860
3081
|
withStyleSize,
|