@seafile/sdoc-editor 0.1.125 → 0.1.127

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 (44) hide show
  1. package/dist/basic-sdk/comment/comment/editor-comment.js +11 -2
  2. package/dist/basic-sdk/comment/comment/style.css +1 -0
  3. package/dist/basic-sdk/constants/index.js +2 -1
  4. package/dist/basic-sdk/editor.js +2 -1
  5. package/dist/basic-sdk/extension/constants/index.js +71 -0
  6. package/dist/basic-sdk/extension/index.js +2 -2
  7. package/dist/basic-sdk/extension/plugins/blockquote/render-elem.js +2 -1
  8. package/dist/basic-sdk/extension/plugins/check-list/index.js +2 -2
  9. package/dist/basic-sdk/extension/plugins/check-list/render-elem.js +7 -10
  10. package/dist/basic-sdk/extension/plugins/code-block/render-elem.js +8 -9
  11. package/dist/basic-sdk/extension/plugins/header/render-elem.js +2 -2
  12. package/dist/basic-sdk/extension/plugins/link/menu/add-link-dialog.js +7 -2
  13. package/dist/basic-sdk/extension/plugins/list/render-elem.js +3 -1
  14. package/dist/basic-sdk/extension/plugins/paragraph/render-elem.js +2 -1
  15. package/dist/basic-sdk/extension/plugins/sdoc-link/dialogs/select-sdoc-file-dialog/index.css +55 -0
  16. package/dist/basic-sdk/extension/plugins/sdoc-link/{menu/sdoc-link-file-dialog.js → dialogs/select-sdoc-file-dialog/index.js} +36 -29
  17. package/dist/basic-sdk/extension/plugins/sdoc-link/dialogs/select-sdoc-file-dialog/local-files/index.css +75 -0
  18. package/dist/basic-sdk/extension/plugins/sdoc-link/{menu/local-files.js → dialogs/select-sdoc-file-dialog/local-files/index.js} +42 -32
  19. package/dist/basic-sdk/extension/plugins/sdoc-link/{menu/sdoc-link-hover-menu.js → hover-menu/index.js} +1 -1
  20. package/dist/basic-sdk/extension/plugins/sdoc-link/menu/index.js +3 -3
  21. package/dist/basic-sdk/extension/plugins/sdoc-link/render-elem.js +2 -2
  22. package/dist/basic-sdk/extension/plugins/table/popover/table-size-popover/index.js +11 -4
  23. package/dist/basic-sdk/extension/plugins/table/render/table-root.js +1 -0
  24. package/dist/basic-sdk/extension/render/render-element.js +20 -7
  25. package/dist/basic-sdk/extension/toolbar/index.js +2 -1
  26. package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +121 -0
  27. package/dist/basic-sdk/extension/toolbar/side-toolbar/index.css +24 -0
  28. package/dist/basic-sdk/extension/toolbar/side-toolbar/index.js +123 -0
  29. package/dist/basic-sdk/extension/toolbar/side-toolbar/insert-below-menu.js +23 -0
  30. package/dist/basic-sdk/extension/toolbar/side-toolbar/insert-block-menu.js +95 -0
  31. package/dist/basic-sdk/extension/toolbar/side-toolbar/side-menu-item.js +35 -0
  32. package/dist/basic-sdk/extension/toolbar/side-toolbar/side-menu.css +64 -0
  33. package/dist/basic-sdk/extension/toolbar/side-toolbar/side-menu.js +76 -0
  34. package/dist/basic-sdk/extension/toolbar/side-toolbar/transform-menus.js +41 -0
  35. package/dist/basic-sdk/layout/article-container.js +3 -2
  36. package/dist/basic-sdk/outline/index.js +6 -6
  37. package/dist/basic-sdk/socket/socket-client.js +1 -1
  38. package/dist/basic-sdk/socket/socket-manager.js +0 -4
  39. package/package.json +1 -1
  40. package/public/locales/en/sdoc-editor.json +7 -1
  41. package/public/locales/zh-CN/sdoc-editor.json +8 -1
  42. package/dist/basic-sdk/extension/plugins/sdoc-link/menu/local-files.css +0 -98
  43. package/dist/basic-sdk/extension/plugins/sdoc-link/menu/sdoc-link-file-dialog.css +0 -35
  44. /package/dist/basic-sdk/extension/plugins/sdoc-link/{menu/sdoc-link-hover-menu.css → hover-menu/index.css} +0 -0
