@blocklet/editor 2.6.10 → 2.6.11
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.
|
@@ -4,11 +4,33 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
|
|
|
4
4
|
import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
|
|
5
5
|
import { $computeTableMapSkipCellCheck, $getTableNodeFromLexicalNodeOrThrow, $getTableRowIndexFromTableCellNode, $isTableCellNode, $isTableRowNode, getDOMCellFromTarget, getTableElement, TableNode, } from '@lexical/table';
|
|
6
6
|
import { calculateZoomLevel, mergeRegister } from '@lexical/utils';
|
|
7
|
-
import { $getNearestNodeFromDOMNode, isHTMLElement } from 'lexical';
|
|
7
|
+
import { $getNearestNodeFromDOMNode, isHTMLElement, SKIP_SCROLL_INTO_VIEW_TAG } from 'lexical';
|
|
8
8
|
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
9
9
|
import { createPortal } from 'react-dom';
|
|
10
10
|
const MIN_ROW_HEIGHT = 33;
|
|
11
11
|
const MIN_COLUMN_WIDTH = 92;
|
|
12
|
+
const DEFAULT_COLUMN_WIDTH = 150;
|
|
13
|
+
// 字符宽度估算常量
|
|
14
|
+
const CHAR_WIDTH_EN = 14; // 英文/数字字符宽度
|
|
15
|
+
const CHAR_WIDTH_CJK = 20; // 中日韩字符宽度
|
|
16
|
+
const CELL_PADDING = 24; // 单元格左右 padding
|
|
17
|
+
const MAX_COLUMN_WIDTH = 300; // 列宽上限,避免过宽
|
|
18
|
+
/**
|
|
19
|
+
* 估算文本的显示宽度(考虑中英文字符宽度差异)
|
|
20
|
+
*/
|
|
21
|
+
function estimateTextWidth(text) {
|
|
22
|
+
let width = 0;
|
|
23
|
+
for (const char of text) {
|
|
24
|
+
// CJK 字符范围(中日韩统一表意文字)
|
|
25
|
+
if (/[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]/.test(char)) {
|
|
26
|
+
width += CHAR_WIDTH_CJK;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
width += CHAR_WIDTH_EN;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return width;
|
|
33
|
+
}
|
|
12
34
|
function TableCellResizer({ editor }) {
|
|
13
35
|
const targetRef = useRef(null);
|
|
14
36
|
const resizerRef = useRef(null);
|
|
@@ -42,8 +64,37 @@ function TableCellResizer({ editor }) {
|
|
|
42
64
|
return tableNode;
|
|
43
65
|
}
|
|
44
66
|
const numColumns = tableNode.getColumnCount();
|
|
45
|
-
const
|
|
46
|
-
|
|
67
|
+
const rows = tableNode.getChildren();
|
|
68
|
+
// 计算每列的最大内容宽度
|
|
69
|
+
const columnMaxWidths = Array(numColumns).fill(0);
|
|
70
|
+
for (const row of rows) {
|
|
71
|
+
if ($isTableRowNode(row)) {
|
|
72
|
+
const cells = row.getChildren();
|
|
73
|
+
let colIndex = 0;
|
|
74
|
+
for (const cell of cells) {
|
|
75
|
+
if ($isTableCellNode(cell) && colIndex < numColumns) {
|
|
76
|
+
const text = cell.getTextContent();
|
|
77
|
+
const textWidth = estimateTextWidth(text);
|
|
78
|
+
// 考虑 colspan 的情况,将宽度平均分配
|
|
79
|
+
const colSpan = cell.getColSpan();
|
|
80
|
+
const widthPerCol = textWidth / colSpan;
|
|
81
|
+
for (let i = 0; i < colSpan && colIndex + i < numColumns; i++) {
|
|
82
|
+
columnMaxWidths[colIndex + i] = Math.max(columnMaxWidths[colIndex + i], widthPerCol);
|
|
83
|
+
}
|
|
84
|
+
colIndex += colSpan;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// 计算最终列宽:内容宽度 + padding,限制在 MIN 和 MAX 之间
|
|
90
|
+
const colWidths = columnMaxWidths.map((contentWidth) => {
|
|
91
|
+
if (contentWidth === 0) {
|
|
92
|
+
return DEFAULT_COLUMN_WIDTH; // 空列使用默认宽度
|
|
93
|
+
}
|
|
94
|
+
const calculatedWidth = contentWidth + CELL_PADDING;
|
|
95
|
+
return Math.min(Math.max(calculatedWidth, MIN_COLUMN_WIDTH), MAX_COLUMN_WIDTH);
|
|
96
|
+
});
|
|
97
|
+
tableNode.setColWidths(colWidths);
|
|
47
98
|
return tableNode;
|
|
48
99
|
}));
|
|
49
100
|
}, [editor]);
|
|
@@ -149,7 +200,7 @@ function TableCellResizer({ editor }) {
|
|
|
149
200
|
}
|
|
150
201
|
const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT);
|
|
151
202
|
tableRow.setHeight(newHeight);
|
|
152
|
-
}, { tag:
|
|
203
|
+
}, { tag: SKIP_SCROLL_INTO_VIEW_TAG });
|
|
153
204
|
}, [activeCell, editor]);
|
|
154
205
|
const getCellNodeHeight = (cell, activeEditor) => {
|
|
155
206
|
const domCellNode = activeEditor.getElementByKey(cell.getKey());
|
|
@@ -191,7 +242,7 @@ function TableCellResizer({ editor }) {
|
|
|
191
242
|
const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH);
|
|
192
243
|
newColWidths[columnIndex] = newWidth;
|
|
193
244
|
tableNode.setColWidths(newColWidths);
|
|
194
|
-
}, { tag:
|
|
245
|
+
}, { tag: SKIP_SCROLL_INTO_VIEW_TAG });
|
|
195
246
|
}, [activeCell, editor]);
|
|
196
247
|
const pointerUpHandler = useCallback((direction) => {
|
|
197
248
|
const handler = (event) => {
|
|
@@ -246,7 +297,6 @@ function TableCellResizer({ editor }) {
|
|
|
246
297
|
height: `${zoneWidth}px`,
|
|
247
298
|
left: `${window.scrollX + left}px`,
|
|
248
299
|
top: `${window.scrollY + top + height - zoneWidth / 2}px`,
|
|
249
|
-
zIndex: 1,
|
|
250
300
|
width: `${width}px`,
|
|
251
301
|
},
|
|
252
302
|
right: {
|
|
@@ -255,7 +305,6 @@ function TableCellResizer({ editor }) {
|
|
|
255
305
|
height: `${height}px`,
|
|
256
306
|
left: `${window.scrollX + left + width - zoneWidth / 2}px`,
|
|
257
307
|
top: `${window.scrollY + top}px`,
|
|
258
|
-
zIndex: 1,
|
|
259
308
|
width: `${zoneWidth}px`,
|
|
260
309
|
},
|
|
261
310
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/editor",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.11",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"ufo": "^1.5.4",
|
|
74
74
|
"url-join": "^4.0.1",
|
|
75
75
|
"zustand": "^4.5.5",
|
|
76
|
-
"@blocklet/pdf": "2.6.
|
|
76
|
+
"@blocklet/pdf": "2.6.11"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@babel/core": "^7.25.2",
|