@seafile/sdoc-editor 1.0.39 → 1.0.41

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,6 +4,8 @@
4
4
  }
5
5
 
6
6
  .sdoc-dropdown-menu .sdoc-seatable-selected-table-list-wrapper {
7
+ position: absolute;
8
+ background-color: #ffff;
7
9
  max-height: 300px;
8
10
  overflow: auto;
9
11
  }
@@ -17,7 +17,8 @@ const withCallout = editor => {
17
17
  insertFragment,
18
18
  deleteBackward,
19
19
  onHotKeyDown,
20
- insertData
20
+ insertData,
21
+ onCopy
21
22
  } = editor;
22
23
  const newEditor = editor;
23
24
  newEditor.deleteBackward = unit => {
@@ -105,6 +106,7 @@ const withCallout = editor => {
105
106
  if (getCalloutEntry(editor)) {
106
107
  event.stopPropagation();
107
108
  }
109
+ return onCopy(event);
108
110
  };
109
111
  return newEditor;
110
112
  };
@@ -1,4 +1,4 @@
1
- import React, { useMemo, useCallback } from 'react';
1
+ import React, { useMemo, useCallback, useRef, useEffect, useState } from 'react';
2
2
  import { COLUMNS_ICON_CONFIG } from '../constants/column';
3
3
  import { insertSeaTableColumn, getColumnType } from '../helpers';
4
4
  import { COLUMN } from '../../../constants/element-type';
@@ -9,7 +9,21 @@ export default function ColumnListMenu(_ref) {
9
9
  editor,
10
10
  insertPosition
11
11
  } = _ref;
12
- const computedBottom = insertPosition ? '0px' : '';
12
+ const columnRef = useRef(null);
13
+ const [computedStyle, setComputedStyle] = useState({});
14
+ useEffect(() => {
15
+ if (insertPosition) {
16
+ setComputedStyle({
17
+ bottom: '0px'
18
+ });
19
+ }
20
+ if (!insertPosition && (columnRef === null || columnRef === void 0 ? void 0 : columnRef.current)) {
21
+ const centerPosition = parseInt(columnRef.current.getBoundingClientRect().height / 2);
22
+ setComputedStyle({
23
+ top: "-".concat(centerPosition, "px")
24
+ });
25
+ }
26
+ }, [insertPosition]);
13
27
  const columns = useMemo(() => {
14
28
  if (!editor.columns) return [];
15
29
  return editor.columns.filter(column => !NOT_SUPPORT_COLUMN_TYPES.includes(column.type));
@@ -32,10 +46,9 @@ export default function ColumnListMenu(_ref) {
32
46
  insertSeaTableColumn(editor, active, option, insertPosition);
33
47
  }, [editor, insertPosition]);
34
48
  return /*#__PURE__*/React.createElement("div", {
49
+ ref: columnRef,
35
50
  className: "column-list-menu",
36
- style: {
37
- bottom: computedBottom
38
- }
51
+ style: computedStyle
39
52
  }, options.map(option => {
40
53
  return /*#__PURE__*/React.createElement("div", {
41
54
  key: option.value,
@@ -1,8 +1,9 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useRef } from 'react';
2
2
  import { UncontrolledPopover } from 'reactstrap';
3
3
  import { insertSeaTableTable, isInsertSeaTableTableDisabled } from '../helpers';
4
4
  import { MENUS_CONFIG_MAP, SEATABLE_TABLE } from '../../../constants';
5
5
  import DropdownMenuItem from '../../../commons/dropdown-menu-item';
6
+ import SeaTableList from './seatable-list';
6
7
  import './index.css';
7
8
  const SeaTableTableMenu = _ref => {
8
9
  let {
@@ -10,10 +11,9 @@ const SeaTableTableMenu = _ref => {
10
11
  readonly,
11
12
  insertPosition
12
13
  } = _ref;
14
+ const seatableRef = useRef(null);
13
15
  const disabled = isInsertSeaTableTableDisabled(editor, readonly);
14
16
  const menuConfig = MENUS_CONFIG_MAP[SEATABLE_TABLE];
15
- const computedBottom = insertPosition ? '0px' : '';
16
- const tables = editor.tables;
17
17
  const onViewClick = useCallback(item => {
18
18
  insertSeaTableTable(editor, item, insertPosition);
19
19
  }, [editor, insertPosition]);
@@ -29,18 +29,13 @@ const SeaTableTableMenu = _ref => {
29
29
  className: "sdoc-menu-popover sdoc-dropdown-menu sdoc-sub-dropdown-menu",
30
30
  placement: "right-start",
31
31
  hideArrow: true,
32
- fade: false
33
- }, /*#__PURE__*/React.createElement("div", {
34
- className: "sdoc-dropdown-menu-container sdoc-seatable-selected-table-list-wrapper",
35
- style: {
36
- bottom: computedBottom
37
- }
38
- }, tables.map(item => {
39
- return /*#__PURE__*/React.createElement("div", {
40
- key: item._id,
41
- className: "sdoc-dropdown-menu-item",
42
- onClick: () => onViewClick(item)
43
- }, item.name);
44
- })))));
32
+ fade: false,
33
+ ref: seatableRef
34
+ }, /*#__PURE__*/React.createElement(SeaTableList, {
35
+ editor: editor,
36
+ readonly: readonly,
37
+ insertPosition: insertPosition,
38
+ onViewClick: onViewClick
39
+ }))));
45
40
  };