@@ -2,12 +2,13 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
3
  import React, { useCallback, useState, useRef, useEffect } from 'react';
4
4
  import { withTranslation } from 'react-i18next';
5
+ import classnames from 'classnames';
5
6
  import slugid from 'slugid';
6
- import context from '../../../../../context';
7
- import { getErrorMsg } from '../../../../../utils';
8
- import toaster from '../../../../../components/toast';
9
- import { getParentPathNameArr, getNewFileListData } from '../helpers';
10
- import './local-files.css';
7
+ import context from '../../../../../../../context';
8
+ import { getErrorMsg } from '../../../../../../../utils';
9
+ import toaster from '../../../../../../../components/toast';
10
+ import { getParentPathNameArr, getNewFileListData } from '../../../helpers';
11
+ import './index.css';
11
12
  var LocalFiles = function LocalFiles(_ref) {
12
13
  var onSelectedFile = _ref.onSelectedFile,
13
14
  toggle = _ref.toggle,
@@ -72,6 +73,7 @@ var LocalFiles = function LocalFiles(_ref) {
72
73
  getFileData(p, item.indexId, fileListData);
73
74
  expandedFolder.add(item.indexId);
74
75
  }
76
+ onSelectedFile(null);
75
77
  setCurrentActiveItem(item);
76
78
  setExpandedFolder(new Set(Array.from(expandedFolder)));
77
79
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -83,51 +85,59 @@ var LocalFiles = function LocalFiles(_ref) {
83
85
  // eslint-disable-next-line react-hooks/exhaustive-deps
84
86
  }, []);
85
87
  var renderFileTree = useCallback(function (data) {
86
- if (!Array.isArray(data)) {
87
- return null;
88
- }
88
+ if (!Array.isArray(data) || data.length === 0) return null;
89
89
  return data.map(function (item) {
90
90
  var _item$children, _item$children2;
91
+ if (!item) return null;
92
+ var type = item.type,
93
+ indexId = item.indexId,
94
+ name = item.name;
95
+ var selected = (currentActiveItem === null || currentActiveItem === void 0 ? void 0 : currentActiveItem.indexId) === indexId;
91
96
  return /*#__PURE__*/React.createElement("div", {
92
- key: item.indexId,
93
- className: "sdoc-local-folder-container"
94
- }, item.type === 'dir' && /*#__PURE__*/React.createElement("div", {
97
+ key: indexId,
98
+ className: "sdoc-folder-container"
99
+ }, type === 'dir' && /*#__PURE__*/React.createElement("div", {
95
100
  ref: folderRef,
96
- className: "sdoc-local-folder",
101
+ className: "sdoc-folder"
102
+ }, /*#__PURE__*/React.createElement("div", {
103
+ className: classnames('sdoc-folder-info sdoc-file-info', {
104
+ 'active': selected,
105
+ 'expanded': expandedFolder.has(indexId)
106
+ }),
97
107
  onClick: function onClick(e) {
98
- onToggle(e, item, fileListData);
108
+ return onToggle(e, item, fileListData);
99
109
  }
100
110
  }, /*#__PURE__*/React.createElement("div", {
101
- className: "sdoc-local-folder-info ".concat((currentActiveItem === null || currentActiveItem === void 0 ? void 0 : currentActiveItem.indexId) === item.indexId ? 'active' : 'inactive')
102
- }, /*#__PURE__*/React.createElement("span", {
103
- className: "".concat(expandedFolder.has(item.indexId) ? 'icon-drop-down-scale' : '')
111
+ className: "sdoc-file-icon-container"
104
112
  }, /*#__PURE__*/React.createElement("i", {
105
- className: "sdocfont ".concat(expandedFolder.has(item.indexId) ? 'sdoc-drop-down' : 'sdoc-right-slide')
106
- })), /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("i", {
107
- className: "sdocfont sdoc-file"
113
+ className: "sdoc-file-icon sdoc-file-icon-toggle sdocfont sdoc-right-slide"
114
+ }), /*#__PURE__*/React.createElement("i", {
115
+ className: "sdoc-file-icon sdocfont sdoc-file sdoc-folder-icon"
108
116
  })), /*#__PURE__*/React.createElement("span", {
109
- className: "sdoc-folder-name"
110
- }, item.name)), /*#__PURE__*/React.createElement("div", {
111
- className: "sdoc-local-folder-children"
112
- }, (item === null || item === void 0 ? void 0 : (_item$children = item.children) === null || _item$children === void 0 ? void 0 : _item$children.length) === 0 && /*#__PURE__*/React.createElement("div", {
113
- className: "sdoc-local-folder-children-empty"
114
- }, t('Empty')), (item === null || item === void 0 ? void 0 : (_item$children2 = item.children) === null || _item$children2 === void 0 ? void 0 : _item$children2.length) > 0 && renderFileTree(item.children))), item.type === 'file' && /*#__PURE__*/React.createElement("div", {
115
- className: "sdoc-local-file-item ".concat((currentActiveItem === null || currentActiveItem === void 0 ? void 0 : currentActiveItem.indexId) === item.indexId ? 'active' : 'inactive'),
117
+ className: "sdoc-folder-name sdoc-file-name"
118
+ }, name)), /*#__PURE__*/React.createElement("div", {
119
+ className: "sdoc-folder-children"
120
+ }, ((_item$children = item.children) === null || _item$children === void 0 ? void 0 : _item$children.length) === 0 && /*#__PURE__*/React.createElement("div", {
121
+ className: "sdoc-folder-children-empty"
122
+ }, "(".concat(t('Empty'), ")")), ((_item$children2 = item.children) === null || _item$children2 === void 0 ? void 0 : _item$children2.length) > 0 && renderFileTree(item.children))), type === 'file' && /*#__PURE__*/React.createElement("div", {
123
+ className: classnames('sdoc-file-info', {
124
+ 'active': selected
125
+ }),
116
126
  onClick: function onClick(e) {
117
127
  onSelectFile(e, item);
118
128
  }
119
- }, /*#__PURE__*/React.createElement("span", {
120
- className: "sdoc-local-file-icon"
129
+ }, /*#__PURE__*/React.createElement("div", {
130
+ className: "sdoc-file-icon-container"
121
131
  }, /*#__PURE__*/React.createElement("i", {
122
- className: "sdocfont sdoc-document"
132
+ className: "sdoc-file-icon sdocfont sdoc-document"
123
133
  })), /*#__PURE__*/React.createElement("span", {
124
- className: "sdoc-local-file-name"
125
- }, item.name)));
134
+ className: "sdoc-file-name"
135
+ }, name)));
126
136
  });
