@ctzhian/tiptap 2.1.0 → 2.1.2

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 (34) hide show
  1. package/dist/Editor/demo.js +19 -1
  2. package/dist/EditorMarkdown/demo.js +7 -8
  3. package/dist/asset/css/index.css +2 -2
  4. package/dist/component/Icons/index.d.ts +5 -0
  5. package/dist/component/Icons/index.js +5 -0
  6. package/dist/component/Icons/skip-down-icon.d.ts +6 -0
  7. package/dist/component/Icons/skip-down-icon.js +13 -0
  8. package/dist/component/Icons/skip-left-icon.d.ts +6 -0
  9. package/dist/component/Icons/skip-left-icon.js +13 -0
  10. package/dist/component/Icons/skip-right-icon.d.ts +6 -0
  11. package/dist/component/Icons/skip-right-icon.js +13 -0
  12. package/dist/component/Icons/skip-up-icon.d.ts +6 -0
  13. package/dist/component/Icons/skip-up-icon.js +13 -0
  14. package/dist/component/Icons/volume-down-line-icon.d.ts +6 -0
  15. package/dist/component/Icons/volume-down-line-icon.js +13 -0
  16. package/dist/extension/component/Attachment/AttachmentContent.d.ts +0 -1
  17. package/dist/extension/component/Attachment/AttachmentContent.js +33 -8
  18. package/dist/extension/component/Attachment/index.js +21 -12
  19. package/dist/extension/component/Audio/AudioPlayer.d.ts +8 -0
  20. package/dist/extension/component/Audio/{Readonly.js → AudioPlayer.js} +129 -175
  21. package/dist/extension/component/Audio/index.js +93 -462
  22. package/dist/extension/component/Image/index.js +25 -9
  23. package/dist/extension/component/Link/LinkContent.js +2 -0
  24. package/dist/extension/component/TableHandle/TableHandleAddButton.d.ts +14 -0
  25. package/dist/extension/component/TableHandle/TableHandleAddButton.js +87 -0
  26. package/dist/extension/component/TableHandle/TableHandleMenu.css +0 -1
  27. package/dist/extension/component/TableHandle/TableHandleMenu.js +6 -5
  28. package/dist/extension/component/TableHandle/index.js +53 -3
  29. package/dist/extension/component/TableSelectionOverlay/index.js +1 -2
  30. package/dist/extension/component/Video/index.js +9 -0
  31. package/dist/extension/node/CodeBlockLowlight.js +3 -2
  32. package/dist/index.css +1 -1
  33. package/package.json +1 -1
  34. package/dist/extension/component/Audio/Readonly.d.ts +0 -8
@@ -139,18 +139,34 @@ var ImageViewWrapper = function ImageViewWrapper(_ref) {
139
139
  useEffect(function () {
140
140
  if (attrs.src && (!attrs.width || attrs.width <= 0)) {
141
141
  getImageDimensions(attrs.src).then(function (dimensions) {
142
- updateAttributes({
143
- src: attrs.src,
144
- width: dimensions.width
145
- });
142
+ try {
143
+ var pos = typeof getPos === 'function' ? getPos() : null;
144
+ if (pos === null || pos === undefined) return;
145
+ var currentNode = editor.state.doc.nodeAt(pos);
146
+ if (!currentNode || currentNode.type.name !== 'image') return;
147
+ updateAttributes({
148
+ src: attrs.src,
149
+ width: dimensions.width
150
+ });
151
+ } catch (error) {
152
+ console.warn('Failed to update image dimensions:', error);
153
+ }
146
154
  }).catch(function (error) {
147
- updateAttributes({
148
- src: attrs.src,
149
- width: 400
150
- });
155
+ try {
156
+ var pos = typeof getPos === 'function' ? getPos() : null;
157
+ if (pos === null || pos === undefined) return;
158
+ var currentNode = editor.state.doc.nodeAt(pos);
159
+ if (!currentNode || currentNode.type.name !== 'image') return;
160
+ updateAttributes({
161
+ src: attrs.src,
162
+ width: 400
163
+ });
164
+ } catch (updateError) {
165
+ console.warn('Failed to update image attributes with fallback width:', updateError);
166
+ }
151
167
  });
152
168
  }
153
- }, [attrs.src, attrs.width, updateAttributes]);
169
+ }, [attrs.src, attrs.width, updateAttributes, getPos, editor]);
154
170
  var handleMouseDown = function handleMouseDown(e, corner) {
155
171
  e.preventDefault();
156
172
  e.stopPropagation();
@@ -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': {
@@ -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
  }
@@ -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';
@@ -386,10 +386,9 @@ export var TableSelectionOverlay = function TableSelectionOverlay(_ref2) {
386
386
  var c = tableDom === null || tableDom === void 0 ? void 0 : tableDom.querySelector('.table-selection-overlay-container');
387
387
  containerRef.current = c !== null && c !== void 0 ? c : null;
388
388
  }, [tableDom]);
389
- if (!isVisible || !selectionRect) {
389
+ if (!isVisible || !selectionRect || !editor || !editor.isEditable) {
390
390
  return null;
391
391
  }
392
- if (!editor) return null;
393
392
  var renderCellMenu = function renderCellMenu() {
394
393
  if (!CellMenu) return null;
395
394
  return /*#__PURE__*/React.createElement("span", {
@@ -283,6 +283,15 @@ var VideoViewWrapper = function VideoViewWrapper(_ref) {
283
283
  video.click();
284
284
  document.body.removeChild(video);
285
285
  }
286
+ }), /*#__PURE__*/React.createElement(Divider, {
287
+ orientation: "vertical",
288
+ flexItem: true,
289
+ sx: {
290
+ height: '1rem',
291
+ mx: 0.5,
292
+ alignSelf: 'center',
293
+ borderColor: 'divider'
294
+ }
286
295
  }), /*#__PURE__*/React.createElement(ToolbarItem, {
287
296
  icon: /*#__PURE__*/React.createElement(AlignLeftIcon, {
288
297
  sx: {
@@ -36,8 +36,9 @@ var CustomCodeBlock = CodeBlockLowlight.configure({
36
36
  });
37
37
  },
38
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') {
39
+ var isFenced = token.codeBlockStyle === 'fenced' || token.raw && /^\s*```/.test(token.raw);
40
+ var isIndented = token.codeBlockStyle === 'indented';
41
+ if (!isFenced && !isIndented) {
41
42
  return [];
42
43
  }
43
44
  if (token.lang === 'mermaid') {
package/dist/index.css CHANGED
@@ -424,7 +424,7 @@
424
424
 
425
425
  .tiptap.ProseMirror table td>*,
426
426
  .tiptap.ProseMirror table th>* {
427
- margin-bottom: 0;
427
+ margin-bottom: 0 !important;
428
428
  }
429
429
 
430
430
  .tiptap.ProseMirror table th {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctzhian/tiptap",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "基于 Tiptap 二次开发的编辑器组件",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -1,8 +0,0 @@
1
- import React from "react";
2
- import { AudioAttributes } from ".";
3
- interface ReadonlyAudioProps {
4
- attrs: AudioAttributes;
5
- onError?: (error: Error) => void;
6
- }
7
- declare const ReadonlyAudio: ({ attrs, onError }: ReadonlyAudioProps) => React.JSX.Element;
8
- export default ReadonlyAudio;