46
41
  export default SeaTableTableMenu;
@@ -0,0 +1,37 @@
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ const SeaTableList = _ref => {
3
+ let {
4
+ editor,
5
+ insertPosition,
6
+ onViewClick
7
+ } = _ref;
8
+ const seatableRef = useRef(null);
9
+ const [computedStyle, setComputedStyle] = useState({});
10
+ const tables = editor.tables;
11
+ useEffect(() => {
12
+ if (insertPosition) {
13
+ setComputedStyle({
14
+ bottom: '0px'
15
+ });
16
+ }
17
+ if (!insertPosition && (seatableRef === null || seatableRef === void 0 ? void 0 : seatableRef.current)) {
18
+ const centerPosition = parseInt(seatableRef.current.getBoundingClientRect().height / 2);
19
+ // 30 is seatable menu height
20
+ setComputedStyle({
21
+ top: "-".concat(centerPosition + 30, "px")
22
+ });
23
+ }
24
+ }, [insertPosition]);
25
+ return /*#__PURE__*/React.createElement("div", {
26
+ ref: seatableRef,
27
+ className: "sdoc-dropdown-menu-container sdoc-seatable-selected-table-list-wrapper",
28
+ style: computedStyle
29
+ }, tables.map(item => {
30
+ return /*#__PURE__*/React.createElement("div", {
31
+ key: item._id,
32
+ className: "sdoc-dropdown-menu-item",
33
+ onClick: () => onViewClick(item)
34
+ }, item.name);
35
+ }));
36
+ };
37
+ export default SeaTableList;
@@ -10,7 +10,7 @@ import { ORDERED_LIST, UNORDERED_LIST, PARAGRAPH, CHECK_LIST_ITEM, IMAGE, TABLE,
10
10
  import { EMPTY_SELECTED_RANGE } from '../../plugins/table/constants';
11
11
  import { unwrapCallout, wrapCallout } from '../../plugins/callout/helper';
12
12
  import { convertToCheck } from '../../plugins/check-list/helpers';
13
- import { getHeaderHeight } from '../../../utils/dom-utils';
13
+ import { WIKI_EDITOR } from '../../../constants';
14
14
  export const onSetNodeType = (editor, element, type) => {
15
15
  if (!type) return;
16
16
  if (type === CALL_OUT) {
@@ -92,18 +92,29 @@ export const onDeleteNode = (editor, element) => {
92
92
  at: path
93
93
  });
94
94
  };
95
- export const getDomTopHeight = (editor, dom, slateNode) => {
96
- const rect = dom.getBoundingClientRect();
95
+ export const getTopValue = (editor, dom, containerDom, slateNode) => {
96
+ if (!dom) return 0;
97
+ if (!containerDom) return 0;
98
+ const currentRect = dom.getBoundingClientRect();
99
+ let containerRect = containerDom.getBoundingClientRect();
100
+ let headerHeight = 0;
101
+ if (editor.editorType === WIKI_EDITOR) {
102
+ const titleDom = document.getElementById('wiki-page-title');
103
+ const coverDom = document.getElementById('wiki-page-cover');
104
+ const titleHeight = (titleDom === null || titleDom === void 0 ? void 0 : titleDom.getBoundingClientRect().height) || 0;
105
+ const coverHeight = (coverDom === null || coverDom === void 0 ? void 0 : coverDom.getBoundingClientRect().height) || 0;
106
+ headerHeight = titleHeight + coverHeight;
107
+ }
108
+ const top = currentRect.y - containerRect.y + containerDom.scrollTop;
97
109
  let offsetY = 0;
98
- const iconOffset = 4; // ensure icon is in the middle of the line
99
- const headerHeight = getHeaderHeight(editor);
100
- const paddingTop = parseFloat(window.getComputedStyle(dom).getPropertyValue('padding-top'));
110
+ let paddingTop = parseFloat(window.getComputedStyle(dom).getPropertyValue('padding-top'));
101
111
  const lineHeight = parseFloat(window.getComputedStyle(dom).getPropertyValue('line-height'));
102
- const disToolBarHeight = 12; // side toolbar icon is 12 px
112
+ const disToolBarHeight = 21; // side toolbar icon line-height is 21
103
113
  if (ADD_POSITION_OFFSET_TYPE.includes(slateNode.type)) {
114
+ paddingTop = slateNode.type === CHECK_LIST_ITEM ? 5 : paddingTop;
104
115
  offsetY = lineHeight / 2 + paddingTop - disToolBarHeight / 2;
105
116
  }
106
- return rect.y - headerHeight + offsetY - iconOffset;
117
+ return top + offsetY - headerHeight;
107
118
  };
108
119
  export const isVoidNode = node => {
109
120
  if (!node) return true;
@@ -6,7 +6,7 @@ import SideMenu from './side-menu';
6
6
  import EventBus from '../../../utils/event-bus';
7
7
  import { useScrollContext } from '../../../hooks/use-scroll-context';
8
8
  import { focusEditor } from '../../core';
9
- import { getDomTopHeight, setSelection, isVoidNode, getNodeEntry, isBlockquote, isList, onWrapListItem } from './helpers';
9
+ import { setSelection, isVoidNode, getNodeEntry, isBlockquote, isList, onWrapListItem, getTopValue } from './helpers';
10
10
  import { insertImageFiles } from '../../plugins/image/helpers';
11
11
  import { INTERNAL_EVENT, WIKI_EDITOR } from '../../../constants';
12
12
  import { CODE_BLOCK, TABLE, BLOCKQUOTE, CHECK_LIST_ITEM, CALL_OUT, TABLE_DRAG_KEY } from '../../constants';
@@ -72,10 +72,9 @@ const SideToolbar = () => {
72
72
  dom = dom.parentNode;
73
73
  }
74
74
  const node = ReactEditor.toSlateNode(editor, dom);
75
- const top = getDomTopHeight(editor, dom, node);
76
75
  const isEmpty = isVoidNode(node);
77
- const offsetY = !editor.editorType ? -1 : 0; // editorType is undefined means sdoc editor
78
- const topValue = top + scrollRef.current.scrollTop + offsetY;
76
+ const containerDom = scrollRef.current;
77
+ const topValue = getTopValue(editor, dom, containerDom, node);
79
78
  if (topValue !== sidePosition.top) setIsMoving(true);
80
79
  let left = 20;
81
80
  if (editor.editorType === WIKI_EDITOR) {
@@ -1,4 +1,3 @@
1
- import { WIKI_EDITOR, DOCUMENT_PLUGIN_EDITOR } from '../constants';
2
1
  export const getDomHeight = dom => {
3
2
  const styles = window.getComputedStyle(dom);
4
3
  const rect = dom.getBoundingClientRect();
@@ -45,25 +44,4 @@ export const getCursorPosition = function () {
45
44
  x: x,
46
45
  y: y
47
46
  };
48
- };
49
-
50
- /**
51
- * Get the height of the header of the editor
52
- * @param {Editor} editor
53
- * @returns {Number} height of the header
54
- */
55
- export const getHeaderHeight = editor => {
56
- const {
57
- editorType
58
- } = editor;
59
- switch (editorType) {
60
- case WIKI_EDITOR:
61
- return (editor === null || editor === void 0 ? void 0 : editor.getHeaderHeight()) || 0;
62
- case DOCUMENT_PLUGIN_EDITOR:
63
- return 67 + 48 + 49 + 37;
64
- default:
65
- // sdoc-editor-page-header height = 56
66
- // sdoc-editor-toolbar height = 37
67
- return 56 + 37;
68
- }
69
47
  };
@@ -14,7 +14,6 @@ const SdocWikiEditor = _ref => {
14
14
  document,
15
15
  docUuid,
16
16
  isWikiReadOnly,
17
- getHeaderHeight,
18
17
  scrollRef
19
18
  } = _ref;
20
19
  context.initApi();
@@ -37,7 +36,6 @@ const SdocWikiEditor = _ref => {
37
36
  newEditor.cursors = cursors || {};
38
37
  newEditor.width = PAGE_EDIT_AREA_WIDTH; // default width
39
38
  newEditor.editorType = WIKI_EDITOR;
40
- newEditor.getHeaderHeight = getHeaderHeight;
41
39
  return newEditor;
42
40
 
43
41
  // eslint-disable-next-line react-hooks/exhaustive-deps
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",