diff --git a/packages/client/src/tiptap/divider.tsx b/packages/client/src/tiptap/divider.tsx
index 6ce90844..eb451e75 100644
--- a/packages/client/src/tiptap/divider.tsx
+++ b/packages/client/src/tiptap/divider.tsx
@@ -1,4 +1,4 @@
-export const Divider = () => {
+export const Divider = ({ vertical = false }) => {
return (
{
height: 24,
margin: '0 6px',
backgroundColor: 'var(--semi-color-border)',
+ transform: `rotate(${vertical ? 90 : 0}deg)`,
}}
>
);
diff --git a/packages/client/src/tiptap/menus/mind/bubble.tsx b/packages/client/src/tiptap/menus/mind/bubble.tsx
index 56d79214..b4547bfb 100644
--- a/packages/client/src/tiptap/menus/mind/bubble.tsx
+++ b/packages/client/src/tiptap/menus/mind/bubble.tsx
@@ -1,74 +1,11 @@
import { useCallback } from 'react';
-import cls from 'classnames';
-import { Space, Button, Popover, Typography } from '@douyinfe/semi-ui';
-import { IconAlignCenter, IconDelete } from '@douyinfe/semi-icons';
+import { Space, Button } from '@douyinfe/semi-ui';
+import { IconDelete } from '@douyinfe/semi-icons';
import { Tooltip } from 'components/tooltip';
-import { IconStructure, IconDrawBoard, IconZoomIn, IconZoomOut } from 'components/icons';
import { BubbleMenu } from '../../views/bubble-menu';
import { Mind } from '../../extensions/mind';
-import { Divider } from '../../divider';
-import { clamp } from '../../utils/clamp';
-import { TEMPLATES, THEMES, MAX_ZOOM, MIN_ZOOM, ZOOM_STEP } from './constant';
-import styles from './bubble.module.scss';
-
-const { Text } = Typography;
export const MindBubbleMenu = ({ editor }) => {
- const { template, theme, zoom, callCenterCount } = editor.getAttributes(Mind.name);
-
- const setZoom = useCallback(
- (type: 'minus' | 'plus') => {
- return () => {
- editor
- .chain()
- .updateAttributes(Mind.name, {
- zoom: clamp(type === 'minus' ? parseInt(zoom) - ZOOM_STEP : parseInt(zoom) + ZOOM_STEP, MIN_ZOOM, MAX_ZOOM),
- })
- .focus()
- .run();
- };
- },
- [editor, zoom]
- );
-
- const setCenter = useCallback(() => {
- const nextValue = Number.isNaN(callCenterCount) ? 1 : Number(callCenterCount) + 1;
-
- editor
- .chain()
- .updateAttributes(Mind.name, {
- callCenterCount: nextValue,
- })
- .focus()
- .run();
- }, [editor, callCenterCount]);
-
- const setTemplate = useCallback(
- (template) => {
- editor
- .chain()
- .updateAttributes(Mind.name, {
- template,
- })
- .focus()
- .run();
- },
- [editor]
- );
-
- const setTheme = useCallback(
- (theme) => {
- editor
- .chain()
- .updateAttributes(Mind.name, {
- theme,
- })
- .focus()
- .run();
- },
- [editor]
- );
-
const deleteNode = useCallback(() => editor.chain().deleteSelection().run(), [editor]);
return (
@@ -80,90 +17,6 @@ export const MindBubbleMenu = ({ editor }) => {
tippyOptions={{ maxWidth: 'calc(100vw - 100px)' }}
>
-
- }
- onClick={setZoom('minus')}
- />
-
- {zoom}
-
-
-
-
- } onClick={setCenter} />
-
-
-
-
- 布局
-
-
- {TEMPLATES.map((item) => {
- return (
- - setTemplate(item.value)}
- >
- {item.label}
-
- );
- })}
-
-
-
- }
- >
- } type="tertiary" theme="borderless" size="small" />
-
-
-
- 主题
-
-
- {THEMES.map((item) => {
- return (
- - setTheme(item.value)}
- >
- {item.label}
-
- );
- })}
-
-
-
- }
- >
- } type="tertiary" theme="borderless" size="small" />
-
-
} type="tertiary" theme="borderless" size="small" />
diff --git a/packages/client/src/tiptap/wrappers/mind/index.module.scss b/packages/client/src/tiptap/wrappers/mind/index.module.scss
index 2093f7f9..d1e1f796 100644
--- a/packages/client/src/tiptap/wrappers/mind/index.module.scss
+++ b/packages/client/src/tiptap/wrappers/mind/index.module.scss
@@ -13,21 +13,15 @@
}
}
- .mindHandlerWrap {
+ .toolbarWrap {
position: absolute;
- right: 20px;
- bottom: 20px;
- z-index: 1000;
- padding: 4px 8px;
- background-color: var(--semi-color-bg-2);
- border: 1px solid var(--node-border-color);
- border-radius: var(--border-radius);
+ top: 50%;
+ left: 0;
opacity: 0;
- box-shadow: var(--box-shadow);
}
&.isActive {
- .mindHandlerWrap {
+ .toolbarWrap {
opacity: 1;
}
}
diff --git a/packages/client/src/tiptap/wrappers/mind/index.tsx b/packages/client/src/tiptap/wrappers/mind/index.tsx
index d517587e..dfc7a481 100644
--- a/packages/client/src/tiptap/wrappers/mind/index.tsx
+++ b/packages/client/src/tiptap/wrappers/mind/index.tsx
@@ -1,16 +1,15 @@
import { NodeViewWrapper } from '@tiptap/react';
import cls from 'classnames';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import { Spin, Button, Typography } from '@douyinfe/semi-ui';
-import { IconMinus, IconPlus, IconAlignCenter } from '@douyinfe/semi-icons';
+import { Spin, Typography } from '@douyinfe/semi-ui';
import deepEqual from 'deep-equal';
import { Resizeable } from 'components/resizeable';
-import { Tooltip } from 'components/tooltip';
import { useToggle } from 'hooks/use-toggle';
-import { MIN_ZOOM, MAX_ZOOM, ZOOM_STEP } from '../../menus/mind/constant';
import { clamp } from '../../utils/clamp';
import { Mind } from '../../extensions/mind';
import { loadKityMinder } from './kityminder';
+import { Toolbar } from './toolbar';
+import { MIN_ZOOM, MAX_ZOOM, ZOOM_STEP } from './toolbar/constant';
import styles from './index.module.scss';
const { Text } = Typography;
@@ -20,7 +19,7 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
const $mind = useRef();
const isMindActive = editor.isActive(Mind.name);
const isEditable = editor.isEditable;
- const { data, template, theme, zoom, callCenterCount, width, height } = node.attrs;
+ const { data, template, theme, zoom, width, height } = node.attrs;
const [loading, toggleLoading] = useToggle(true);
const [error, setError] = useState(null);
@@ -55,12 +54,6 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
[updateAttributes]
);
- const setCenter = useCallback(() => {
- const minder = $mind.current;
- if (!minder) return;
- minder.execCommand('camera');
- }, []);
-
const setZoom = useCallback(
(type: 'minus' | 'plus') => {
return () => {
@@ -73,16 +66,45 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
MAX_ZOOM
);
minder.execCommand('zoom', nextZoom);
+ isEditable && updateAttributes({ zoom: nextZoom });
};
},
- [editor, zoom]
+ [editor, zoom, isEditable, updateAttributes]
+ );
+
+ const setCenter = useCallback(() => {
+ const minder = $mind.current;
+ if (!minder) return;
+ minder.execCommand('camera');
+ }, []);
+
+ // 布局
+ const setTemplate = useCallback(
+ (template) => {
+ const minder = $mind.current;
+ if (!minder) return;
+ minder.execCommand('template', template);
+ isEditable && updateAttributes({ template });
+ },
+ [updateAttributes, isEditable]
+ );
+
+ // 主题
+ const setTheme = useCallback(
+ (theme) => {
+ const minder = $mind.current;
+ if (!minder) return;
+ minder.execCommand('theme', theme);
+ isEditable && updateAttributes({ theme });
+ },
+ [updateAttributes, isEditable]
);
const saveData = useCallback(() => {
const minder = $mind.current;
if (!minder) return;
- updateAttributes({ data: minder.exportJson() });
- }, [updateAttributes]);
+ isEditable && updateAttributes({ data: minder.exportJson() });
+ }, [updateAttributes, isEditable]);
// 加载依赖
useEffect(() => {
@@ -113,6 +135,8 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
if (!isEditable) {
minder.disable();
+ } else {
+ minder.enable();
}
$mind.current = minder;
@@ -125,6 +149,7 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
return () => {
if ($mind.current) {
$mind.current.off('contentChange', onChange);
+ $mind.current.destroy();
}
};
}, [loading]);
@@ -133,14 +158,33 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
useEffect(() => {
const minder = $mind.current;
if (!minder) return;
+
const currentData = minder.exportJson();
const isEqual = deepEqual(currentData, data);
if (isEqual) return;
-
// TODO: 也许刷新更好些
minder.importJson(data);
}, [data]);
+ // 启用/禁用
+ useEffect(() => {
+ const minder = $mind.current;
+ if (!minder) return;
+
+ if (!isEditable) {
+ minder.disable();
+ } else {
+ minder.enable();
+ }
+ }, [isEditable]);
+
+ // 缩放
+ useEffect(() => {
+ const minder = $mind.current;
+ if (!minder) return;
+ minder.execCommand('zoom', parseInt(zoom));
+ }, [zoom]);
+
// 布局
useEffect(() => {
const minder = $mind.current;
@@ -155,30 +199,6 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
minder.execCommand('theme', theme);
}, [theme]);
- // 缩放
- useEffect(() => {
- const minder = $mind.current;
- if (!minder) return;
- minder.execCommand('zoom', parseInt(zoom));
- }, [zoom]);
-
- // 启用/禁用
- useEffect(() => {
- const minder = $mind.current;
- if (!minder) return;
-
- if (isEditable) {
- minder.enable();
- } else {
- minder.disable();
- }
- }, [isEditable]);
-
- // 居中
- useEffect(() => {
- setCenter();
- }, [callCenterCount]);
-
return (
{isEditable ? (
@@ -188,38 +208,19 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
) : (
{content}
)}
-
- {!isEditable && (
-
-
- }
- onClick={setZoom('minus')}
- />
-
-
- }
- onClick={setZoom('plus')}
- />
-
-
- }
- onClick={setCenter}
- />
-
-
- )}
+
+
+
);
};
diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/index.ts b/packages/client/src/tiptap/wrappers/mind/kityminder/index.ts
index 13a6cc9d..5f57db3c 100644
--- a/packages/client/src/tiptap/wrappers/mind/kityminder/index.ts
+++ b/packages/client/src/tiptap/wrappers/mind/kityminder/index.ts
@@ -1,7 +1,10 @@
export const loadKityMinder = async (): Promise => {
if (typeof window !== 'undefined') {
if (window.kityminder) {
- if (window.kityminder.Editor) return;
+ if (window.kityminder.Editor) {
+ console.log('无需重复');
+ return;
+ }
}
}
diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/focus.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/focus.js
index fd884342..4139d994 100644
--- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/focus.js
+++ b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/focus.js
@@ -4,10 +4,10 @@ define(function (require, exports, module) {
Minder.registerInitHook(function () {
this.on('beforemousedown', function (e) {
- this.focus();
// FIXME:如果遇到事件触发问题,需要检查这里
if (e.kityEvent.targetShape.__KityClassName === 'Paper') return;
e.preventDefault();
+ this.focus();
});
this.on('paperrender', function () {
this.focus();
diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/readonly.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/readonly.js
index ddacc116..cfa2bf26 100644
--- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/readonly.js
+++ b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/readonly.js
@@ -7,57 +7,56 @@
* @copyright: Baidu FEX, 2014
*/
-define(function(require, exports, module) {
- var kity = require('./kity');
- var Minder = require('./minder');
- var MinderEvent = require('./event');
+define(function (require, exports, module) {
+ var kity = require('./kity');
+ var Minder = require('./minder');
+ var MinderEvent = require('./event');
- Minder.registerInitHook(function(options) {
- if (options.readOnly) {
- this.setDisabled();
+ Minder.registerInitHook(function (options) {
+ if (options.readOnly) {
+ this.setDisabled();
+ }
+ });
+
+ kity.extendClass(Minder, {
+ disable: function () {
+ var me = this;
+ //禁用命令
+ me.bkqueryCommandState = me.queryCommandState;
+ me.bkqueryCommandValue = me.queryCommandValue;
+ me.queryCommandState = function (type) {
+ var cmd = this._getCommand(type);
+ if (cmd && cmd.enableReadOnly) {
+ return me.bkqueryCommandState.apply(me, arguments);
}
- });
-
- kity.extendClass(Minder, {
-
- disable: function() {
- var me = this;
- //禁用命令
- me.bkqueryCommandState = me.queryCommandState;
- me.bkqueryCommandValue = me.queryCommandValue;
- me.queryCommandState = function(type) {
- var cmd = this._getCommand(type);
- if (cmd && cmd.enableReadOnly) {
- return me.bkqueryCommandState.apply(me, arguments);
- }
- return -1;
- };
- me.queryCommandValue = function(type) {
- var cmd = this._getCommand(type);
- if (cmd && cmd.enableReadOnly) {
- return me.bkqueryCommandValue.apply(me, arguments);
- }
- return null;
- };
- this.setStatus('readonly');
- me._interactChange();
- },
-
- enable: function() {
- var me = this;
-
- if (me.bkqueryCommandState) {
- me.queryCommandState = me.bkqueryCommandState;
- delete me.bkqueryCommandState;
- }
- if (me.bkqueryCommandValue) {
- me.queryCommandValue = me.bkqueryCommandValue;
- delete me.bkqueryCommandValue;
- }
-
- this.setStatus('normal');
-
- me._interactChange();
+ return -1;
+ };
+ me.queryCommandValue = function (type) {
+ var cmd = this._getCommand(type);
+ if (cmd && cmd.enableReadOnly) {
+ return me.bkqueryCommandValue.apply(me, arguments);
}
- });
-});
\ No newline at end of file
+ return null;
+ };
+ this.setStatus('readonly');
+ me._interactChange();
+ },
+
+ enable: function () {
+ var me = this;
+
+ if (me.bkqueryCommandState) {
+ me.queryCommandState = me.bkqueryCommandState;
+ delete me.bkqueryCommandState;
+ }
+ if (me.bkqueryCommandValue) {
+ me.queryCommandValue = me.bkqueryCommandValue;
+ delete me.bkqueryCommandValue;
+ }
+
+ this.setStatus('normal');
+
+ me._interactChange();
+ },
+ });
+});
diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/view.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/view.js
index cf23741f..7f4f823f 100644
--- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/view.js
+++ b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/view.js
@@ -222,22 +222,23 @@ define(function (require, exports, module) {
let dx = 0;
let dy = 0;
- if (!focusNode || focusNode.type === 'root') {
- // 默认居中
- const parentNode = km.getPaper().node;
- const shapeNode = km.getRoot().rc.container.node;
- const { width: pw, height: ph, x: px, y: py } = parentNode.getBoundingClientRect();
- const { width: sw, height: sh, x, y } = shapeNode.getBBox();
- dx = pw / 2 - x - sw / 2;
- dy = ph / 2 - y - sh / 2;
- dragger.moveTo(new kity.Point(dx, dy), duration);
- } else {
- var viewport = km.getPaper().getViewPort();
- var offset = focusNode.getRenderContainer().getRenderBox('view');
- dx = viewport.center.x - offset.x - offset.width / 2;
- dy = viewport.center.y - offset.y;
- dragger.move(new kity.Point(dx, dy), duration);
- }
+ // if (!focusNode || focusNode.type === 'root') {
+ // // 默认居中
+ // const parentNode = km.getPaper().node;
+ // const shapeNode = km.getRoot().rc.container.node;
+ // const { width: pw, height: ph, x: px, y: py } = parentNode.getBoundingClientRect();
+ // const { width: sw, height: sh, x, y } = shapeNode.getBBox();
+ // dx = pw / 2 - x - sw / 2;
+ // dy = ph / 2 - y - sh / 2;
+ // dragger.moveTo(new kity.Point(dx, dy), duration);
+ // } else {
+ focusNode = focusNode || km.getRoot();
+ var viewport = km.getPaper().getViewPort();
+ var offset = focusNode.getRenderContainer().getRenderBox('view');
+ dx = viewport.center.x - offset.x - offset.width / 2;
+ dy = viewport.center.y - offset.y;
+ dragger.move(new kity.Point(dx, dy), duration);
+ // }
this.setContentChanged(false);
},
diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/receiver.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/receiver.js
index ba34c3d2..1dc96e22 100644
--- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/receiver.js
+++ b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/receiver.js
@@ -7,139 +7,137 @@
* @copyright: Baidu FEX, 2014
*/
-define(function(require, exports, module) {
- var key = require('../tool/key');
+define(function (require, exports, module) {
+ var key = require('../tool/key');
- function ReceiverRuntime() {
- var fsm = this.fsm;
- var minder = this.minder;
- var me = this;
+ function ReceiverRuntime() {
+ var fsm = this.fsm;
+ var minder = this.minder;
+ var me = this;
- // 接收事件的 div
- var element = document.createElement('div');
- element.contentEditable = true;
- /**
- * @Desc: 增加tabindex属性使得element的contenteditable不管是trur还是false都能有focus和blur事件
- * @Editor: Naixor
- * @Date: 2015.09.14
- */
- element.setAttribute('tabindex', -1);
- element.classList.add('receiver');
- element.onkeydown = element.onkeypress = element.onkeyup = dispatchKeyEvent;
- element.addEventListener('compositionstart', dispatchKeyEvent);
- // element.addEventListener('compositionend', dispatchKeyEvent);
- this.container.appendChild(element);
+ // 接收事件的 div
+ var element = document.createElement('div');
+ element.contentEditable = true;
+ /**
+ * @Desc: 增加tabindex属性使得element的contenteditable不管是trur还是false都能有focus和blur事件
+ * @Editor: Naixor
+ * @Date: 2015.09.14
+ */
+ element.setAttribute('tabindex', -1);
+ element.classList.add('receiver');
+ element.onkeydown = element.onkeypress = element.onkeyup = dispatchKeyEvent;
+ element.addEventListener('compositionstart', dispatchKeyEvent);
+ // element.addEventListener('compositionend', dispatchKeyEvent);
+ this.container.appendChild(element);
- // receiver 对象
- var receiver = {
- element: element,
- selectAll: function() {
- // 保证有被选中的
- if (!element.innerHTML) element.innerHTML = ' ';
- var range = document.createRange();
- var selection = window.getSelection();
- range.selectNodeContents(element);
- selection.removeAllRanges();
- selection.addRange(range);
- element.focus();
- },
- /**
- * @Desc: 增加enable和disable方法用于解决热核态的输入法屏蔽问题
- * @Editor: Naixor
- * @Date: 2015.09.14
- */
- enable: function() {
- element.setAttribute("contenteditable", true);
- },
- disable: function() {
- element.setAttribute("contenteditable", false);
- },
- /**
- * @Desc: hack FF下div contenteditable的光标丢失BUG
- * @Editor: Naixor
- * @Date: 2015.10.15
- */
- fixFFCaretDisappeared: function() {
- element.removeAttribute("contenteditable");
- element.setAttribute("contenteditable", "true");
- element.blur();
- element.focus();
- },
- /**
- * 以此事件代替通过mouse事件来判断receiver丢失焦点的事件
- * @editor Naixor
- * @Date 2015-12-2
- */
- onblur: function (handler) {
- element.onblur = handler;
- }
- };
- receiver.selectAll();
+ // receiver 对象
+ var receiver = {
+ element: element,
+ selectAll: function () {
+ // 保证有被选中的
+ if (!element.innerHTML) element.innerHTML = ' ';
+ var range = document.createRange();
+ var selection = window.getSelection();
+ range.selectNodeContents(element);
+ selection.removeAllRanges();
+ selection.addRange(range);
+ element.focus();
+ },
+ /**
+ * @Desc: 增加enable和disable方法用于解决热核态的输入法屏蔽问题
+ * @Editor: Naixor
+ * @Date: 2015.09.14
+ */
+ enable: function () {
+ element.setAttribute('contenteditable', true);
+ },
+ disable: function () {
+ element.setAttribute('contenteditable', false);
+ },
+ /**
+ * @Desc: hack FF下div contenteditable的光标丢失BUG
+ * @Editor: Naixor
+ * @Date: 2015.10.15
+ */
+ fixFFCaretDisappeared: function () {
+ element.removeAttribute('contenteditable');
+ element.setAttribute('contenteditable', 'true');
+ element.blur();
+ element.focus();
+ },
+ /**
+ * 以此事件代替通过mouse事件来判断receiver丢失焦点的事件
+ * @editor Naixor
+ * @Date 2015-12-2
+ */
+ onblur: function (handler) {
+ element.onblur = handler;
+ },
+ };
+ receiver.selectAll();
- minder.on('beforemousedown', receiver.selectAll);
- minder.on('receiverfocus', receiver.selectAll);
- minder.on('readonly', function() {
- // 屏蔽minder的事件接受,删除receiver和hotbox
- minder.disable();
- editor.receiver.element.parentElement.removeChild(editor.receiver.element);
- editor.hotbox.$container.removeChild(editor.hotbox.$element);
- });
+ minder.on('beforemousedown', receiver.selectAll);
+ minder.on('receiverfocus', receiver.selectAll);
+ minder.on('readonly', function () {
+ // 屏蔽minder的事件接受,删除receiver和hotbox
+ minder.disable();
+ editor.receiver.element.parentElement.removeChild(editor.receiver.element);
+ editor.hotbox.$container.removeChild(editor.hotbox.$element);
+ });
- // 侦听器,接收到的事件会派发给所有侦听器
- var listeners = [];
+ // 侦听器,接收到的事件会派发给所有侦听器
+ var listeners = [];
- // 侦听指定状态下的事件,如果不传 state,侦听所有状态
- receiver.listen = function(state, listener) {
- if (arguments.length == 1) {
- listener = state;
- state = '*';
- }
- listener.notifyState = state;
- listeners.push(listener);
- };
+ // 侦听指定状态下的事件,如果不传 state,侦听所有状态
+ receiver.listen = function (state, listener) {
+ if (arguments.length == 1) {
+ listener = state;
+ state = '*';
+ }
+ listener.notifyState = state;
+ listeners.push(listener);
+ };
- function dispatchKeyEvent(e) {
- e.is = function(keyExpression) {
- var subs = keyExpression.split('|');
- for (var i = 0; i < subs.length; i++) {
- if (key.is(this, subs[i])) return true;
- }
- return false;
- };
- var listener, jumpState;
- for (var i = 0; i < listeners.length; i++) {
-
- listener = listeners[i];
- // 忽略不在侦听状态的侦听器
- if (listener.notifyState != '*' && listener.notifyState != fsm.state()) {
- continue;
- }
-
- /**
- *
- * 对于所有的侦听器,只允许一种处理方式:跳转状态。
- * 如果侦听器确定要跳转,则返回要跳转的状态。
- * 每个事件只允许一个侦听器进行状态跳转
- * 跳转动作由侦听器自行完成(因为可能需要在跳转时传递 reason),返回跳转结果即可。
- * 比如:
- *
- * ```js
- * receiver.listen('normal', function(e) {
- * if (isSomeReasonForJumpState(e)) {
- * return fsm.jump('newstate', e);
- * }
- * });
- * ```
- */
- if (listener.call(null, e)) {
- return;
- }
- }
+ function dispatchKeyEvent(e) {
+ e.is = function (keyExpression) {
+ var subs = keyExpression.split('|');
+ for (var i = 0; i < subs.length; i++) {
+ if (key.is(this, subs[i])) return true;
+ }
+ return false;
+ };
+ var listener, jumpState;
+ for (var i = 0; i < listeners.length; i++) {
+ listener = listeners[i];
+ // 忽略不在侦听状态的侦听器
+ if (listener.notifyState != '*' && listener.notifyState != fsm.state()) {
+ continue;
}
- this.receiver = receiver;
+ /**
+ *
+ * 对于所有的侦听器,只允许一种处理方式:跳转状态。
+ * 如果侦听器确定要跳转,则返回要跳转的状态。
+ * 每个事件只允许一个侦听器进行状态跳转
+ * 跳转动作由侦听器自行完成(因为可能需要在跳转时传递 reason),返回跳转结果即可。
+ * 比如:
+ *
+ * ```js
+ * receiver.listen('normal', function(e) {
+ * if (isSomeReasonForJumpState(e)) {
+ * return fsm.jump('newstate', e);
+ * }
+ * });
+ * ```
+ */
+ if (listener.call(null, e)) {
+ return;
+ }
+ }
}
- return module.exports = ReceiverRuntime;
+ this.receiver = receiver;
+ }
+ return (module.exports = ReceiverRuntime);
});
diff --git a/packages/client/src/tiptap/menus/mind/constant.ts b/packages/client/src/tiptap/wrappers/mind/toolbar/constant.ts
similarity index 100%
rename from packages/client/src/tiptap/menus/mind/constant.ts
rename to packages/client/src/tiptap/wrappers/mind/toolbar/constant.ts
diff --git a/packages/client/src/tiptap/menus/mind/bubble.module.scss b/packages/client/src/tiptap/wrappers/mind/toolbar/index.module.scss
similarity index 65%
rename from packages/client/src/tiptap/menus/mind/bubble.module.scss
rename to packages/client/src/tiptap/wrappers/mind/toolbar/index.module.scss
index e538df72..f3363816 100644
--- a/packages/client/src/tiptap/menus/mind/bubble.module.scss
+++ b/packages/client/src/tiptap/wrappers/mind/toolbar/index.module.scss
@@ -1,3 +1,22 @@
+.wrap {
+ position: absolute;
+ top: 50%;
+ left: 1em;
+ z-index: 1000;
+ display: flex;
+ padding: 4px;
+ overflow-x: auto;
+ background-color: var(--semi-color-nav-bg);
+ border: 1px solid var(--semi-color-border);
+ border-radius: 3px;
+ transform: translateY(-50%);
+ flex-direction: column;
+ row-gap: 8px;
+ align-items: center;
+ box-shadow: var(--box-shadow);
+ user-select: none;
+}
+
.sectionWrap {
margin-top: 16px;
diff --git a/packages/client/src/tiptap/wrappers/mind/toolbar/index.tsx b/packages/client/src/tiptap/wrappers/mind/toolbar/index.tsx
new file mode 100644
index 00000000..f7af2fb1
--- /dev/null
+++ b/packages/client/src/tiptap/wrappers/mind/toolbar/index.tsx
@@ -0,0 +1,157 @@
+import cls from 'classnames';
+import { Button, Popover, Typography } from '@douyinfe/semi-ui';
+import { IconMinus, IconPlus, IconAlignCenter } from '@douyinfe/semi-icons';
+import { Tooltip } from 'components/tooltip';
+import { IconStructure, IconDrawBoard, IconZoomIn, IconZoomOut } from 'components/icons';
+import { Divider } from '../../../divider';
+import { TEMPLATES, THEMES, MAX_ZOOM, MIN_ZOOM } from './constant';
+import styles from './index.module.scss';
+
+const { Text } = Typography;
+
+interface IProps {
+ isEditable: boolean;
+ zoom: number | string;
+ template: string;
+ theme: string;
+ setZoomMinus: () => void;
+ setZoomPlus: () => void;
+ setCenter: () => void;
+ setTemplate: (arg: string) => void;
+ setTheme: (arg: string) => void;
+}
+
+export const Toolbar: React.FC = ({
+ isEditable,
+ template,
+ theme,
+ zoom,
+ setZoomMinus,
+ setZoomPlus,
+ setCenter,
+ setTemplate,
+ setTheme,
+}) => {
+ return (
+
+ {isEditable ? (
+ <>
+
+ }
+ onClick={setZoomMinus}
+ />
+
+
{zoom}
+
+
+
+
+ } onClick={setCenter} />
+
+
+
+ 布局
+
+
+ {TEMPLATES.map((item) => {
+ return (
+ - setTemplate(item.value)}
+ >
+ {item.label}
+
+ );
+ })}
+
+
+
+ }
+ >
+ } type="tertiary" theme="borderless" size="small" />
+
+
+
+ 主题
+
+
+ {THEMES.map((item) => {
+ return (
+ - setTheme(item.value)}
+ >
+ {item.label}
+
+ );
+ })}
+
+
+
+ }
+ >
+ } type="tertiary" theme="borderless" size="small" />
+
+ >
+ ) : (
+ <>
+
+ }
+ onClick={setZoomMinus}
+ />
+
+
+ }
+ onClick={setZoomPlus}
+ />
+
+
+ }
+ onClick={setCenter}
+ />
+
+ >
+ )}
+
+ );
+};