UNPKG

@rxflow/base

Version:

BaseFlow - 核心 Flow 组件库

225 lines (223 loc) 9.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _FullscreenExitOutlined = _interopRequireDefault(require("@ant-design/icons/FullscreenExitOutlined")); var _FullscreenOutlined = _interopRequireDefault(require("@ant-design/icons/FullscreenOutlined")); var _ZoomInOutlined = _interopRequireDefault(require("@ant-design/icons/lib/icons/ZoomInOutlined")); var _ZoomOutOutlined = _interopRequireDefault(require("@ant-design/icons/lib/icons/ZoomOutOutlined")); var _react = require("@xyflow/react"); var _ahooks = require("ahooks"); var _antd = require("antd"); var _classcat = _interopRequireDefault(require("classcat")); var _react2 = _interopRequireWildcard(require("react")); var _jsxRuntime = require("react/jsx-runtime"); var _shallow = require("zustand/shallow"); var _icons = require("./icons"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* * @author: yanxianliang * @date: 2025-06-09 09:45 * @desc: 画布控制器 * * Copyright (c) 2025 by yanxianliang, All Rights Reserved. */ const selector = s => ({ isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable, minZoomReached: s.transform[2] <= s.minZoom, maxZoomReached: s.transform[2] >= s.maxZoom }); function Controls({ style, showZoom = true, showFitView = true, showInteractive = false, showFullscreen = true, showMiniMap, containerRef, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position = 'bottom-left', orientation = 'vertical', 'aria-label': ariaLabel = 'React Flow controls', minimapVisible, setMinimapVisible, showForceLayout }) { const [isFullscreen, { toggleFullscreen }] = (0, _ahooks.useFullscreen)(containerRef); const tooltipPlacement = (0, _react2.useMemo)(() => { switch (position) { case 'top-left': case 'center-left': case 'top-center': if (orientation === 'horizontal') { return 'bottom'; } return 'right'; case 'top-right': case 'center-right': if (orientation === 'horizontal') { return 'bottom'; } return 'left'; case 'bottom-left': case 'bottom-center': if (orientation === 'horizontal') { return 'top'; } return 'right'; case 'bottom-right': if (orientation === 'horizontal') { return 'top'; } return 'left'; default: return 'top'; } }, []); const store = (0, _react.useStoreApi)(); const { isInteractive, minZoomReached, maxZoomReached } = (0, _react.useStore)(selector, _shallow.shallow); const { zoomIn, zoomOut, fitView } = (0, _react.useReactFlow)(); const onZoomInHandler = () => { zoomIn(); onZoomIn?.(); }; const onZoomOutHandler = () => { zoomOut(); onZoomOut?.(); }; const onFitViewHandler = () => { fitView(fitViewOptions); onFitView?.(); }; const onToggleInteractivity = () => { store.setState({ nodesDraggable: !isInteractive, nodesConnectable: !isInteractive, elementsSelectable: !isInteractive }); onInteractiveChange?.(!isInteractive); }; const onForceLayout = () => { // TODO 美化布局 }; const onToggleMiniMap = () => { setMinimapVisible(!minimapVisible); }; const orientationClass = orientation === 'horizontal' ? 'horizontal' : 'vertical'; return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Panel, { className: (0, _classcat.default)(['react-flow__controls', orientationClass, className]), position: position, style: style, "data-testid": "rf__controls", "aria-label": ariaLabel, children: [showZoom && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, { title: '放大', placement: tooltipPlacement, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, { onClick: onZoomInHandler, className: "react-flow__controls-zoomin", title: '放大', "aria-label": 'zoom in', disabled: maxZoomReached, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ZoomInOutlined.default, {}) }) }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, { title: '缩小', placement: tooltipPlacement, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, { onClick: onZoomOutHandler, className: "react-flow__controls-zoomout", title: '缩小', "aria-label": 'zoom out', disabled: minZoomReached, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ZoomOutOutlined.default, {}) }) }) })] }), showFitView && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, { title: '自适应视图', placement: tooltipPlacement, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, { className: "react-flow__controls-fitview", onClick: onFitViewHandler, title: '自适应视图', "aria-label": 'fit view', children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.FitViewIcon, {}) }) }) }), showFullscreen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, { title: isFullscreen ? '取消全屏' : '全屏', placement: tooltipPlacement, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, { className: "react-flow__controls-fullscreen", onClick: toggleFullscreen, title: isFullscreen ? '取消全屏' : '全屏', "aria-label": "toggle fullscreen", children: isFullscreen ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_FullscreenExitOutlined.default, {}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_FullscreenOutlined.default, {}) }) }) }), showMiniMap && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, { title: minimapVisible ? '关闭缩略图' : '开启缩略图', placement: tooltipPlacement, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, { className: "react-flow__controls-interactive", onClick: onToggleMiniMap, title: minimapVisible ? '关闭缩略图' : '开启缩略图', "aria-label": "toggle minimap", children: minimapVisible ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.UnMinimap, {}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.Minimap, {}) }) }) }), showInteractive && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, { title: isInteractive ? '解锁' : '锁定', placement: tooltipPlacement, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, { className: "react-flow__controls-interactive", onClick: onToggleInteractivity, title: isInteractive ? '解锁' : '锁定', "aria-label": "toggle interactivity", children: isInteractive ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.UnlockIcon, {}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.LockIcon, {}) }) }) }), showForceLayout && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, { title: '美化布局', placement: tooltipPlacement, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, { className: "react-flow__controls-layout", onClick: onForceLayout, title: '美化布局', "aria-label": "force layout", children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.ForceLayout, {}) }) }) }), children] }); } var _default = exports.default = /*#__PURE__*/(0, _react2.memo)(Controls);