@ctzhian/tiptap 2.0.0 → 2.1.1

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.
Files changed (68) hide show
  1. package/dist/Editor/demo.js +151 -123
  2. package/dist/EditorToolbar/index.js +11 -9
  3. package/dist/asset/css/index.css +7 -9
  4. package/dist/component/ActionDropdown/index.d.ts +5 -0
  5. package/dist/component/ActionDropdown/index.js +8 -3
  6. package/dist/component/FloatingPopover/index.d.ts +2 -2
  7. package/dist/component/HoverPopover/index.d.ts +2 -0
  8. package/dist/component/HoverPopover/index.js +22 -3
  9. package/dist/component/Icons/{expand-horizontal-line.js → expand-horizontal-line-icon.js} +1 -1
  10. package/dist/component/Icons/index.d.ts +8 -2
  11. package/dist/component/Icons/index.js +9 -3
  12. package/dist/component/Icons/skip-down-icon.d.ts +6 -0
  13. package/dist/component/Icons/skip-down-icon.js +13 -0
  14. package/dist/component/Icons/skip-left-icon.d.ts +6 -0
  15. package/dist/component/Icons/skip-left-icon.js +13 -0
  16. package/dist/component/Icons/skip-right-icon.d.ts +6 -0
  17. package/dist/component/Icons/skip-right-icon.js +13 -0
  18. package/dist/component/Icons/skip-up-icon.d.ts +6 -0
  19. package/dist/component/Icons/skip-up-icon.js +13 -0
  20. package/dist/component/Icons/volume-down-line-icon.d.ts +6 -0
  21. package/dist/component/Icons/volume-down-line-icon.js +13 -0
  22. package/dist/extension/component/Alert/index.js +141 -137
  23. package/dist/extension/component/Attachment/AttachmentContent.d.ts +0 -1
  24. package/dist/extension/component/Attachment/AttachmentContent.js +33 -8
  25. package/dist/extension/component/Attachment/index.js +21 -12
  26. package/dist/extension/component/Audio/AudioPlayer.d.ts +8 -0
  27. package/dist/extension/component/Audio/{Readonly.js → AudioPlayer.js} +129 -175
  28. package/dist/extension/component/Audio/index.js +93 -462
  29. package/dist/extension/component/Flow/Edit.d.ts +1 -1
  30. package/dist/extension/component/Flow/Edit.js +3 -31
  31. package/dist/extension/component/Flow/index.js +20 -19
  32. package/dist/extension/component/Image/index.d.ts +1 -0
  33. package/dist/extension/component/Image/index.js +16 -2
  34. package/dist/extension/component/Link/LinkContent.js +2 -0
  35. package/dist/extension/component/Link/index.js +1 -1
  36. package/dist/extension/component/TableCellHandleMenu/index.js +60 -3
  37. package/dist/extension/component/TableHandle/TableHandleAddButton.d.ts +14 -0
  38. package/dist/extension/component/TableHandle/TableHandleAddButton.js +87 -0
  39. package/dist/extension/component/TableHandle/TableHandleMenu.css +0 -1
  40. package/dist/extension/component/TableHandle/TableHandleMenu.js +7 -6
  41. package/dist/extension/component/TableHandle/index.js +53 -3
  42. package/dist/extension/component/TableSelectionOverlay/index.js +4 -12
  43. package/dist/extension/component/UploadProgress/index.d.ts +1 -1
  44. package/dist/extension/component/Video/Insert.js +4 -2
  45. package/dist/extension/component/Video/Readonly.js +4 -11
  46. package/dist/extension/component/Video/index.d.ts +2 -1
  47. package/dist/extension/component/Video/index.js +456 -65
  48. package/dist/extension/extension/ImeComposition.d.ts +2 -0
  49. package/dist/extension/extension/ImeComposition.js +145 -0
  50. package/dist/extension/extension/index.d.ts +1 -0
  51. package/dist/extension/extension/index.js +1 -0
  52. package/dist/extension/index.js +2 -2
  53. package/dist/extension/node/CodeBlockLowlight.js +3 -2
  54. package/dist/extension/node/Flow/index.d.ts +0 -3
  55. package/dist/extension/node/Flow/index.js +7 -4
  56. package/dist/extension/node/Link/index.js +4 -3
  57. package/dist/extension/node/Table.js +18 -82
  58. package/dist/extension/node/TableOfContents/index.d.ts +5 -3
  59. package/dist/extension/node/TableOfContents/index.js +22 -2
  60. package/dist/extension/node/Video.d.ts +1 -0
  61. package/dist/extension/node/Video.js +38 -6
  62. package/dist/hook/index.js +1 -1
  63. package/dist/index.css +17 -20
  64. package/dist/util/index.d.ts +9 -0
  65. package/dist/util/index.js +26 -0
  66. package/package.json +1 -1
  67. package/dist/extension/component/Audio/Readonly.d.ts +0 -8
  68. /package/dist/component/Icons/{expand-horizontal-line.d.ts → expand-horizontal-line-icon.d.ts} +0 -0
