mirror of https://github.com/fantasticit/think.git
tiptap: dragable
This commit is contained in:
parent
95400da337
commit
42822dc49e
|
@ -47,6 +47,7 @@ export const tildeInputRegex = /^~~~([a-z]+)?[\s\n]$/;
|
||||||
|
|
||||||
export const BuiltInCodeBlock = Node.create<CodeBlockOptions>({
|
export const BuiltInCodeBlock = Node.create<CodeBlockOptions>({
|
||||||
name: 'codeBlock',
|
name: 'codeBlock',
|
||||||
|
draggable: true,
|
||||||
|
|
||||||
addOptions() {
|
addOptions() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -18,6 +18,7 @@ export const Countdown = Node.create({
|
||||||
group: 'block',
|
group: 'block',
|
||||||
selectable: true,
|
selectable: true,
|
||||||
atom: true,
|
atom: true,
|
||||||
|
draggable: true,
|
||||||
|
|
||||||
addOptions() {
|
addOptions() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -15,6 +15,7 @@ export const DocumentChildren = Node.create({
|
||||||
name: 'documentChildren',
|
name: 'documentChildren',
|
||||||
group: 'block',
|
group: 'block',
|
||||||
atom: true,
|
atom: true,
|
||||||
|
draggable: true,
|
||||||
|
|
||||||
addOptions() {
|
addOptions() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -21,6 +21,7 @@ export const DocumentReference = Node.create({
|
||||||
name: 'documentReference',
|
name: 'documentReference',
|
||||||
group: 'block',
|
group: 'block',
|
||||||
atom: true,
|
atom: true,
|
||||||
|
draggable: true,
|
||||||
|
|
||||||
addAttributes() {
|
addAttributes() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -25,6 +25,7 @@ export const Flow = Node.create({
|
||||||
group: 'block',
|
group: 'block',
|
||||||
selectable: true,
|
selectable: true,
|
||||||
atom: true,
|
atom: true,
|
||||||
|
draggable: true,
|
||||||
|
|
||||||
addAttributes() {
|
addAttributes() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -27,6 +27,7 @@ export const Iframe = Node.create({
|
||||||
group: 'block',
|
group: 'block',
|
||||||
selectable: true,
|
selectable: true,
|
||||||
atom: true,
|
atom: true,
|
||||||
|
draggable: true,
|
||||||
|
|
||||||
addOptions() {
|
addOptions() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -35,6 +35,7 @@ export const Mind = Node.create({
|
||||||
group: 'block',
|
group: 'block',
|
||||||
selectable: true,
|
selectable: true,
|
||||||
atom: true,
|
atom: true,
|
||||||
|
draggable: true,
|
||||||
inline: false,
|
inline: false,
|
||||||
|
|
||||||
addAttributes() {
|
addAttributes() {
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
export { Paragraph } from '@tiptap/extension-paragraph';
|
import TitapParagraph from '@tiptap/extension-paragraph';
|
||||||
|
|
||||||
|
export const Paragraph = TitapParagraph.extend({
|
||||||
|
draggable: true,
|
||||||
|
});
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
min-width: 48px;
|
min-width: 48px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow-x: auto;
|
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
background-color: var(--semi-color-fill-0);
|
background-color: var(--semi-color-fill-0);
|
||||||
counter-reset: line 0;
|
counter-reset: line 0;
|
||||||
|
@ -24,7 +23,6 @@
|
||||||
max-height: 370px;
|
max-height: 370px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
overflow: auto;
|
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { IconClose, IconDownload, IconPlayCircle } from '@douyinfe/semi-icons';
|
import { IconClose, IconDownload, IconPlayCircle } from '@douyinfe/semi-icons';
|
||||||
import { Button, Collapsible, Progress, Space, Spin, Toast, Typography } from '@douyinfe/semi-ui';
|
import { Button, Collapsible, Progress, Space, Spin, Toast, Typography } from '@douyinfe/semi-ui';
|
||||||
import { FILE_CHUNK_SIZE } from '@think/domains';
|
import { FILE_CHUNK_SIZE } from '@think/domains';
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { Tooltip } from 'components/tooltip';
|
import { Tooltip } from 'components/tooltip';
|
||||||
import { useToggle } from 'hooks/use-toggle';
|
import { useToggle } from 'hooks/use-toggle';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { uploadFile } from 'services/file';
|
import { uploadFile } from 'services/file';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
import { download, extractFileExtension, extractFilename, normalizeFileSize } from 'tiptap/prose-utils';
|
import { download, extractFileExtension, extractFilename, normalizeFileSize } from 'tiptap/prose-utils';
|
||||||
|
|
||||||
import { getFileTypeIcon } from './file-icon';
|
import { getFileTypeIcon } from './file-icon';
|
||||||
|
@ -154,5 +154,5 @@ export const AttachmentWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
return <NodeViewWrapper as="div">{content}</NodeViewWrapper>;
|
return <DragableWrapper editor={editor}>{content}</DragableWrapper>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { NodeViewContent, NodeViewWrapper } from '@tiptap/react';
|
import { NodeViewContent } from '@tiptap/react';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { EmojiPicker } from 'components/emoji-picker';
|
import { EmojiPicker } from 'components/emoji-picker';
|
||||||
import { convertColorToRGBA } from 'helpers/color';
|
import { convertColorToRGBA } from 'helpers/color';
|
||||||
import { Theme, ThemeEnum } from 'hooks/use-theme';
|
import { Theme, ThemeEnum } from 'hooks/use-theme';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ export const CalloutWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper id="js-callout-container" className={cls(styles.wrap)}>
|
<DragableWrapper editor={editor} id="js-callout-container" className={cls(styles.wrap)}>
|
||||||
<div
|
<div
|
||||||
className={cls(styles.innerWrap, 'render-wrapper')}
|
className={cls(styles.innerWrap, 'render-wrapper')}
|
||||||
style={{
|
style={{
|
||||||
|
@ -46,6 +47,6 @@ export const CalloutWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { IconCopy } from '@douyinfe/semi-icons';
|
import { IconCopy } from '@douyinfe/semi-icons';
|
||||||
import { Button, Select, Tooltip } from '@douyinfe/semi-ui';
|
import { Button, Select, Tooltip } from '@douyinfe/semi-ui';
|
||||||
import { NodeViewContent, NodeViewWrapper } from '@tiptap/react';
|
import { NodeViewContent } from '@tiptap/react';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { copy } from 'helpers/copy';
|
import { copy } from 'helpers/copy';
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ export const CodeBlockWrapper = ({ editor, node: { attrs }, updateAttributes, ex
|
||||||
const $container = useRef<HTMLPreElement>();
|
const $container = useRef<HTMLPreElement>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className={cls(styles.wrap, 'render-wrapper')}>
|
<DragableWrapper editor={editor} className={cls(styles.wrap, 'render-wrapper')}>
|
||||||
<div className={styles.handleWrap}>
|
<div className={styles.handleWrap}>
|
||||||
<Select
|
<Select
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -43,6 +44,6 @@ export const CodeBlockWrapper = ({ editor, node: { attrs }, updateAttributes, ex
|
||||||
<pre ref={$container}>
|
<pre ref={$container}>
|
||||||
<NodeViewContent as="code" />
|
<NodeViewContent as="code" />
|
||||||
</pre>
|
</pre>
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Space, Typography } from '@douyinfe/semi-ui';
|
import { Space, Typography } from '@douyinfe/semi-ui';
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import Countdown from 'react-countdown';
|
import Countdown from 'react-countdown';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
@ -32,11 +32,11 @@ export const CountdownWrapper = ({ editor, node }) => {
|
||||||
const { title, date } = node.attrs;
|
const { title, date } = node.attrs;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper>
|
<DragableWrapper editor={editor}>
|
||||||
<div className={cls(styles.wrap, 'render-wrapper')}>
|
<div className={cls(styles.wrap, 'render-wrapper')}>
|
||||||
<Text>{title}</Text>
|
<Text>{title}</Text>
|
||||||
<Countdown date={date} renderer={renderer}></Countdown>
|
<Countdown date={date} renderer={renderer}></Countdown>
|
||||||
</div>
|
</div>
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Typography } from '@douyinfe/semi-ui';
|
import { Typography } from '@douyinfe/semi-ui';
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { DataRender } from 'components/data-render';
|
import { DataRender } from 'components/data-render';
|
||||||
import { Empty } from 'components/empty';
|
import { Empty } from 'components/empty';
|
||||||
|
@ -8,6 +7,7 @@ import { useChildrenDocument } from 'data/document';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@ export const DocumentChildrenWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
}, [node.attrs, wikiId, documentId, updateAttributes]);
|
}, [node.attrs, wikiId, documentId, updateAttributes]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper
|
<DragableWrapper
|
||||||
|
editor={editor}
|
||||||
as="div"
|
as="div"
|
||||||
className={cls('render-wrapper', styles.wrap, isEditable && styles.isEditable, 'documentChildren')}
|
className={cls('render-wrapper', styles.wrap, isEditable && styles.isEditable, 'documentChildren')}
|
||||||
>
|
>
|
||||||
|
@ -77,6 +78,6 @@ export const DocumentChildrenWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
<Text type="tertiary">当前页面无法使用子文档</Text>
|
<Text type="tertiary">当前页面无法使用子文档</Text>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { IconDocument } from 'components/icons';
|
import { IconDocument } from 'components/icons';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
@ -48,8 +48,8 @@ export const DocumentReferenceWrapper = ({ editor, node, updateAttributes }) =>
|
||||||
}, [wikiId, documentId, isEditable, isShare, title]);
|
}, [wikiId, documentId, isEditable, isShare, title]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper as="div" className={cls(styles.wrap, isEditable && 'render-wrapper')}>
|
<DragableWrapper editor={editor} as="div" className={cls(styles.wrap, isEditable && 'render-wrapper')}>
|
||||||
{content}
|
{content}
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
.draggableItem {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.dragHandle {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.3rem;
|
||||||
|
left: -1.5rem;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
cursor: grab;
|
||||||
|
opacity: 0;
|
||||||
|
background-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 16"><path fill-opacity="0.2" d="M4 14c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zM2 6C.9 6 0 6.9 0 8s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6C.9 0 0 .9 0 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" /></svg>');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.isEditable {
|
||||||
|
&:hover {
|
||||||
|
.dragHandle {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Editor } from '@tiptap/core';
|
||||||
|
import { NodeViewWrapper } from '@tiptap/react';
|
||||||
|
import cls from 'classnames';
|
||||||
|
import React, { ElementType } from 'react';
|
||||||
|
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
|
export const DragableWrapper: React.FC<{
|
||||||
|
editor: Editor;
|
||||||
|
as?: ElementType;
|
||||||
|
id?: string;
|
||||||
|
className?: string;
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
}> = ({ editor, as = 'div', id, className, style = {}, children }) => {
|
||||||
|
const isEditable = editor.isEditable;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NodeViewWrapper
|
||||||
|
as={as}
|
||||||
|
id={id}
|
||||||
|
className={cls(styles.draggableItem, isEditable && styles.isEditable, className)}
|
||||||
|
style={style}
|
||||||
|
>
|
||||||
|
<div className={styles.dragHandle} contentEditable="false" draggable="true" data-drag-handle />
|
||||||
|
<div className={styles.content}>{children}</div>
|
||||||
|
</NodeViewWrapper>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,5 +1,4 @@
|
||||||
import { Button, Space, Spin, Typography } from '@douyinfe/semi-ui';
|
import { Button, Space, Spin, Typography } from '@douyinfe/semi-ui';
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { IconFlow, IconMindCenter, IconZoomIn, IconZoomOut } from 'components/icons';
|
import { IconFlow, IconMindCenter, IconZoomIn, IconZoomOut } from 'components/icons';
|
||||||
import { Resizeable } from 'components/resizeable';
|
import { Resizeable } from 'components/resizeable';
|
||||||
|
@ -8,6 +7,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import VisibilitySensor from 'react-visibility-sensor';
|
import VisibilitySensor from 'react-visibility-sensor';
|
||||||
import { load, renderXml } from 'thirtypart/diagram';
|
import { load, renderXml } from 'thirtypart/diagram';
|
||||||
import { Flow } from 'tiptap/core/extensions/flow';
|
import { Flow } from 'tiptap/core/extensions/flow';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
import { getEditorContainerDOMSize } from 'tiptap/prose-utils';
|
import { getEditorContainerDOMSize } from 'tiptap/prose-utils';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
@ -95,7 +95,7 @@ export const FlowWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
}, [toggleLoading, data]);
|
}, [toggleLoading, data]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className={cls(styles.wrap, isActive && styles.isActive)}>
|
<DragableWrapper editor={editor} className={cls(styles.wrap, isActive && styles.isActive)}>
|
||||||
<VisibilitySensor onChange={onViewportChange}>
|
<VisibilitySensor onChange={onViewportChange}>
|
||||||
<Resizeable isEditable={isEditable} width={width} height={height} maxWidth={maxWidth} onChangeEnd={onResize}>
|
<Resizeable isEditable={isEditable} width={width} height={height} maxWidth={maxWidth} onChangeEnd={onResize}>
|
||||||
<div
|
<div
|
||||||
|
@ -134,6 +134,6 @@ export const FlowWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
</div>
|
</div>
|
||||||
</Resizeable>
|
</Resizeable>
|
||||||
</VisibilitySensor>
|
</VisibilitySensor>
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Typography } from '@douyinfe/semi-ui';
|
import { Typography } from '@douyinfe/semi-ui';
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { Resizeable } from 'components/resizeable';
|
import { Resizeable } from 'components/resizeable';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
import { getEditorContainerDOMSize } from 'tiptap/prose-utils';
|
import { getEditorContainerDOMSize } from 'tiptap/prose-utils';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
@ -22,7 +22,7 @@ export const IframeWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper>
|
<DragableWrapper editor={editor}>
|
||||||
<Resizeable width={width} maxWidth={maxWidth} height={height} isEditable={isEditable} onChangeEnd={onResize}>
|
<Resizeable width={width} maxWidth={maxWidth} height={height} isEditable={isEditable} onChangeEnd={onResize}>
|
||||||
<div className={cls(styles.wrap, 'render-wrapper')}>
|
<div className={cls(styles.wrap, 'render-wrapper')}>
|
||||||
{url ? (
|
{url ? (
|
||||||
|
@ -36,6 +36,6 @@ export const IframeWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Resizeable>
|
</Resizeable>
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Spin, Typography } from '@douyinfe/semi-ui';
|
import { Spin, Typography } from '@douyinfe/semi-ui';
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
|
||||||
import { Resizeable } from 'components/resizeable';
|
import { Resizeable } from 'components/resizeable';
|
||||||
import { useToggle } from 'hooks/use-toggle';
|
import { useToggle } from 'hooks/use-toggle';
|
||||||
import { useCallback, useEffect, useRef } from 'react';
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
import { LazyLoadImage } from 'react-lazy-load-image-component';
|
import { LazyLoadImage } from 'react-lazy-load-image-component';
|
||||||
import { uploadFile } from 'services/file';
|
import { uploadFile } from 'services/file';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
import {
|
import {
|
||||||
extractFileExtension,
|
extractFileExtension,
|
||||||
extractFilename,
|
extractFilename,
|
||||||
|
@ -69,7 +69,7 @@ export const ImageWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
}, [src, hasTrigger, selectFile, updateAttributes]);
|
}, [src, hasTrigger, selectFile, updateAttributes]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper as="div" style={{ textAlign, fontSize: 0, maxWidth: '100%' }}>
|
<DragableWrapper editor={editor} style={{ textAlign, fontSize: 0, maxWidth: '100%' }}>
|
||||||
<Resizeable
|
<Resizeable
|
||||||
className={'render-wrapper'}
|
className={'render-wrapper'}
|
||||||
width={width || maxWidth}
|
width={width || maxWidth}
|
||||||
|
@ -93,6 +93,6 @@ export const ImageWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
<LazyLoadImage src={src} alt={alt} width={width} height={height} />
|
<LazyLoadImage src={src} alt={alt} width={width} height={height} />
|
||||||
)}
|
)}
|
||||||
</Resizeable>
|
</Resizeable>
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Button, Space, Spin, Typography } from '@douyinfe/semi-ui';
|
import { Button, Space, Spin, Typography } from '@douyinfe/semi-ui';
|
||||||
import { NodeViewWrapper } from '@tiptap/react';
|
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import { IconMind, IconMindCenter, IconZoomIn, IconZoomOut } from 'components/icons';
|
import { IconMind, IconMindCenter, IconZoomIn, IconZoomOut } from 'components/icons';
|
||||||
import { Resizeable } from 'components/resizeable';
|
import { Resizeable } from 'components/resizeable';
|
||||||
|
@ -11,6 +10,7 @@ import VisibilitySensor from 'react-visibility-sensor';
|
||||||
import { load, renderMind } from 'thirtypart/kityminder';
|
import { load, renderMind } from 'thirtypart/kityminder';
|
||||||
import { Mind } from 'tiptap/core/extensions/mind';
|
import { Mind } from 'tiptap/core/extensions/mind';
|
||||||
import { MAX_ZOOM, MIN_ZOOM, ZOOM_STEP } from 'tiptap/core/menus/mind/constant';
|
import { MAX_ZOOM, MIN_ZOOM, ZOOM_STEP } from 'tiptap/core/menus/mind/constant';
|
||||||
|
import { DragableWrapper } from 'tiptap/core/wrappers/dragable';
|
||||||
import { clamp, getEditorContainerDOMSize } from 'tiptap/prose-utils';
|
import { clamp, getEditorContainerDOMSize } from 'tiptap/prose-utils';
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
import styles from './index.module.scss';
|
||||||
|
@ -108,7 +108,7 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
}, [width, height, setCenter]);
|
}, [width, height, setCenter]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className={cls(styles.wrap, isActive && styles.isActive)}>
|
<DragableWrapper editor={editor} className={cls(styles.wrap, isActive && styles.isActive)}>
|
||||||
<VisibilitySensor onChange={onViewportChange}>
|
<VisibilitySensor onChange={onViewportChange}>
|
||||||
<Resizeable isEditable={isEditable} width={width} height={height} maxWidth={maxWidth} onChangeEnd={onResize}>
|
<Resizeable isEditable={isEditable} width={width} height={height} maxWidth={maxWidth} onChangeEnd={onResize}>
|
||||||
<div
|
<div
|
||||||
|
@ -162,6 +162,6 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => {
|
||||||
</div>
|
</div>
|
||||||
</Resizeable>
|
</Resizeable>
|
||||||
</VisibilitySensor>
|
</VisibilitySensor>
|
||||||
</NodeViewWrapper>
|
</DragableWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue