@seafile/sdoc-editor 0.4.22 → 0.4.24

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 (23) hide show
  1. package/dist/basic-sdk/assets/css/dropdown-menu.css +1 -1
  2. package/dist/basic-sdk/constants/index.js +2 -1
  3. package/dist/basic-sdk/extension/plugins/callout/helper.js +1 -10
  4. package/dist/basic-sdk/extension/plugins/callout/render-elem/color-selector.js +18 -21
  5. package/dist/basic-sdk/extension/plugins/callout/render-elem/index.js +33 -32
  6. package/dist/basic-sdk/extension/plugins/table/constants/index.js +8 -1
  7. package/dist/basic-sdk/extension/plugins/table/helpers.js +104 -86
  8. package/dist/basic-sdk/extension/plugins/table/render/index.css +47 -1
  9. package/dist/basic-sdk/extension/plugins/table/render/index.js +27 -3
  10. package/dist/basic-sdk/extension/plugins/table/render/render-cell.js +22 -20
  11. package/dist/basic-sdk/extension/plugins/table/render/resize-handlers/column-resize-handler.js +25 -45
  12. package/dist/basic-sdk/extension/plugins/table/render/resize-handlers/first-column-left-resize-handler.js +21 -41
  13. package/dist/basic-sdk/extension/plugins/table/render/resize-handlers/index.js +44 -35
  14. package/dist/basic-sdk/extension/plugins/table/render/resize-handlers/row-resize-handler.js +22 -32
  15. package/dist/basic-sdk/extension/plugins/table/render/resize-mask/index.js +133 -0
  16. package/dist/basic-sdk/extension/plugins/table/render/table-header/rows-header/row-header.js +9 -15
  17. package/package.json +1 -1
  18. package/public/media/sdoc-editor-font/iconfont.eot +0 -0
  19. package/public/media/sdoc-editor-font/iconfont.svg +16 -2
  20. package/public/media/sdoc-editor-font/iconfont.ttf +0 -0
  21. package/public/media/sdoc-editor-font/iconfont.woff +0 -0
  22. package/public/media/sdoc-editor-font/iconfont.woff2 +0 -0
  23. package/public/media/sdoc-editor-font.css +38 -10
@@ -13,7 +13,7 @@
13
13
  }
14
14
 
