UNPKG

@ant-design/pro-flow

Version:
177 lines (175 loc) 7.62 kB
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _taggedTemplateLiteral from "@babel/runtime/helpers/esm/taggedTemplateLiteral"; var _templateObject, _templateObject2; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import { createStyles, cx } from 'antd-style'; import isEqual from 'fast-deep-equal'; import { debounce } from 'lodash-es'; import { forwardRef, useCallback, useEffect, useMemo, useRef } from 'react'; import { Flexbox } from 'react-layout-kit'; import ReactFlow, { Background, BackgroundVariant, SelectionMode, useNodesInitialized, useOnViewportChange, useReactFlow } from 'reactflow'; import 'reactflow/dist/style.css'; import CanvasLoading from "../../CanvasLoading"; import ContextMenu from "../features/ContextMenu"; import ControlAction from "../features/ControlAction"; import { useFlowEditor } from "../hooks/useFlowEditor"; import { useHotkeyManager } from "../hooks/useHotkeyManager"; import { flowEditorSelectors, useStore } from "../store"; import { jsx as _jsx } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime"; export var useStyles = createStyles(function (_ref) { var css = _ref.css, token = _ref.token; return { container: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n background: ", ";\n\n -webkit-font-smoothing: antialiased;\n\n .react-flow__pane {\n cursor: default;\n }\n .react-flow__edge-path,\n .react-flow__connection-path {\n stroke: ", ";\n stroke-width: 3px;\n }\n\n .react-flow__edge.selected .react-flow__edge-path,\n .react-flow__edge:focus .react-flow__edge-path,\n .react-flow__edge:focus-visible .react-flow__edge-path {\n stroke: ", ";\n stroke-width: 4px;\n }\n "])), token.colorBgLayout, token.colorBorder, token.colorPrimary), minimap: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n overflow: hidden;\n height: 150px;\n background: ", ";\n border-radius: 4px;\n "])), token.colorBgContainer) }; }); var FlowEditor = /*#__PURE__*/forwardRef(function (_ref2, ref) { var nodeTypes = _ref2.nodeTypes, _ref2$contextMenuEnab = _ref2.contextMenuEnabled, contextMenuEnabled = _ref2$contextMenuEnab === void 0 ? true : _ref2$contextMenuEnab, style = _ref2.style, className = _ref2.className, flowProps = _ref2.flowProps, defaultViewport = _ref2.defaultViewport, children = _ref2.children, _ref2$background = _ref2.background, background = _ref2$background === void 0 ? true : _ref2$background, _ref2$miniMap = _ref2.miniMap, miniMap = _ref2$miniMap === void 0 ? true : _ref2$miniMap, _ref2$hotkeyManager = _ref2.hotkeyManager, hotkeyManager = _ref2$hotkeyManager === void 0 ? true : _ref2$hotkeyManager, onNodesInit = _ref2.onNodesInit, _ref2$beforeConnect = _ref2.beforeConnect, beforeConnect = _ref2$beforeConnect === void 0 ? function () { return true; } : _ref2$beforeConnect, _ref2$onConnect = _ref2.onConnect, onConnect = _ref2$onConnect === void 0 ? function () {} : _ref2$onConnect, _ref2$afterConnect = _ref2.afterConnect, afterConnect = _ref2$afterConnect === void 0 ? function () {} : _ref2$afterConnect; var _useStyles = useStyles(), theme = _useStyles.theme, styles = _useStyles.styles; var nodes = useStore(flowEditorSelectors.nodeList, isEqual); var edges = useStore(flowEditorSelectors.edgeList, isEqual); var editor = useFlowEditor(); var nodesInitialized = useNodesInitialized(); var firstRender = useRef(false); var flowInit = useMemo(function () { if (nodesInitialized) { return true; } if (nodes.length > 0) { return false; } else { return true; } }, [nodes, nodesInitialized]); var _useStore = useStore(function (s) { return [s.handleNodesChange, s.handleEdgesChange, s.updateEdgesOnConnection, s.onViewPortChange // s.onEdgesChange, ]; }), _useStore2 = _slicedToArray(_useStore, 4), handleNodesChange = _useStore2[0], handleEdgesChange = _useStore2[1], updateEdgesOnConnection = _useStore2[2], onViewPortChange // onEdgesChange, = _useStore2[3]; var instance = useReactFlow(); // 添加快捷键监听 useHotkeyManager(hotkeyManager); // 抛出 viewport 变化的事件 useOnViewportChange({ onChange: onViewPortChange ? debounce(onViewPortChange, 300) : undefined }); useEffect(function () { if (firstRender.current) { return; } firstRender.current = true; // 先把画布的 viewport 设置好 if (!defaultViewport) { instance.fitView(); } else { instance.setViewport(defaultViewport); } }, [nodesInitialized]); useEffect(function () { if (nodesInitialized) { onNodesInit === null || onNodesInit === void 0 || onNodesInit(editor); } }, [nodesInitialized]); var handleConnect = useCallback(function (connection) { if (!beforeConnect(connection)) { return; } if (onConnect) { onConnect(connection); } var edge = updateEdgesOnConnection(connection); if (afterConnect && edge) { afterConnect(edge); } }, [onConnect, beforeConnect, afterConnect]); return /*#__PURE__*/_jsxs(Flexbox, { height: '100%', width: '100%', style: { position: 'relative' }, children: [!flowInit && /*#__PURE__*/_jsx(CanvasLoading, {}), /*#__PURE__*/_jsxs(ReactFlow, _objectSpread(_objectSpread({ nodeTypes: nodeTypes, ref: ref, className: cx(styles.container, className) // 如果外部传入 viewport,则使用外部的 viewport , defaultViewport: defaultViewport // 否则就 fit view , fitView: !defaultViewport, fitViewOptions: { padding: 3 }, nodes: nodes, edges: edges // snapToGrid , snapGrid: [20, 20], minZoom: 0.05 // 画布配置逻辑 , panOnScroll: true, panOnDrag: false, zoomOnScroll: false, selectionOnDrag: true, style: style }, flowProps), {}, { // 选择模式逻辑 selectionMode: SelectionMode.Partial, selectionKeyCode: ['Meta', 'Shift'], multiSelectionKeyCode: ['Meta', 'Shift'], selectNodesOnDrag: true, onNodesChange: handleNodesChange, onEdgesChange: handleEdgesChange // Connect 相关逻辑 , onConnect: handleConnect, disableKeyboardA11y: true, proOptions: { hideAttribution: true }, children: [background && /*#__PURE__*/_jsx(Background, { color: theme.colorTextQuaternary, variant: BackgroundVariant.Dots, size: 2 }), miniMap && /*#__PURE__*/_jsx(ControlAction, {}), contextMenuEnabled && /*#__PURE__*/_jsx(ContextMenu, {}), children] }))] }); }); export default FlowEditor;