@ctzhian/tiptap 1.12.23 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -152,7 +152,7 @@ var Reader = function Reader() {
152
152
  }
153
153
  return onUpload;
154
154
  }(),
155
- content: ':'
155
+ content: "<p>fadsjlfkas</p><div data-type=\"flow\" data-code=\"C4Context\n title System Context diagram for Internet Banking System\n Enterprise_Boundary(b0, &quot;BankBoundary0&quot;) {\n Person(customerA, &quot;Banking Customer A&quot;, &quot;A customer of the bank, with personal bank accounts.&quot;)\n Person(customerB, &quot;Banking Customer B&quot;)\n Person_Ext(customerC, &quot;Banking Customer C&quot;, &quot;desc&quot;)\n\n Person(customerD, &quot;Banking Customer D&quot;, &quot;A customer of the bank, &lt;br/&gt; with personal bank accounts.&quot;)\n\n System(SystemAA, &quot;Internet Banking System&quot;, &quot;Allows customers to view information about their bank accounts, and make payments.&quot;)\n\n Enterprise_Boundary(b1, &quot;BankBoundary&quot;) {\n SystemDb_Ext(SystemE, &quot;Mainframe Banking System&quot;, &quot;Stores all of the core banking information about customers, accounts, transactions, etc.&quot;)\n\n System_Boundary(b2, &quot;BankBoundary2&quot;) {\n System(SystemA, &quot;Banking System A&quot;)\n System(SystemB, &quot;Banking System B&quot;, &quot;A system of the bank, with personal bank accounts. next line.&quot;)\n }\n\n System_Ext(SystemC, &quot;E-mail system&quot;, &quot;The internal Microsoft Exchange e-mail system.&quot;)\n SystemDb(SystemD, &quot;Banking System D Database&quot;, &quot;A system of the bank, with personal bank accounts.&quot;)\n\n Boundary(b3, &quot;BankBoundary3&quot;, &quot;boundary&quot;) {\n SystemQueue(SystemF, &quot;Banking System F Queue&quot;, &quot;A system of the bank.&quot;)\n SystemQueue_Ext(SystemG, &quot;Banking System G Queue&quot;, &quot;A system of the bank, with personal bank accounts.&quot;)\n }\n }\n }\n\n BiRel(customerA, SystemAA, &quot;Uses&quot;)\n BiRel(SystemAA, SystemE, &quot;Uses&quot;)\n Rel(SystemAA, SystemC, &quot;Sends e-mails&quot;, &quot;SMTP&quot;)\n Rel(SystemC, customerA, &quot;Sends e-mails to&quot;)\" data-width=\"100%\" data-height=\"auto\"></div><p>fsajdlkfjadsl</p>"
156
156
  }),
157
157
  editor = _useTiptap.editor;
