mirror of https://github.com/fantasticit/think.git
tiptap: add toolbar for flow
This commit is contained in:
parent
cd894ef446
commit
9cd1a06f53
|
@ -71370,8 +71370,11 @@ GraphViewer.prototype.init = function (b, c, e) {
|
||||||
null != c &&
|
null != c &&
|
||||||
((this.xmlDocument = c.ownerDocument), (this.xmlNode = c), (this.xml = mxUtils.getXml(c)), null != b)
|
((this.xmlDocument = c.ownerDocument), (this.xmlNode = c), (this.xml = mxUtils.getXml(c)), null != b)
|
||||||
) {
|
) {
|
||||||
|
var self = this;
|
||||||
var f = mxUtils.bind(this, function () {
|
var f = mxUtils.bind(this, function () {
|
||||||
this.graph = new Graph(b);
|
const graph = new Graph(b);
|
||||||
|
this.graph = graph;
|
||||||
|
self.graph = graph;
|
||||||
this.graph.enableFlowAnimation = !0;
|
this.graph.enableFlowAnimation = !0;
|
||||||
this.graph.defaultPageBackgroundColor = 'transparent';
|
this.graph.defaultPageBackgroundColor = 'transparent';
|
||||||
this.graph.transparentBackground = !1;
|
this.graph.transparentBackground = !1;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
import { NodeViewWrapper } from '@tiptap/react';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
|
import { Button, Space } from '@douyinfe/semi-ui';
|
||||||
|
import { IconMindCenter, IconZoomOut, IconZoomIn } from 'components/icons';
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
import { Resizeable } from 'components/resizeable';
|
import { Resizeable } from 'components/resizeable';
|
||||||
import { getEditorContainerDOMSize } from 'tiptap/prose-utils';
|
import { getEditorContainerDOMSize } from 'tiptap/prose-utils';
|
||||||
|
@ -7,27 +9,51 @@ import { Flow } from 'tiptap/core/extensions/flow';
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
const INHERIT_SIZE_STYLE = { width: '100%', height: '100%', maxWidth: '100%', overflow: 'hidden', padding: '1rem' };
|
const INHERIT_SIZE_STYLE = { width: '100%', height: '100%', maxWidth: '100%', overflow: 'hidden', padding: '1rem' };
|
||||||
|
const ICON_STYLE = { fontSize: '0.85em' };
|
||||||
|
|
||||||
export const FlowWrapper = ({ editor, node, updateAttributes }) => {
|
export const FlowWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
const isEditable = editor.isEditable;
|
const isEditable = editor.isEditable;
|
||||||
const isActive = editor.isActive(Flow.name);
|
const isActive = editor.isActive(Flow.name);
|
||||||
const { width: maxWidth } = getEditorContainerDOMSize(editor);
|
const { width: maxWidth } = getEditorContainerDOMSize(editor);
|
||||||
const { data, width, height } = node.attrs;
|
const { data, width, height } = node.attrs;
|
||||||
|
const $viewer = useRef(null);
|
||||||
const $container = useRef<HTMLElement>();
|
const $container = useRef<HTMLElement>();
|
||||||
|
|
||||||
const graphData = useMemo(() => {
|
const graphData = useMemo(() => {
|
||||||
const content = data.replace(/<!--.*?-->/gs, '').trim();
|
const content = data.replace(/<!--.*?-->/gs, '').trim();
|
||||||
const config = JSON.stringify({
|
const config = JSON.stringify({
|
||||||
highlight: '#00afff',
|
'lightbox': false,
|
||||||
lightbox: false,
|
'nav': false,
|
||||||
nav: false,
|
'resize': true,
|
||||||
resize: true,
|
'xml': content,
|
||||||
xml: content,
|
'zoom': 1,
|
||||||
zoom: 0.8,
|
'auto-fit': true,
|
||||||
|
'allow-zoom-in': true,
|
||||||
|
'allow-zoom-out': true,
|
||||||
|
'forceCenter': true,
|
||||||
});
|
});
|
||||||
return config;
|
return config;
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const center = useCallback(() => {
|
||||||
|
const graph = $viewer.current && $viewer.current.graph;
|
||||||
|
if (!graph) return;
|
||||||
|
graph.fit();
|
||||||
|
graph.center(true, false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const zoomOut = useCallback(() => {
|
||||||
|
const graph = $viewer.current && $viewer.current.graph;
|
||||||
|
if (!graph) return;
|
||||||
|
graph.zoomOut();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const zoomIn = useCallback(() => {
|
||||||
|
const graph = $viewer.current && $viewer.current.graph;
|
||||||
|
if (!graph) return;
|
||||||
|
graph.zoomIn();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const onResize = useCallback(
|
const onResize = useCallback(
|
||||||
(size) => {
|
(size) => {
|
||||||
updateAttributes({ width: size.width, height: size.height });
|
updateAttributes({ width: size.width, height: size.height });
|
||||||
|
@ -37,11 +63,14 @@ export const FlowWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
|
|
||||||
const render = useCallback((div) => {
|
const render = useCallback((div) => {
|
||||||
if (!div) return;
|
if (!div) return;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const DrawioViewer = window.GraphViewer;
|
const DrawioViewer = window.GraphViewer;
|
||||||
if (DrawioViewer) {
|
if (DrawioViewer) {
|
||||||
div.innerHTML = '';
|
div.innerHTML = '';
|
||||||
DrawioViewer.createViewerForElement(div);
|
DrawioViewer.createViewerForElement(div, (viewer) => {
|
||||||
|
$viewer.current = viewer;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -61,7 +90,35 @@ export const FlowWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
<NodeViewWrapper className={cls(styles.wrap, isActive && styles.isActive)}>
|
<NodeViewWrapper className={cls(styles.wrap, isActive && styles.isActive)}>
|
||||||
<Resizeable isEditable={isEditable} width={width} height={height} maxWidth={maxWidth} onChangeEnd={onResize}>
|
<Resizeable isEditable={isEditable} width={width} height={height} maxWidth={maxWidth} onChangeEnd={onResize}>
|
||||||
<div className={cls(styles.renderWrap, 'render-wrapper')} style={INHERIT_SIZE_STYLE}>
|
<div className={cls(styles.renderWrap, 'render-wrapper')} style={INHERIT_SIZE_STYLE}>
|
||||||
<div className="mxgraph" ref={setMxgraph} data-mxgraph={graphData}></div>
|
<div className="mxgraph" style={{ width, height }} ref={setMxgraph} data-mxgraph={graphData}></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.toolbarWrap}>
|
||||||
|
<Space spacing={2}>
|
||||||
|
<Button
|
||||||
|
type="tertiary"
|
||||||
|
theme="borderless"
|
||||||
|
size="small"
|
||||||
|
onClick={center}
|
||||||
|
icon={<IconMindCenter style={ICON_STYLE} />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="tertiary"
|
||||||
|
theme="borderless"
|
||||||
|
size="small"
|
||||||
|
onClick={zoomOut}
|
||||||
|
icon={<IconZoomOut style={ICON_STYLE} />}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="tertiary"
|
||||||
|
theme="borderless"
|
||||||
|
size="small"
|
||||||
|
onClick={zoomIn}
|
||||||
|
icon={<IconZoomIn style={ICON_STYLE} />}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</Resizeable>
|
</Resizeable>
|
||||||
</NodeViewWrapper>
|
</NodeViewWrapper>
|
||||||
|
|
Loading…
Reference in New Issue