127
137
  // eslint-disable-next-line react-hooks/exhaustive-deps
128
138
  }, [fileListData, currentActiveItem, expandedFolder]);
129
139
  return /*#__PURE__*/React.createElement("div", {
130
- className: "sdoc-local-files-library"
140
+ className: "sdoc-files-tree"
131
141
  }, renderFileTree(fileListData));
132
142
  };
133
143
  export default withTranslation('sdoc-editor')(LocalFiles);
@@ -6,7 +6,7 @@ import { withTranslation } from 'react-i18next';
6
6
  import { ElementPopover } from '../../../commons';
7
7
  import toaster from '../../../../../components/toast';
8
8
  import { getUrl, onCopySdocLinkNode } from '../helpers';
9
- import './sdoc-link-hover-menu.css';
9
+ import './index.css';
10
10
  var SdocLinkHoverMenu = function SdocLinkHoverMenu(_ref) {
11
11
  var editor = _ref.editor,
12
12
  menuPosition = _ref.menuPosition,
@@ -5,7 +5,7 @@ import { withTranslation } from 'react-i18next';
5
5
  import { SDOC_LINK, MENUS_CONFIG_MAP } from '../../../constants';
6
6
  import { MenuItem } from '../../../commons';
7
7
  import { getType, isMenuDisabled } from '../helpers';
8
- import InsertSdocFileDialog from './sdoc-link-file-dialog';
8
+ import SelectSdocFileDialog from '../dialogs/select-sdoc-file-dialog';
9
9
  import './index.css';
10
10
  var SdocLinkMenu = function SdocLinkMenu(_ref) {
11
11
  var isRichEditor = _ref.isRichEditor,
@@ -77,9 +77,9 @@ var SdocLinkMenu = function SdocLinkMenu(_ref) {
77
77
  onMouseDown: onInsertSdocFile
78
78
  }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("i", {
79
79
  className: "sdocfont sdoc-document"
80
- })), /*#__PURE__*/React.createElement("span", null, t('Sdoc_document')))), showInsertDialog && /*#__PURE__*/React.createElement(InsertSdocFileDialog, {
80
+ })), /*#__PURE__*/React.createElement("span", null, t('Sdoc_document')))), showInsertDialog && /*#__PURE__*/React.createElement(SelectSdocFileDialog, {
81
81
  editor: editor,
82
- onDialogToggle: onDialogToggle
82
+ toggle: onDialogToggle
83
83
  }));