158
158
  return /*#__PURE__*/React.createElement(EditorThemeProvider, {
@@ -84,7 +84,7 @@ var CustomBubbleMenu = function CustomBubbleMenu(_ref) {
84
84
  // return cellSelection.$anchorCell.pos !== cellSelection.$headCell.pos;
85
85
  // }
86
86
  // }
87
- if (editor.state.selection.empty || editor.isActive('image') || editor.isActive('video') || editor.isActive('audio') || editor.isActive('emoji') || editor.isActive('codeBlock') || editor.isActive('blockMath') || editor.isActive('inlineMath') || editor.isActive('blockLink') || editor.isActive('inlineLink') || editor.isActive('blockAttachment') || editor.isActive('inlineAttachment') || editor.isActive('horizontalRule') || editor.isActive('iframe') || editor.isActive('yamlFormat')) {
87
+ if (editor.state.selection.empty || editor.isActive('image') || editor.isActive('video') || editor.isActive('audio') || editor.isActive('emoji') || editor.isActive('codeBlock') || editor.isActive('blockMath') || editor.isActive('inlineMath') || editor.isActive('blockLink') || editor.isActive('inlineLink') || editor.isActive('blockAttachment') || editor.isActive('inlineAttachment') || editor.isActive('horizontalRule') || editor.isActive('iframe') || editor.isActive('yamlFormat') || editor.isActive('flow')) {
88
88
  return false;
89
89
  }
90
90
  return true;
@@ -1,7 +1,7 @@
1
1
  import { getShortcutKeyText } from "../../../util";
2
2
  import { Typography } from '@mui/material';
3
3
  import React from 'react';
4
- import { AddCircleFillIcon, ArrowDownSLineIcon, AttachmentLineIcon, CheckboxCircleFillIcon, CloseCircleFillIcon, CodeBoxLineIcon, CodeLineIcon, CodeSSlashLineIcon, DoubleQuotesLIcon, EmotionLineIcon, ErrorWarningFillIcon, FormulaIcon, FunctionsIcon, ImageLineIcon, Information2FillIcon, Information2LineIcon, MenuFold2FillIcon, MovieLineIcon, Music2LineIcon, SeparatorIcon, SquareRootIcon, Table2Icon, UserSmileFillIcon, WindowFillIcon } from "../../Icons";
4
+ import { AddCircleFillIcon, ArrowDownSLineIcon, AttachmentLineIcon, CheckboxCircleFillIcon, CloseCircleFillIcon, CodeBoxLineIcon, CodeLineIcon, CodeSSlashLineIcon, DoubleQuotesLIcon, EmotionLineIcon, ErrorWarningFillIcon, FlowChartIcon, FormulaIcon, FunctionsIcon, ImageLineIcon, Information2FillIcon, Information2LineIcon, MenuFold2FillIcon, MovieLineIcon, Music2LineIcon, SeparatorIcon, SquareRootIcon, Table2Icon, UserSmileFillIcon, WindowFillIcon } from "../../Icons";
5
5
  import Menu from "../../Menu";
6
6
  import ToolbarItem from "../Item";
7
7
  import TableSizePicker from "../TableSizePicker";
@@ -145,6 +145,17 @@ var EditorInsert = function EditorInsert(_ref) {
145
145
  size: '0'
146
146
  });
147
147
  }
148
+ }, {
149
+ label: '流程图',
150
+ key: 'flow',
151
+ icon: /*#__PURE__*/React.createElement(FlowChartIcon, {
152
+ sx: {
153
+ fontSize: '1rem'
154
+ }
155
+ }),
156
+ onClick: function onClick() {
157
+ return editor.commands.setFlow({});
158
+ }
148
159
  }, {
149
160
  label: '表格',
150
161
  key: 'table',
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { AttachmentLineIcon, CodeBoxLineIcon, CodeLineIcon, DoubleQuotesLIcon, EmotionLineIcon, FunctionsIcon, H1Icon, H2Icon, H3Icon, H4Icon, H5Icon, H6Icon, ImageLineIcon, Information2LineIcon, LinkIcon, ListCheck2Icon, ListOrdered2Icon, ListUnorderedIcon, MenuFold2FillIcon, MovieLineIcon, Music2LineIcon, SeparatorIcon, SquareRootIcon, Table2Icon, TextWrapIcon, WindowFillIcon } from "../component/Icons";
2
+ import { AttachmentLineIcon, CodeBoxLineIcon, CodeLineIcon, DoubleQuotesLIcon, EmotionLineIcon, FlowChartIcon, FunctionsIcon, H1Icon, H2Icon, H3Icon, H4Icon, H5Icon, H6Icon, ImageLineIcon, Information2LineIcon, LinkIcon, ListCheck2Icon, ListOrdered2Icon, ListUnorderedIcon, MenuFold2FillIcon, MovieLineIcon, Music2LineIcon, SeparatorIcon, SquareRootIcon, Table2Icon, WindowFillIcon } from "../component/Icons";
3
3
  export var slashCommands = [{
4
4
  title: '标题1',
5
5
  shortcutKey: ['ctrl', 'alt', '1'],
@@ -130,8 +130,8 @@ export var slashCommands = [{
130
130
  editor.chain().focus().deleteRange(range).toggleTaskList().run();
131
131
  }
132
132
  }, {
133
- title: '换行',
134
- icon: /*#__PURE__*/React.createElement(TextWrapIcon, {
133
+ title: '表情',
134
+ icon: /*#__PURE__*/React.createElement(EmotionLineIcon, {
135
135
  sx: {
136
136
  fontSize: '1rem'
137
137
  }
@@ -139,18 +139,6 @@ export var slashCommands = [{
139
139
  command: function command(_ref10) {
140
140
  var editor = _ref10.editor,
141
141
  range = _ref10.range;
142
- editor.chain().focus().deleteRange(range).insertContent('<br />').run();
143
- }
144
- }, {
145
- title: '表情',
146
- icon: /*#__PURE__*/React.createElement(EmotionLineIcon, {
147
- sx: {
148
- fontSize: '1rem'
149
- }
150
- }),
151
- command: function command(_ref11) {
152
- var editor = _ref11.editor,
153
- range = _ref11.range;
154
142
  editor.chain().deleteRange(range).insertContentAt(range.from, ' : ').focus(range.from + 2).run();
155
143
  }
156
144
  }, {
@@ -160,9 +148,9 @@ export var slashCommands = [{
160
148
  fontSize: '1rem'
161
149
  }
162
150
  }),
163
- command: function command(_ref12) {
164
- var editor = _ref12.editor,
165
- range = _ref12.range;
151
+ command: function command(_ref11) {
152
+ var editor = _ref11.editor,
153
+ range = _ref11.range;
166
154
  editor.chain().focus().deleteRange(range).setHorizontalRule().run();
167
155
  }
168
156
  }, {
@@ -173,9 +161,9 @@ export var slashCommands = [{
173
161
  fontSize: '1rem'
174
162
  }
175
163
  }),
176
- command: function command(_ref13) {
177
- var editor = _ref13.editor,
178
- range = _ref13.range;
164
+ command: function command(_ref12) {
165
+ var editor = _ref12.editor,
166
+ range = _ref12.range;
179
167
  editor.chain().focus().deleteRange(range).toggleBlockquote().run();
180
168
  }
181
169
  }, {
@@ -186,9 +174,9 @@ export var slashCommands = [{
186
174
  fontSize: '1rem'
187
175
  }
188
176
  }),
189
- command: function command(_ref14) {
190
- var editor = _ref14.editor,
191
- range = _ref14.range;
177
+ command: function command(_ref13) {
178
+ var editor = _ref13.editor,
179
+ range = _ref13.range;
192
180
  editor.chain().focus().deleteRange(range).setMark('code').run();
193
181
  }
194
182
  }, {
@@ -199,9 +187,9 @@ export var slashCommands = [{
199
187
  fontSize: '1rem'
200
188
  }
201
189
  }),
202
- command: function command(_ref15) {
203
- var editor = _ref15.editor,
204
- range = _ref15.range;
190
+ command: function command(_ref14) {
191
+ var editor = _ref14.editor,
192
+ range = _ref14.range;
205
193
  editor.chain().focus().deleteRange(range).toggleCodeBlock().run();
206
194
  }
207
195
  }, {
@@ -212,9 +200,9 @@ export var slashCommands = [{
212
200
  fontSize: '1rem'
213
201
  }
214
202
  }),
215
- command: function command(_ref16) {
216
- var editor = _ref16.editor,
217
- range = _ref16.range;
203
+ command: function command(_ref15) {
204
+ var editor = _ref15.editor,
205
+ range = _ref15.range;
218
206
  editor.chain().focus().deleteRange(range).setInlineLink({
219
207
  href: ''
220
208
  }).run();
@@ -227,10 +215,25 @@ export var slashCommands = [{
227
215
  fontSize: '1rem'
228
216
  }
229
217
  }),
218
+ command: function command(_ref16) {
219
+ var editor = _ref16.editor,
220
+ range = _ref16.range;
221
+ editor.chain().focus().deleteRange(range).setDetails().run();
222
+ }
223
+ }, {
224
+ title: '流程图',
225
+ icon: /*#__PURE__*/React.createElement(FlowChartIcon, {
226
+ sx: {
227
+ fontSize: '1rem'
228
+ }
229
+ }),
230
230
  command: function command(_ref17) {
231
231
  var editor = _ref17.editor,
232
232
  range = _ref17.range;
233
- editor.chain().focus().deleteRange(range).setDetails().run();
233
+ editor.chain().focus().deleteRange(range).setFlow({
234
+ code: '',
235
+ width: '100%'
236
+ }).run();
234
237
  }
235
238
  }, {
236
239
  title: 'iframe',
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { FlowAttributes } from ".";
3
+ type EditFlowProps = {
4
+ anchorEl: HTMLDivElement | null;
5
+ attrs: FlowAttributes;
6
+ updateAttributes: (attrs: FlowAttributes) => void;
7
+ onCancel: () => void;
8
+ };
9
+ declare const EditFlow: ({ anchorEl, attrs, updateAttributes, onCancel, }: EditFlowProps) => React.JSX.Element;
10
+ export default EditFlow;
@@ -0,0 +1,97 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { FloatingPopover } from "../../../component/FloatingPopover";
8
+ import { Button, Stack, TextField } from "@mui/material";
9
+ import React, { useEffect, useMemo, useState } from "react";
10
+ var EditFlow = function EditFlow(_ref) {
11
+ var anchorEl = _ref.anchorEl,
12
+ attrs = _ref.attrs,
13
+ updateAttributes = _ref.updateAttributes,
14
+ onCancel = _ref.onCancel;
15
+ var _useState = useState(attrs.code || ''),
16
+ _useState2 = _slicedToArray(_useState, 2),
17
+ editCode = _useState2[0],
18
+ setEditCode = _useState2[1];
19
+
20
+ // 当 attrs.code 更新时,同步更新 editCode
21
+ useEffect(function () {
22
+ setEditCode(attrs.code || '');
23
+ }, [attrs.code]);
24
+
25
+ // 创建虚拟元素,表示 flow-wrapper 的中心点
26
+ var centerVirtualElement = useMemo(function () {
27
+ if (!anchorEl) return null;
28
+ return {
29
+ getBoundingClientRect: function getBoundingClientRect() {
30
+ // 每次调用时重新计算,确保位置实时更新
31
+ var rect = anchorEl.getBoundingClientRect();
32
+ var centerX = rect.left + rect.width / 2;
33
+ var centerY = rect.top + rect.height / 2;
34
+ return {
35
+ width: 0,
36
+ height: 0,
37
+ x: centerX,
38
+ y: centerY,
39
+ top: centerY,
40
+ left: centerX,
41
+ right: centerX,
42
+ bottom: centerY
43
+ };
44
+ }
45
+ };
46
+ }, [anchorEl]);
47
+ var handleSaveFlow = function handleSaveFlow() {
48
+ var trimmedCode = editCode.trim();
49
+ if (!trimmedCode) return;
50
+ updateAttributes({
51
+ code: trimmedCode
52
+ });
53
+ onCancel();
54
+ };
55
+ return /*#__PURE__*/React.createElement(FloatingPopover, {
56
+ open: true,
57
+ anchorEl: centerVirtualElement,
58
+ onClose: onCancel,
59
+ placement: "top",
60
+ style: {
61
+ transform: 'translate(-50%, 0)'
62
+ }
63
+ }, /*#__PURE__*/React.createElement(Stack, {
64
+ gap: 2,
65
+ sx: {
66
+ p: 2,
67
+ width: 600
68
+ }
69
+ }, /*#__PURE__*/React.createElement(TextField, {
70
+ fullWidth: true,
71
+ multiline: true,
72
+ rows: 12,
73
+ value: editCode,
74
+ onChange: function onChange(e) {
75
+ return setEditCode(e.target.value);
76
+ },
77
+ placeholder: "\u8F93\u5165 Mermaid \u6D41\u7A0B\u56FE\u4EE3\u7801",
78
+ sx: {
79
+ '& .MuiInputBase-input': {
80
+ fontFamily: 'monospace',
81
+ fontSize: '0.875rem'
82
+ }
83
+ }
84
+ }), /*#__PURE__*/React.createElement(Stack, {
85
+ direction: "row",
86
+ gap: 1
87
+ }, /*#__PURE__*/React.createElement(Button, {
88
+ variant: "outlined",
89
+ fullWidth: true,
90
+ onClick: onCancel
91
+ }, "\u53D6\u6D88"), /*#__PURE__*/React.createElement(Button, {
92
+ variant: "contained",
93
+ fullWidth: true,
94
+ onClick: handleSaveFlow
95
+ }, "\u4FDD\u5B58"))));
96
+ };
97
+ export default EditFlow;
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import { FlowAttributes } from ".";
3
+ type InsertFlowProps = {
4
+ updateAttributes: (attrs: FlowAttributes) => void;
5
+ };
6
+ declare const InsertFlow: ({ updateAttributes, }: InsertFlowProps) => React.JSX.Element;
7
+ export default InsertFlow;
@@ -0,0 +1,108 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { FloatingPopover } from "../../../component/FloatingPopover";
8
+ import { FlowChartIcon } from "../../../component/Icons";
9
+ import { Box, Button, Stack, TextField } from "@mui/material";
10
+ import { NodeViewWrapper } from "@tiptap/react";
11
+ import React, { useState } from "react";
12
+ var InsertFlow = function InsertFlow(_ref) {
13
+ var updateAttributes = _ref.updateAttributes;
14
+ var _useState = useState(''),
15
+ _useState2 = _slicedToArray(_useState, 2),
16
+ editCode = _useState2[0],
17
+ setEditCode = _useState2[1];
18
+ var _useState3 = useState(null),
19
+ _useState4 = _slicedToArray(_useState3, 2),
20
+ anchorEl = _useState4[0],
21
+ setAnchorEl = _useState4[1];
22
+ var handleShowPopover = function handleShowPopover(event) {
23
+ return setAnchorEl(event.currentTarget);
24
+ };
25
+ var handleClosePopover = function handleClosePopover() {
26
+ return setAnchorEl(null);
27
+ };
28
+ var handleInsertFlow = function handleInsertFlow() {
29
+ var trimmedCode = editCode.trim();
30
+ if (!trimmedCode) return;
31
+ updateAttributes({
32
+ code: trimmedCode,
33
+ width: '100%'
34
+ });
35
+ handleClosePopover();
36
+ };
37
+ return /*#__PURE__*/React.createElement(NodeViewWrapper, {
38
+ className: "flow-wrapper",
39
+ "data-drag-handle": true
40
+ }, /*#__PURE__*/React.createElement(Stack, {
41
+ direction: 'row',
42
+ alignItems: 'center',
43
+ gap: 2,
44
+ onClick: handleShowPopover,
45
+ sx: {
46
+ border: '1px dashed',
47
+ borderColor: 'divider',
48
+ borderRadius: 'var(--mui-shape-borderRadius)',
49
+ px: 2,
50
+ py: 1.5,
51
+ minWidth: 200,
52
+ textAlign: 'center',
53
+ color: 'text.secondary',
54
+ bgcolor: 'action.default',
55
+ cursor: 'pointer',
56
+ '&:hover': {
57
+ bgcolor: 'action.hover'
58
+ },
59
+ '&:active': {
60
+ bgcolor: 'action.selected'
61
+ }
62
+ }
63
+ }, /*#__PURE__*/React.createElement(FlowChartIcon, {
64
+ sx: {
65
+ fontSize: '1rem',
66
+ position: 'relative',
67
+ flexShrink: 0
68
+ }
69
+ }), /*#__PURE__*/React.createElement(Box, {
70
+ sx: {
71
+ fontSize: '0.875rem',
72
+ position: 'relative',
73
+ flexGrow: 1,
74
+ textAlign: 'left'
75
+ }
76
+ }, "\u70B9\u51FB\u6B64\u5904\u5D4C\u5165\u6216\u7C98\u8D34\u6D41\u7A0B\u56FE\u4EE3\u7801")), /*#__PURE__*/React.createElement(FloatingPopover, {
77
+ open: Boolean(anchorEl),
78
+ anchorEl: anchorEl,
79
+ onClose: handleClosePopover,
80
+ placement: "bottom"
81
+ }, /*#__PURE__*/React.createElement(Stack, {
82
+ gap: 2,
83
+ sx: {
84
+ p: 2,
85
+ width: 600
86
+ }
87
+ }, /*#__PURE__*/React.createElement(TextField, {
88
+ fullWidth: true,
89
+ multiline: true,
90
+ rows: 12,
91
+ value: editCode,
92
+ onChange: function onChange(e) {
93
+ return setEditCode(e.target.value);
94
+ },
95
+ placeholder: "\u8F93\u5165 Mermaid \u6D41\u7A0B\u56FE\u4EE3\u7801",
96
+ sx: {
97
+ '& .MuiInputBase-input': {
98
+ fontFamily: 'monospace',
99
+ fontSize: '0.875rem'
100
+ }
101
+ }
102
+ }), /*#__PURE__*/React.createElement(Button, {
103
+ variant: "contained",
104
+ fullWidth: true,
105
+ onClick: handleInsertFlow
106
+ }, "\u63D0\u4EA4"))));
107
+ };
108
+ export default InsertFlow;
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import { FlowAttributes } from ".";
3
+ interface ReadonlyFlowProps {
4
+ attrs: FlowAttributes;
5
+ onError?: (error: Error) => void;
6
+ }
7
+ declare const ReadonlyFlow: ({ attrs, onError }: ReadonlyFlowProps) => React.JSX.Element | null;
8
+ export default ReadonlyFlow;
@@ -0,0 +1,65 @@
1
+ import { Box } from "@mui/material";
2
+ import { NodeViewWrapper } from "@tiptap/react";
3
+ import React from "react";
4
+ import { useMermaidRender } from "./useMermaidRender";
5
+ var ReadonlyFlow = function ReadonlyFlow(_ref) {
6
+ var attrs = _ref.attrs,
7
+ onError = _ref.onError;
8
+ var _useMermaidRender = useMermaidRender({
9
+ code: attrs.code,
10
+ onError: onError,
11
+ showLoading: false,
12
+ idPrefix: 'mermaid-readonly'
13
+ }),
14
+ svgContent = _useMermaidRender.svgContent,
15
+ error = _useMermaidRender.error;
16
+ if (!attrs.code || attrs.code.trim() === '') {
17
+ return null;
18
+ }
19
+ return /*#__PURE__*/React.createElement(NodeViewWrapper, {
20
+ className: "flow-wrapper"
21
+ }, /*#__PURE__*/React.createElement(Box, {
22
+ sx: {
23
+ position: 'relative',
24
+ display: 'inline-block',
25
+ border: '1px solid',
26
+ borderColor: 'divider',
27
+ borderRadius: 'var(--mui-shape-borderRadius)',
28
+ width: attrs.width || '100%',
29
+ height: 'auto'
30
+ }
31
+ }, /*#__PURE__*/React.createElement(Box, {
32
+ sx: {
33
+ width: '100%',
34
+ height: '100%',
35
+ minHeight: '200px',
36
+ display: 'flex',
37
+ alignItems: 'center',
38
+ justifyContent: 'center',
39
+ bgcolor: 'background.default',
40
+ borderRadius: 'var(--mui-shape-borderRadius)'
41
+ }
42
+ }, error && /*#__PURE__*/React.createElement(Box, {
43
+ sx: {
44
+ color: 'error.main',
45
+ padding: '20px',
46
+ textAlign: 'center',
47
+ fontSize: '14px'
48
+ }
49
+ }, error), svgContent && !error && /*#__PURE__*/React.createElement(Box, {
50
+ dangerouslySetInnerHTML: {
51
+ __html: svgContent
52
+ },
53
+ sx: {
54
+ width: '100%',
55
+ display: 'flex',
56
+ alignItems: 'center',
57
+ justifyContent: 'center',
58
+ '& svg': {
59
+ maxWidth: '100%',
60
+ height: 'auto'
61
+ }
62
+ }
63
+ }))));
64
+ };
65
+ export default ReadonlyFlow;
@@ -0,0 +1,9 @@
1
+ import { EditorFnProps } from "../../../type";
2
+ import { NodeViewProps } from '@tiptap/react';
3
+ import React from "react";
4
+ export interface FlowAttributes {
5
+ code: string;
6
+ width?: string | number;
7
+ }
8
+ declare const FlowViewWrapper: React.FC<NodeViewProps & EditorFnProps>;
9
+ export default FlowViewWrapper;
@@ -0,0 +1,354 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { DeleteLineIcon, EditLineIcon } from "../../../component/Icons";
8
+ import { ToolbarItem } from "../../../component/Toolbar";
9
+ import { alpha, Box, Stack, useTheme } from "@mui/material";
10
+ import { NodeViewWrapper } from '@tiptap/react';
11
+ import React, { useCallback, useEffect, useRef, useState } from "react";
12
+ import { HoverPopover } from "../../../component/HoverPopover";
13
+ import EditFlow from "./Edit";
14
+ import InsertFlow from "./Insert";
15
+ import ReadonlyFlow from "./Readonly";
16
+ import { useMermaidRender } from "./useMermaidRender";
17
+ var FlowViewWrapper = function FlowViewWrapper(_ref) {
18
+ var editor = _ref.editor,
19
+ node = _ref.node,
20
+ _updateAttributes = _ref.updateAttributes,
21
+ deleteNode = _ref.deleteNode,
22
+ selected = _ref.selected,
23
+ onError = _ref.onError;
24
+ var attrs = node.attrs;
25
+ var theme = useTheme();
26
+ var _useState = useState(false),
27
+ _useState2 = _slicedToArray(_useState, 2),
28
+ isHovering = _useState2[0],
29
+ setIsHovering = _useState2[1];
30
+ var _useState3 = useState(false),
31
+ _useState4 = _slicedToArray(_useState3, 2),
32
+ isEditing = _useState4[0],
33
+ setIsEditing = _useState4[1];
34
+ var _useState5 = useState(false),
35
+ _useState6 = _slicedToArray(_useState5, 2),
36
+ isDragging = _useState6[0],
37
+ setIsDragging = _useState6[1];
38
+ var _useState7 = useState(null),
39
+ _useState8 = _slicedToArray(_useState7, 2),
40
+ dragCorner = _useState8[0],
41
+ setDragCorner = _useState8[1];
42
+ var dragStartXRef = useRef(0);
43
+ var dragStartWidthRef = useRef(0);
44
+ var flowWrapperRef = useRef(null);
45
+ var flowContentRef = useRef(null);
46
+
47
+ // 获取当前实际显示的流程图宽度
48
+ var getCurrentDisplayWidth = function getCurrentDisplayWidth() {
49
+ if (flowWrapperRef.current) {
50
+ return flowWrapperRef.current.offsetWidth;
51
+ }
52
+ // 如果 ref 不存在,使用容器宽度计算
53
+ var containerWidth = 800;
54
+ return getPixelValue(attrs.width, containerWidth);
55
+ };
56
+
57
+ // 将 width 转换为像素值
58
+ var getPixelValue = function getPixelValue(value, containerSize) {
59
+ var defaultPercent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100;
60
+ if (!value) return containerSize * (defaultPercent / 100);
61
+ if (typeof value === 'number') return value;
62
+ if (typeof value === 'string') {
63
+ if (value.endsWith('%')) {
64
+ var percent = parseFloat(value);
65
+ return containerSize * (percent / 100);
66
+ }
67
+ if (value.endsWith('px')) {
68
+ return parseFloat(value);
69
+ }
70
+ return parseFloat(value) || containerSize * (defaultPercent / 100);
71
+ }
72
+ return containerSize * (defaultPercent / 100);
73
+ };
74
+
75
+ // 将像素值转换回字符串格式
76
+ var formatValue = function formatValue(pixels, original) {
77
+ if (typeof original === 'string' && original.endsWith('%')) {
78
+ var _flowWrapperRef$curre;
79
+ // 如果原来是百分比,保持百分比格式
80
+ var containerWidth = ((_flowWrapperRef$curre = flowWrapperRef.current) === null || _flowWrapperRef$curre === void 0 || (_flowWrapperRef$curre = _flowWrapperRef$curre.parentElement) === null || _flowWrapperRef$curre === void 0 ? void 0 : _flowWrapperRef$curre.clientWidth) || 800;
81
+ var percent = Math.round(pixels / containerWidth * 100);
82
+ return "".concat(percent, "%");
83
+ }
84
+ return Math.round(pixels);
85
+ };
86
+ var handleMouseDown = function handleMouseDown(e, corner) {
87
+ e.preventDefault();
88
+ e.stopPropagation();
89
+ setIsDragging(true);
90
+ setDragCorner(corner);
91
+ dragStartXRef.current = e.clientX;
92
+ dragStartWidthRef.current = getCurrentDisplayWidth();
93
+ };
94
+ var handleMouseMove = useCallback(function (e) {
95
+ if (!isDragging || !dragCorner) return;
96
+ var deltaX = e.clientX - dragStartXRef.current;
97
+ var newWidth;
98
+
99
+ // 根据不同的角计算宽度变化
100
+ if (dragCorner === 'top-right' || dragCorner === 'bottom-right') {
101
+ // 右侧角:向右拉伸,宽度增加
102
+ newWidth = dragStartWidthRef.current + deltaX;
103
+ } else {
104
+ // 左侧角:向左拉伸,宽度增加(deltaX 为负时宽度增加)
105
+ newWidth = dragStartWidthRef.current - deltaX;
106
+ }
107
+ newWidth = Math.max(200, Math.min(1920, newWidth));
108
+ _updateAttributes({
109
+ width: formatValue(newWidth, attrs.width),
110
+ code: attrs.code
111
+ });
112
+ }, [isDragging, dragCorner, attrs.width, _updateAttributes]);
113
+ var handleMouseUp = useCallback(function () {
114
+ setIsDragging(false);
115
+ setDragCorner(null);
116
+ }, []);
117
+ useEffect(function () {
118
+ if (isDragging) {
119
+ document.addEventListener('mousemove', handleMouseMove);
120
+ document.addEventListener('mouseup', handleMouseUp);
121
+ return function () {
122
+ document.removeEventListener('mousemove', handleMouseMove);
123
+ document.removeEventListener('mouseup', handleMouseUp);
124
+ };
125
+ }
126
+ }, [isDragging, handleMouseMove, handleMouseUp]);
127
+ var handleShowPopover = function handleShowPopover() {
128
+ return setIsEditing(true);
129
+ };
130
+ if (!editor.isEditable) {
131
+ return /*#__PURE__*/React.createElement(ReadonlyFlow, {
132
+ attrs: attrs,
133
+ onError: onError
134
+ });
135
+ }
136
+ if (!attrs.code || attrs.code.trim() === '') {
137
+ return /*#__PURE__*/React.createElement(InsertFlow, {
138
+ updateAttributes: _updateAttributes
139
+ });
140
+ }
141
+ return /*#__PURE__*/React.createElement(NodeViewWrapper, {
142
+ className: "flow-wrapper ".concat(selected ? 'ProseMirror-selectednode' : '')
143
+ }, /*#__PURE__*/React.createElement(Box, {
144
+ ref: flowContentRef,
145
+ sx: {
146
+ position: 'relative'
147
+ },
148
+ onMouseEnter: function onMouseEnter() {
149
+ return setIsHovering(true);
150
+ },
151
+ onMouseLeave: function onMouseLeave() {
152
+ return setIsHovering(false);
153
+ }
154
+ }, /*#__PURE__*/React.createElement(Box, {
155
+ ref: flowWrapperRef,
156
+ sx: {
157
+ position: 'relative',
158
+ border: '2px solid',
159
+ borderColor: isHovering || isDragging ? alpha(theme.palette.primary.main, 0.3) : 'transparent',
160
+ borderRadius: 'var(--mui-shape-borderRadius)',
161
+ bgcolor: 'background.paper',
162
+ width: attrs.width || '100%',
163
+ height: 'auto',
164
+ transition: 'border-color 0.2s ease'
165
+ }
166
+ }, /*#__PURE__*/React.createElement(HoverPopover, {
167
+ style: {
168
+ width: '100%'
169
+ },
170
+ actions: /*#__PURE__*/React.createElement(Stack, {
171
+ direction: 'row',
172
+ alignItems: 'center',
173
+ sx: {
174
+ p: 0.5
175
+ }
176
+ }, /*#__PURE__*/React.createElement(ToolbarItem, {
177
+ icon: /*#__PURE__*/React.createElement(EditLineIcon, {
178
+ sx: {
179
+ fontSize: '1rem'
180
+ }
181
+ }),
182
+ tip: "\u7F16\u8F91\u6D41\u7A0B\u56FE",
183
+ onClick: handleShowPopover
184
+ }), /*#__PURE__*/React.createElement(ToolbarItem, {
185
+ icon: /*#__PURE__*/React.createElement(DeleteLineIcon, {
186
+ sx: {
187
+ fontSize: '1rem'
188
+ }
189
+ }),
190
+ tip: "\u5220\u9664\u6D41\u7A0B\u56FE",
191
+ onClick: deleteNode
192
+ })),
193
+ placement: "top",
194
+ offset: 4
195
+ }, /*#__PURE__*/React.createElement(Box, {
196
+ sx: {
197
+ width: '100%',
198
+ height: '100%',
199
+ minHeight: '200px',
200
+ display: 'flex',
201
+ alignItems: 'center',
202
+ justifyContent: 'center',
203
+ bgcolor: 'background.default',
204
+ borderRadius: 'var(--mui-shape-borderRadius)'
205
+ }
206
+ }, /*#__PURE__*/React.createElement(FlowDiagram, {
207
+ key: attrs.code,
208
+ code: attrs.code,
209
+ onError: onError
210
+ })), (isHovering || isDragging) && !isEditing && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Box, {
211
+ onMouseDown: function onMouseDown(e) {
212
+ return handleMouseDown(e, 'top-left');
213
+ },
214
+ sx: {
215
+ position: 'absolute',
216
+ left: -4,
217
+ top: -4,
218
+ width: 12,
219
+ height: 12,
220
+ bgcolor: 'background.default',
221
+ cursor: 'nwse-resize',
222
+ borderRadius: '50%',
223
+ border: '2px solid',
224
+ borderColor: isDragging && dragCorner === 'top-left' ? 'primary.main' : alpha(theme.palette.primary.main, 0.3),
225
+ '&:hover': {
226
+ borderColor: 'primary.main'
227
+ },
228
+ transition: 'background-color 0.2s ease',
229
+ zIndex: 10
230
+ }
231
+ }), /*#__PURE__*/React.createElement(Box, {
232
+ onMouseDown: function onMouseDown(e) {
233
+ return handleMouseDown(e, 'top-right');
234
+ },
235
+ sx: {
236
+ position: 'absolute',
237
+ right: -4,
238
+ top: -4,
239
+ width: 12,
240
+ height: 12,
241
+ bgcolor: 'background.default',
242
+ cursor: 'nesw-resize',
243
+ borderRadius: '50%',
244
+ border: '2px solid',
245
+ borderColor: isDragging && dragCorner === 'top-right' ? 'primary.main' : alpha(theme.palette.primary.main, 0.3),
246
+ '&:hover': {
247
+ borderColor: 'primary.main'
248
+ },
249
+ transition: 'background-color 0.2s ease',
250
+ zIndex: 10
251
+ }
252
+ }), /*#__PURE__*/React.createElement(Box, {
253
+ onMouseDown: function onMouseDown(e) {
254
+ return handleMouseDown(e, 'bottom-left');
255
+ },
256
+ sx: {
257
+ position: 'absolute',
258
+ left: -4,
259
+ bottom: -2,
260
+ width: 12,
261
+ height: 12,
262
+ cursor: 'nesw-resize',
263
+ borderRadius: '50%',
264
+ border: '2px solid',
265
+ bgcolor: 'background.default',
266
+ borderColor: isDragging && dragCorner === 'bottom-left' ? 'primary.main' : alpha(theme.palette.primary.main, 0.3),
267
+ '&:hover': {
268
+ borderColor: 'primary.main'
269
+ },
270
+ transition: 'background-color 0.2s ease',
271
+ zIndex: 10
272
+ }
273
+ }), /*#__PURE__*/React.createElement(Box, {
274
+ onMouseDown: function onMouseDown(e) {
275
+ return handleMouseDown(e, 'bottom-right');
276
+ },
277
+ sx: {
278
+ position: 'absolute',
279
+ right: -4,
280
+ bottom: -2,
281
+ width: 12,
282
+ height: 12,
283
+ bgcolor: 'background.default',
284
+ cursor: 'nwse-resize',
285
+ borderRadius: '50%',
286
+ border: '2px solid',
287
+ borderColor: isDragging && dragCorner === 'bottom-right' ? 'primary.main' : alpha(theme.palette.primary.main, 0.3),
288
+ '&:hover': {
289
+ borderColor: 'primary.main'
290
+ },
291
+ transition: 'background-color 0.2s ease',
292
+ zIndex: 10
293
+ }
294
+ }))))), isEditing && /*#__PURE__*/React.createElement(EditFlow, {
295
+ anchorEl: flowContentRef.current,
296
+ attrs: attrs,
297
+ updateAttributes: function updateAttributes(newAttrs) {
298
+ _updateAttributes(newAttrs);
299
+ setIsEditing(false);
300
+ },
301
+ onCancel: function onCancel() {
302
+ return setIsEditing(false);
303
+ }
304
+ }));
305
+ };
306
+ var FlowDiagram = function FlowDiagram(_ref2) {
307
+ var code = _ref2.code,
308
+ onError = _ref2.onError;
309
+ var _useMermaidRender = useMermaidRender({
310
+ code: code,
311
+ onError: onError,
312
+ showLoading: true,
313
+ idPrefix: 'mermaid'
314
+ }),
315
+ svgContent = _useMermaidRender.svgContent,
316
+ error = _useMermaidRender.error,
317
+ loading = _useMermaidRender.loading;
318
+ return /*#__PURE__*/React.createElement(Box, {
319
+ sx: {
320
+ width: '100%',
321
+ minHeight: loading ? '100px' : 'auto',
322
+ display: 'flex',
323
+ alignItems: 'center',
324
+ justifyContent: 'center',
325
+ '& svg': {
326
+ maxWidth: '100%',
327
+ height: 'auto'
328
+ }
329
+ }
330
+ }, loading && !error && /*#__PURE__*/React.createElement(Box, {
331
+ sx: {
332
+ color: 'text.secondary',
333
+ fontSize: '14px'
334
+ }
335
+ }, "\u6B63\u5728\u6E32\u67D3..."), error && /*#__PURE__*/React.createElement(Box, {
336
+ sx: {
337
+ color: 'error.main',
338
+ padding: '20px',
339
+ textAlign: 'center',
340
+ fontSize: '14px'
341
+ }
342
+ }, error), svgContent && !error && /*#__PURE__*/React.createElement(Box, {
343
+ dangerouslySetInnerHTML: {
344
+ __html: svgContent
345
+ },
346
+ sx: {
347
+ width: '100%',
348
+ display: 'flex',
349
+ alignItems: 'center',
350
+ justifyContent: 'center'
351
+ }
352
+ }));
353
+ };
354
+ export default FlowViewWrapper;
@@ -0,0 +1,16 @@
1
+ interface UseMermaidRenderOptions {
2
+ code: string;
3
+ onError?: (error: Error) => void;
4
+ showLoading?: boolean;
5
+ idPrefix?: string;
6
+ }
7
+ interface UseMermaidRenderReturn {
8
+ svgContent: string;
9
+ error: string | null;
10
+ loading: boolean;
11
+ }
12
+ /**
13
+ * 自定义 Hook:处理 Mermaid 流程图渲染
14
+ */
15
+ export declare const useMermaidRender: ({ code, onError, showLoading, idPrefix, }: UseMermaidRenderOptions) => UseMermaidRenderReturn;
16
+ export {};
@@ -0,0 +1,138 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
5
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
9
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
11
+ import mermaid from 'mermaid';
12
+ import { useEffect, useRef, useState } from 'react';
13
+ import { extractSvgFromResult, generateMermaidId, initMermaid } from "./utils";
14
+ /**
15
+ * 自定义 Hook:处理 Mermaid 流程图渲染
16
+ */
17
+ export var useMermaidRender = function useMermaidRender(_ref) {
18
+ var code = _ref.code,
19
+ onError = _ref.onError,
20
+ _ref$showLoading = _ref.showLoading,
21
+ showLoading = _ref$showLoading === void 0 ? true : _ref$showLoading,
22
+ _ref$idPrefix = _ref.idPrefix,
23
+ idPrefix = _ref$idPrefix === void 0 ? 'mermaid' : _ref$idPrefix;
24
+ var _useState = useState(''),
25
+ _useState2 = _slicedToArray(_useState, 2),
26
+ svgContent = _useState2[0],
27
+ setSvgContent = _useState2[1];
28
+ var _useState3 = useState(null),
29
+ _useState4 = _slicedToArray(_useState3, 2),
30
+ error = _useState4[0],
31
+ setError = _useState4[1];
32
+ var _useState5 = useState(showLoading),
33
+ _useState6 = _slicedToArray(_useState5, 2),
34
+ loading = _useState6[0],
35
+ setLoading = _useState6[1];
36
+ var renderIdRef = useRef(null);
37
+ var rafIdRef = useRef(null);
38
+ useEffect(function () {
39
+ if (!code || !code.trim()) {
40
+ setLoading(false);
41
+ setSvgContent('');
42
+ setError(null);
43
+ return;
44
+ }
45
+
46
+ // 初始化 mermaid
47
+ initMermaid();
48
+ var id = generateMermaidId(idPrefix);
49
+ renderIdRef.current = id;
50
+ setLoading(showLoading);
51
+ setError(null);
52
+ setSvgContent('');
53
+ var isCancelled = false;
54
+ var renderMermaid = /*#__PURE__*/function () {
55
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
56
+ var codeToRender, result, svg, errorMessage;
57
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
58
+ while (1) switch (_context.prev = _context.next) {
59
+ case 0:
60
+ _context.prev = 0;
61
+ if (!isCancelled) {
62
+ _context.next = 3;
63
+ break;
64
+ }
65
+ return _context.abrupt("return");
66
+ case 3:
67
+ codeToRender = code.trim();
68
+ _context.next = 6;
69
+ return mermaid.render(id, codeToRender);
70
+ case 6:
71
+ result = _context.sent;
72
+ svg = extractSvgFromResult(result);
73
+ if (!isCancelled) {
74
+ _context.next = 10;
75
+ break;
76
+ }
77
+ return _context.abrupt("return");
78
+ case 10:
79
+ if (!(svg && svg.length > 0)) {
80
+ _context.next = 16;
81
+ break;
82
+ }
83
+ setSvgContent(svg);
84
+ setError(null);
85
+ setLoading(false);
86
+ _context.next = 17;
87
+ break;
88
+ case 16:
89
+ throw new Error('渲染结果为空,请检查流程图代码是否正确');
90
+ case 17:
91
+ _context.next = 28;
92
+ break;
93
+ case 19:
94
+ _context.prev = 19;
95
+ _context.t0 = _context["catch"](0);
96
+ if (!isCancelled) {
97
+ _context.next = 23;
98
+ break;
99
+ }
100
+ return _context.abrupt("return");
101
+ case 23:
102
+ errorMessage = _context.t0.message || '流程图渲染失败';
103
+ setError(errorMessage);
104
+ setLoading(false);
105
+ setSvgContent('');
106
+ onError === null || onError === void 0 || onError(_context.t0);
107
+ case 28:
108
+ case "end":
109
+ return _context.stop();
110
+ }
111
+ }, _callee, null, [[0, 19]]);
112
+ }));
113
+ return function renderMermaid() {
114
+ return _ref2.apply(this, arguments);
115
+ };
116
+ }();
117
+
118
+ // 使用 requestAnimationFrame 确保 DOM 已准备好
119
+ rafIdRef.current = requestAnimationFrame(function () {
120
+ if (!isCancelled) {
121
+ renderMermaid();
122
+ }
123
+ });
124
+ return function () {
125
+ isCancelled = true;
126
+ if (rafIdRef.current !== null) {
127
+ cancelAnimationFrame(rafIdRef.current);
128
+ rafIdRef.current = null;
129
+ }
130
+ renderIdRef.current = null;
131
+ };
132
+ }, [code, onError, showLoading, idPrefix]);
133
+ return {
134
+ svgContent: svgContent,
135
+ error: error,
136
+ loading: loading
137
+ };
138
+ };
@@ -0,0 +1,9 @@
1
+ export declare const initMermaid: () => void;
2
+ /**
3
+ * 生成唯一的 mermaid 渲染 ID
4
+ */
5
+ export declare const generateMermaidId: (prefix?: string) => string;
6
+ /**
7
+ * 从 mermaid 渲染结果中提取 SVG
8
+ */
9
+ export declare const extractSvgFromResult: (result: any) => string;
@@ -0,0 +1,32 @@
1
+ import mermaid from 'mermaid';
2
+
3
+ /**
4
+ * 初始化 mermaid(只执行一次)
5
+ */
6
+ var mermaidInitialized = false;
7
+ export var initMermaid = function initMermaid() {
8
+ if (!mermaidInitialized) {
9
+ mermaid.initialize({
10
+ startOnLoad: false,
11
+ theme: 'default',
12
+ securityLevel: 'loose',
13
+ fontFamily: 'inherit'
14
+ });
15
+ mermaidInitialized = true;
16
+ }
17
+ };
18
+
19
+ /**
20
+ * 生成唯一的 mermaid 渲染 ID
21
+ */
22
+ export var generateMermaidId = function generateMermaidId() {
23
+ var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'mermaid';
24
+ return "".concat(prefix, "-").concat(Date.now(), "-").concat(Math.random().toString(36).substr(2, 9));
25
+ };
26
+
27
+ /**
28
+ * 从 mermaid 渲染结果中提取 SVG
29
+ */
30
+ export var extractSvgFromResult = function extractSvgFromResult(result) {
31
+ return result.svg || result.svgCode || '';
32
+ };
@@ -25,7 +25,7 @@ var SlashCommandsList = /*#__PURE__*/forwardRef(function (_ref, ref) {
25
25
  }, /*#__PURE__*/React.createElement(Stack, {
26
26
  direction: 'row',
27
27
  flexWrap: 'wrap'
28
- }, items.slice(0, 17).map(function (item, index) {
28
+ }, items.slice(0, 18).map(function (item, index) {
29
29
  return /*#__PURE__*/React.createElement(ToolbarItem, {
30
30
  key: index,
31
31
  shortcutKey: (item === null || item === void 0 ? void 0 : item.shortcutKey) || [],
@@ -15,7 +15,7 @@ import { PLACEHOLDER } from "../contants/placeholder";
15
15
  import { AiWritingExtension, SlashCommands, StructuredDiffExtension } from "./extension";
16
16
  import { CodeExtension } from "./mark/Code";
17
17
  import CustomLink from "./mark/Link";
18
- import { AlertExtension, AudioExtension, BlockAttachmentExtension, BlockLinkExtension, CodeBlockLowlightExtension, CustomBlockMathExtension, CustomHorizontalRule, CustomInlineMathExtension, CustomSubscript, CustomSuperscript, DetailsContentExtension, DetailsExtension, DetailsSummaryExtension, EmojiExtension, FileHandlerExtension, IframeExtension, ImageExtension, Indent, InlineAttachmentExtension, InlineLinkExtension, InlineUploadProgressExtension, ListExtension, MentionExtension, TableExtension, TableOfContents, UploadProgressExtension, VerticalAlign, VideoExtension, YamlFormat, YoutubeExtension } from "./node";
18
+ import { AlertExtension, AudioExtension, BlockAttachmentExtension, BlockLinkExtension, CodeBlockLowlightExtension, CustomBlockMathExtension, CustomHorizontalRule, CustomInlineMathExtension, CustomSubscript, CustomSuperscript, DetailsContentExtension, DetailsExtension, DetailsSummaryExtension, EmojiExtension, FileHandlerExtension, FlowExtension, IframeExtension, ImageExtension, Indent, InlineAttachmentExtension, InlineLinkExtension, InlineUploadProgressExtension, ListExtension, MentionExtension, TableExtension, TableOfContents, UploadProgressExtension, VerticalAlign, VideoExtension, YamlFormat, YoutubeExtension } from "./node";
19
19
  export var getExtensions = function getExtensions(_ref) {
20
20
  var contentType = _ref.contentType,
21
21
  limit = _ref.limit,
@@ -126,7 +126,7 @@ export var getExtensions = function getExtensions(_ref) {
126
126
  }
127
127
  if (!(exclude !== null && exclude !== void 0 && exclude.includes('indent'))) {
128
128
  defaultExtensions.push(Indent.configure({
129
- types: ['paragraph', 'heading', 'blockquote', 'alert', 'codeBlock', 'horizontalRule', 'orderedList', 'bulletList', 'taskList', 'taskItem', 'listItem', 'details', 'detailsContent', 'detailsSummary', 'table', 'image', 'video', 'audio', 'iframe', 'blockAttachment', 'inlineAttachment', 'blockLink', 'blockMath', 'inlineMath'],
129
+ types: ['paragraph', 'heading', 'blockquote', 'alert', 'codeBlock', 'horizontalRule', 'orderedList', 'bulletList', 'taskList', 'taskItem', 'listItem', 'details', 'detailsContent', 'detailsSummary', 'table', 'image', 'video', 'audio', 'iframe', 'flow', 'blockAttachment', 'inlineAttachment', 'blockLink', 'blockMath', 'inlineMath'],
130
130
  maxLevel: 8,
131
131
  indentPx: 32
132
132
  }));
@@ -169,6 +169,11 @@ export var getExtensions = function getExtensions(_ref) {
169
169
  var Youtube = YoutubeExtension(youtube);
170
170
  defaultExtensions.push(Youtube);
171
171
  }
172
+ if (!(exclude !== null && exclude !== void 0 && exclude.includes('flow'))) {
173
+ defaultExtensions.push(FlowExtension({
174
+ onError: onError
175
+ }));
176
+ }
172
177
  if (extensionsProps && extensionsProps.length > 0) {
173
178
  defaultExtensions.push.apply(defaultExtensions, _toConsumableArray(extensionsProps));
174
179
  }
@@ -35,6 +35,21 @@ var CustomCodeBlock = CodeBlockLowlight.configure({
35
35
  }
36
36
  });
37
37
  },
38
+ parseMarkdown: function parseMarkdown(token, helpers) {
39
+ var _token$raw;
40
+ if (((_token$raw = token.raw) === null || _token$raw === void 0 ? void 0 : _token$raw.startsWith('```')) === false && token.codeBlockStyle !== 'indented') {
41
+ return [];
42
+ }
43
+ if (token.lang === 'mermaid') {
44
+ return helpers.createNode('flow', {
45
+ code: token.text || '',
46
+ width: '100%'
47
+ }, []);
48
+ }
49
+ return helpers.createNode('codeBlock', {
50
+ language: token.lang || null
51
+ }, token.text ? [helpers.createTextNode(token.text)] : []);
52
+ },
38
53
  addNodeView: function addNodeView() {
39
54
  return ReactNodeViewRenderer(CodeBlockView);
40
55
  }
@@ -1,4 +1,4 @@
1
1
  import { UploadFunction } from "../../type";
2
2
  export declare const FileHandlerExtension: (props: {
3
3
  onUpload?: UploadFunction;
4
- }) => import("@tiptap/core").Extension<Omit<import("@tiptap/extension-file-handler").FileHandlePluginOptions, "key" | "editor">, any>;
4
+ }) => import("@tiptap/core").Extension<Omit<import("@tiptap/extension-file-handler").FileHandlePluginOptions, "editor" | "key">, any>;
@@ -0,0 +1,18 @@
1
+ import { EditorFnProps } from "../../../type";
2
+ import { Node } from '@tiptap/core';
3
+ declare module '@tiptap/core' {
4
+ interface Commands<ReturnType> {
5
+ flow: {
6
+ /**
7
+ * Insert a flow diagram
8
+ */
9
+ setFlow: (options: {
10
+ code?: string;
11
+ width?: string | number;
12
+ }) => ReturnType;
13
+ };
14
+ }
15
+ }
16
+ export type FlowExtensionProps = EditorFnProps;
17
+ export declare const FlowExtension: (props: FlowExtensionProps) => Node<any, any>;
18
+ export default FlowExtension;
@@ -0,0 +1,103 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ 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; }
3
+ 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; }
4
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ import { mergeAttributes, Node } from '@tiptap/core';
8
+ import { ReactNodeViewRenderer } from '@tiptap/react';
9
+ import FlowViewWrapper from "../../component/Flow";
10
+ export var FlowExtension = function FlowExtension(props) {
11
+ return Node.create({
12
+ name: 'flow',
13
+ group: 'block',
14
+ atom: true,
15
+ selectable: true,
16
+ draggable: true,
17
+ addAttributes: function addAttributes() {
18
+ return {
19
+ code: {
20
+ default: '',
21
+ parseHTML: function parseHTML(element) {
22
+ return element.getAttribute('data-code') || '';
23
+ },
24
+ renderHTML: function renderHTML(attributes) {
25
+ if (!attributes.code) return {};
26
+ return {
27
+ 'data-code': attributes.code
28
+ };
29
+ }
30
+ },
31
+ width: {
32
+ default: '100%',
33
+ parseHTML: function parseHTML(element) {
34
+ return element.getAttribute('data-width') || '100%';
35
+ },
36
+ renderHTML: function renderHTML(attributes) {
37
+ if (!attributes.width) return {};
38
+ return {
39
+ 'data-width': String(attributes.width)
40
+ };
41
+ }
42
+ }
43
+ };
44
+ },
45
+ parseHTML: function parseHTML() {
46
+ return [{
47
+ tag: 'div[data-type="flow"]',
48
+ getAttrs: function getAttrs(dom) {
49
+ if (!(dom instanceof HTMLElement)) return false;
50
+ var code = dom.getAttribute('data-code') || '';
51
+ var width = dom.getAttribute('data-width') || '100%';
52
+ return {
53
+ code: code,
54
+ width: width
55
+ };
56
+ }
57
+ }];
58
+ },
59
+ renderHTML: function renderHTML(_ref) {
60
+ var HTMLAttributes = _ref.HTMLAttributes,
61
+ node = _ref.node;
62
+ var attrs = node.attrs;
63
+ return ['div', mergeAttributes({
64
+ 'data-type': 'flow'
65
+ }, attrs.code ? {
66
+ 'data-code': attrs.code
67
+ } : {}, attrs.width ? {
68
+ 'data-width': String(attrs.width)
69
+ } : {}, this.options.HTMLAttributes, HTMLAttributes)];
70
+ },
71
+ renderMarkdown: function renderMarkdown(node) {
72
+ var _ref2 = node.attrs,
73
+ code = _ref2.code;
74
+ if (!code) return '';
75
+ return "```mermaid\n".concat(code, "\n```");
76
+ },
77
+ addCommands: function addCommands() {
78
+ var _this = this;
79
+ return {
80
+ setFlow: function setFlow(options) {
81
+ return function (_ref3) {
82
+ var commands = _ref3.commands;
83
+ return commands.insertContent({
84
+ type: _this.name,
85
+ attrs: {
86
+ code: options.code || '',
87
+ width: options.width || '100%'
88
+ }
89
+ });
90
+ };
91
+ }
92
+ };
93
+ },
94
+ addNodeView: function addNodeView() {
95
+ return ReactNodeViewRenderer(function (renderProps) {
96
+ return FlowViewWrapper(_objectSpread(_objectSpread({}, renderProps), {}, {
97
+ onError: props.onError
98
+ }));
99
+ });
100
+ }
101
+ });
102
+ };
103
+ export default FlowExtension;
@@ -5,6 +5,7 @@ export * from './CodeBlockLowlight';
5
5
  export * from './Details';
6
6
  export * from './Emoji';
7
7
  export * from './FileHandler';
8
+ export * from './Flow';
8
9
  export * from './HorizontalRule';
9
10
  export * from './Iframe';
10
11
  export * from './Image';
@@ -5,6 +5,7 @@ export * from "./CodeBlockLowlight";
5
5
  export * from "./Details";
6
6
  export * from "./Emoji";
7
7
  export * from "./FileHandler";
8
+ export * from "./Flow";
8
9
  export * from "./HorizontalRule";
9
10
  export * from "./Iframe";
10
11
  export * from "./Image";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctzhian/tiptap",
3
- "version": "1.12.23",
3
+ "version": "1.13.0",
4
4
  "description": "基于 Tiptap 二次开发的编辑器组件",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -121,6 +121,7 @@
121
121
  "katex": "^0.16.22",
122
122
  "linkifyjs": "^4.3.2",
123
123
  "lowlight": "^3.3.0",
124
+ "mermaid": "^10.9.5",
124
125
  "react-ace": "^14.0.1",
125
126
  "react-colorful": "^5.6.1",
126
127
  "react-image-crop": "^11.0.10",