@@ -6,7 +6,7 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
6
6
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
7
  import { FloatingPopover } from "../../../component/FloatingPopover";
8
8
  import { Button, Stack, TextField } from "@mui/material";
9
- import React, { useEffect, useMemo, useState } from "react";
9
+ import React, { useEffect, useState } from "react";
10
10
  var EditFlow = function EditFlow(_ref) {
11
11
  var anchorEl = _ref.anchorEl,
12
12
  attrs = _ref.attrs,
@@ -16,34 +16,9 @@ var EditFlow = function EditFlow(_ref) {
16
16
  _useState2 = _slicedToArray(_useState, 2),
17
17
  editCode = _useState2[0],
18
18
  setEditCode = _useState2[1];
19
-
20
- // 当 attrs.code 更新时,同步更新 editCode
21
19
  useEffect(function () {
22
20
  setEditCode(attrs.code || '');
23
21
  }, [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
22
  var handleSaveFlow = function handleSaveFlow() {
48
23
  var trimmedCode = editCode.trim();
49
24
  if (!trimmedCode) return;
@@ -54,12 +29,9 @@ var EditFlow = function EditFlow(_ref) {
54
29
  };
55
30
  return /*#__PURE__*/React.createElement(FloatingPopover, {
56
31
  open: true,
57
- anchorEl: centerVirtualElement,
32
+ anchorEl: anchorEl,
58
33
  onClose: onCancel,
59
- placement: "top",
60
- style: {
61
- transform: 'translate(-50%, 0)'
62
- }
34
+ placement: "bottom"
63
35
  }, /*#__PURE__*/React.createElement(Stack, {
64
36
  gap: 2,
65
37
  sx: {
@@ -35,26 +35,26 @@ var FlowViewWrapper = function FlowViewWrapper(_ref) {
35
35
  _useState6 = _slicedToArray(_useState5, 2),
36
36
  isDragging = _useState6[0],
37
37
  setIsDragging = _useState6[1];
38
- var _useState7 = useState(null),
38
+ var _useState7 = useState(false),
39
39
  _useState8 = _slicedToArray(_useState7, 2),
40
- dragCorner = _useState8[0],
41
- setDragCorner = _useState8[1];
40
+ keepHoverPopoverOpen = _useState8[0],
41
+ setKeepHoverPopoverOpen = _useState8[1];
42
+ var _useState9 = useState(null),
43
+ _useState10 = _slicedToArray(_useState9, 2),
44
+ dragCorner = _useState10[0],
45
+ setDragCorner = _useState10[1];
42
46
  var dragStartXRef = useRef(0);
43
47
  var dragStartWidthRef = useRef(0);
44
48
  var flowWrapperRef = useRef(null);
45
49
  var flowContentRef = useRef(null);
46
-
47
- // 获取当前实际显示的流程图宽度
50
+ var editButtonRef = useRef(null);
48
51
  var getCurrentDisplayWidth = function getCurrentDisplayWidth() {
49
52
  if (flowWrapperRef.current) {
50
53
  return flowWrapperRef.current.offsetWidth;
51
54
  }
52
- // 如果 ref 不存在,使用容器宽度计算
53
55
  var containerWidth = 800;
54
56
  return getPixelValue(attrs.width, containerWidth);
55
57
  };
56
-
57
- // 将 width 转换为像素值
58
58
  var getPixelValue = function getPixelValue(value, containerSize) {
59
59
  var defaultPercent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100;
60
60
  if (!value) return containerSize * (defaultPercent / 100);
@@ -81,7 +81,7 @@ var FlowViewWrapper = function FlowViewWrapper(_ref) {
81
81
  var percent = Math.round(pixels / containerWidth * 100);
82
82
  return "".concat(percent, "%");
83
83
  }
84
- return Math.round(pixels);
84
+ return "".concat(Math.round(pixels), "px");
85
85
  };
86
86
  var handleMouseDown = function handleMouseDown(e, corner) {
87
87
  e.preventDefault();
@@ -95,13 +95,9 @@ var FlowViewWrapper = function FlowViewWrapper(_ref) {
95
95
  if (!isDragging || !dragCorner) return;
96
96
  var deltaX = e.clientX - dragStartXRef.current;
97
97
  var newWidth;
98
-
99
- // 根据不同的角计算宽度变化
100
98
  if (dragCorner === 'top-right' || dragCorner === 'bottom-right') {
101
- // 右侧角:向右拉伸,宽度增加
102
99
  newWidth = dragStartWidthRef.current + deltaX;
103
100
  } else {
104
- // 左侧角:向左拉伸,宽度增加(deltaX 为负时宽度增加)
105
101
  newWidth = dragStartWidthRef.current - deltaX;
106
102
  }
107
103
  newWidth = Math.max(200, Math.min(1920, newWidth));
@@ -125,7 +121,12 @@ var FlowViewWrapper = function FlowViewWrapper(_ref) {
125
121
  }
126
122
  }, [isDragging, handleMouseMove, handleMouseUp]);
127
123
  var handleShowPopover = function handleShowPopover() {
128
- return setIsEditing(true);
124
+ setKeepHoverPopoverOpen(true);
125
+ setIsEditing(true);
126
+ };
127
+ var handleEditCancel = function handleEditCancel() {
128
+ setIsEditing(false);
129
+ setKeepHoverPopoverOpen(false);
129
130
  };
130
131
  if (!editor.isEditable) {
131
132
  return /*#__PURE__*/React.createElement(ReadonlyFlow, {
@@ -167,6 +168,7 @@ var FlowViewWrapper = function FlowViewWrapper(_ref) {
167
168
  style: {
168
169
  width: '100%'
169
170
  },
171
+ keepOpen: keepHoverPopoverOpen,
170
172
  actions: /*#__PURE__*/React.createElement(Stack, {
171
173
  direction: 'row',
172
174
  alignItems: 'center',
@@ -174,6 +176,7 @@ var FlowViewWrapper = function FlowViewWrapper(_ref) {
174
176
  p: 0.5
175
177
  }
176
178
  }, /*#__PURE__*/React.createElement(ToolbarItem, {
179
+ ref: editButtonRef,
177
180
  icon: /*#__PURE__*/React.createElement(EditLineIcon, {
178
181
  sx: {
179
182
  fontSize: '1rem'
@@ -292,15 +295,13 @@ var FlowViewWrapper = function FlowViewWrapper(_ref) {
292
295
  zIndex: 10
293
296
  }
294
297
  }))))), isEditing && /*#__PURE__*/React.createElement(EditFlow, {
295
- anchorEl: flowContentRef.current,
298
+ anchorEl: editButtonRef.current,
296
299
  attrs: attrs,
297
300
  updateAttributes: function updateAttributes(newAttrs) {
298
301
  _updateAttributes(newAttrs);
299
- setIsEditing(false);
302
+ handleEditCancel();
300
303
  },
301
- onCancel: function onCancel() {
302
- return setIsEditing(false);
303
- }
304
+ onCancel: handleEditCancel
304
305
  }));
305
306
  };
306
307
  var FlowDiagram = function FlowDiagram(_ref2) {
@@ -1,6 +1,7 @@
1
1
  import { EditorFnProps } from "../../../type";
2
2
  import { NodeViewProps } from "@tiptap/react";
3
3
  import React from "react";
4
+ import 'react-photo-view/dist/react-photo-view.css';
4
5
  export interface ImageAttributes {
5
6
  src: string;
6
7
  title?: string;
@@ -14,6 +14,8 @@ import { ToolbarItem } from "../../../component/Toolbar";
14
14
  import { alpha, Box, Button, Divider, Stack, TextField, useTheme } from "@mui/material";
15
15
  import { NodeViewWrapper } from "@tiptap/react";
16
16
  import React, { useCallback, useEffect, useRef, useState } from "react";
17
+ import { PhotoView } from "react-photo-view";
18
+ import 'react-photo-view/dist/react-photo-view.css';
17
19
  import { HoverPopover } from "../../../component/HoverPopover";
18
20
  import CropImage from "./Crop";
19
21
  import InsertImage from "./Insert";
@@ -157,6 +159,15 @@ var ImageViewWrapper = function ImageViewWrapper(_ref) {
157
159
  dragStartXRef.current = e.clientX;
158
160
  dragStartWidthRef.current = getCurrentDisplayWidth();
159
161
  };
162
+ var handleImageClick = function handleImageClick(e) {
163
+ // 如果正在拖拽调整大小,阻止预览
164
+ if (isDragging || dragCorner) {
165
+ e.preventDefault();
166
+ e.stopPropagation();
167
+ return;
168
+ }
169
+ // 允许 PhotoView 处理点击事件进行预览
170
+ };
160
171
  var handleMouseMove = useCallback(function (e) {
161
172
  if (!isDragging || !dragCorner) return;
162
173
  var deltaX = e.clientX - dragStartXRef.current;
@@ -383,6 +394,8 @@ var ImageViewWrapper = function ImageViewWrapper(_ref) {
383
394
  onMouseLeave: function onMouseLeave() {
384
395
  return setIsHovering(false);
385
396
  }
397
+ }, /*#__PURE__*/React.createElement(PhotoView, {
398
+ src: attrs.src
386
399
  }, /*#__PURE__*/React.createElement("img", {
387
400
  ref: imageRef,
388
401
  src: attrs.src,
@@ -390,14 +403,15 @@ var ImageViewWrapper = function ImageViewWrapper(_ref) {
390
403
  style: {
391
404
  maxWidth: '100%',
392
405
  height: 'auto',
393
- cursor: 'default',
406
+ cursor: isDragging ? 'default' : 'pointer',
394
407
  border: '2px solid',
395
408
  borderColor: isHovering || isDragging ? alpha(theme.palette.primary.main, 0.3) : 'transparent'
396
409
  },
410
+ onClick: handleImageClick,
397
411
  onError: function onError(e) {
398
412
  _onError === null || _onError === void 0 || _onError(e);
399
413
  }
400
- }), (isHovering || isDragging) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Box, {
414
+ })), (isHovering || isDragging) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Box, {
401
415
  onMouseDown: function onMouseDown(e) {
402
416
  return handleMouseDown(e, 'top-left');
403
417
  },
@@ -22,6 +22,7 @@ export var LinkContent = function LinkContent(_ref) {
22
22
  border: '1px solid',
23
23
  borderColor: 'divider',
24
24
  cursor: 'pointer',
25
+ textAlign: 'left',
25
26
  borderRadius: 'var(--mui-shape-borderRadius)',
26
27
  p: 2,
27
28
  textDecoration: 'none',
@@ -39,6 +40,7 @@ export var LinkContent = function LinkContent(_ref) {
39
40
  borderColor: 'divider',
40
41
  color: 'text.primary',
41
42
  cursor: 'pointer',
43
+ textAlign: 'left',
42
44
  borderRadius: 'var(--mui-shape-borderRadius)',
43
45
  p: 2,
44
46
  ':hover': {
@@ -114,7 +114,7 @@ var LinkViewWrapper = function LinkViewWrapper(_ref) {
114
114
  fontSize: '1rem'
115
115
  }
116
116
  }),
117
- tip: "\u590D\u5236",
117
+ tip: "\u590D\u5236\u94FE\u63A5",
118
118
  onClick: handleCopyLink
119
119
  }), /*#__PURE__*/React.createElement(ToolbarItem, {
120
120
  icon: /*#__PURE__*/React.createElement(LinkUnlinkIcon, {
@@ -18,6 +18,7 @@ import { DeleteBack2LineIcon } from "../../../component/Icons/delete-back-2-line
18
18
  import { getThemeTextBgColor, getThemeTextColor } from "../../../contants/enums";
19
19
  import { Box, Divider, Typography } from '@mui/material';
20
20
  import { useTheme } from '@mui/material/styles';
21
+ import { TextSelection } from '@tiptap/pm/state';
21
22
  import { CellSelection, cellAround, deleteCellSelection, mergeCells, splitCell } from '@tiptap/pm/tables';
22
23
  import { useEditorState } from '@tiptap/react';
23
24
  import React, { forwardRef, useCallback, useEffect, useState } from 'react';
@@ -147,10 +148,66 @@ export var TableCellHandleMenu = /*#__PURE__*/forwardRef(function (_ref, ref) {
147
148
  }
148
149
  }),
149
150
  onClick: function onClick() {
151
+ if (!editor) return;
152
+ if (editor.state.storedMarks) {
153
+ var textStyleMarkType = editor.schema.marks.textStyle;
154
+ if (textStyleMarkType) {
155
+ editor.view.dispatch(editor.state.tr.removeStoredMark(textStyleMarkType));
156
+ }
157
+ }
150
158
  setTimeout(function () {
151
- editor.chain().focus().toggleMark('textStyle', {
152
- color: it.value
153
- }).run();
159
+ var _editor$state = editor.state,
160
+ selection = _editor$state.selection,
161
+ doc = _editor$state.doc;
162
+ var textStyleMark = editor.schema.marks.textStyle;
163
+ if (!textStyleMark) return;
164
+ if (selection instanceof CellSelection) {
165
+ var tr = editor.state.tr;
166
+ var hasContent = false;
167
+ selection.forEachCell(function (cellNode, cellPos) {
168
+ if (cellNode.content.size > 0) {
169
+ hasContent = true;
170
+ var from = cellPos + 1;
171
+ var to = cellPos + cellNode.nodeSize - 1;
172
+ if (from < to) {
173
+ var $from = doc.resolve(from);
174
+ var $to = doc.resolve(to);
175
+ var cellTextSelection = TextSelection.between($from, $to, 1);
176
+ if (cellTextSelection) {
177
+ var mark = textStyleMark.create({
178
+ color: it.value
179
+ });
180
+ tr.addMark(from, to, mark);
181
+ }
182
+ }
183
+ }
184
+ });
185
+ if (hasContent) {
186
+ editor.view.dispatch(tr);
187
+ editor.commands.focus();
188
+ }
189
+ } else {
190
+ var $anchor = selection.$anchor;
191
+ var cell = cellAround($anchor);
192
+ if (cell) {
193
+ var cellNode = doc.nodeAt(cell.pos);
194
+ if (cellNode && cellNode.content.size > 0) {
195
+ var from = cell.pos + 1;
196
+ var to = cell.pos + cellNode.nodeSize - 1;
197
+ if (from < to) {
198
+ var $from = doc.resolve(from);
199
+ var $to = doc.resolve(to);
200
+ var newSelection = TextSelection.between($from, $to, 1);
201
+ if (newSelection) {
202
+ editor.view.dispatch(editor.state.tr.setSelection(newSelection));
203
+ }
204
+ }
205
+ }
206
+ }
207
+ editor.chain().focus().toggleMark('textStyle', {
208
+ color: it.value
209
+ }).run();
210
+ }
154
211
  }, 0);
155
212
  }
156
213
  };
@@ -0,0 +1,14 @@
1
+ import type { Node } from '@tiptap/pm/model';
2
+ import type { Editor } from '@tiptap/react';
3
+ import React from 'react';
4
+ import type { Orientation } from '../../../util/table-utils';
5
+ interface TableHandleAddButtonProps {
6
+ editor?: Editor | null;
7
+ orientation: Orientation;
8
+ index?: number;
9
+ tableNode?: Node;
10
+ tablePos?: number;
11
+ direction: 'before' | 'after';
12
+ }
13
+ export declare const TableHandleAddButton: ({ editor, orientation, index, tableNode, tablePos, direction, }: TableHandleAddButtonProps) => React.JSX.Element | null;
14
+ export {};
@@ -0,0 +1,87 @@
1
+ import { SkipDownIcon, SkipLeftIcon, SkipRightIcon, SkipUpIcon } from "../../../component/Icons";
2
+ import { Box } from '@mui/material';
3
+ import { TableMap } from '@tiptap/pm/tables';
4
+ import React, { useCallback } from 'react';
5
+ import { selectCellsByCoords } from "../../../util/table-utils";
6
+ export var TableHandleAddButton = function TableHandleAddButton(_ref) {
7
+ var editor = _ref.editor,
8
+ orientation = _ref.orientation,
9
+ index = _ref.index,
10
+ tableNode = _ref.tableNode,
11
+ tablePos = _ref.tablePos,
12
+ direction = _ref.direction;
13
+ var handleClick = useCallback(function () {
14
+ if (!editor || !tableNode || typeof tablePos !== 'number' || typeof index !== 'number') {
15
+ return;
16
+ }
17
+ try {
18
+ // 先选中当前行/列
19
+ var _TableMap$get = TableMap.get(tableNode),
20
+ width = _TableMap$get.width,
21
+ height = _TableMap$get.height;
22
+ var start = orientation === 'row' ? {
23
+ row: index,
24
+ col: 0
25
+ } : {
26
+ row: 0,
27
+ col: index
28
+ };
29
+ var end = orientation === 'row' ? {
30
+ row: index,
31
+ col: width - 1
32
+ } : {
33
+ row: height - 1,
34
+ col: index
35
+ };
36
+
37
+ // 选中行/列
38
+ selectCellsByCoords(editor, tablePos, [start, end], {
39
+ mode: 'dispatch',
40
+ dispatch: editor.view.dispatch.bind(editor.view)
41
+ });
42
+
43
+ // 执行插入操作
44
+ if (orientation === 'row') {
45
+ editor.chain().focus()[direction === 'before' ? 'addRowBefore' : 'addRowAfter']().run();
46
+ } else {
47
+ editor.chain().focus()[direction === 'before' ? 'addColumnBefore' : 'addColumnAfter']().run();
48
+ }
49
+ } catch (error) {
50
+ console.warn('Failed to add row/column:', error);
51
+ }
52
+ }, [editor, orientation, index, tableNode, tablePos, direction]);
53
+ if (!(editor !== null && editor !== void 0 && editor.isEditable)) return null;
54
+ var iconStyle = {
55
+ width: '0.75rem',
56
+ height: '0.75rem',
57
+ flexShrink: 0
58
+ };
59
+ var Icon = orientation === 'row' ? direction === 'before' ? SkipUpIcon : SkipDownIcon : direction === 'before' ? SkipLeftIcon : SkipRightIcon;
60
+ var ariaLabel = orientation === 'row' ? direction === 'before' ? '上方插入行' : '下方插入行' : direction === 'before' ? '左侧插入列' : '右侧插入列';
61
+ return /*#__PURE__*/React.createElement(Box, {
62
+ component: "button",
63
+ onClick: handleClick,
64
+ sx: {
65
+ border: 'none',
66
+ display: 'flex',
67
+ alignItems: 'center',
68
+ justifyContent: 'center',
69
+ backgroundColor: 'var(--mui-palette-background-paper3)',
70
+ borderRadius: 'var(--mui-shape-borderRadius)',
71
+ cursor: 'pointer',
72
+ padding: 0,
73
+ width: orientation === 'row' ? '0.75rem' : '2rem',
74
+ height: '0.75rem',
75
+ transition: 'background-color 0.2s ease-in-out',
76
+ '&:hover': {
77
+ backgroundColor: 'var(--mui-palette-primary-main)',
78
+ '& .MuiSvgIcon-root': {
79
+ color: 'var(--mui-palette-common-white)'
80
+ }
81
+ }
82
+ },
83
+ "aria-label": ariaLabel
84
+ }, /*#__PURE__*/React.createElement(Icon, {
85
+ sx: iconStyle
86
+ }));
87
+ };
@@ -32,5 +32,4 @@
32
32
 
33
33
  .tiptap-table-handle-menu.column {
34
34
  height: 0.75rem;
35
- width: var(--table-handle-ref-width);
36
35
  }
@@ -534,7 +534,7 @@ export var TableHandleMenu = function TableHandleMenu(_ref) {
534
534
  my: 0.5
535
535
  }
536
536
  }),
537
- key: 'divider2'
537
+ key: 'divider3'
538
538
  }, {
539
539
  key: 'duplicate',
540
540
  label: orientation === 'row' ? '复制当前行' : '复制当前列',
@@ -615,7 +615,7 @@ export var TableHandleMenu = function TableHandleMenu(_ref) {
615
615
  }, []);
616
616
  var ariaLabel = orientation === 'row' ? 'Row actions' : 'Column actions';
617
617
  if (!(editor !== null && editor !== void 0 && editor.isEditable)) return null;
618
- var handleButton = /*#__PURE__*/React.createElement(Box, {
618
+ var menuButton = /*#__PURE__*/React.createElement(Box, {
619
619
  component: "button",
620
620
  className: "tiptap-table-handle-menu ".concat(isDragging ? 'is-dragging' : '', " ").concat(orientation),
621
621
  draggable: true,
@@ -634,11 +634,12 @@ export var TableHandleMenu = function TableHandleMenu(_ref) {
634
634
  padding: 0
635
635
  }, orientation === 'row' ? {
636
636
  width: '0.75rem',
637
- height: 'var(--table-handle-ref-height, 40px)'
637
+ height: '0.75rem'
638
638
  } : {
639
- height: '0.75rem',
640
- width: 'var(--table-handle-ref-width, 100px)'
639
+ width: '100%',
640
+ height: '0.75rem'
641
641
  }), {}, {
642
+ transition: 'background-color 0.2s ease-in-out',
642
643
  '&.is-dragging': {
643
644
  backgroundColor: 'var(--mui-palette-primary-main)',
644
645
  '& .MuiSvgIcon-root': {
@@ -663,7 +664,7 @@ export var TableHandleMenu = function TableHandleMenu(_ref) {
663
664
  }));
664
665
  return /*#__PURE__*/React.createElement(Menu, {
665
666
  width: 216,
666
- context: handleButton,
667
+ context: menuButton,
667
668
  list: menuList,
668
669
  anchorOrigin: {
669
670
  vertical: orientation === 'row' ? 'top' : 'bottom',
@@ -7,6 +7,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
7
  import { FloatingPortal } from '@floating-ui/react';
8
8
  import React, { useCallback, useMemo, useState } from 'react';
9
9
  import { colDragStart, rowDragStart } from "../../node/TableHandler/plugin";
10
+ import { TableHandleAddButton } from "./TableHandleAddButton";
10
11
  import { TableHandleMenu } from "./TableHandleMenu";
11
12
  import { useTableHandlePositioning } from "./use-table-handle-positioning";
12
13
  import { useTableHandleState } from "./use-table-handle-state";
@@ -63,7 +64,22 @@ export function TableHandle(_ref) {
63
64
  }, shouldShowRow && /*#__PURE__*/React.createElement("div", {
64
65
  ref: rowHandle.ref,
65
66
  style: rowHandle.style
66
- }, /*#__PURE__*/React.createElement(TableHandleMenu, {
67
+ }, /*#__PURE__*/React.createElement("div", {
68
+ style: {
69
+ display: 'flex',
70
+ flexDirection: 'column',
71
+ gap: '0.125rem',
72
+ width: '0.75rem',
73
+ height: 'var(--table-handle-ref-height, 40px)'
74
+ }
75
+ }, /*#__PURE__*/React.createElement(TableHandleAddButton, {
76
+ editor: editor,
77
+ orientation: "row",
78
+ index: state.rowIndex,
79
+ tablePos: state.blockPos,
80
+ tableNode: state.block,
81
+ direction: "before"
82
+ }), /*#__PURE__*/React.createElement(TableHandleMenu, {
67
83
  editor: editor,
68
84
  orientation: "row",
69
85
  index: state.rowIndex,
@@ -74,9 +90,36 @@ export function TableHandle(_ref) {
74
90
  onOpenChange: function onOpenChange(open) {
75
91
  return handleMenuOpenChange('row', open);
76
92
  }
77
- })), shouldShowColumn && /*#__PURE__*/React.createElement("div", {
93
+ }), /*#__PURE__*/React.createElement(TableHandleAddButton, {
94
+ editor: editor,
95
+ orientation: "row",
96
+ index: state.rowIndex,
97
+ tablePos: state.blockPos,
98
+ tableNode: state.block,
99
+ direction: "after"
100
+ }))), shouldShowColumn && /*#__PURE__*/React.createElement("div", {
78
101
  ref: colHandle.ref,
79
102
  style: colHandle.style
103
+ }, /*#__PURE__*/React.createElement("div", {
104
+ style: {
105
+ display: 'flex',
106
+ flexDirection: 'row',
107
+ gap: '0.125rem',
108
+ height: '0.75rem',
109
+ width: 'var(--table-handle-ref-width, 100px)'
110
+ }
111
+ }, /*#__PURE__*/React.createElement(TableHandleAddButton, {
112
+ editor: editor,
113
+ orientation: "column",
114
+ index: state.colIndex,
115
+ tablePos: state.blockPos,
116
+ tableNode: state.block,
117
+ direction: "before"
118
+ }), /*#__PURE__*/React.createElement("div", {
119
+ style: {
120
+ flex: 1,
121
+ minWidth: 0
122
+ }
80
123
  }, /*#__PURE__*/React.createElement(TableHandleMenu, {
81
124
  editor: editor,
82
125
  orientation: "column",
@@ -88,6 +131,13 @@ export function TableHandle(_ref) {
88
131
  onOpenChange: function onOpenChange(open) {
89
132
  return handleMenuOpenChange('column', open);
90
133
  }
91
- })));
134
+ })), /*#__PURE__*/React.createElement(TableHandleAddButton, {
135
+ editor: editor,
136
+ orientation: "column",
137
+ index: state.colIndex,
138
+ tablePos: state.blockPos,
139
+ tableNode: state.block,
140
+ direction: "after"
141
+ }))));
92
142
  }
93
143
  TableHandle.displayName = 'TableHandle';
@@ -34,6 +34,7 @@ var getCellAtCoordinates = function getCellAtCoordinates(state, view, x, y) {
34
34
  return cellAround($pos);
35
35
  };
36
36
  var getSelectionBoundingRect = function getSelectionBoundingRect(view, selection) {
37
+ if (!(selection instanceof CellSelection)) return null;
37
38
  var cells = [];
38
39
  selection.forEachCell(function (_node, pos) {
39
40
  var dom = view.nodeDOM(pos);
@@ -242,8 +243,7 @@ export var TableSelectionOverlay = function TableSelectionOverlay(_ref2) {
242
243
  var activeHandleRef = useRef(null);
243
244
  var containerRef = useRef(null);
244
245
  var _useFloating = useFloating({
245
- placement: 'top-start',
246
- strategy: 'absolute'
246
+ placement: 'top-start'
247
247
  }),
248
248
  refs = _useFloating.refs,
249
249
  floatingStyles = _useFloating.floatingStyles,
@@ -384,14 +384,7 @@ export var TableSelectionOverlay = function TableSelectionOverlay(_ref2) {
384
384
  }, [editor, updateSelectionRect, updateTableDom]);
385
385
  useEffect(function () {
386
386
  var c = tableDom === null || tableDom === void 0 ? void 0 : tableDom.querySelector('.table-selection-overlay-container');
387
- if (!c) {
388
- // Try to find .table-controls as fallback
389
- var wrapper = tableDom === null || tableDom === void 0 ? void 0 : tableDom.closest('.tableWrapper');
390
- var controls = wrapper === null || wrapper === void 0 ? void 0 : wrapper.querySelector('.table-controls');
391
- containerRef.current = controls !== null && controls !== void 0 ? controls : null;
392
- } else {
393
- containerRef.current = c;
394
- }
387
+ containerRef.current = c !== null && c !== void 0 ? c : null;
395
388
  }, [tableDom]);
396
389
  if (!isVisible || !selectionRect) {
397
390
  return null;
@@ -412,9 +405,8 @@ export var TableSelectionOverlay = function TableSelectionOverlay(_ref2) {
412
405
  onResizeStart: createResizeHandler
413
406
  }));
414
407
  };
415
- var rootElement = containerRef.current || document.body;
416
408
  return /*#__PURE__*/React.createElement(FloatingPortal, {
417
- root: rootElement
409
+ root: containerRef.current
418
410
  }, /*#__PURE__*/React.createElement("div", {
419
411
  ref: refs.setFloating,
420
412
  style: _objectSpread(_objectSpread({}, floatingStyles), {}, {
@@ -7,6 +7,6 @@ export interface UploadProgressAttributes {
7
7
  tempId: string;
8
8
  }
9
9
  export declare const getFileIcon: (fileType: string) => React.JSX.Element;
10
- export declare const getFileTypeText: (fileType: string) => "音频" | "图片" | "视频" | "文件";
10
+ export declare const getFileTypeText: (fileType: string) => "图片" | "视频" | "音频" | "文件";
11
11
  declare const UploadProgressView: React.FC<NodeViewProps>;
12
12
  export default UploadProgressView;
@@ -85,7 +85,8 @@ var InsertVideo = function InsertVideo(_ref) {
85
85
  autoplay: attrs.autoplay,
86
86
  loop: attrs.loop,
87
87
  muted: attrs.muted,
88
- poster: attrs.poster
88
+ poster: attrs.poster,
89
+ align: attrs.align
89
90
  });
90
91
  }
91
92
  _context.next = 15;
@@ -139,7 +140,8 @@ var InsertVideo = function InsertVideo(_ref) {
139
140
  autoplay: attrs.autoplay,
140
141
  loop: attrs.loop,
141
142
  muted: attrs.muted,
142
- poster: attrs.poster
143
+ poster: attrs.poster,
144
+ align: attrs.align
143
145
  });
144
146
  handleClosePopover();
145
147
  _context2.next = 15;
@@ -8,15 +8,7 @@ var ReadonlyVideo = function ReadonlyVideo(_ref) {
8
8
  className: "video-wrapper"
9
9
  }, /*#__PURE__*/React.createElement(Box, {
10
10
  sx: {
11
- position: 'relative',
12
- display: 'inline-block',
13
- border: '1px solid',
14
- borderColor: 'divider',
15
- borderRadius: 'var(--mui-shape-borderRadius)',
16
- p: '0.25rem',
17
- '&:hover .video-controls': {
18
- opacity: 1
19
- }
11
+ textAlign: attrs.align || undefined
20
12
  }
21
13
  }, /*#__PURE__*/React.createElement("video", {
22
14
  src: attrs.src,
@@ -25,11 +17,12 @@ var ReadonlyVideo = function ReadonlyVideo(_ref) {
25
17
  autoPlay: attrs.autoplay,
26
18
  loop: attrs.loop,
27
19
  muted: attrs.muted,
28
- width: attrs.width,
20
+ width: attrs.width || undefined,
29
21
  style: {
30
22
  maxWidth: '100%',
23
+ cursor: 'pointer',
31
24
  height: 'auto',
32
- display: 'block'
25
+ display: 'inline-block'
33
26
  },
34
27
  onError: function onError(e) {
35
28
  _onError === null || _onError === void 0 || _onError(e);