UNPKG

@ichooss/xflow

Version:

[English (US)](README.md) | 简体中文

1,384 lines (1,344 loc) 38.5 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // ../../node_modules/.pnpm/classnames@2.3.2/node_modules/classnames/index.js var require_classnames = __commonJS({ "../../node_modules/.pnpm/classnames@2.3.2/node_modules/classnames/index.js"(exports, module) { (function() { "use strict"; var hasOwn = {}.hasOwnProperty; var nativeCodeString = "[native code]"; function classNames2() { var classes = []; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (!arg) continue; var argType = typeof arg; if (argType === "string" || argType === "number") { classes.push(arg); } else if (Array.isArray(arg)) { if (arg.length) { var inner = classNames2.apply(null, arg); if (inner) { classes.push(inner); } } } else if (argType === "object") { if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]")) { classes.push(arg.toString()); continue; } for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes.push(key); } } } } return classes.join(" "); } if (typeof module !== "undefined" && module.exports) { classNames2.default = classNames2; module.exports = classNames2; } else if (typeof define === "function" && typeof define.amd === "object" && define.amd) { define("classnames", [], function() { return classNames2; }); } else { window.classNames = classNames2; } })(); } }); // src/index.ts import { Graph as Graph2, Point as Point2, Rectangle, Line, Path, Polyline, Dom, Vector, Edge, Markup } from "@antv/x6"; // src/components/Wrapper.tsx import React2 from "react"; // src/hooks/useGraphInstance.ts import { useContext } from "react"; // src/context/GraphContext.tsx import React, { createContext, useState } from "react"; var GraphContext = createContext({ graph: null, setGraph: () => { } }); var GraphProvider = ({ children }) => { const [graph, setGraph] = useState(null); return /* @__PURE__ */ React.createElement(GraphContext.Provider, { value: { graph, setGraph } }, children); }; // src/hooks/useGraphInstance.ts var useGraphInstance = () => { const { graph } = useContext(GraphContext); return graph; }; // src/components/Wrapper.tsx var Wrapper = ({ children }) => { const graph = useGraphInstance(); if (graph) { return /* @__PURE__ */ React2.createElement(React2.Fragment, null, children); } return null; }; // src/components/XFlow.tsx import React4 from "react"; // src/context/StoreContext.tsx import React3, { createContext as createContext2, useRef } from "react"; // src/store/index.ts import { produce, original } from "immer"; import { create } from "zustand"; // src/util/algorithm.ts var getSuperGraph = (graph, nodeId, nodeIds = []) => { nodeIds.push(nodeId); const incomingEdges = graph.getIncomingEdges(nodeId); incomingEdges?.forEach((edge) => { const source = edge.getSourceCellId(); getSuperGraph(graph, source, nodeIds); }); return nodeIds; }; var getSubGraph = (graph, nodeId, nodeIds = []) => { nodeIds.push(nodeId); const outgoingEdges = graph.getOutgoingEdges(nodeId); outgoingEdges?.forEach((edge) => { const target = edge.getTargetCellId(); getSubGraph(graph, target, nodeIds); }); return nodeIds; }; // src/util/object.ts import { ObjectExt } from "@antv/x6"; function apply(target, patchItem) { if (typeof patchItem !== "object" || Array.isArray(patchItem) || !patchItem) { return JSON.parse(JSON.stringify(patchItem)); } if (typeof patchItem === "object" && patchItem.toJSON !== void 0 && typeof patchItem.toJSON === "function") { return patchItem.toJSON(); } let targetResult = target; if (typeof target !== "object") { targetResult = { ...patchItem }; } Object.keys(patchItem).forEach((k) => { if (!Object.prototype.hasOwnProperty.call(targetResult, k)) targetResult[k] = patchItem[k]; if (patchItem[k] === null) { delete targetResult[k]; } else if (targetResult[k] !== null && targetResult[k] !== void 0) { targetResult[k] = apply(targetResult[k], patchItem[k]); } }); return targetResult; } function flatten(obj, delim = "/", stop) { const ret = {}; Object.keys(obj).forEach((key) => { const val = obj[key]; let deep = ObjectExt.isPlainObject(val); if (deep && stop && stop(val)) { deep = false; } if (deep) { const flatObject = flatten(val, delim, stop); Object.keys(flatObject).forEach((flatKey) => { ret[key + delim + flatKey] = flatObject[flatKey]; }); } else { ret[key] = val; } }); for (const key in obj) { if (!Object.prototype.hasOwnProperty.call(obj, key)) { continue; } } return ret; } // src/store/index.ts import { StringExt } from "@antv/x6"; var createGraphStore = () => { return create((set) => ({ nodes: [], edges: [], changeList: [], initData: (data, options) => set( produce((state) => { state.nodes = data.nodes; state.edges = data.edges; if (!options?.silent) { state.changeList.push({ command: "init", data }); } }) ), addNodes: (ns, options) => set( produce((state) => { if (!ns.length) return; ns.forEach((n) => { if (!n.id) { n.id = StringExt.uuid(); } }); const duplicated = state.nodes.find( (n) => ns.some((m) => m.id && m.id === n.id) ); if (!duplicated) { state.nodes.push(...ns); if (!options?.silent) { state.changeList.push({ command: "addNodes", data: ns }); } } else { console.error(`node id=${duplicated.id} already existed`); } }) ), removeNodes: (ids, options) => set( produce((state) => { if (!ids.length) return; state.nodes = state.nodes.filter((n) => !ids.includes(n.id)); if (!options?.silent) { state.changeList.push({ command: "removeNodes", data: ids }); } }) ), updateNode: (id, data, options) => set( produce((state) => { const node = state.nodes.find((n) => n.id === id); if (node) { const changed = typeof data === "function" ? data(original(node) || {}) : data; if (changed.id !== void 0 || changed.shape !== void 0) { console.error(`id and shape can't be changed`); return; } apply(node, changed); if (!options?.silent) { state.changeList.push({ command: "updateNode", data: { id, data: changed } }); } } }) ), addEdges: (es, options) => set( produce((state) => { if (!es.length) return; es.forEach((e) => { if (!e.id) { e.id = StringExt.uuid(); } }); const duplicated = state.edges.find( (e) => es.some((m) => m.id && m.id === e.id) ); if (!duplicated) { state.edges.push(...es); if (!options?.silent) { state.changeList.push({ command: "addEdges", data: es }); } } else { console.error(`edge id=${duplicated.id} already existed`); } }) ), removeEdges: (ids, options) => set( produce((state) => { if (!ids.length) return; state.edges = state.edges.filter((n) => !ids.includes(n.id)); if (!options?.silent) { state.changeList.push({ command: "removeEdges", data: ids }); } }) ), updateEdge: (id, data, options) => set( produce((state) => { const edge = state.edges.find((n) => n.id === id); if (edge) { const changed = typeof data === "function" ? data(original(edge) || {}) : data; if (changed.id !== void 0 || changed.shape !== void 0) { console.error(`id and shape can't be changed`); return; } apply(edge, changed); if (!options?.silent) { state.changeList.push({ command: "updateEdge", data: { id, data: changed } }); } } }) ), clearChangeList: () => set( produce((state) => { state.changeList = []; }) ) })); }; // src/context/StoreContext.tsx var StoreContext = createContext2(null); var StoreProvider = ({ children }) => { const storeRef = useRef(); if (!storeRef.current) { storeRef.current = createGraphStore(); } return /* @__PURE__ */ React3.createElement(StoreContext.Provider, { value: storeRef.current }, children); }; // src/components/XFlow.tsx import "./index-5FC5FO7Q.less"; var XFlow = ({ children }) => { return /* @__PURE__ */ React4.createElement(StoreProvider, null, /* @__PURE__ */ React4.createElement(GraphProvider, null, children)); }; // src/components/Graph.tsx import { Graph, Options } from "@antv/x6"; import { Keyboard } from "@antv/x6-plugin-keyboard"; import { Scroller } from "@antv/x6-plugin-scroller"; import { Selection } from "@antv/x6-plugin-selection"; import React6, { useContext as useContext3, useRef as useRef4, useEffect as useEffect5 } from "react"; // src/components/State.tsx import { FunctionExt, ObjectExt as ObjectExt2, Point } from "@antv/x6"; import { useEffect as useEffect4 } from "react"; // src/hooks/useGraphStore.ts import { useContext as useContext2 } from "react"; import { useStore } from "zustand"; var useGraphStore = (selector) => { const store = useContext2(StoreContext); if (!store) { throw new Error("can only be get inside the xflow component."); } return useStore(store, selector); }; // src/hooks/useGraphEvent.ts import { useEffect } from "react"; // src/hooks/useLatest.ts import { useRef as useRef2 } from "react"; function useLatest(value) { const ref = useRef2(value); ref.current = value; return ref; } // src/hooks/useGraphEvent.ts var useGraphEvent = (name, callback) => { const cbRef = useLatest(callback); const graph = useGraphInstance(); useEffect(() => { if (graph) { cbRef.current = callback; graph.on(name, (args) => { cbRef.current(args); }); } return () => { if (graph && cbRef.current) { graph.off(name, cbRef.current); } }; }, [graph]); }; // src/hooks/useDnd.ts import { Dnd } from "@antv/x6-plugin-dnd"; import { useCallback, useEffect as useEffect2, useRef as useRef3 } from "react"; var useDnd = (options) => { const graph = useGraphInstance(); const ref = useRef3(); useEffect2(() => { if (graph && !ref.current) { ref.current = new Dnd({ target: graph, getDragNode: (node) => node.clone({ keepId: true }), getDropNode: (node) => node.clone({ keepId: true }), ...options }); } }, [graph]); const startDrag = useCallback( (n, e) => { if (graph && ref.current) { e.persist(); ref.current.start(graph.createNode(n), e.nativeEvent); } }, [graph] ); return { startDrag }; }; // src/hooks/useClipboard.ts import { useCallback as useCallback3 } from "react"; // src/hooks/useLoaded.ts import { useCallback as useCallback2 } from "react"; var useLoaded = (name) => { const graph = useGraphInstance(); const isLoaded = useCallback2( (cb) => { if (!graph) { console.warn("graph can only be get inside the xflow component."); return false; } const plugin = graph.getPlugin(name); if (!plugin) { if (cb) { return cb(); } console.warn(`${name} is not loaded, please use ${name} component first.`); return false; } return true; }, [graph, name] ); return { isLoaded }; }; // src/hooks/useClipboard.ts var useClipboard = () => { const graph = useGraphInstance(); const { isLoaded } = useLoaded("clipboard"); const copy = useCallback3( (ids, copyOptions) => { if (isLoaded() && graph) { const cells = ids.map((id) => graph?.getCellById(id)).filter(Boolean); graph.copy(cells, copyOptions); } }, [graph, isLoaded] ); const cut = useCallback3( (ids, cutOptions) => { if (isLoaded() && graph) { const cells = ids.map((id) => graph?.getCellById(id)).filter(Boolean); graph.cut(cells, cutOptions); } }, [graph, isLoaded] ); const paste = useCallback3( (pasteOptions) => { if (isLoaded() && graph) { const cells = graph.paste(pasteOptions); return cells; } return []; }, [graph, isLoaded] ); return { copy, cut, paste }; }; // src/hooks/useExport.ts import { Export } from "@antv/x6-plugin-export"; import { useCallback as useCallback4 } from "react"; var useExport = () => { const graph = useGraphInstance(); const { isLoaded } = useLoaded("export"); const ensure = useCallback4(() => { return isLoaded(() => { graph?.use(new Export()); return true; }); }, [graph, isLoaded]); const exportPNG = useCallback4( (fileName = "chart", options = {}) => { if (ensure() && graph) { graph.exportPNG(fileName, options); } }, [graph, ensure] ); const exportJPEG = useCallback4( (fileName = "chart", options = {}) => { if (ensure() && graph) { graph.exportJPEG(fileName, options); } }, [graph, ensure] ); const exportSVG = useCallback4( (fileName = "chart", options = {}) => { if (ensure() && graph) { graph.exportSVG(fileName, options); } }, [graph, ensure] ); return { exportPNG, exportJPEG, exportSVG }; }; // src/hooks/useHistory.ts import { useCallback as useCallback5, useState as useState2 } from "react"; var useHistory = () => { const graph = useGraphInstance(); const { isLoaded } = useLoaded("history"); const [canUndo, setCanUndo] = useState2(false); const [canRedo, setCanRedo] = useState2(false); const undo = useCallback5( (options) => { if (isLoaded() && graph) { return graph.undo(options); } return null; }, [graph, isLoaded] ); const redo = useCallback5( (options) => { if (isLoaded() && graph) { return graph.redo(options); } return null; }, [graph, isLoaded] ); useGraphEvent("history:change", () => { if (graph) { setCanUndo(graph.canUndo()); setCanRedo(graph.canRedo()); } }); return { undo, redo, canUndo, canRedo }; }; // src/hooks/useKeyboard.ts import { useEffect as useEffect3 } from "react"; var useKeyboard = (key, callback, action) => { const cbRef = useLatest(callback); const graph = useGraphInstance(); useEffect3(() => { if (graph) { cbRef.current = callback; graph.bindKey( key, (e) => { cbRef.current(e); }, action ); } return () => { if (graph) { graph.unbindKey(key); } }; }, [graph]); }; // src/components/State.tsx var INNER_CALL = "__inner__"; var preprocess = (key, value, graph) => { if (key === "position") { const { x, y } = Point.create(value).snapToGrid(graph.getGridSize()); return { position: { x, y } }; } if (key === "size") { return { size: { width: value.width, height: value.height } }; } return { [key]: value }; }; var XFlowState = (props) => { const { centerView, centerViewOptions, fitView, fitViewOptions } = props; const graph = useGraphInstance(); const updateNode = useGraphStore((state) => state.updateNode); const updateEdge = useGraphStore((state) => state.updateEdge); const addNodes = useGraphStore((state) => state.addNodes); const addEdges = useGraphStore((state) => state.addEdges); const removeNodes = useGraphStore((state) => state.removeNodes); const removeEdges = useGraphStore((state) => state.removeEdges); const changeList = useGraphStore((state) => state.changeList); const clearChangeList = useGraphStore((state) => state.clearChangeList); const changeSelectionStatus = (status) => { if (graph) { const added = status.filter((item) => item.selected); const removed = status.filter((item) => !item.selected); graph.select( added.map((item) => item.id), { [INNER_CALL]: true } ); graph.unselect( removed.map((item) => item.id), { [INNER_CALL]: true } ); } }; const changeAnimatedStatus = (status) => { if (graph) { status.forEach((item) => { const cell = graph.getCellById(item.id); if (cell) { if (item.animated) { let strokeDasharray = 5; let animation = "animated-line 30s infinite linear"; if (typeof item.animated !== "boolean") { if (item.animated.strokeDasharray) strokeDasharray = item.animated.strokeDasharray; if (item.animated.animation) animation = item.animated.animation; } cell.attr("line/strokeDasharray", strokeDasharray, { [INNER_CALL]: true }); cell.attr("line/style/animation", animation, { [INNER_CALL]: true }); } else { cell.attr("line/strokeDasharray", 0, { [INNER_CALL]: true }); cell.attr("line/style/animation", "", { [INNER_CALL]: true }); } } }); } }; const initData = (g, data) => { g.fromJSON(ObjectExt2.cloneDeep(data)); if (centerView) { g.centerContent(centerViewOptions); } if (fitView) { g.zoomToFit({ maxScale: 1, ...fitViewOptions }); } const { nodes, edges } = data; changeSelectionStatus([...nodes, ...edges]); changeAnimatedStatus([...edges]); }; const onSpecialPropChange = (id, data) => { if (graph) { const keys = Object.keys(data); if (keys.includes("selected")) { const selected = !!data.selected; changeSelectionStatus([{ id, selected }]); } else if (keys.includes("animated")) { const animated = !!data.animated; changeAnimatedStatus([{ id, animated }]); } } }; const onPropChange = (id, data, batchName) => { if (graph) { const cell = graph.getCellById(id); if (cell) { graph.startBatch(batchName); const changed = cell.preprocess(data, true); const properties = flatten(changed); Object.keys(properties).forEach((key) => { cell.setPropByPath(key, properties[key], { [INNER_CALL]: true, rewrite: true }); }); onSpecialPropChange(id, data); graph.stopBatch(batchName); } } }; const handleGraphChange = (g, changes) => { changes.forEach((changeItem) => { const { command, data } = changeItem; switch (command) { case "init": initData(g, data); break; case "addNodes": const nodes = ObjectExt2.cloneDeep(data); g.addNodes(nodes, { [INNER_CALL]: true }); changeSelectionStatus(nodes); break; case "removeNodes": g.removeCells(data, { [INNER_CALL]: true }); break; case "updateNode": onPropChange(data.id, data.data, "updateNode"); break; case "addEdges": const edges = ObjectExt2.cloneDeep(data); g.addEdges(edges, { [INNER_CALL]: true }); changeSelectionStatus(edges); changeAnimatedStatus(edges); break; case "removeEdges": g.removeCells(data, { [INNER_CALL]: true }); break; case "updateEdge": onPropChange(data.id, data.data, "updateEdge"); break; default: break; } }); clearChangeList(); }; useEffect4(() => { if (graph && changeList.length) { handleGraphChange(graph, changeList); } }, [changeList, graph]); useGraphEvent("cell:added", ({ cell, options }) => { if (!options[INNER_CALL]) { if (cell.isNode()) { const nodes = [cell.toJSON()]; addNodes(nodes, { silent: true }); changeSelectionStatus(nodes); } else if (cell.isEdge()) { const edges = [cell.toJSON()]; addEdges(edges, { silent: true }); changeSelectionStatus(edges); changeAnimatedStatus(edges); } } }); useGraphEvent("cell:removed", ({ cell, options }) => { if (!options[INNER_CALL]) { if (cell.isNode()) { removeNodes([cell.id], { silent: true }); } else if (cell.isEdge()) { removeEdges([cell.id], { silent: true }); } } }); useGraphEvent( "cell:change:*", FunctionExt.debounce( ({ cell, key, current, options }) => { if (!options[INNER_CALL] && graph) { if (cell.isNode()) { updateNode(cell.id, preprocess(key, current, graph), { silent: true }); } else if (cell.isEdge()) { updateEdge(cell.id, { [key]: current }, { silent: true }); } } }, 100 ) ); useGraphEvent("selection:changed", ({ added, removed, options }) => { if (!options[INNER_CALL]) { added.forEach((item) => { if (item.isNode()) { updateNode(item.id, { selected: true }, { silent: true }); } else if (item.isEdge()) { updateEdge(item.id, { selected: true }, { silent: true }); } }); removed.forEach((item) => { if (item.isNode()) { updateNode(item.id, { selected: false }, { silent: true }); } else if (item.isEdge()) { updateEdge(item.id, { selected: false }, { silent: true }); } }); } }); return null; }; // src/components/Graph.tsx var XFlowGraph = (props) => { const container = useRef4(null); const { className, style, readonly, virtual, minScale, maxScale, zoomable, zoomOptions, pannable, panOptions, embedable, embedOptions, restrict, restrictOptions, connectionOptions, selectOptions, keyboardOptions, scroller, scrollerOptions, connectionEdgeOptions, defaultHighlightOptions, embedHighlightOptions, nodeAvailableHighlightOptions, magnetAvailableHighlightOptions, magnetAdsorbedHighlightOptions, onEdgeLabelRendered } = props; const { graph, setGraph } = useContext3(GraphContext); useEffect5(() => { const g = new Graph({ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion container: container.current, autoResize: true, virtual, scaling: { min: minScale, max: maxScale }, connecting: { ...connectionOptions, createEdge: connectionOptions?.createEdge || function() { return this.createEdge({ shape: "edge", ...connectionEdgeOptions }); } }, highlighting: { default: defaultHighlightOptions, embedding: embedHighlightOptions, nodeAvailable: nodeAvailableHighlightOptions, magnetAvailable: magnetAvailableHighlightOptions, magnetAdsorbed: magnetAdsorbedHighlightOptions }, onEdgeLabelRendered }); g.use(new Selection({ enabled: true, ...selectOptions })); g.use(new Keyboard({ enabled: true, ...keyboardOptions })); if (scroller) { g.use(new Scroller({ enabled: true, ...scrollerOptions })); } setGraph(g); return () => { if (g) { g.dispose(); setGraph(null); } }; }, []); useEffect5(() => { if (graph) { if (readonly) { graph.options.interacting = false; } else { graph.options.interacting = { nodeMovable: (view) => { const cell = view.cell; return cell.prop("draggable") !== false; }, edgeMovable: (view) => { const cell = view.cell; return cell.prop("draggable") !== false; } }; } } }, [graph, readonly]); useEffect5(() => { if (graph) { if (zoomable) { graph.enableMouseWheel(); graph.options.mousewheel = { ...Options.defaults.mousewheel, ...zoomOptions, enabled: true }; } else { graph.disableMouseWheel(); } } }, [graph, zoomable, zoomOptions]); useEffect5(() => { if (graph) { if (pannable) { graph.options.panning = { ...Options.defaults.panning, enabled: true, ...panOptions }; graph.enablePanning(); } else { graph.disablePanning(); } } }, [graph, pannable, panOptions]); useEffect5(() => { if (graph) { if (embedable) { graph.options.embedding = { ...Options.defaults.embedding, enabled: true, validate: () => true, ...embedOptions }; } else { graph.options.embedding = { enabled: false, validate: () => false }; } } }, [graph, embedable, embedOptions]); useEffect5(() => { if (graph) { if (restrict) { graph.options.translating = { restrict: restrictOptions ? restrictOptions.bound : restrict }; } else { graph.options.translating = { restrict: false }; } } }, [graph, restrict, restrictOptions]); return /* @__PURE__ */ React6.createElement("div", { style: { width: "100%", height: "100%", ...style }, className }, /* @__PURE__ */ React6.createElement("div", { ref: container, style: { width: "100%", height: "100%" } }), /* @__PURE__ */ React6.createElement(Wrapper, null, /* @__PURE__ */ React6.createElement( XFlowState, { connectionEdgeOptions, centerView: props.centerView, centerViewOptions: props.centerViewOptions, fitView: props.fitView, fitViewOptions: props.fitViewOptions } ))); }; // src/components/Grid.tsx import { useEffect as useEffect6 } from "react"; var Grid = (props) => { const graph = useGraphInstance(); const { visible, size, type, options } = props; useEffect6(() => { if (graph) { graph.clearGrid(); graph.drawGrid({ type, ...options }); graph.showGrid(); } }, [graph, type, options]); useEffect6(() => { if (graph) { if (visible === false) { graph.hideGrid(); } else { graph.showGrid(); } } }, [graph, visible]); useEffect6(() => { if (graph) { if (size) { graph.setGridSize(size); } } }, [graph, size]); return null; }; // src/components/Background.tsx import { useEffect as useEffect7 } from "react"; var Background = (props) => { const graph = useGraphInstance(); useEffect7(() => { if (graph) { graph.clearBackground(); graph.drawBackground(props); } }, [graph, props]); return null; }; // src/components/Clipboard.tsx import { Clipboard as C } from "@antv/x6-plugin-clipboard"; import { useEffect as useEffect8 } from "react"; var Clipboard = (props) => { const graph = useGraphInstance(); useEffect8(() => { if (graph) { if (graph.getPlugin("clipboard")) { graph.disposePlugins("clipboard"); } graph.use( new C({ enabled: true, ...props }) ); } }, [graph, props]); return null; }; // src/components/History.tsx import { History as H } from "@antv/x6-plugin-history"; import { useEffect as useEffect9 } from "react"; var History = (props) => { const graph = useGraphInstance(); useEffect9(() => { if (graph) { if (graph.getPlugin("history")) { graph.disposePlugins("history"); } graph.use( new H({ enabled: true, ...props }) ); } }, [graph, props]); return null; }; // src/components/Minimap.tsx import { NodeView } from "@antv/x6"; import { MiniMap as M } from "@antv/x6-plugin-minimap"; import React11, { useEffect as useEffect10, useRef as useRef5 } from "react"; var _SimpleNodeView = class extends NodeView { renderMarkup() { const tag = this.cell.shape === "circle" ? "circle" : "rect"; return this.renderJSONMarkup({ tagName: tag, selector: "body" }); } update() { super.update({ body: { refWidth: "100%", refHeight: "100%", fill: _SimpleNodeView.nodeBackground } }); } }; var SimpleNodeView = _SimpleNodeView; __publicField(SimpleNodeView, "nodeBackground", "#8f8f8f"); var Minimap = (props) => { const { style, className, simple, simpleNodeBackground, ...others } = props; const ref = useRef5(null); const graph = useGraphInstance(); useEffect10(() => { if (graph && ref.current) { if (graph.getPlugin("minimap")) { graph.disposePlugins("minimap"); } SimpleNodeView.nodeBackground = simpleNodeBackground || SimpleNodeView.nodeBackground; graph.use( new M({ container: ref.current, width: 200, height: 160, padding: 10, graphOptions: simple ? { createCellView(cell) { if (cell.isEdge()) { return null; } if (cell.isNode()) { return SimpleNodeView; } return void 0; } } : void 0, ...others }) ); } }, [graph, others]); return /* @__PURE__ */ React11.createElement("div", { ref, style: { ...style }, className }); }; // src/components/Snapline.tsx import { Snapline as S } from "@antv/x6-plugin-snapline"; import { useEffect as useEffect11 } from "react"; var Snapline = (props) => { const graph = useGraphInstance(); useEffect11(() => { if (graph) { if (graph.getPlugin("snapline")) { graph.disposePlugins("snapline"); } graph.use( new S({ enabled: true, ...props }) ); } }, [graph, props]); return null; }; // src/components/Transform.tsx import { Transform as T } from "@antv/x6-plugin-transform"; import { useEffect as useEffect12 } from "react"; var Transform = (props) => { const graph = useGraphInstance(); const { resizing, rotating } = props; const parseOptions = (options) => { if (typeof options === "boolean") { return options; } if (typeof options === "object") { return { enabled: true, ...options }; } return false; }; useEffect12(() => { if (graph) { if (graph.getPlugin("transform")) { graph.disposePlugins("transform"); } graph.use( new T({ resizing: parseOptions(resizing), rotating: parseOptions(rotating) }) ); } }, [graph, resizing, rotating]); return null; }; // src/components/Control.tsx var import_classnames = __toESM(require_classnames()); import Tippy from "@tippyjs/react"; import { Plus, Minus, Minimize, Dice5 } from "lucide-react"; import React14, { useEffect as useEffect13, useState as useState3 } from "react"; import "tippy.js/dist/tippy.css"; import "./index-5FC5FO7Q.less"; var ControlEnum = /* @__PURE__ */ ((ControlEnum2) => { ControlEnum2["ZoomTo"] = "zoomTo"; ControlEnum2["ZoomIn"] = "zoomIn"; ControlEnum2["ZoomOut"] = "zoomOut"; ControlEnum2["ZoomToFit"] = "zoomToFit"; ControlEnum2["ZoomToOrigin"] = "zoomToOrigin"; return ControlEnum2; })(ControlEnum || {}); var dropDownItems = [ { key: "1", label: "50%" }, { key: "2", label: "75%" }, { key: "3", label: "100%" }, { key: "4", label: "125%" }, { key: "5", label: "150%" } ]; var ControlToolMap = { ["zoomIn" /* ZoomIn */]: { label: "\u653E\u5927", icon: /* @__PURE__ */ React14.createElement(Plus, { color: "#545456", size: 20 }) }, ["zoomOut" /* ZoomOut */]: { label: "\u7F29\u5C0F", icon: /* @__PURE__ */ React14.createElement(Minus, { color: "#545456", size: 20 }) }, ["zoomTo" /* ZoomTo */]: { label: "\u7F29\u653E\u81F3", icon: /* @__PURE__ */ React14.createElement(Plus, { color: "#545456", size: 20 }) }, ["zoomToFit" /* ZoomToFit */]: { label: "\u81EA\u9002\u5E94\u7A97\u53E3\u5927\u5C0F", icon: /* @__PURE__ */ React14.createElement(Minimize, { color: "#545456", size: 20 }) }, ["zoomToOrigin" /* ZoomToOrigin */]: { label: "\u5B9E\u9645\u50CF\u7D20\u5C55\u793A", icon: /* @__PURE__ */ React14.createElement(Dice5, { color: "#545456", size: 20 }) } }; var ControlActionList = [ "zoomTo", "zoomIn", "zoomOut", "zoomToFit", "zoomToOrigin" ]; var Control = (props) => { const { items, direction = "horizontal", placement = "top" } = props; const graph = useGraphInstance(); const [zoom, setZoom] = useState3(1); useGraphEvent("scale", ({ sx }) => { setZoom(sx); }); useEffect13(() => { if (graph) { setZoom(graph.zoom()); } }, [graph, props]); const changeZoom = (type, args) => { if (!graph) return; const key = parseInt(args || "1", 10); const zoomNum = 0.25 * (key + 1); switch (type) { case "zoomIn" /* ZoomIn */: if (zoom < 1.5) { graph.zoom(0.25); } break; case "zoomOut" /* ZoomOut */: if (zoom > 0.5) { graph.zoom(-0.25); } break; case "zoomToFit" /* ZoomToFit */: graph.zoomToFit({ maxScale: 1 }); break; case "zoomToOrigin" /* ZoomToOrigin */: graph.zoomTo(1); break; case "zoomTo" /* ZoomTo */: graph.zoomTo(zoomNum); break; default: break; } setZoom(graph.zoom()); }; const isToolButtonEnabled = (type) => { if (type == "zoomIn" /* ZoomIn */) { return zoom < 1.5; } else if (type === "zoomOut" /* ZoomOut */) { return zoom > 0.51; } return true; }; return /* @__PURE__ */ React14.createElement( "div", { className: (0, import_classnames.default)("toolButton", { toolbuttonVertical: direction === "vertical" }) }, items.map((tool) => { if (tool === "zoomTo") { return /* @__PURE__ */ React14.createElement( Tippy, { key: tool, content: /* @__PURE__ */ React14.createElement("div", { className: "tippyBtnContent" }, dropDownItems.map((item) => { return /* @__PURE__ */ React14.createElement("button", { key: item.key, onClick: () => changeZoom(tool, item.key) }, item.label); })), interactive: true, placement: "top", arrow: false, theme: "light-border" }, /* @__PURE__ */ React14.createElement("button", { className: "dropDownBtn" }, `${Math.floor(zoom * 100)}%`) ); } else if (ControlActionList.includes(tool)) { return /* @__PURE__ */ React14.createElement( Tippy, { key: tool, content: ControlToolMap[tool].label, placement, arrow: true }, /* @__PURE__ */ React14.createElement( "button", { onClick: () => changeZoom(tool), disabled: !isToolButtonEnabled(tool) }, ControlToolMap[tool].icon ) ); } else { return null; } }) ); }; // src/index.ts export * from "@antv/x6-react-shape"; export { Background, Clipboard, Control, ControlEnum, Dom, Edge, Graph2 as Graph, Grid, History, Line, Markup, Minimap, Path, Point2 as Point, Polyline, Rectangle, Snapline, Transform, Vector, Wrapper, XFlow, XFlowGraph, apply, flatten, getSubGraph, getSuperGraph, useClipboard, useDnd, useExport, useGraphEvent, useGraphInstance, useGraphStore, useHistory, useKeyboard }; /*! Bundled license information: classnames/index.js: (*! Copyright (c) 2018 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames *) */ //# sourceMappingURL=index.esm.js.map