84
84
  };
85
85
  export default withTranslation('sdoc-editor')(SdocLinkMenu);
@@ -3,7 +3,7 @@ import React, { useCallback, useEffect, useState, useRef } from 'react';
3
3
  import { Range } from '@seafile/slate';
4
4
  import { useScrollContext } from '../../../hooks/use-scroll-context';
5
5
  import { unwrapLinkNode, getUrl } from './helpers';
6
- import InsertHoverMenu from './menu/sdoc-link-hover-menu';
6
+ import HoverMenu from './hover-menu';
7
7
  import './render-elem.css';
8
8
  var SdocFileLink = function SdocFileLink(_ref) {
9
9
  var editor = _ref.editor,
@@ -104,7 +104,7 @@ var SdocFileLink = function SdocFileLink(_ref) {
104
104
  e.preventDefault();
105
105
  },
106
106
  title: element.title
107
- }, children))), isShowInsertHoverMenu && Range.isCollapsed(editor.selection) && /*#__PURE__*/React.createElement(InsertHoverMenu, {
107
+ }, children))), isShowInsertHoverMenu && Range.isCollapsed(editor.selection) && /*#__PURE__*/React.createElement(HoverMenu, {
108
108
  editor: editor,
109
109
  menuPosition: menuPosition,
110
110
  element: element,
@@ -106,15 +106,22 @@ var TableSizePopover = /*#__PURE__*/function (_Component) {
106
106
  var _this$state2 = this.state,
107
107
  selectedSize = _this$state2.selectedSize,
108
108
  isShowCustomSizeDialog = _this$state2.isShowCustomSizeDialog;
109
- var t = this.props.t;
109
+ var _this$props = this.props,
110
+ _this$props$trigger = _this$props.trigger,
111
+ trigger = _this$props$trigger === void 0 ? 'legacy' : _this$props$trigger,
112
+ _this$props$placement = _this$props.placement,
113
+ placement = _this$props$placement === void 0 ? 'bottom-start' : _this$props$placement,
114
+ popperClassName = _this$props.popperClassName,
115
+ t = _this$props.t;
110
116
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(UncontrolledPopover, {
111
117
  target: this.props.target,
112
118
  className: "sdoc-selected-table-size-popover",
113
- trigger: "legacy",
114
- placement: "bottom-start",
119
+ trigger: trigger,
120
+ placement: placement,
115
121
  hideArrow: true,
116
122
  fade: false,
117
- ref: this.setRef
123
+ ref: this.setRef,
124
+ popperClassName: popperClassName
118
125
  }, /*#__PURE__*/React.createElement("div", {
119
126
  className: "sdoc-selected-table-size-container w-100 h-100 d-flex flex-column"
120
127
  }, /*#__PURE__*/React.createElement("div", {
@@ -34,6 +34,7 @@ var TableRoot = function TableRoot(_ref) {
34
34
  className: classnames('sdoc-table-wrapper position-relative', attributes.className, {
35
35
  'scroll': allWidth > editor.width
36
36
  }),
37
+ "data-root": "true",
37
38
  style: _objectSpread(_objectSpread({}, attributes.style), {}, {
38
39
  maxWidth: editor.width ? editor.width : '100%'
39
40
  })
@@ -1,14 +1,23 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import React from 'react';
2
+ import React, { useCallback } from 'react';
3
3
  import { useSlateStatic } from '@seafile/slate-react';
4
4
  import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, LIST_LIC, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE, SDOC_LINK } from '../constants';
5
5
  import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin } from '../plugins';
6
+ import EventBus from '../../utils/event-bus';
7
+ import { INTERNAL_EVENT } from '../../constants';
6
8
  var CustomElement = function CustomElement(props) {
7
9
  var editor = useSlateStatic();
8
- var element = props.element;
10
+ var element = props.element,
11
+ attributes = props.attributes;
12
+ var onMouseEnter = useCallback(function (event) {
13
+ event.stopPropagation();
14
+ var eventBus = EventBus.getInstance();
15
+ eventBus.dispatch(INTERNAL_EVENT.ON_MOUSE_ENTER_BLOCK, event);
16
+ }, []);
9
17
  switch (element.type) {
10
18
  case PARAGRAPH:
11
19
  {
20
+ attributes['onMouseEnter'] = onMouseEnter;
12
21
  var _ParagraphPlugin$rend = _slicedToArray(ParagraphPlugin.renderElements, 1),
13
22
  renderParagraph = _ParagraphPlugin$rend[0];
14
23
  return renderParagraph(props);
@@ -20,6 +29,7 @@ var CustomElement = function CustomElement(props) {
20
29
  case HEADER5:
21
30
  case HEADER6:
22
31
  {
32
+ attributes['onMouseEnter'] = onMouseEnter;
23
33
  var _HeaderPlugin$renderE = _slicedToArray(HeaderPlugin.renderElements, 1),
24
34
  renderHeader = _HeaderPlugin$renderE[0];
25
35
  return renderHeader(props, editor);
@@ -32,6 +42,7 @@ var CustomElement = function CustomElement(props) {
32
42
  }
33
43
  case BLOCKQUOTE:
34
44
  {
45
+ attributes['onMouseEnter'] = onMouseEnter;
35
46
  var _BlockquotePlugin$ren = _slicedToArray(BlockquotePlugin.renderElements, 1),
36
47
  renderBlockquote = _BlockquotePlugin$ren[0];
37
48
  return renderBlockquote(props, editor);
@@ -45,6 +56,7 @@ var CustomElement = function CustomElement(props) {
45
56
  }
46
57
  case LIST_ITEM:
47
58
  {
59
+ attributes['onMouseEnter'] = onMouseEnter;
48
60
  var _ListPlugin$renderEle2 = _slicedToArray(ListPlugin.renderElements, 2),
49
61
  renderListItem = _ListPlugin$renderEle2[1];
50
62
  return renderListItem(props, editor);
@@ -57,14 +69,14 @@ var CustomElement = function CustomElement(props) {
57
69
  }
58
70
  case CHECK_LIST_ITEM:
59
71
  {
60
- var _CheckListPlugin$rend = _slicedToArray(CheckListPlugin.renderElements, 2),
61
- CheckListItem = _CheckListPlugin$rend[1];
62
- return /*#__PURE__*/React.createElement(CheckListItem, Object.assign({}, props, {
63
- editor: editor
64
- }));
72
+ attributes['onMouseEnter'] = onMouseEnter;
73
+ var _CheckListPlugin$rend = _slicedToArray(CheckListPlugin.renderElements, 1),
74
+ renderCheckListItem = _CheckListPlugin$rend[0];
75
+ return renderCheckListItem(props, editor);
65
76
  }
66
77
  case CODE_BLOCK:
67
78
  {
79
+ attributes['onMouseEnter'] = onMouseEnter;
68
80
  var _CodeBlockPlugin$rend = _slicedToArray(CodeBlockPlugin.renderElements, 1),
69
81
  renderCodeBlock = _CodeBlockPlugin$rend[0];
70
82
  return renderCodeBlock(props, editor);
@@ -83,6 +95,7 @@ var CustomElement = function CustomElement(props) {
83
95
  }
84
96
  case ELEMENT_TYPE.TABLE:
85
97
  {
98
+ attributes['onMouseEnter'] = onMouseEnter;
86
99
  var _TablePlugin$renderEl = _slicedToArray(TablePlugin.renderElements, 1),
87
100
  renderTable = _TablePlugin$renderEl[0];
88
101
  return renderTable(props, editor);
@@ -1,3 +1,4 @@
1
1
  import Toolbar from './header-toolbar';
2
2
  import ContextToolbar from './context-toolbar';
3
- export { Toolbar, ContextToolbar };
3
+ import SideToolbar from './side-toolbar';
4
+ export { Toolbar, ContextToolbar, SideToolbar };
@@ -0,0 +1,121 @@
1
+ import { Transforms, Editor } from '@seafile/slate';
2
+ import { ReactEditor } from '@seafile/slate-react';
3
+ import copy from 'copy-to-clipboard';
4
+ import slugid from 'slugid';
5
+ import { toggleList } from '../../plugins/list/transforms';
6
+ import { generateImageNode } from '../../plugins/image/helpers';
7
+ import { generateEmptyTable } from '../../plugins/table/helpers';
8
+ import { genLinkNode } from '../../plugins/link/helpers';
9
+ import { generateEmptyElement } from '../../core';
10
+ import { ORDERED_LIST, UNORDERED_LIST, PARAGRAPH, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE } from '../../constants';
11
+ export var onSetNodeType = function onSetNodeType(editor, element, type) {
12
+ if (!type) return;
13
+ if ([ORDERED_LIST, UNORDERED_LIST].includes(type)) {
14
+ toggleList(editor, type);
15
+ return;
16
+ }
17
+ if (type === CHECK_LIST_ITEM) {
18
+ var newType = element.type === CHECK_LIST_ITEM ? PARAGRAPH : CHECK_LIST_ITEM;
19
+ Transforms.setNodes(editor, {
20
+ type: newType
21
+ });
22
+ return;
23
+ }
24
+ if (['left', 'center', 'right'].includes(type)) {
25
+ Transforms.setNodes(editor, {
26
+ 'align': type
27
+ });
28
+ return;
29
+ }
30
+ Transforms.setNodes(editor, {
31
+ type: type
32
+ });
33
+ };
34
+ export var setSelection = function setSelection(editor, element) {
35
+ if (element) {
36
+ var path = ReactEditor.findPath(editor, element);
37
+ Transforms.select(editor, path);
38
+ }
39
+ };
40
+ export var onCopyNode = function onCopyNode(editor) {
41
+ var newData = editor.setFragmentData(new DataTransfer());
42
+ copy('copy', {
43
+ onCopy: function onCopy(clipboardData) {
44
+ newData.types.forEach(function (type) {
45
+ var data = newData.getData(type);
46
+ clipboardData.setData(type, data);
47
+ });
48
+ }
49
+ });
50
+ };
51
+ export var onDeleteNode = function onDeleteNode(editor, element) {
52
+ var path = ReactEditor.findPath(editor, element);
53
+ Transforms.removeNodes(editor, {
54
+ at: path
55
+ });
56
+ };
57
+ export var insertBelowImage = function insertBelowImage(editor, src, selection) {
58
+ if (!src) return;
59
+ var p = generateEmptyElement(PARAGRAPH);
60
+ var imageNode = generateImageNode(src);
61
+ p.children[0] = imageNode;
62
+ var path = Editor.path(editor, selection);
63
+ Transforms.insertNodes(editor, p, {
64
+ at: [path[0] + 1]
65
+ });
66
+ };
67
+ export var insertBelowCodeBlock = function insertBelowCodeBlock(editor, language) {
68
+ var newCodeBlockNode = {
69
+ id: slugid.nice(),
70
+ type: CODE_BLOCK,
71
+ language: language,
72
+ style: {
73
+ white_space: 'nowrap' // default nowrap
74
+ },
75
+
76
+ children: [{
77
+ id: slugid.nice(),
78
+ type: CODE_LINE,
79
+ children: [{
80
+ text: '',
81
+ id: slugid.nice()
82
+ }]
83
+ }]
84
+ };
85
+ var path = Editor.path(editor, editor.selection);
86
+ Transforms.insertNodes(editor, newCodeBlockNode, {
87
+ mode: 'highest',
88
+ at: [path[0] + 1]
89
+ });
90
+ };
91
+ export var insertBelowTable = function insertBelowTable(editor, size, selection) {
92
+ if (!size) return;
93
+ var tableNode = generateEmptyTable(editor, size);
94
+ var path = Editor.path(editor, selection);
95
+ Transforms.insertNodes(editor, tableNode, {
96
+ at: [path[0] + 1]
97
+ });
98
+ };
99
+ export var insertBelowLink = function insertBelowLink(editor, title, url) {
100
+ if (!title || !url) return;
101
+ var p = generateEmptyElement(PARAGRAPH);
102
+ var linkNode = genLinkNode(url, title);
103
+ p.children[0] = {
104
+ id: slugid.nice(),
105
+ text: ' '
106
+ };
107
+ p.children[1] = linkNode;
108
+ p.children[2] = {
109
+ id: slugid.nice(),
110
+ text: ' '
111
+ };
112
+ var path = Editor.path(editor, editor.selection);
113
+ Transforms.insertNodes(editor, p, {
114
+ at: [path[0] + 1]
115
+ });
116
+ };
117
+ export var getDomTopHeight = function getDomTopHeight(dom) {
118
+ var HEADER_HEIGHT = 56 + 44;
119
+ var rect = dom.getBoundingClientRect();
120
+ return rect.y - HEADER_HEIGHT;
121
+ };
@@ -0,0 +1,24 @@
1
+ .sdoc-side-toolbar-container {
2
+ position: absolute;
3
+ left: 0px;
4
+ top: 0px;
5
+ }
6
+
7
+ .sdoc-side-toolbar-container .sdoc-side-op-icon {
8
+ border-radius: 3px;
9
+ padding: 0px 3px;
10
+ height: 24px;
11
+ color: #BDBDBD;
12
+ margin-right: 1px;
13
+ transform: rotate(180deg);
14
+ cursor: pointer;
15
+ }
16
+
17
+ .sdoc-side-toolbar-container .sdoc-side-op-icon :first-child {
18
+ font-size: 14px;
19
+ }
20
+
21
+ .sdoc-side-toolbar-container .side-op-icon-active {
22
+ background-color: #F2F2F2;
23
+ border-radius: 2px;
24
+ }
@@ -0,0 +1,123 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
3
+ import classnames from 'classnames';
4
+ import { Node } from '@seafile/slate';
5
+ import { ReactEditor, useSlateStatic } from '@seafile/slate-react';
6
+ import EventBus from '../../../utils/event-bus';
7
+ import { useScrollContext } from '../../../hooks/use-scroll-context';
8
+ import { INTERNAL_EVENT } from '../../../constants';
9
+ import { getDomTopHeight, setSelection } from './helpers';
10
+ import SideMenu from './side-menu';
11
+ import './index.css';
12
+ var SideToolbar = function SideToolbar() {
13
+ var editor = useSlateStatic();
14
+ var scrollRef = useScrollContext();
15
+ var menuRef = useRef(null);
16
+ var _useState = useState(null),
17
+ _useState2 = _slicedToArray(_useState, 2),
18
+ slateNode = _useState2[0],
19
+ setSlateNode = _useState2[1];
20
+ var _useState3 = useState({}),
21
+ _useState4 = _slicedToArray(_useState3, 2),
22
+ sidePosition = _useState4[0],
23
+ setSidePosition = _useState4[1];
24
+ var _useState5 = useState(false),
25
+ _useState6 = _slicedToArray(_useState5, 2),
26
+ isActive = _useState6[0],
27
+ setActive = _useState6[1];
28
+ var _useState7 = useState(false),
29
+ _useState8 = _slicedToArray(_useState7, 2),
30
+ isNodeEmpty = _useState8[0],
31
+ setNodeEmpty = _useState8[1];
32
+ var _useState9 = useState(false),
33
+ _useState10 = _slicedToArray(_useState9, 2),
34
+ isShowSideMenu = _useState10[0],
35
+ setShowSideMenu = _useState10[1];
36
+ var _useState11 = useState({}),
37
+ _useState12 = _slicedToArray(_useState11, 2),
38
+ menuPosition = _useState12[0],
39
+ setMenuPosition = _useState12[1];
40
+ var onReset = useCallback(function () {
41
+ setShowSideMenu(false);
42
+ setMenuPosition({});
43
+ setSlateNode(null);
44
+ setActive(false);
45
+ }, []);
46
+ useEffect(function () {
47
+ var observerRefValue;
48
+ if (isShowSideMenu) {
49
+ scrollRef.current.addEventListener('scroll', onReset);
50
+ observerRefValue = scrollRef.current;
51
+ } else {
52
+ scrollRef.current.removeEventListener('scroll', onReset);
53
+ observerRefValue = null;
54
+ }
55
+ return function () {
56
+ if (observerRefValue) {
57
+ observerRefValue.removeEventListener('scroll', onReset);
58
+ }
59
+ };
60
+ // eslint-disable-next-line react-hooks/exhaustive-deps
61
+ }, [isShowSideMenu]);
62
+ useEffect(function () {
63
+ var handleMouseEnter = function handleMouseEnter(e) {
64
+ if (isShowSideMenu) return;
65
+ var dom = e.target;
66
+ while (((_dom = dom) === null || _dom === void 0 ? void 0 : (_dom$dataset = _dom.dataset) === null || _dom$dataset === void 0 ? void 0 : _dom$dataset.root) !== 'true') {
67
+ var _dom, _dom$dataset;
68
+ if (!dom.parentNode) return;
69
+ dom = dom.parentNode;
70
+ }
71
+ var top = getDomTopHeight(dom);
72
+ var node = ReactEditor.toSlateNode(editor, dom);
73
+ var isEmpty = Node.string(node) === '';
74
+ setSidePosition({
75
+ top: top + scrollRef.current.scrollTop,
76
+ left: 20
77
+ });
78
+ setSlateNode(node);
79
+ setNodeEmpty(isEmpty);
80
+ };
81
+ var eventBus = EventBus.getInstance();
82
+ var unSubscribeMouseEnter = eventBus.subscribe(INTERNAL_EVENT.ON_MOUSE_ENTER_BLOCK, handleMouseEnter);
83
+ return unSubscribeMouseEnter;
84
+ }, [editor, isShowSideMenu, scrollRef]);
85
+ var onActiveToggle = useCallback(function () {
86
+ if (isShowSideMenu) return;
87
+ setActive(!isActive);
88
+ }, [isActive, isShowSideMenu]);
89
+ var onShowSideMenuToggle = useCallback(function () {
90
+ setSelection(editor, slateNode);
91
+ var _menuRef$current$getB = menuRef.current.getBoundingClientRect(),
92
+ top = _menuRef$current$getB.top,
93
+ left = _menuRef$current$getB.left;
94
+ setShowSideMenu(!isShowSideMenu);
95
+ setMenuPosition({
96
+ top: top,
97
+ left: left
98
+ });
99
+ }, [editor, isShowSideMenu, slateNode]);
100
+ var iconClass = classnames('sdocfont', {
101
+ 'sdoc-more-vertical': !isActive,
102
+ 'sdoc-more-vertical-right': isActive && !isNodeEmpty,
103
+ 'sdoc-append': isActive && isNodeEmpty
104
+ });
105
+ return /*#__PURE__*/React.createElement("div", {
106
+ className: "sdoc-side-toolbar-container",
107
+ style: sidePosition
108
+ }, slateNode && /*#__PURE__*/React.createElement("div", {
109
+ ref: menuRef,
110
+ className: "sdoc-side-op-icon",
111
+ onMouseEnter: onActiveToggle,
112
+ onMouseLeave: onActiveToggle,
113
+ onClick: onShowSideMenuToggle
114
+ }, /*#__PURE__*/React.createElement("span", {
115
+ className: iconClass
116
+ })), isShowSideMenu && /*#__PURE__*/React.createElement(SideMenu, {
117
+ slateNode: slateNode,
118
+ isNodeEmpty: isNodeEmpty,
119
+ menuPosition: menuPosition,
120
+ onReset: onReset
121
+ }));
122
+ };
123
+ export default SideToolbar;
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { UncontrolledPopover } from 'reactstrap';
3
+ import { insertBelowImage, insertBelowTable, insertBelowLink, insertBelowCodeBlock } from './helpers';
4
+ import InsertBlockMenu from './insert-block-menu';
5
+ var InsertBelowMenu = function InsertBelowMenu(_ref) {
6
+ var target = _ref.target;
7
+ return /*#__PURE__*/React.createElement(UncontrolledPopover, {
8
+ target: target,
9
+ className: "sdoc-side-menu-insert-below-popover",
10
+ trigger: "hover",
11
+ placement: "right-start",
12
+ hideArrow: true,
13
+ fade: false
14
+ }, /*#__PURE__*/React.createElement("div", {
15
+ className: "sdoc-side-inner-menu"
16
+ }, /*#__PURE__*/React.createElement(InsertBlockMenu, {
17
+ insertImage: insertBelowImage,
18
+ insertTable: insertBelowTable,
19
+ insertLink: insertBelowLink,
20
+ insertCodeBlock: insertBelowCodeBlock
21
+ })));
22
+ };
23
+ export default InsertBelowMenu;