@seafile/sdoc-editor 0.5.14 → 0.5.16

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 (22) hide show
  1. package/dist/basic-sdk/constants/index.js +4 -1
  2. package/dist/basic-sdk/editor/editable-article.js +7 -4
  3. package/dist/basic-sdk/extension/constants/index.js +1 -0
  4. package/dist/basic-sdk/extension/plugins/table/constants/index.js +4 -1
  5. package/dist/basic-sdk/extension/plugins/table/helpers.js +312 -1
  6. package/dist/basic-sdk/extension/plugins/table/render/drag-handlers/column-drag-handler.js +17 -0
  7. package/dist/basic-sdk/extension/plugins/table/render/drag-handlers/index.js +45 -0
  8. package/dist/basic-sdk/extension/plugins/table/render/drag-handlers/row-drag-handler.js +17 -0
  9. package/dist/basic-sdk/extension/plugins/table/render/index.js +10 -4
  10. package/dist/basic-sdk/extension/plugins/table/render/render-cell.js +55 -7
  11. package/dist/basic-sdk/extension/plugins/table/render/table-header/columns-header/column-header.js +28 -4
  12. package/dist/basic-sdk/extension/plugins/table/render/table-header/columns-header/index.js +6 -2
  13. package/dist/basic-sdk/extension/plugins/table/render/table-header/index.css +11 -0
  14. package/dist/basic-sdk/extension/plugins/table/render/table-header/index.js +63 -20
  15. package/dist/basic-sdk/extension/plugins/table/render/table-header/rows-header/index.js +6 -2
  16. package/dist/basic-sdk/extension/plugins/table/render/table-header/rows-header/row-header.js +28 -4
  17. package/dist/basic-sdk/extension/toolbar/side-toolbar/event.js +3 -0
  18. package/dist/basic-sdk/extension/toolbar/side-toolbar/index.js +4 -2
  19. package/package.json +1 -1
  20. package/public/locales/en/sdoc-editor.json +3 -1
  21. package/public/locales/zh_CN/sdoc-editor.json +3 -1
  22. package/public/media/sdoc-editor-font/iconfont.svg +0 -3
@@ -19,7 +19,10 @@ export const INTERNAL_EVENT = {
19
19
  UPDATE_SEARCH_REPLACE_HIGHLIGHT: 'update_search_replace_highlight',
20
20
  TABLE_CELL_MOUSE_ENTER: 'table_cell_mouse_enter',
21
21
  HANDLE_MENTION_TEMP_CHOSEN: 'handle_mention_temp_chosen',
22
- UPDATE_MENTION_TEMP_CONTENT: 'update_mention_temp_content'
22
+ UPDATE_MENTION_TEMP_CONTENT: 'update_mention_temp_content',
23
+ TABLE_COLUMN_START_DRAG: 'table_column_start_drag',
24
+ TABLE_SHOW_DRAG_HANDLER: 'table_show_drag_handler',
25
+ TABLE_HIDE_DRAG_HANDLER: 'table_show_drag_handler'
23
26
  };
24
27
  export const REVISION_DIFF_KEY = 'diff';
25
28
  export const REVISION_DIFF_VALUE = '1';
@@ -14,6 +14,7 @@ import { ArticleContainer } from '../layout';
14
14
  import { useScrollContext } from '../hooks/use-scroll-context';
15
15
  import { SetNodeToDecorations } from '../highlight';
16
16
  import { IMAGE } from '../extension/constants';