15
15
  .sdoc-dropdown-menu .sdoc-dropdown-menu-item {
16
- height: 28px;
16
+ height: 30px;
17
17
  width: 100%;
18
18
  padding: 4px 24px;
19
19
  user-select: none;
@@ -16,7 +16,8 @@ export const INTERNAL_EVENT = {
16
16
  UNSEEN_NOTIFICATIONS_COUNT: 'unseen_notifications_count',
17
17
  CLOSE_CALLOUT_COLOR_PICKER: 'close_callout_color_picker',
18
18
  OPEN_SEARCH_REPLACE_MODAL: 'open_search_replace_modal',
19
- UPDATE_SEARCH_REPLACE_HIGHLIGHT: 'update_search_replace_highlight'
19
+ UPDATE_SEARCH_REPLACE_HIGHLIGHT: 'update_search_replace_highlight',
20
+ TABLE_CELL_MOUSE_ENTER: 'table_cell_mouse_enter'
20
21
  };
21
22
  export const REVISION_DIFF_KEY = 'diff';
22
23
  export const REVISION_DIFF_VALUE = '1';
@@ -1,6 +1,6 @@
1
1
  import { Editor, Node, Path, Transforms } from '@seafile/slate';
2
2
  import { CALL_OUT } from '../../constants/element-type';
3
- import { findPath, focusEditor, generateEmptyElement, getSelectedElems, isRangeAcrossBlocks } from '../../core';
3
+ import { focusEditor, generateEmptyElement, getSelectedElems, isRangeAcrossBlocks } from '../../core';
4
4
  import { CALLOUT_ALLOWED_INSIDE_TYPES, CALLOUT_COLOR_MAP } from './constant';
5
5
  export const isMenuActive = editor => {
6
6
  const {
@@ -91,15 +91,6 @@ export const getCalloutEntry = function (editor) {
91
91
  });
92
92
  return aboveNodeEntry;
93
93
  };
94
-
95
- // Use in render-elem, to judge whether to display placeholder
96
- export const isFocusOnElement = (editor, element) => {
97
- var _editor$selection, _editor$selection$anc;
98
- if (!editor.selection || !element) return false;
99
- const elementPath = findPath(editor, element);
100
- const isSelectOnElement = Path.isAncestor(elementPath, editor === null || editor === void 0 ? void 0 : (_editor$selection = editor.selection) === null || _editor$selection === void 0 ? void 0 : (_editor$selection$anc = _editor$selection.anchor) === null || _editor$selection$anc === void 0 ? void 0 : _editor$selection$anc.path);
101
- return isSelectOnElement;
102
- };
103
94
  export const isCalloutContentEmpty = calloutEntry => {
104
95
  const [calloutNode] = calloutEntry;
105
96
  const contentString = Node.string(calloutNode);
@@ -1,39 +1,34 @@
1
- import React, { forwardRef, useCallback, useImperativeHandle, useRef } from 'react';
1
+ import React, { useCallback } from 'react';
2
2
  import { Transforms } from '@seafile/slate';
3
3
  import { CALLOUT_COLOR_MAP } from '../constant';
4
4
  import { findPath } from '../../../core';
5
5
  import { changeFillBackgroundColor } from '../helper';
6
6
  import { ElementPopover } from '../../../commons';
7
7
  import './index.css';
8
- const ColorSelector = (_ref, ref) => {
8
+ const ColorSelector = _ref => {
9
9
  let {
10
10
  editor,
11
11
  element,
12
12
  popoverPosition
13
13
  } = _ref;
14
- const selectorRef = useRef(null);
15
- const handleClickColor = useCallback((editor, element, background_color) => {
14
+ const onColorClick = useCallback(event => {
15
+ const {
16
+ backgroundColor
17
+ } = event.target.dataset;
16
18
  const currentPath = findPath(editor, element);
17
19
  Transforms.select(editor, currentPath);
18
- changeFillBackgroundColor(editor, background_color);
19
- }, []);
20
- useImperativeHandle(ref, () => ({
21
- colorSelectorContainer: selectorRef.current
22
- }));
23
- const isShowCheckedIcon = useCallback((element, currentBackgroundColor) => {
20
+ changeFillBackgroundColor(editor, backgroundColor);
21
+ }, [editor, element]);
22
+ const isShowCheckedIcon = useCallback(currentBackgroundColor => {
24
23
  const {
25
24
  background_color
26
- } = element.style;
25
+ } = element.style || {};
27
26
  return background_color && background_color === currentBackgroundColor;
28
- }, []);
27
+ }, [element.style]);
29
28
  return /*#__PURE__*/React.createElement(ElementPopover, null, /*#__PURE__*/React.createElement("div", {
30
29
  className: "sdoc-callout-color-selector-container",
31
- ref: selectorRef,
32
30
  contentEditable: false,
33
- style: {
34
- top: popoverPosition.top,
35
- left: popoverPosition.left
36
- }
31
+ style: popoverPosition
37
32
  }, /*#__PURE__*/React.createElement("ul", {
38
33
  className: "sdoc-color-selector-list"
39
34
  }, Object.values(CALLOUT_COLOR_MAP).map((_ref2, index) => {
@@ -44,14 +39,16 @@ const ColorSelector = (_ref, ref) => {
44
39
  return /*#__PURE__*/React.createElement("li", {
45
40
  key: "sdoc-callout-color-selector-".concat(index),
46
41
  className: "sdoc-callout-color-item",
47
- onClick: () => handleClickColor(editor, element, Object.keys(CALLOUT_COLOR_MAP)[index]),
42
+ "data-border-color": border_color,
43
+ "data-background-color": background_color,
48
44
  style: {
49
45
  borderColor: border_color,
50
46
  backgroundColor: background_color
51
- }
52
- }, isShowCheckedIcon(element, background_color) && /*#__PURE__*/React.createElement("i", {
47
+ },
48
+ onClick: onColorClick
49
+ }, isShowCheckedIcon(background_color) && /*#__PURE__*/React.createElement("i", {
53
50
  className: "sdoc-callout-color-checked-icon sdocfont sdoc-check-mark"
54
51
  }));
55
52
  }))));
56
53
  };
57
- export default forwardRef(ColorSelector);
54
+ export default ColorSelector;
@@ -1,12 +1,10 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
- import React, { useCallback, useEffect, useRef, useState } from 'react';
3
- import { useReadOnly } from '@seafile/slate-react';
2
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import { Node } from '@seafile/slate';
4
+ import { useReadOnly, useSelected } from '@seafile/slate-react';
4
5
  import { useTranslation } from 'react-i18next';
5
6
  import ColorSelector from './color-selector';
6
7
  import { CALLOUT_COLOR_MAP } from '../constant';
7
- import { isFocusOnElement } from '../helper';
8
- import { Editor } from '@seafile/slate';
9
- import { findPath } from '../../../core';
10
8
  import { INTERNAL_EVENT } from '../../../../constants';
11
9
  import EventBus from '../../../../utils/event-bus';
12
10
  import { useScrollContext } from '../../../../hooks/use-scroll-context';
@@ -17,24 +15,40 @@ const renderCallout = (_ref, editor) => {
17
15
  children,
18
16
  element
19
17
  } = _ref;
20
- const [isShowColorSelector, setIsShowColorSelector] = useState(false);
21
- const [popoverPosition, setPopoverPosition] = useState({
22
- top: '',
23
- left: ''
24
- });
25
18
  const readOnly = useReadOnly();
26
19
  const scrollRef = useScrollContext();
27
- const calloutRef = useRef();
28
- const colorSelectorRef = useRef({
29
- colorSelectorContainer: null
30
- });
20
+ const isSelected = useSelected();
31
21
  const {
32
22
  t
33
23
  } = useTranslation();
34
- const {
35
- background_color
36
- } = element.style;
37
- const isFocusOnCallout = isFocusOnElement(editor, element);
24
+ const calloutRef = useRef();
25
+ const [isShowColorSelector, setIsShowColorSelector] = useState(false);
26
+ const [popoverPosition, setPopoverPosition] = useState({
27
+ top: '',
28
+ left: ''
29
+ });
30
+ const containerStyle = useMemo(() => {
31
+ const {
32
+ background_color = 'transparent'
33
+ } = element.style;
34
+ let borderColor = 'transparent';
35
+ if (isSelected) {
36
+ var _CALLOUT_COLOR_MAP$ba;
37
+ borderColor = (_CALLOUT_COLOR_MAP$ba = CALLOUT_COLOR_MAP[background_color]) === null || _CALLOUT_COLOR_MAP$ba === void 0 ? void 0 : _CALLOUT_COLOR_MAP$ba.border_color;
38
+ }
39
+ return {
40
+ backgroundColor: background_color,
41
+ borderColor
42
+ };
43
+ }, [element.style, isSelected]);
44
+ const isShowPlaceholder = useCallback(() => {
45
+ if (isSelected) return false;
46
+ // If element contains more than one element or element is not paragraph, show placeholder
47
+ const isContainUnitElement = element.children.length !== 1 || element.children.some(childElement => childElement.type !== 'paragraph');
48
+ if (isContainUnitElement) return false;
49
+ const elementContent = Node.string(element);
50
+ return !elementContent.length;
51
+ }, [element, isSelected]);
38
52
  const handleCloseColorSelector = useCallback(() => {
39
53
  setIsShowColorSelector(false);
40
54
  }, []);
@@ -87,15 +101,6 @@ const renderCallout = (_ref, editor) => {
87
101
  const handleClick = useCallback(e => {
88
102
  handleDisplayColorSelector();
89
103
  }, [handleDisplayColorSelector]);
90
- const isShowPlaceholder = useCallback(() => {
91
- if (isFocusOnCallout) return false;
92
- // If element contains more than one element or element is not paragraph, show placeholder
93
- const isContainUnitElement = element.children.length !== 1 || element.children.some(childElement => childElement.type !== 'paragraph');
94
- if (isContainUnitElement) return false;
95
- const elementPath = findPath(editor, element);
96
- const elementContent = Editor.string(editor, elementPath);
97
- return !elementContent.length;
98
- }, [editor, element, isFocusOnCallout]);
99
104
  return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
100
105
  "data-id": element.id,
101
106
  className: "sdoc-callout-white-wrapper",
@@ -104,15 +109,11 @@ const renderCallout = (_ref, editor) => {
104
109
  onClick: handleClick,
105
110
  ref: calloutRef,
106
111
  className: "".concat(attributes.className, " sdoc-callout-container"),
107
- style: {
108
- backgroundColor: background_color ? CALLOUT_COLOR_MAP[background_color].background_color : 'transparent',
109
- borderColor: isFocusOnCallout ? CALLOUT_COLOR_MAP[background_color].border_color : 'transparent'
110
- }
112
+ style: containerStyle
111
113
  }, children, isShowPlaceholder() && /*#__PURE__*/React.createElement("div", {
112
114
  contentEditable: false,
113
115
  className: "sdoc-callout-placeholder"
114
116
  }, t('Please_enter...')), isShowColorSelector && /*#__PURE__*/React.createElement(ColorSelector, {
115
- ref: colorSelectorRef,
116
117
  editor: editor,
117
118
  element: element,
118
119
  popoverPosition: popoverPosition
@@ -38,4 +38,11 @@ export const TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP = {
38
38
  'sdoc-table-header-0099f4': 'sdoc-table-body-0099f4'
39
39
  };
40
40
  export const INHERIT_CELL_STYLE_WHEN_SELECT_SINGLE = ['background_color'];
41
- export const INHERIT_CELL_STYLE_WHEN_SELECT_MULTIPLE = ['background_color', 'text_align'];
41
+ export const INHERIT_CELL_STYLE_WHEN_SELECT_MULTIPLE = ['background_color', 'text_align'];
42
+ export const RESIZE_MASK_TOP = 'top';
43
+ export const RESIZE_MASK_RIGHT = 'right';
44
+ export const RESIZE_MASK_BOTTOM = 'bottom';
45
+ export const RESIZE_MASK_LEFT = 'left';
46
+ export const RESIZE_HANDLER_ROW = 'row';
47
+ export const RESIZE_HANDLER_COLUMN = 'column';
48
+ export const RESIZE_HANDLER_FIRST_COLUMN = 'first_column';
@@ -1249,6 +1249,25 @@ export const getRowHeight = (element, rowIndex) => {
1249
1249
  const rowHeight = style[TABLE_ROW_STYLE.MIN_HEIGHT] || TABLE_ROW_MIN_HEIGHT;
1250
1250
  return rowIndex === 0 ? rowHeight + 1 : rowHeight;
1251
1251
  };
1252
+ export const getRowDomHeight = (editor, row) => {
1253
+ let height = 0;
1254
+ for (const cell of row.children) {
1255
+ const {
1256
+ is_combined,
1257
+ rowspan = 1
1258
+ } = cell;
1259
+ if (is_combined || rowspan > 1) continue;
1260
+ const cellDom = ReactEditor.toDOMNode(editor, cell);
1261
+ if (!cellDom) break;
1262
+ height = cellDom.getBoundingClientRect().height;
1263
+ break;
1264
+ }
1265
+ // if the row is empty, get the height from style
1266
+ if (!height) {
1267
+ height = row.style[TABLE_ROW_STYLE.MIN_HEIGHT] || TABLE_ROW_MIN_HEIGHT;
1268
+ }
1269
+ return height;
1270
+ };
1252
1271
  const normalizeTableCell = (editor, cell) => {
1253
1272
  if (!cell) return generateTableCell(editor);
1254
1273
  let newCell = _objectSpread({
@@ -1398,96 +1417,95 @@ export const getCellHighlightClassName = (primaryColorClassName, rowIndex) => {
1398
1417
  }
1399
1418
  return className;
1400
1419
  };
1401
- export const getRowBottomPositions = (editor, rows) => {
1402
- const recorder = [];
1403
- let bottomPosition = 0;
1404
- rows.forEach(row => {
1405
- let cellHeight;
1406
- row.children.forEach(cell => {
1407
- const currentCellHeight = ReactEditor.toDOMNode(editor, cell).getBoundingClientRect().height;
1408
- if (!cellHeight || currentCellHeight < cellHeight) cellHeight = currentCellHeight;
1409
- });
1410
- bottomPosition += cellHeight;
1411
- recorder.push(bottomPosition);
1412
- });
1413
- return recorder;
1420
+ export const focusClosestCellWhenJustifyCellSize = (editor, adjustingCell) => {
1421
+ const cellPath = ReactEditor.findPath(editor, adjustingCell);
1422
+ focusEditor(editor, Editor.end(editor, cellPath));
1414
1423
  };
1415
- export const focusClosestCellWhenJustifyCellSize = _ref => {
1416
- let {
1417
- editor,
1418
- rowIndex,
1419
- columnIndex,
1420
- table,
1421
- mouseDownInfo,
1422
- rowBottoms
1423
- } = _ref;
1424
- if (!editor) return;
1425
- const {
1426
- columns
1427
- } = table;
1428
- // Get cursor position in table, calculate columnIndex and rowIndex
1429
- const tableDom = ReactEditor.toDOMNode(editor, table);
1430
- const {
1431
- left,
1432
- top
1433
- } = tableDom.getBoundingClientRect();
1434
- const {
1435
- positionY,
1436
- positionX
1437
- } = mouseDownInfo;
1438
- const tableScrollWrapper = document.querySelector('.sdoc-table-scroll-wrapper');
1439
- const scrollX = tableScrollWrapper.scrollLeft;
1440
- const tableInnerX = positionX - left + scrollX;
1441
- const tableInnerY = positionY - top;
1442
- // Calculate columnIndex
1443
- if (columnIndex === undefined) {
1444
- let passedColumnsWidth = 0;
1445
- columns.some((_ref2, index) => {
1446
- let {
1447
- width
1448
- } = _ref2;
1449
- passedColumnsWidth += width;
1450
- if (passedColumnsWidth > tableInnerX) {
1451
- columnIndex = index;
1452
- return true;
1453
- }
1454
- return false;
1455
- });
1424
+ const searchCombinedMainCell = (table, startRowIndex, startColIndex) => {
1425
+ for (let rowIndex = startRowIndex; rowIndex >= 0; rowIndex--) {
1426
+ const row = table.children[rowIndex];
1427
+ for (let cellIndex = startColIndex; cellIndex >= 0; cellIndex--) {
1428
+ const currentCell = row.children[cellIndex];
1429
+ const {
1430
+ colspan = 0,
1431
+ rowspan = 0
1432
+ } = currentCell;
1433
+ if (colspan <= 1 && rowspan <= 1) continue;
1434
+ const isInColRange = cellIndex + colspan >= startColIndex;
1435
+ const isInRowRange = rowIndex + rowspan >= startRowIndex;
1436
+ if (isInColRange && isInRowRange) {
1437
+ return {
1438
+ currentCell,
1439
+ rowIndex,
1440
+ cellIndex
1441
+ };
1442
+ } else break;
1443
+ }
1456
1444
  }
1457
- // Calculate rowIndex
1458
- if (rowIndex === undefined) {
1459
- rowBottoms.some((bottom, index) => {
1460
- if (bottom >= tableInnerY) {
1461
- rowIndex = index;
1462
- return true;
1463
- }
1464
- return false;
1465
- });
1445
+ };
1446
+ export const getResizeMaskCellInfo = (editor, table, rowIndex, cellIndex) => {
1447
+ // The cell shown cursor as resize (mouse is on this cell)
1448
+ const focusCellIndex = cellIndex;
1449
+ let focusCell = table.children[rowIndex].children[cellIndex];
1450
+ // The cell dominating resize handlers (the true cell to be resized)
1451
+ let cell = table.children[rowIndex].children[cellIndex];
1452
+ // Resolve combined cell
1453
+ if (cell.is_combined) {
1454
+ const targetCellInfo = searchCombinedMainCell(table, rowIndex, cellIndex);
1455
+ cellIndex = targetCellInfo.cellIndex;
1456
+ rowIndex = targetCellInfo.rowIndex;
1457
+ cell = targetCellInfo.currentCell;
1466
1458
  }
1467
- // Correct focus position
1468
- const is_combined = table.children[rowIndex].children[columnIndex].is_combined;
1469
- if (is_combined) {
1470
- for (let i = columnIndex - 1; i >= 0; i--) {
1471
- const {
1472
- is_combined: ci_is_combined,
1473
- colspan: ci_colspan
1474
- } = table.children[rowIndex].children[i];
1475
- if (!ci_is_combined && ci_colspan && i + ci_colspan - 1 >= columnIndex) {
1476
- columnIndex = i;
1477
- break;
1478
- }
1459
+ const columns = table.columns;
1460
+ const focussedCell = ReactEditor.toDOMNode(editor, cell);
1461
+ const {
1462
+ colspan,
1463
+ rowspan
1464
+ } = focusCell;
1465
+ let width = columns[cellIndex].width;
1466
+ let height = focussedCell.getBoundingClientRect().height;
1467
+ // Calculate cell width and height
1468
+ if (colspan > 1) {
1469
+ let index = cellIndex + 1;
1470
+ while (index < cellIndex + colspan) {
1471
+ width += columns[index].width;
1472
+ index++;
1479
1473
  }
1480
- for (let j = rowIndex - 1; j >= 0; j--) {
1481
- const {
1482
- is_combined: ri_is_combined,
1483
- rowspan: ri_rowspan
1484
- } = table.children[j].children[columnIndex];
1485
- if (!ri_is_combined && ri_rowspan && j + ri_rowspan - 1 >= rowIndex) {
1486
- rowIndex = j;
1487
- break;
1488
- }
1474
+ }
1475
+ if (rowspan > 1) {
1476
+ let index = rowIndex + 1;
1477
+ while (index < rowIndex + rowspan) {
1478
+ const currentCell = table.children[index].children[cellIndex];
1479
+ const currentHeight = ReactEditor.toDOMNode(editor, currentCell).getBoundingClientRect().height;
1480
+ height += currentHeight;
1481
+ index++;
1489
1482
  }
1490
1483
  }
1491
- const focusPath = ReactEditor.findPath(editor, table.children[rowIndex].children[columnIndex]);
1492
- focusEditor(editor, Editor.end(editor, focusPath));
1484
+ return {
1485
+ width,
1486
+ height,
1487
+ top: focussedCell.offsetTop,
1488
+ left: focussedCell.offsetLeft,
1489
+ rowIndex,
1490
+ cellIndex,
1491
+ cell,
1492
+ focusCellIndex
1493
+ };
1494
+ };
1495
+
1496
+ // Table alternate highlight
1497
+ export const getHighlightClass = (editor, cellPath) => {
1498
+ var _tableEntry$;
1499
+ const [tableEntry] = Editor.nodes(editor, {
1500
+ at: cellPath,
1501
+ match: n => n.type === ELEMENT_TYPE.TABLE
1502
+ });
1503
+ const {
1504
+ alternate_highlight,
1505
+ alternate_highlight_color
1506
+ } = ((_tableEntry$ = tableEntry[0]) === null || _tableEntry$ === void 0 ? void 0 : _tableEntry$.ui) || {};
1507
+ if (!alternate_highlight) return '';
1508
+ const rowIndex = cellPath[cellPath.length - 2];
1509
+ const className = getCellHighlightClassName(alternate_highlight_color, rowIndex);
1510
+ return className;
1493
1511
  };
@@ -3,7 +3,7 @@
3
3
  margin: 16px 0;
4
4
  }
5
5
 
6
- .sdoc-table-wrapper + .sdoc-table-wrapper {
6
+ .sdoc-table-wrapper+.sdoc-table-wrapper {
7
7
  margin-top: 32px;
8
8
  }
9
9
 
@@ -68,6 +68,7 @@
68
68
  bottom: -2.5px;
69
69
  left: 0;
70
70
  z-index: 1;
71
+ pointer-events: none;
71
72
  }
72
73
 
73
74
  .sdoc-table-wrapper .table-row-height-just:hover {
@@ -88,6 +89,7 @@
88
89
  width: 5px;
89
90
  top: 0;
90
91
  z-index: 1;
92
+ pointer-events: none;
91
93
  }
92
94
 
93
95
  .sdoc-table-wrapper .table-cell-width-just:hover {
@@ -110,3 +112,47 @@
110
112
  .sdoc-table-wrapper .sdoc-table-selected-range .table-cell *::selection {
111
113
  background-color: unset;
112
114
  }
115
+
116
+ .sdoc-table-resize-mask {
117
+ position: absolute;
118
+ top: 0;
119
+ left: 0;
120
+ user-select: none;
121
+ opacity: 0;
122
+ z-index: 2;
123
+ pointer-events: none;
124
+ }
125
+
126
+ .sdoc-table-resize-mask .sdoc-table-resize-top {
127
+ position: absolute;
128
+ top: 1px;
129
+ width: 100%;
130
+ height: 1px;
131
+ cursor: row-resize;
132
+ }
133
+
134
+ .sdoc-table-resize-mask>div {
135
+ position: absolute;
136
+ pointer-events: auto;
137
+ }
138
+
139
+ .sdoc-table-resize-mask .sdoc-table-resize-bottom {
140
+ bottom: 1px;
141
+ width: 100%;
142
+ height: 1px;
143
+ cursor: row-resize;
144
+ }
145
+
146
+ .sdoc-table-resize-mask .sdoc-table-resize-right {
147
+ right: -1px;
148
+ width: 1px;
149
+ height: 100%;
150
+ cursor: col-resize;
151
+ }
152
+
153
+ .sdoc-table-resize-mask .sdoc-table-resize-left {
154
+ left: -1px;
155
+ width: 1px;
156
+ height: 100%;
157
+ cursor: col-resize;
158
+ }
@@ -15,6 +15,7 @@ import { registerResizeEvents, unregisterResizeEvents } from '../../../../utils/
15
15
  import TableRoot from './table-root';
16
16
  import TableHeader from './table-header';
17
17
  import { findPath } from '../../../core';
18
+ import ResizeMask from './resize-mask';
18
19
  import './index.css';
19
20
  import './alternate-color.css';
20
21
  const Table = _ref => {
@@ -36,6 +37,9 @@ const Table = _ref => {
36
37
  const oldColumns = getTableColumns(editor, element);
37
38
  const [columns, setColumns] = useState(oldColumns);
38
39
  const path = findPath(editor, element);
40
+ const [resizeCellMaskInfo, setResizeCellMaskInfo] = useState({});
41
+ const [isShowResizeHandlers, setIsShowResizeHandlers] = useState(false);
42
+ const [isDraggingResizeHandler, setIsDraggingResizeHandler] = useState(false);
39
43
  const onMouseDown = useCallback(event => {
40
44
  if (event.button !== 0) return; // right click not deal
41
45
  setIsSettingSelectRange(true);
@@ -146,7 +150,6 @@ const Table = _ref => {
146
150
  });
147
151
  };
148
152
  }
149
-
150
153
  // eslint-disable-next-line react-hooks/exhaustive-deps
151
154
  }, [element, isSettingSelectRange, selectedRange, element]);
152
155
  const setRange = useCallback((table, range) => {
@@ -168,6 +171,17 @@ const Table = _ref => {
168
171
  'sdoc-table-selected': isSelected,
169
172
  'sdoc-table-selected-range': !ObjectUtils.isSameObject(selectedRange, EMPTY_SELECTED_RANGE)
170
173
  });
174
+ const handleShowResizeHandler = useCallback(cellInfo => {
175
+ setResizeCellMaskInfo(cellInfo);
176
+ setIsShowResizeHandlers(true);
177
+ }, []);
178
+ const hideResizeHandlers = useCallback(() => {
179
+ setIsShowResizeHandlers(false);
180
+ setIsDraggingResizeHandler(false);
181
+ }, []);
182
+ const handlerStartDragging = useCallback(() => {
183
+ setIsDraggingResizeHandler(true);
184
+ }, []);
171
185
  let style = element.style ? _objectSpread({}, element.style) : {};
172
186
  const columnWidthList = columns.map(item => "".concat(item.width, "px"));
173
187
  style.gridTemplateColumns = columnWidthList.join(' ');
@@ -191,8 +205,18 @@ const Table = _ref => {
191
205
  onMouseDown: onMouseDown,
192
206
  ref: table,
193
207
  "data-id": element.id
194
- }, children, !isSettingSelectRange && /*#__PURE__*/React.createElement(ResizeHandlers, {
195
- element: element
208
+ }, children, !isSettingSelectRange && /*#__PURE__*/React.createElement(ResizeMask, {
209
+ editor: editor,
210
+ table: element,
211
+ handleShowResizeHandler: handleShowResizeHandler,
212
+ hideResizeHandlers: hideResizeHandlers,
213
+ handlerStartDragging: handlerStartDragging,
214
+ isDraggingResizeHandler: isDraggingResizeHandler
215
+ }), !isSettingSelectRange && isShowResizeHandlers && /*#__PURE__*/React.createElement(ResizeHandlers, {
216
+ hideResizeHandlers: hideResizeHandlers,
217
+ element: element,
218
+ resizeCellMaskInfo: resizeCellMaskInfo,
219
+ isDraggingResizeHandler: isDraggingResizeHandler
196
220
  }))))));
197
221
  };
198
222
  function renderTable(props) {
@@ -7,8 +7,9 @@ import ObjectUtils from '../../../../utils/object-utils';
7
7
  import { findPath, focusEditor } from '../../../core';
8
8
  import { useResizeHandlersContext, useTableSelectedRangeContext } from './hooks';
9
9
  import { EMPTY_SELECTED_RANGE, SELECTED_TABLE_CELL_BACKGROUND_COLOR, TABLE_CELL_STYLE } from '../constants';
10
- import { getTableColumns, colorBlend, getCellHighlightClassName } from '../helpers';
11
- import { ELEMENT_TYPE } from '../../../constants';
10
+ import { getTableColumns, colorBlend, getHighlightClass } from '../helpers';
11
+ import EventBus from '../../../../utils/event-bus';
12
+ import { INTERNAL_EVENT } from '../../../../constants';
12
13
  const TableCell = _ref => {
13
14
  let {
14
15
  attributes,
@@ -22,6 +23,8 @@ const TableCell = _ref => {
22
23
  const pathLength = cellPath.length;
23
24
  const rowIndex = cellPath[pathLength - 2];
24
25
  const cellIndex = cellPath[pathLength - 1];
26
+ const rowEntry = Editor.parent(editor, cellPath);
27
+ const tableEntry = Editor.parent(editor, rowEntry[1]);
25
28
  const {
26
29
  minColIndex,
27
30
  maxColIndex,
@@ -71,23 +74,18 @@ const TableCell = _ref => {
71
74
  if (element.style) {
72
75
  style = _objectSpread(_objectSpread({}, element.style), style);
73
76
  }
74
-
75
- // Table alternate highlight
76
- const highlightClass = useMemo(() => {
77
- var _tableEntry$;
78
- const [tableEntry] = Editor.nodes(editor, {
79
- at: cellPath,
80
- match: n => n.type === ELEMENT_TYPE.TABLE
77
+ const onMouseMove = mouseDownEvent => {
78
+ const eventBus = EventBus.getInstance();
79
+ const tableId = tableEntry[0].id;
80
+ eventBus.dispatch(INTERNAL_EVENT.TABLE_CELL_MOUSE_ENTER, {
81
+ mouseDownEvent,
82
+ cell: element,
83
+ rowIndex,
84
+ cellIndex,
85
+ tableId
81
86
  });
82
- const {
83
- alternate_highlight,
84
- alternate_highlight_color
85
- } = ((_tableEntry$ = tableEntry[0]) === null || _tableEntry$ === void 0 ? void 0 : _tableEntry$.ui) || {};
86
- if (!alternate_highlight) return '';
87
- const className = getCellHighlightClassName(alternate_highlight_color, rowIndex);
88
- return className;
89
- // eslint-disable-next-line react-hooks/exhaustive-deps
90
- }, [editor, rowIndex]);
87
+ };
88
+ const highlightClass = useMemo(() => getHighlightClass(editor, cellPath), [cellPath, editor]);
91
89
  return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
92
90
  style: _objectSpread(_objectSpread({}, element.style), style),
93
91
  className: classnames('table-cell', attributes.className, highlightClass, {
@@ -100,7 +98,8 @@ const TableCell = _ref => {
100
98
  "data-id": element.id,
101
99
  "row-index": rowIndex,
102
100
  "cell-index": cellIndex,
103
- onContextMenu: onContextMenu
101
+ onContextMenu: onContextMenu,
102
+ onMouseMove: onMouseMove
104
103
  }), children);
105
104
  };
106
105
  function renderTableCell(props) {
@@ -121,6 +120,9 @@ function renderTableCell(props) {
121
120
  const rowIndex = cellPath[pathLength - 2];
122
121
  const cellIndex = cellPath[pathLength - 1];
123
122
 
123
+ // eslint-disable-next-line react-hooks/rules-of-hooks
124
+ const highlightClass = useMemo(() => getHighlightClass(editor, cellPath), [cellPath, editor]);
125
+
124
126
  // const cellValue = element;
125
127
  let style = attributes.style || {};
126
128
  if (ObjectUtils.hasProperty(element.style, TABLE_CELL_STYLE.TEXT_ALIGN)) {
@@ -145,7 +147,7 @@ function renderTableCell(props) {
145
147
  style.gridArea = "".concat(rowIndex + 1, " / ").concat(cellIndex + 1, " / span ").concat(rowspan, " / span ").concat(colspan);
146
148
  return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
147
149
  style: _objectSpread(_objectSpread({}, element.style), style),
148
- className: classnames('table-cell', attributes.className),
150
+ className: classnames('table-cell', highlightClass, attributes.className),
149
151
  "data-id": element.id
150
152
  }), children);
151
153
  }