17
+ import { isPreventResetTableSelectedRange } from '../extension/plugins/table/helpers';
17
18
  const EditableArticle = _ref => {
18
19
  let {
19
20
  isShowComment,
@@ -31,10 +32,12 @@ const EditableArticle = _ref => {
31
32
  const eventProxy = useMemo(() => new EventProxy(editor), []);
32
33
  const onMouseDown = useCallback(event => {
33
34
  if (event.button === 0) {
34
- // Compatible with the editor which unload table plugin
35
- editor.reSetTableSelectedRange && editor.reSetTableSelectedRange();
36
- const eventBus = EventBus.getInstance();
37
- eventBus.dispatch(INTERNAL_EVENT.CANCEL_TABLE_SELECT_RANGE);
35
+ const isPreventReset = isPreventResetTableSelectedRange(event);
36
+ if (!isPreventReset) {
37
+ editor.reSetTableSelectedRange();
38
+ const eventBus = EventBus.getInstance();
39
+ eventBus.dispatch(INTERNAL_EVENT.CANCEL_TABLE_SELECT_RANGE);
40
+ }
38
41
  }
39
42
  // eslint-disable-next-line react-hooks/exhaustive-deps
40
43
  }, []);
@@ -21,6 +21,7 @@ export const HEADER_TITLE_MAP = {
21
21
  };
22
22
  export const TRANSPARENT = 'transparent';
23
23
  export const CLIPBOARD_FORMAT_KEY = 'x-slate-fragment';
24
+ export const TABLE_DRAG_KEY = 'drag-table/json';
24
25
  export const CLIPBOARD_ORIGIN_SDOC_KEY = 'origin-sdoc-uuid';
25
26
  export const INSERT_FILE_DISPLAY_TYPE = ['text_link', 'icon_link', 'card_link'];
26
27
  export const INSERT_POSITION = {
@@ -46,4 +46,7 @@ export const RESIZE_MASK_BOTTOM = 'bottom';
46
46
  export const RESIZE_MASK_LEFT = 'left';
47
47
  export const RESIZE_HANDLER_ROW = 'row';
48
48
  export const RESIZE_HANDLER_COLUMN = 'column';
49
- export const RESIZE_HANDLER_FIRST_COLUMN = 'first_column';
49
+ export const RESIZE_HANDLER_FIRST_COLUMN = 'first_column';
50
+ export const DRAG_HANDLER_ROW = 'row';
51
+ export const DRAG_HANDLER_COLUMN = 'column';
52
+ export const CELL_SELECTED = 'cell-selected';
@@ -5,7 +5,7 @@ import { ReactEditor } from '@seafile/slate-react';
5
5
  import deepCopy from 'deep-copy';
6
6
  import { getNodeType, getParentNode, getSelectedNodeByType, isTextNode, getSelectedElems, focusEditor, getNode, findPath, replaceNodeChildren, replaceNode, getSelectedNodeEntryByType, getAboveBlockNode } from '../../core';
7
7
  import { ELEMENT_TYPE, KEYBOARD, CLIPBOARD_FORMAT_KEY, INSERT_POSITION } from '../../constants';
8
- import { TABLE_MAX_ROWS, TABLE_MAX_COLUMNS, EMPTY_SELECTED_RANGE, TABLE_ROW_MIN_HEIGHT, TABLE_CELL_MIN_WIDTH, TABLE_ELEMENT, TABLE_ELEMENT_POSITION, TABLE_ROW_STYLE, INHERIT_CELL_STYLE_WHEN_SELECT_MULTIPLE, INHERIT_CELL_STYLE_WHEN_SELECT_SINGLE, TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP } from './constants';
8
+ import { TABLE_MAX_ROWS, TABLE_MAX_COLUMNS, EMPTY_SELECTED_RANGE, TABLE_ROW_MIN_HEIGHT, TABLE_CELL_MIN_WIDTH, TABLE_ELEMENT, TABLE_ELEMENT_POSITION, TABLE_ROW_STYLE, INHERIT_CELL_STYLE_WHEN_SELECT_MULTIPLE, INHERIT_CELL_STYLE_WHEN_SELECT_SINGLE, TABLE_ALTERNATE_HIGHLIGHT_CLASS_MAP, CELL_SELECTED, DRAG_HANDLER_COLUMN, DRAG_HANDLER_ROW } from './constants';
9
9
  import EventBus from '../../../utils/event-bus';
10
10
  import { INTERNAL_EVENT, PAGE_EDIT_AREA_WIDTH } from '../../../constants';
11
11
  import ObjectUtils from '../../../utils/object-utils';
@@ -1426,6 +1426,8 @@ export const focusClosestCellWhenJustifyCellSize = (editor, adjustingCell) => {
1426
1426
  const cellPath = ReactEditor.findPath(editor, adjustingCell);
1427
1427
  focusEditor(editor, Editor.end(editor, cellPath));
1428
1428
  };
1429
+
1430
+ // Search main cell of combined cell
1429
1431
  const searchCombinedMainCell = (table, startRowIndex, startColIndex) => {
1430
1432
  for (let rowIndex = startRowIndex; rowIndex >= 0; rowIndex--) {
1431
1433
  const row = table.children[rowIndex];
@@ -1534,4 +1536,313 @@ export const adjustCombinedCellRange = (table, range) => {
1534
1536
  if (isRowCombined && isColCombined) return EMPTY_SELECTED_RANGE;
1535
1537
  }
1536
1538
  return range;
1539
+ };
1540
+
1541
+ /**
1542
+ * Do not reset table selected range, when drag table column / row
1543
+ * @param {MouseEvent} event
1544
+ * @returns {Boolean}
1545
+ */
1546
+ export const isPreventResetTableSelectedRange = event => {
1547
+ const {
1548
+ target
1549
+ } = event;
1550
+ const draggable = target.getAttribute('draggable');
1551
+ const isColumnHeader = target.classList.contains('sdoc-table-column-header');
1552
+ const isRowHeader = target.classList.contains('sdoc-table-row-header');
1553
+ const isHeader = isColumnHeader || isRowHeader;
1554
+ const isPreventReset = isHeader || draggable === 'true';
1555
+ return isPreventReset;
1556
+ };
1557
+
1558
+ /**
1559
+ * Check drag type, column or row
1560
+ */
1561
+ export const getTableDragType = (table, selectedRange) => {
1562
+ const rowCount = table.children.length;
1563
+ const {
1564
+ minRowIndex,
1565
+ maxRowIndex
1566
+ } = selectedRange;
1567
+ const isSelectColumn = minRowIndex === 0 && maxRowIndex === rowCount - 1;
1568
+ return isSelectColumn ? DRAG_HANDLER_COLUMN : DRAG_HANDLER_ROW;
1569
+ };
1570
+ const updateTableColumns = (editor, table, targetColIndex, startColIndex, endColIndex) => {
1571
+ const columns = [...table.columns];
1572
+ const deleteCount = endColIndex - startColIndex + 1;
1573
+ const newColumns = columns.splice(startColIndex, deleteCount);
1574
+ columns.splice(targetColIndex, 0, ...newColumns);
1575
+ updateColumnWidth(editor, table, columns);
1576
+ };
1577
+ export const moveColumns = (editor, targetColIndex, startColIndex, endColIndex) => {
1578
+ // Get selected table information
1579
+ const {
1580
+ table,
1581
+ tablePath
1582
+ } = getSelectedInfo(editor);
1583
+ // Check if moving columns forward or backward
1584
+ const isMoveToFroward = targetColIndex < startColIndex;
1585
+
1586
+ // Iterate over each row in the table
1587
+ table.children.forEach((row, rowIndex) => {
1588
+ if (isMoveToFroward) {
1589
+ // Calculate target and source paths for moving columns forward
1590
+ const targetPath = [...tablePath, rowIndex, targetColIndex];
1591
+ const sourcePath = [...tablePath, rowIndex, endColIndex];
1592
+
1593
+ // Move columns forward by inserting nodes
1594
+ for (let insertIndex = endColIndex; insertIndex >= startColIndex; insertIndex--) {
1595
+ const insertNode = row.children[insertIndex];
1596
+ Transforms.removeNodes(editor, {
1597
+ at: sourcePath
1598
+ });
1599
+ Transforms.insertNodes(editor, insertNode, {
1600
+ at: targetPath
1601
+ });
1602
+ }
1603
+ } else {
1604
+ // Calculate target and source paths for moving columns backward
1605
+ const targetPath = [...tablePath, rowIndex, targetColIndex - 1];
1606
+ const sourcePath = [...tablePath, rowIndex, startColIndex];
1607
+
1608
+ // Move columns backward by inserting nodes
1609
+ for (let insertIndex = startColIndex; insertIndex <= endColIndex; insertIndex++) {
1610
+ const insertNode = row.children[insertIndex];
1611
+ Transforms.removeNodes(editor, {
1612
+ at: sourcePath
1613
+ });
1614
+ Transforms.insertNodes(editor, insertNode, {
1615
+ at: targetPath
1616
+ });
1617
+ }
1618
+ }
1619
+ });
1620
+
1621
+ // Update table columns after moving
1622
+ updateTableColumns(editor, table, targetColIndex, startColIndex, endColIndex);
1623
+
1624
+ // Set new selected range after moving columns
1625
+ const newSelectRange = {
1626
+ minRowIndex: 0,
1627
+ maxRowIndex: table.children.length - 1,
1628
+ minColIndex: targetColIndex,
1629
+ maxColIndex: targetColIndex + endColIndex - startColIndex
1630
+ };
1631
+ setTableSelectedRange(editor, newSelectRange);
1632
+ };
1633
+
1634
+ /**
1635
+ * Calculate the new selected range after dragging a column or row in the table.
1636
+ * @param {Object} table - The table object containing columns and rows.
1637
+ * @param {string} moveType - The type of drag operation (DRAG_HANDLER_COLUMN for column, DRAG_HANDLER_ROW for row).
1638
+ * @param {number} targetIndex - The index of the target column or row after dragging.
1639
+ * @param {number} startIndex - The index of the starting column or row before dragging.
1640
+ * @param {number} endIndex - The index of the ending column or row before dragging.
1641
+ * @returns {Object} - The new selected range after the drag operation.
1642
+ */
1643
+ export const getTableSelectedRangeAfterDrag = (table, moveType, targetIndex, startIndex, endIndex) => {
1644
+ // Calculate the total number of columns and rows in the table
1645
+ const colCount = table.columns.length;
1646
+ const rowCount = table.children.length;
1647
+
1648
+ // Initialize the new selected range with full table range
1649
+ const newSelectRange = {
1650
+ minRowIndex: 0,
1651
+ maxRowIndex: rowCount - 1,
1652
+ minColIndex: 0,
1653
+ maxColIndex: colCount - 1
1654
+ };
1655
+
1656
+ // Determine if the drag movement is forward or backward
1657
+ const isMoveToFroward = targetIndex < startIndex;
1658
+
1659
+ // Adjust selected range based on the type of drag operation
1660
+ if (moveType === DRAG_HANDLER_COLUMN) {
1661
+ if (isMoveToFroward) {
1662
+ newSelectRange.minColIndex = targetIndex;
1663
+ newSelectRange.maxColIndex = targetIndex + endIndex - startIndex;
1664
+ } else {
1665
+ const moveCount = endIndex - startIndex + 1;
1666
+ newSelectRange.minColIndex = targetIndex - moveCount;
1667
+ newSelectRange.maxColIndex = targetIndex - 1;
1668
+ }
1669
+ } else {
1670
+ if (isMoveToFroward) {
1671
+ newSelectRange.minRowIndex = targetIndex;
1672
+ newSelectRange.maxRowIndex = targetIndex + endIndex - startIndex;
1673
+ } else {
1674
+ const moveCount = endIndex - startIndex + 1;
1675
+ newSelectRange.minRowIndex = targetIndex - moveCount;
1676
+ newSelectRange.maxRowIndex = targetIndex - 1;
1677
+ }
1678
+ }
1679
+ return newSelectRange;
1680
+ };
1681
+ export const moveRows = (editor, targetRowIndex, startRowIndex, endRowIndex) => {
1682
+ const {
1683
+ table,
1684
+ tablePath
1685
+ } = getSelectedInfo(editor);
1686
+ const isMoveToFroward = targetRowIndex < startRowIndex;
1687
+ const targetPath = [...tablePath, isMoveToFroward ? targetRowIndex : targetRowIndex - 1];
1688
+ const sourcePath = [...tablePath, isMoveToFroward ? endRowIndex : startRowIndex];
1689
+ if (isMoveToFroward) {
1690
+ for (let insertIndex = endRowIndex; insertIndex >= startRowIndex; insertIndex--) {
1691
+ const insertNode = table.children[insertIndex];
1692
+ Transforms.removeNodes(editor, {
1693
+ at: sourcePath
1694
+ });
1695
+ Transforms.insertNodes(editor, insertNode, {
1696
+ at: targetPath
1697
+ });
1698
+ }
1699
+ } else {
1700
+ for (let insertIndex = startRowIndex; insertIndex <= endRowIndex; insertIndex++) {
1701
+ const insertNode = table.children[insertIndex];
1702
+ Transforms.removeNodes(editor, {
1703
+ at: sourcePath
1704
+ });
1705
+ Transforms.insertNodes(editor, insertNode, {
1706
+ at: targetPath
1707
+ });
1708
+ }
1709
+ }
1710
+ const newSelectRange = {
1711
+ minRowIndex: targetRowIndex,
1712
+ maxRowIndex: targetRowIndex + endRowIndex - startRowIndex,
1713
+ minColIndex: 0,
1714
+ maxColIndex: table.children.length - 1
1715
+ };
1716
+ setTableSelectedRange(editor, newSelectRange);
1717
+ };
1718
+ export const generateDragMoveElement = tipText => {
1719
+ const canvasId = 'sdoc-drag-image';
1720
+ let canvas = document.getElementById(canvasId);
1721
+ if (!canvas) {
1722
+ canvas = document.createElement('canvas');
1723
+ canvas.width = 150;
1724
+ canvas.height = 30;
1725
+ canvas.id = canvasId;
1726
+ document.body.appendChild(canvas);
1727
+ }
1728
+ canvas.style.display = 'block';
1729
+ canvas.style.position = 'fixed';
1730
+ const context = canvas.getContext('2d');
1731
+ context.clearRect(0, 0, canvas.width, canvas.height);
1732
+ context.textAlign = 'center';
1733
+ context.fillStyle = 'rgb(66, 129, 219)';
1734
+ context.fillRect(0, 0, canvas.width, canvas.height);
1735
+ context.font = '12px';
1736
+ context.textBaseline = 'middle';
1737
+ context.fillStyle = 'white';
1738
+ context.fillText(tipText, canvas.width / 2, canvas.height / 2);
1739
+ return canvas;
1740
+ };
1741
+ export const isHideDragHandlerLine = (editor, displayType, table, cellPath) => {
1742
+ const pathLength = cellPath.length;
1743
+ const rowIndex = cellPath[pathLength - 2];
1744
+ const cellIndex = cellPath[pathLength - 1];
1745
+ let preCellDom = null;
1746
+ if (displayType === DRAG_HANDLER_COLUMN && cellIndex > 1) {
1747
+ const prevCell = table.children[rowIndex].children[cellIndex - 1];
1748
+ preCellDom = ReactEditor.toDOMNode(editor, prevCell);
1749
+ } else if (displayType === DRAG_HANDLER_ROW && rowIndex > 1) {
1750
+ const prevCell = table.children[rowIndex - 1].children[cellIndex];
1751
+ preCellDom = ReactEditor.toDOMNode(editor, prevCell);
1752
+ }
1753
+ const isPrevCellSelected = preCellDom ? preCellDom.classList.contains(CELL_SELECTED) : false;
1754
+
1755
+ // Check if the previous cell is selected
1756
+ if (isPrevCellSelected) return true;
1757
+
1758
+ // Check if the combined cell
1759
+ if (displayType === DRAG_HANDLER_COLUMN) {
1760
+ const isCombined = table.children.some(row => row.children[cellIndex].is_combined);
1761
+ return isCombined;
1762
+ } else {
1763
+ const isCombined = table.children[rowIndex].children.some(cell => cell.is_combined);
1764
+ return isCombined;
1765
+ }
1766
+ };
1767
+ export const getTableRowSelectedRange = (table, rowIndex) => {
1768
+ const row = table.children[rowIndex];
1769
+ const columnCount = row.children.length;
1770
+ let minRowIndex = rowIndex;
1771
+ let maxRowIndex = rowIndex;
1772
+ let minColIndex = 0;
1773
+ let maxColIndex = columnCount - 1;
1774
+ const findRowRange = findRowIndex => {
1775
+ let checkRow = table.children[findRowIndex];
1776
+ const combinedIndexes = checkRow.children.reduce((acc, cell, index) => {
1777
+ if (cell.is_combined) acc.push(index);
1778
+ if (cell.rowspan > 1) {
1779
+ maxRowIndex = Math.max(maxRowIndex, findRowIndex + cell.rowspan - 1);
1780
+ findRowRange(maxRowIndex);
1781
+ }
1782
+ return acc;
1783
+ }, []);
1784
+ combinedIndexes.some(combinedIndex => {
1785
+ const {
1786
+ rowIndex: mainCellRowIndex,
1787
+ currentCell
1788
+ } = searchCombinedMainCell(table, findRowIndex, combinedIndex);
1789
+ if (minRowIndex > mainCellRowIndex) {
1790
+ minRowIndex = mainCellRowIndex;
1791
+ findRowRange(minRowIndex, 0);
1792
+ return false;
1793
+ } else if (maxRowIndex < mainCellRowIndex + currentCell.rowspan - 1) {
1794
+ maxRowIndex = mainCellRowIndex + currentCell.rowspan - 1;
1795
+ findRowRange(maxRowIndex, 0);
1796
+ return false;
1797
+ }
1798
+ return false;
1799
+ });
1800
+ };
1801
+ findRowRange(rowIndex);
1802
+ return {
1803
+ minRowIndex,
1804
+ maxRowIndex,
1805
+ minColIndex,
1806
+ maxColIndex
1807
+ };
1808
+ };
1809
+ export const getTableColumnSelectedRange = (table, columnIndex) => {
1810
+ let minRowIndex = 0;
1811
+ let maxRowIndex = table.children.length - 1;
1812
+ let minColIndex = columnIndex;
1813
+ let maxColIndex = columnIndex;
1814
+ const findColRange = findColIndex => {
1815
+ let combinedIndexes = [];
1816
+ table.children.forEach((row, rowIndex) => {
1817
+ const cell = row.children[findColIndex];
1818
+ if (cell.is_combined) combinedIndexes.push(rowIndex);
1819
+ if (cell.colspan > 1) {
1820
+ maxColIndex = Math.max(maxColIndex, findColIndex + cell.colspan - 1);
1821
+ findColRange(maxColIndex);
1822
+ }
1823
+ });
1824
+ combinedIndexes.some(combinedIndex => {
1825
+ const {
1826
+ cellIndex: mainCellColIndex,
1827
+ currentCell
1828
+ } = searchCombinedMainCell(table, combinedIndex, findColIndex);
1829
+ if (minColIndex > mainCellColIndex) {
1830
+ minColIndex = mainCellColIndex;
1831
+ findColRange(minColIndex, 0);
1832
+ return false;
1833
+ } else if (maxColIndex < mainCellColIndex + currentCell.colspan - 1) {
1834
+ maxColIndex = mainCellColIndex + currentCell.colspan - 1;
1835
+ findColRange(maxColIndex, 0);
1836
+ return false;
1837
+ }
1838
+ return false;
1839
+ });
1840
+ };
1841
+ findColRange(columnIndex);
1842
+ return {
1843
+ minRowIndex,
1844
+ maxRowIndex,
1845
+ minColIndex,
1846
+ maxColIndex
1847
+ };
1537
1848
  };
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import '../../render/index.css';
3
+ const ColumnDragHandler = _ref => {
4
+ let {
5
+ left
6
+ } = _ref;
7
+ return /*#__PURE__*/React.createElement("div", {
8
+ className: "table-cell-width-just position-absolute resizing",
9
+ contentEditable: false,
10
+ style: {
11
+ left
12
+ }
13
+ }, /*#__PURE__*/React.createElement("div", {
14
+ className: "table-cell-width-just-color-tip"
15
+ }));
16
+ };
17
+ export default ColumnDragHandler;
@@ -0,0 +1,45 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import RowDragHandler from './row-drag-handler';
3
+ import ColumnDragHandler from './column-drag-handler';
4
+ import EventBus from '../../../../../utils/event-bus';
5
+ import { INTERNAL_EVENT } from '../../../../../constants';
6
+ import { DRAG_HANDLER_ROW, DRAG_HANDLER_COLUMN } from '../../constants';
7
+ const DragHandlers = _ref => {
8
+ let {
9
+ table
10
+ } = _ref;
11
+ const [linePosition, setLinePosition] = useState({
12
+ top: 0,
13
+ left: 0
14
+ });
15
+ const [displayType, setDisplayType] = useState('');
16
+ const tableID = table.id;
17
+ const handleShowResizeHandler = useCallback(_ref2 => {
18
+ let {
19
+ displayType,
20
+ left,
21
+ top,
22
+ tableId
23
+ } = _ref2;
24
+ if (tableId !== tableID) return;
25
+ const maskOffset = 2;
26
+ setLinePosition({
27
+ top,
28
+ left: left - maskOffset
29
+ });
30
+ setDisplayType(displayType);
31
+ }, [tableID]);
32
+ useEffect(() => {
33
+ const eventBus = EventBus.getInstance();
34
+ const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.TABLE_SHOW_DRAG_HANDLER, handleShowResizeHandler);
35
+ return () => {
36
+ unsubscribe();
37
+ };
38
+ }, [handleShowResizeHandler]);
39
+ return /*#__PURE__*/React.createElement(React.Fragment, null, displayType === DRAG_HANDLER_ROW && /*#__PURE__*/React.createElement(RowDragHandler, {
40
+ top: linePosition.top
41
+ }), displayType === DRAG_HANDLER_COLUMN && /*#__PURE__*/React.createElement(ColumnDragHandler, {
42
+ left: linePosition.left
43
+ }));
44
+ };
45
+ export default DragHandlers;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import '../../render/index.css';
3
+ const RowDragHandler = _ref => {
4
+ let {
5
+ top
6
+ } = _ref;
7
+ return /*#__PURE__*/React.createElement("div", {
8
+ className: "table-row-height-just position-absolute resizing",
9
+ contentEditable: false,
10
+ style: {
11
+ top
12
+ }
13
+ }, /*#__PURE__*/React.createElement("div", {
14
+ className: "table-row-height-just-color-tip"
15
+ }));
16
+ };
17
+ export default RowDragHandler;
@@ -16,6 +16,7 @@ import TableRoot from './table-root';
16
16
  import TableHeader from './table-header';
17
17
  import { findPath } from '../../../core';
18
18
  import ResizeMask from './resize-mask';
19
+ import DragHandlers from './drag-handlers';
19
20
  import './index.css';
20
21
  import './alternate-color.css';
21
22
  const Table = _ref => {
@@ -40,6 +41,7 @@ const Table = _ref => {
40
41
  const [resizeCellMaskInfo, setResizeCellMaskInfo] = useState({});
41
42
  const [isShowResizeHandlers, setIsShowResizeHandlers] = useState(false);
42
43
  const [isDraggingResizeHandler, setIsDraggingResizeHandler] = useState(false);
44
+ const [isDragMove, setIsDragMove] = useState(false);
43
45
  const onMouseDown = useCallback(event => {
44
46
  if (event.button !== 0) return; // right click not deal
45
47
  setIsSettingSelectRange(true);
@@ -68,12 +70,12 @@ const Table = _ref => {
68
70
  setSelectedRange(range);
69
71
  setTableSelectedRange(editor, range);
70
72
  const {
71
- maxRowIndex,
72
- maxColIndex
73
+ minRowIndex,
74
+ minColIndex
73
75
  } = range;
74
76
  const selection = {
75
77
  offset: 0,
76
- path: [...path, maxRowIndex, maxColIndex, 0]
78
+ path: [...path, minRowIndex, minColIndex, 0]
77
79
  };
78
80
  Transforms.setSelection(editor, {
79
81
  anchor: selection,
@@ -200,8 +202,10 @@ const Table = _ref => {
200
202
  columns: columns,
201
203
  attributes: attributes
202
204
  }, isSelected && /*#__PURE__*/React.createElement(TableHeader, {
205
+ editor: editor,
203
206
  table: element,
204
- setSelectedRange: setSelectedRangeByClick
207
+ setSelectedRange: setSelectedRangeByClick,
208
+ setIsDragMove: setIsDragMove
205
209
  }), /*#__PURE__*/React.createElement("div", {
206
210
  className: classnames(tableContainerClassName),
207
211
  style: style,
@@ -220,6 +224,8 @@ const Table = _ref => {
220
224
  element: element,
221
225
  resizeCellMaskInfo: resizeCellMaskInfo,
222
226
  isDraggingResizeHandler: isDraggingResizeHandler
227
+ }), isDragMove && /*#__PURE__*/React.createElement(DragHandlers, {
228
+ table: element
223
229
  }))))));
224
230
  };
225
231
  function renderTable(props) {
@@ -1,15 +1,16 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import React, { useCallback, useMemo } from 'react';
2
+ import React, { useCallback, useMemo, useRef } from 'react';
3
3
  import classnames from 'classnames';
4
4
  import { useSlateStatic, useReadOnly } from '@seafile/slate-react';
5
5
  import { Editor, Transforms } from '@seafile/slate';
6
6
  import ObjectUtils from '../../../../utils/object-utils';
7
7
  import { findPath, focusEditor } from '../../../core';
8
8
  import { useTableSelectedRangeContext } from './hooks';
9
- import { EMPTY_SELECTED_RANGE, SELECTED_TABLE_CELL_BACKGROUND_COLOR, TABLE_CELL_STYLE } from '../constants';
10
- import { colorBlend, getHighlightClass } from '../helpers';
9
+ import { CELL_SELECTED, DRAG_HANDLER_COLUMN, EMPTY_SELECTED_RANGE, SELECTED_TABLE_CELL_BACKGROUND_COLOR, TABLE_CELL_STYLE } from '../constants';
10
+ import { colorBlend, getHighlightClass, getResizeMaskCellInfo, getTableDragType, moveColumns, moveRows, isHideDragHandlerLine, getTableSelectedRangeAfterDrag } from '../helpers';
11
11
  import EventBus from '../../../../utils/event-bus';
12
12
  import { INTERNAL_EVENT } from '../../../../constants';
13
+ import { TABLE_DRAG_KEY } from '../../../constants';
13
14
  const TableCell = _ref => {
14
15
  let {
15
16
  attributes,
@@ -36,6 +37,9 @@ const TableCell = _ref => {
36
37
  const isSelectedLastCell = isSelected && cellIndex === maxColIndex;
37
38
  const isSelectedFirstRow = isSelected && rowIndex === minRowIndex;
38
39
  const isSelectedLastRow = isSelected && rowIndex === maxRowIndex;
40
+ const eventBus = EventBus.getInstance();
41
+ const tableId = tableEntry[0].id;
42
+ const canDrop = useRef(false);
39
43
  const onContextMenu = useCallback(event => {
40
44
  const path = findPath(editor, element);
41
45
  focusEditor(editor, path);
@@ -74,8 +78,6 @@ const TableCell = _ref => {
74
78
  style = _objectSpread(_objectSpread({}, element.style), style);
75
79
  }
76
80
  const onMouseMove = mouseDownEvent => {
77
- const eventBus = EventBus.getInstance();
78
- const tableId = tableEntry[0].id;
79
81
  eventBus.dispatch(INTERNAL_EVENT.TABLE_CELL_MOUSE_ENTER, {
80
82
  mouseDownEvent,
81
83
  cell: element,
@@ -86,10 +88,54 @@ const TableCell = _ref => {
86
88
  };
87
89
  // eslint-disable-next-line react-hooks/exhaustive-deps
88
90
  const highlightClass = useMemo(() => getHighlightClass(editor, cellPath), []);
91
+ const onDragOver = useCallback(event => {
92
+ const {
93
+ target
94
+ } = event;
95
+ const table = tableEntry[0];
96
+ const displayType = getTableDragType(table, selectedRange);
97
+ const resizeMaskCellInfo = getResizeMaskCellInfo(editor, table, rowIndex, cellIndex);
98
+ const cellInfo = _objectSpread(_objectSpread({}, resizeMaskCellInfo), {}, {
99
+ displayType,
100
+ mouseDownEvent: event,
101
+ tableId
102
+ });
103
+ const isHideHandleLine = isHideDragHandlerLine(editor, displayType, table, cellPath);
104
+ canDrop.current = !isHideHandleLine;
105
+ if (target.classList.contains(CELL_SELECTED) || isHideHandleLine) {
106
+ cellInfo.top = -9999;
107
+ cellInfo.left = -9999;
108
+ }
109
+ eventBus.dispatch(INTERNAL_EVENT.TABLE_SHOW_DRAG_HANDLER, cellInfo);
110
+ }, [cellIndex, cellPath, editor, eventBus, rowIndex, selectedRange, tableEntry, tableId]);
111
+ const handleDrop = useCallback(event => {
112
+ event.stopPropagation();
113
+ event.preventDefault();
114
+ if (!canDrop.current) return;
115
+ const {
116
+ target
117
+ } = event;
118
+ if (target.classList.contains(CELL_SELECTED)) return;
119
+ const dragDataJson = event.dataTransfer.getData(TABLE_DRAG_KEY);
120
+ if (!dragDataJson) return;
121
+ const dragData = JSON.parse(dragDataJson);
122
+ if (dragData) {
123
+ const {
124
+ tableId: dragTableId,
125
+ startIndex,
126
+ endIndex,
127
+ dragType
128
+ } = dragData;
129
+ if (dragTableId !== tableId) return;
130
+ dragType === DRAG_HANDLER_COLUMN ? moveColumns(editor, cellIndex, startIndex, endIndex) : moveRows(editor, rowIndex, startIndex, endIndex);
131
+ const range = dragType === DRAG_HANDLER_COLUMN ? getTableSelectedRangeAfterDrag(tableEntry[0], dragType, cellIndex, startIndex, endIndex) : getTableSelectedRangeAfterDrag(tableEntry[0], dragType, rowIndex, startIndex, endIndex);
132
+ eventBus.dispatch(INTERNAL_EVENT.SET_TABLE_SELECT_RANGE, tableEntry[0], range);
133
+ }
134
+ }, [cellIndex, editor, eventBus, rowIndex, tableEntry, tableId]);
89
135
  return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
90
136
  style: _objectSpread(_objectSpread({}, element.style), style),
91
137
  className: classnames('table-cell', attributes.className, highlightClass, {
92
- 'cell-selected': isSelected,
138
+ [CELL_SELECTED]: isSelected,
93
139
  'cell-light-height-left-border': isSelectedFirstCell,
94
140
  'cell-light-height-right-border': isSelectedLastCell,
95
141
  'cell-light-height-top-border': isSelectedFirstRow,
@@ -99,7 +145,9 @@ const TableCell = _ref => {
99
145
  "row-index": rowIndex,
100
146
  "cell-index": cellIndex,
101
147
  onContextMenu: onContextMenu,
102
- onMouseMove: onMouseMove
148
+ onMouseMove: onMouseMove,
149
+ onDragOver: onDragOver,
150
+ onDrop: handleDrop
103
151
  }), /*#__PURE__*/React.createElement("div", {
104
152
  className: "sdoc-cell-container"
105
153
  }, children));
@@ -1,4 +1,4 @@
1
- import React, { useRef, useCallback } from 'react';
1
+ import React, { useRef, useCallback, useMemo } from 'react';
2
2
  import classnames from 'classnames';
3
3
  import { useSlateStatic } from '@seafile/slate-react';
4
4
  import ObjectUtils from '../../../../../../utils/object-utils';
@@ -13,15 +13,35 @@ const ColumnHeader = _ref => {
13
13
  setAddIconPosition,
14
14
  setInsertColumnIndex,
15
15
  selectRange,
16
- tableSize
16
+ tableSize,
17
+ handleDragStart,
18
+ handleDragEnd
17
19
  } = _ref;
18
20
  const editor = useSlateStatic();
21
+ const {
22
+ tableSelectedRange
23
+ } = editor;
19
24
  const columnHeaderRef = useRef(null);
20
25
  const tableRoot = useTableRootContext();
21
26
  const selectedRange = useTableSelectedRangeContext();
22
27
  const currentCell = getSelectedNodeByType(editor, ELEMENT_TYPE.TABLE_CELL);
23
28
  const currentCellPath = currentCell ? findPath(editor, currentCell, [-1, -1]) : [-1, -1];
24
29
  const pathLength = currentCellPath.length;
30
+ const canDrag = useMemo(() => {
31
+ const {
32
+ minRowIndex,
33
+ maxRowIndex,
34
+ minColIndex,
35
+ maxColIndex
36
+ } = tableSelectedRange;
37
+ const [rowNum] = tableSize;
38
+ const isSelectColumn = minRowIndex === 0 && maxRowIndex === rowNum - 1;
39
+ const isSelectRangeColumn = minColIndex <= index && index <= maxColIndex;
40
+ const isSelectAllColumn = minColIndex === 0 && maxColIndex === tableSize[1] - 1;
41
+ if (tableSize[1] === 1 || isSelectAllColumn) return false;
42
+ if (isSelectColumn && isSelectRangeColumn) return true;
43
+ return false;
44
+ }, [index, tableSelectedRange, tableSize]);
25
45
  const onMouseMove = useCallback(event => {
26
46
  const {
27
47
  left,
@@ -58,15 +78,19 @@ const ColumnHeader = _ref => {
58
78
  return /*#__PURE__*/React.createElement("div", {
59
79
  className: classnames('sdoc-table-column-header h-100', {
60
80
  'range-selected': isSelectedAColumn && isSelectedRangeColumn,
61
- 'range-selected-tip': !isSelectedAColumn && isSelectedRangeColumn || currentCellPath[pathLength - 1] === index
81
+ 'range-selected-tip': !isSelectedAColumn && isSelectedRangeColumn || currentCellPath[pathLength - 1] === index,
82
+ 'drag': canDrag
62
83
  }),
63
84
  ref: columnHeaderRef,
64
85
  onMouseMove: onMouseMove,
65
86
  onMouseLeave: onMouseLeave,
66
87
  onClick: () => selectRange(index),
88
+ onDragStart: handleDragStart,
89
+ onDragEnd: handleDragEnd,
67
90
  style: {
68
91
  width: column.width
69
- }
92
+ },
93
+ draggable: canDrag
70
94
  });
71
95
  };
72
96
  export default ColumnHeader;
@@ -9,7 +9,9 @@ const ColumnsHeader = _ref => {
9
9
  let {
10
10
  table,
11
11
  selectRange,
12
- tableSize
12
+ tableSize,
13
+ handleDragStart,
14
+ handleDragEnd
13
15
  } = _ref;
14
16
  const editor = useSlateStatic();
15
17
  const [insertColumnIndex, setInsertColumnIndex] = useState(0);
@@ -55,7 +57,9 @@ const ColumnsHeader = _ref => {
55
57
  tableSize: tableSize,
56
58
  setAddIconPosition: setAddIconPosition,
57
59
  setInsertColumnIndex: setInsertColumnIndex,
58
- selectRange: selectRange
60
+ selectRange: selectRange,
61
+ handleDragStart: handleDragStart,
62
+ handleDragEnd: handleDragEnd
59
63
  });
60
64
  }))), addIconPosition && /*#__PURE__*/React.createElement("div", {
61
65
  className: classnames('position-fixed sdoc-table-add-element-icon-content', {
@@ -10,6 +10,11 @@
10
10
  flex-shrink: 0;
11
11
  border-right: 1px solid rgba(0, 0, 0, .08);
12
12
  background-color: rgb(243, 245, 247);
13
+ cursor: pointer;
14
+ }
15
+
16
+ .sdoc-table-wrapper .sdoc-table-columns-header .sdoc-table-column-header.drag {
17
+ cursor: move;
13
18
  }
14
19
 
15
20
  /* row-header */
@@ -28,6 +33,11 @@
28
33
  width: 100%;
29
34
  background-color: rgb(243, 245, 247);
30
35
  border-bottom: 1px solid rgba(0, 0, 0, .08);
36
+ cursor: pointer;
37
+ }
38
+
39
+ .sdoc-table-wrapper .sdoc-table-rows-header .sdoc-table-row-header.drag {
40
+ cursor: move;
31
41
  }
32
42
 
33
43
  .sdoc-table-wrapper .sdoc-table-rows-columns-header {
@@ -71,3 +81,4 @@
71
81
  .sdoc-table-wrapper .sdoc-table-add-element-icon-content:hover {
72
82
  cursor: pointer;
73
83
  }
84
+
@@ -1,36 +1,34 @@
1
1
  import React, { useCallback } from 'react';
2
+ import { useTranslation } from 'react-i18next';
2
3
  import ColumnsHeader from './columns-header';
3
4
  import RowsHeader from './rows-header';
4
- import { useResizeHandlersContext } from '../hooks';
5
+ import { useResizeHandlersContext, useTableSelectedRangeContext } from '../hooks';
5
6
  import RowsColumnsHeader from './rows-columns-header';
7
+ import { generateDragMoveElement, getTableDragType, getTableRowSelectedRange, getTableColumnSelectedRange } from '../../helpers';
8
+ import { DRAG_HANDLER_COLUMN, DRAG_HANDLER_ROW, EMPTY_SELECTED_RANGE } from '../../constants';
9
+ import { TABLE_DRAG_KEY } from '../../../../constants';
6
10
  import './index.css';
7
11
  const TableHeader = _ref => {
8
12
  let {
13
+ editor,
9
14
  table,
10
- setSelectedRange
15
+ setSelectedRange,
16
+ setIsDragMove
11
17
  } = _ref;
18
+ const {
19
+ t
20
+ } = useTranslation();
12
21
  const columns = useResizeHandlersContext();
22
+ const selectedRange = useTableSelectedRangeContext() || EMPTY_SELECTED_RANGE;
13
23
  const selectColumn = useCallback(columnIndex => {
14
- const rowsCount = table.children.length;
15
- const range = {
16
- minRowIndex: 0,
17
- maxRowIndex: rowsCount - 1,
18
- minColIndex: columnIndex,
19
- maxColIndex: columnIndex
20
- };
21
- setSelectedRange(range);
24
+ const selectedRange = getTableColumnSelectedRange(table, columnIndex);
25
+ setSelectedRange(selectedRange);
22
26
 
23
27
  // eslint-disable-next-line react-hooks/exhaustive-deps
24
28
  }, [table, columns]);
25
29
  const selectRow = useCallback(rowIndex => {
26
- const columnsCount = columns.length;
27
- const range = {
28
- minRowIndex: rowIndex,
29
- maxRowIndex: rowIndex,
30
- minColIndex: 0,
31
- maxColIndex: columnsCount - 1
32
- };
33
- setSelectedRange(range);
30
+ const selectedRange = getTableRowSelectedRange(table, rowIndex);
31
+ setSelectedRange(selectedRange);
34
32
 
35
33
  // eslint-disable-next-line react-hooks/exhaustive-deps
36
34
  }, [table, columns]);
@@ -48,17 +46,62 @@ const TableHeader = _ref => {
48
46
  // eslint-disable-next-line react-hooks/exhaustive-deps
49
47
  }, [table, columns]);
50
48
  const tableSize = [table.children.length, columns.length];
49
+ const handleDragStart = event => {
50
+ event.stopPropagation();
51
+ const {
52
+ tableSelectedRange
53
+ } = editor;
54
+ const tableId = table.id;
55
+ const {
56
+ minColIndex,
57
+ maxColIndex,
58
+ minRowIndex,
59
+ maxRowIndex
60
+ } = tableSelectedRange;
61
+ const dragType = getTableDragType(table, selectedRange);
62
+ const startIndex = dragType === DRAG_HANDLER_COLUMN ? minColIndex : minRowIndex;
63
+ const endIndex = dragType === DRAG_HANDLER_ROW ? maxRowIndex : maxColIndex;
64
+ const data = {
65
+ tableId,
66
+ dragType,
67
+ startIndex,
68
+ endIndex
69
+ };
70
+ const dragData = JSON.stringify(data);
71
+ event.dataTransfer.setData(TABLE_DRAG_KEY, dragData);
72
+ event.dataTransfer.effectAllowed = 'move';
73
+ const moveCount = endIndex - startIndex + 1;
74
+ const tipText = dragType === DRAG_HANDLER_COLUMN ? t('Move_column_count', {
75
+ count: moveCount
76
+ }) : t('Move_row_count', {
77
+ count: moveCount
78
+ });
79
+ const dragImage = generateDragMoveElement(tipText);
80
+ event.dataTransfer.setDragImage(dragImage, 0, 0);
81
+ setIsDragMove(true);
82
+ // eslint-disable-next-line react-hooks/exhaustive-deps
83
+ };
84
+
85
+ const handleDragEnd = event => {
86
+ setIsDragMove(false);
87
+ const indicator = document.getElementById('sdoc-drag-image');
88
+ indicator.style.display = 'none';
89
+ };
51
90
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(ColumnsHeader, {
52
91
  table: table,
53
92
  selectRange: selectColumn,
54
- tableSize: tableSize
93
+ tableSize: tableSize,
94
+ handleDragStart: handleDragStart,
95
+ handleDragEnd: handleDragEnd
55
96
  }), /*#__PURE__*/React.createElement(RowsColumnsHeader, {
56
97
  selectRange: selectTable,
57
98
  tableSize: tableSize
58
99
  }), /*#__PURE__*/React.createElement(RowsHeader, {
59
100
  table: table,
60
101
  selectRange: selectRow,
61
- tableSize: tableSize
102
+ tableSize: tableSize,
103
+ handleDragStart: handleDragStart,
104
+ handleDragEnd: handleDragEnd
62
105
  }));
63
106
  };
64
107
  export default TableHeader;
@@ -9,7 +9,9 @@ const RowsHeader = _ref => {
9
9
  let {
10
10
  table,
11
11
  selectRange,
12
- tableSize
12
+ tableSize,
13
+ handleDragStart,
14
+ handleDragEnd
13
15
  } = _ref;
14
16
  const editor = useSlateStatic();
15
17
  const {
@@ -54,7 +56,9 @@ const RowsHeader = _ref => {
54
56
  tableSize: tableSize,
55
57
  setAddIconPosition: setAddIconPosition,
56
58
  setInsertRowIndex: setInsertRowIndex,
57
- selectRange: selectRange
59
+ selectRange: selectRange,
60
+ handleDragStart: handleDragStart,
61
+ handleDragEnd: handleDragEnd
58
62
  });
59
63
  })), addIconPosition && /*#__PURE__*/React.createElement("div", {
60
64
  className: classnames('position-fixed sdoc-table-add-element-icon-content', {
@@ -1,4 +1,4 @@
1
- import React, { useRef, useCallback, useState, useEffect } from 'react';
1
+ import React, { useRef, useCallback, useState, useEffect, useMemo } from 'react';
2
2
  import { useSlateStatic } from '@seafile/slate-react';
3
3
  import classnames from 'classnames';
4
4
  import ObjectUtils from '../../../../../../utils/object-utils';
@@ -15,9 +15,14 @@ const RowHeader = _ref => {
15
15
  setAddIconPosition,
16
16
  setInsertRowIndex,
17
17
  selectRange,
18
- tableSize
18
+ tableSize,
19
+ handleDragStart,
20
+ handleDragEnd
19
21
  } = _ref;
20
22
  const editor = useSlateStatic();
23
+ const {
24
+ tableSelectedRange
25
+ } = editor;
21
26
  useEffect(() => {
22
27
  setRowHeight(getRowDomHeight(editor, row));
23
28
  }, [editor, row, tableSize]);
@@ -30,6 +35,21 @@ const RowHeader = _ref => {
30
35
  const currentCell = getSelectedNodeByType(editor, ELEMENT_TYPE.TABLE_CELL);
31
36
  const currentCellPath = currentCell ? findPath(editor, currentCell, [-1, -1]) : [-1, -1];
32
37
  const pathLength = currentCellPath.length;
38
+ const canDrag = useMemo(() => {
39
+ const {
40
+ minRowIndex,
41
+ maxRowIndex,
42
+ minColIndex,
43
+ maxColIndex
44
+ } = tableSelectedRange;
45
+ const [, colNum] = tableSize;
46
+ const isSelectRow = minColIndex === 0 && maxColIndex === colNum - 1;
47
+ const isSelectRangeRow = minRowIndex <= index && index <= maxRowIndex;
48
+ const isSelectAllRows = minRowIndex === 0 && maxRowIndex === tableSize[0] - 1;
49
+ if (tableSize[0] === 1 || isSelectAllRows) return false;
50
+ if (isSelectRow && isSelectRangeRow) return true;
51
+ return false;
52
+ }, [index, tableSelectedRange, tableSize]);
33
53
  useEffect(() => {
34
54
  if (elementHasImage(row)) {
35
55
  // There is a delay in image loading
@@ -80,7 +100,8 @@ const RowHeader = _ref => {
80
100
  return /*#__PURE__*/React.createElement("div", {
81
101
  className: classnames('sdoc-table-row-header', {
82
102
  'range-selected': isSelectedARow && isSelectedSomeRow,
83
- 'range-selected-tip': !isSelectedARow && isSelectedSomeRow || currentCellPath[pathLength - 2] === index
103
+ 'range-selected-tip': !isSelectedARow && isSelectedSomeRow || currentCellPath[pathLength - 2] === index,
104
+ 'drag': canDrag
84
105
  }),
85
106
  style: {
86
107
  height: rowHeight
@@ -88,7 +109,10 @@ const RowHeader = _ref => {
88
109
  ref: rowHeaderRef,
89
110
  onClick: () => selectRange(index),
90
111
  onMouseMove: onMouseMove,
91
- onMouseLeave: onMouseLeave
112
+ onMouseLeave: onMouseLeave,
113
+ onDragStart: handleDragStart,
114
+ onDragEnd: handleDragEnd,
115
+ draggable: canDrag
92
116
  });
93
117
  };
94
118
  export default RowHeader;
@@ -1,5 +1,6 @@
1
1
  import EventBus from '../../../utils/event-bus';
2
2
  import { INTERNAL_EVENT } from '../../../constants';
3
+ import { TABLE_DRAG_KEY } from '../../constants';
3
4
  export const onMouseEnter = (event, element) => {
4
5
  event.stopPropagation();
5
6
  const eventBus = EventBus.getInstance();
@@ -8,6 +9,8 @@ export const onMouseEnter = (event, element) => {
8
9
  export const onDragOver = event => {
9
10
  event.stopPropagation();
10
11
  event.preventDefault();
12
+ const dragTypes = event.dataTransfer.types;
13
+ if (dragTypes.includes(TABLE_DRAG_KEY)) return;
11
14
  const eventBus = EventBus.getInstance();
12
15
  eventBus.dispatch(INTERNAL_EVENT.ON_DRAG_OVER_BLOCK, event);
13
16
  };
@@ -9,7 +9,7 @@ import { focusEditor } from '../../core';
9
9
  import { getDomTopHeight, setSelection, isVoidNode, getNodeEntry, isBlockquote, isList, onWrapListItem } from './helpers';
10
10
  import { insertImageFiles } from '../../plugins/image/helpers';
11
11
  import { INTERNAL_EVENT } from '../../../constants';
12
- import { CODE_BLOCK, TABLE, BLOCKQUOTE, CHECK_LIST_ITEM, CALL_OUT } from '../../constants';
12
+ import { CODE_BLOCK, TABLE, BLOCKQUOTE, CHECK_LIST_ITEM, CALL_OUT, TABLE_DRAG_KEY } from '../../constants';
13
13
  import { getCalloutEntry } from '../../plugins/callout/helper';
14
14
  import './index.css';
15
15
  let sourceElement = null;
@@ -105,9 +105,11 @@ const SideToolbar = () => {
105
105
  leaveElement.classList.remove('sdoc-draging');
106
106
  }, []);
107
107
  const drop = useCallback(event => {
108
+ const dragTypes = event.dataTransfer.types;
108
109
  targetElement = event.currentTarget;
109
110
  targetElement.classList.remove('sdoc-draging');
110
-
111
+ // Prevent dragging table data to the editor
112
+ if (dragTypes.includes(TABLE_DRAG_KEY)) return;
111
113
  // Drag local image files to sdoc
112
114
  if (event.dataTransfer.files.length > 0) {
113
115
  const [, targetPath] = getNodeEntry(editor, targetElement);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.5.14",
3
+ "version": "0.5.16",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -448,5 +448,7 @@
448
448
  "Create": "Create",
449
449
  "Top_align": "Top",
450
450
  "Center_align": "Middle",
451
- "Bottom_align": "Bottom"
451
+ "Bottom_align": "Bottom",
452
+ "Move_column_count": "Moving {{count}} column(s)",
453
+ "Move_row_count": "Moving {{count}} row(s)"
452
454
  }
@@ -448,5 +448,7 @@
448
448
  "Create": "创建",
449
449
  "Top_align": "顶端对齐",
450
450
  "Center_align": "居中对齐",
451
- "Bottom_align": "底端对齐"
451
+ "Bottom_align": "底端对齐",
452
+ "Move_column_count": "正在移动{{count}}列",
453
+ "Move_row_count": "正在移动{{count}}行"
452
454
  }
@@ -14,15 +14,12 @@
14
14
  />
15
15
  <missing-glyph />
16
16
 
17
- <<<<<<< HEAD
18
17
  <glyph glyph-name="sdoc-center-alignment" unicode="&#58984;" d="M560 896v-128H832v-320h-272v-128H928v-320H560v-128h-96v128H96V320h368v128H192V768h272V896h96zM832 224H192v-128h640v128zM736 672H288v-128h448V672z" horiz-adv-x="1024" />
19
18
 
20
19
  <glyph glyph-name="sdoc-bottom-alignment" unicode="&#58985;" d="M0-64v96h1024v-96H0z m448 192V832H128v-704h320z m-96 96H224V736h128v-512z m544-96V640H576v-512h320z m-96 96h-128V544h128v-320z" horiz-adv-x="1024" />
21
20
 
22
21
  <glyph glyph-name="sdoc-top-alignment" unicode="&#58986;" d="M0 832v-96h1024V832H0z m448-192v-704H128V640h320z m-96-96H224v-512h128V544z m544 96v-512H576V640h320z m-96-96h-128v-320h128V544z" horiz-adv-x="1024" />
23
22
 
24
- =======
25
- >>>>>>> 6ce93a64 (feat: read all)
26
23
  <glyph glyph-name="sdoc-all-read" unicode="&#58973;" d="M883.2 768h121.6c9.6 0 19.2-9.6 19.2-19.2v-60.8c0-6.4-9.6-16-19.2-16h-121.6c-9.6 0-19.2 9.6-19.2 19.2V748.8c0 9.6 9.6 19.2 19.2 19.2z m-284.8-704h406.4c12.8 0 22.4-9.6 22.4-19.2v-60.8c0-9.6-9.6-19.2-22.4-19.2H598.4c-12.8 0-22.4 9.6-22.4 19.2v60.8c0 9.6 9.6 19.2 22.4 19.2z m403.2 352c12.8 0 22.4-9.6 22.4-19.2v-60.8c0-9.6-9.6-19.2-22.4-19.2h-246.4c-12.8 0-22.4 9.6-22.4 19.2v60.8c0 9.6 9.6 19.2 22.4 19.2h246.4zM761.6 860.8c-3.2 3.2-9.6 3.2-12.8 3.2-6.4 0-9.6-3.2-12.8-9.6L304 70.4 67.2 256c-9.6 6.4-22.4 3.2-28.8-6.4L0 188.8c-3.2-9.6 0-22.4 9.6-28.8l336-256L819.2 803.2c6.4 9.6 3.2 22.4-6.4 28.8l-51.2 28.8z" horiz-adv-x="1027" />
27
24
 
28
25
  <glyph glyph-name="sdoc-freezed" unicode="&#58983;" d="M512 384m-512 0a512 512 0 1 1 1024 0 512 512 0 1 1-1024 0ZM316.8 716.8c118.4 70.4 265.6 70.4 384 3.2s192-195.2 192-332.8c0-137.6-73.6-265.6-195.2-332.8-182.4-105.6-416-41.6-521.6 140.8S134.4 608 316.8 716.8z m348.8-604.8c137.6 80 195.2 249.6 131.2 396.8L259.2 195.20000000000005c92.8-124.8 268.8-163.2 406.4-83.2zM352 652.8c-137.6-80-192-249.6-128-393.6l537.6 310.4c-96 128-272 163.2-409.6 83.2z" horiz-adv-x="1024" />