@seafile/sdoc-editor 0.1.88 → 0.1.89

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 (30) hide show
  1. package/dist/basic-sdk/assets/css/dropdown-menu.css +6 -0
  2. package/dist/basic-sdk/assets/css/layout.css +2 -0
  3. package/dist/basic-sdk/editor.js +2 -2
  4. package/dist/basic-sdk/extension/commons/{modal-portal → element-popover}/index.js +11 -8
  5. package/dist/basic-sdk/extension/constants/index.js +4 -2
  6. package/dist/basic-sdk/extension/index.js +2 -1
  7. package/dist/basic-sdk/extension/menu/color-menu/color-item.js +2 -2
  8. package/dist/basic-sdk/extension/menu/color-menu/index.css +47 -19
  9. package/dist/basic-sdk/extension/menu/color-menu/index.js +38 -27
  10. package/dist/basic-sdk/extension/menu/menu.css +52 -1
  11. package/dist/basic-sdk/extension/plugins/code-block/hover-menu/index.js +3 -3
  12. package/dist/basic-sdk/extension/plugins/link/render-elem.js +2 -1
  13. package/dist/basic-sdk/extension/plugins/table/dialog/custom-table-size-dialog/index.js +1 -1
  14. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/common-menu.js +9 -5
  15. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/index.css +16 -7
  16. package/dist/basic-sdk/extension/plugins/table/menu/active-table-menu/index.js +6 -4
  17. package/dist/basic-sdk/extension/plugins/table/menu/table-context-menu/index.js +3 -3
  18. package/dist/basic-sdk/extension/plugins/table/render/render-cell.js +2 -2
  19. package/dist/basic-sdk/extension/plugins/text-align/menu/index.js +81 -110
  20. package/dist/basic-sdk/extension/plugins/text-style/menu/index.js +5 -2
  21. package/dist/basic-sdk/extension/toolbar/context-toolbar/index.css +10 -0
  22. package/dist/basic-sdk/extension/toolbar/context-toolbar/index.js +55 -0
  23. package/dist/basic-sdk/hooks/use-selection-position.js +11 -3
  24. package/dist/components/more-dropdown/index.js +36 -73
  25. package/dist/layout/layout.css +3 -0
  26. package/dist/utils/local-storage-utils.js +16 -2
  27. package/package.json +1 -1
  28. package/dist/basic-sdk/extension/plugins/text-align/menu/style.css +0 -53
  29. package/dist/components/more-dropdown/style.css +0 -64
  30. /package/dist/basic-sdk/extension/plugins/table/{number-input.js → dialog/custom-table-size-dialog/number-input.js} +0 -0
@@ -16,8 +16,14 @@
16
16
  width: 100%;
17
17
  padding: 4px 24px;
18
18
  user-select: none;
19
+ display: flex;
20
+ align-items: center;
19
21
  }
20
22
 
21
23
  .sdoc-dropdown-menu .sdoc-dropdown-menu-item:hover {
22
24
  background-color: rgb(245, 245, 245);
23
25
  }
26
+
27
+ .sdoc-dropdown-menu .sdoc-dropdown-menu-item .sdocfont {
28
+ font-size: 14px;
29
+ }
@@ -14,6 +14,8 @@
14
14
  background-color: #fff;
15
15
  user-select: none;
16
16
  border-bottom: 1px solid #e5e6e8;
17
+ position: relative;
18
+ z-index: 102;
17
19
  }
18
20
 
19
21
  .sdoc-editor-container .sdoc-editor-content {
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
4
- import defaultEditor, { renderLeaf, renderElement, Toolbar } from './extension';
4
+ import defaultEditor, { renderLeaf, renderElement, Toolbar, ContextToolbar } from './extension';
5
5
  import { focusEditor, getAboveBlockNode, getNextNode, getPrevNode, isSelectionAtBlockEnd, isSelectionAtBlockStart } from './extension/core';
6
6
  import { withSocketIO } from './socket';
7
7
  import withNodeId from './node-id';
@@ -232,7 +232,7 @@ var SDocEditor = function SDocEditor(_ref) {
232
232
  editor: editor,
233
233
  value: slateValue,
234
234
  onChange: onChange
235
- }, /*#__PURE__*/React.createElement(CommentContextProvider, null, /*#__PURE__*/React.createElement("div", {
235
+ }, /*#__PURE__*/React.createElement(ContextToolbar, null), /*#__PURE__*/React.createElement(CommentContextProvider, null, /*#__PURE__*/React.createElement("div", {
236
236
  className: "article",
237
237
  ref: articleRef
238
238
  }, /*#__PURE__*/React.createElement(SetNodeToDecorations, null), /*#__PURE__*/React.createElement(Editable, {
@@ -4,12 +4,12 @@ import _inherits from "@babel/runtime/helpers/esm/inherits";
4
4
  import _createSuper from "@babel/runtime/helpers/esm/createSuper";
5
5
  import React from 'react';
6
6
  import ReactDOM from 'react-dom';
7
- var ModalPortal = /*#__PURE__*/function (_React$Component) {
8
- _inherits(ModalPortal, _React$Component);
9
- var _super = _createSuper(ModalPortal);
10
- function ModalPortal(props) {
7
+ var ElementPopover = /*#__PURE__*/function (_React$Component) {
8
+ _inherits(ElementPopover, _React$Component);
9
+ var _super = _createSuper(ElementPopover);
10
+ function ElementPopover(props) {
11
11
  var _this;
12
- _classCallCheck(this, ModalPortal);
12
+ _classCallCheck(this, ElementPopover);
13
13
  _this = _super.call(this, props);
14
14
  _this.state = {
15
15
  isMounted: false
@@ -18,9 +18,12 @@ var ModalPortal = /*#__PURE__*/function (_React$Component) {
18
18
  if (props.className) {
19
19
  _this.el.className = props.className;
20
20
  }
21
+ if (props.style) {
22
+ _this.el.style = props.style;
23
+ }
21
24
  return _this;
22
25
  }
23
- _createClass(ModalPortal, [{
26
+ _createClass(ElementPopover, [{
24
27
  key: "componentDidMount",
25
28
  value: function componentDidMount() {
26
29
  document.body.appendChild(this.el);
@@ -36,6 +39,6 @@ var ModalPortal = /*#__PURE__*/function (_React$Component) {
36
39
  return ReactDOM.createPortal(this.props.children, this.el);
37
40
  }
38
41
  }]);
39
- return ModalPortal;
42
+ return ElementPopover;
40
43
  }(React.Component);
41
- export default ModalPortal;
44
+ export default ElementPopover;
@@ -72,7 +72,8 @@ export var MENUS_CONFIG_MAP = (_MENUS_CONFIG_MAP = {}, _defineProperty(_MENUS_CO
72
72
  text: 'Highlight_color',
73
73
  type: HIGHLIGHT_COLOR,
74
74
  isColor: true,
75
- localStorageKey: 'sdoc-recent-used-highlight-colors'
75
+ recentUsedColorsKey: 'sdoc-recent-used-highlight-colors',
76
+ lastUsedColorKey: 'sdoc-last-used-highlight-color'
76
77
  }, {
77
78
  id: "sdoc-font-".concat(COLOR),
78
79
  iconClass: 'sdocfont sdoc-font-color',
@@ -80,7 +81,8 @@ export var MENUS_CONFIG_MAP = (_MENUS_CONFIG_MAP = {}, _defineProperty(_MENUS_CO
80
81
  type: COLOR,
81
82
  defaultColor: DEFAULT_FONT_COLOR,
82
83
  isColor: true,
83
- localStorageKey: 'sdoc-recent-used-font-colors'
84
+ recentUsedColorsKey: 'sdoc-recent-used-font-colors',
85
+ lastUsedColorKey: 'sdoc-last-used-font-color'
84
86
  }]), _defineProperty(_MENUS_CONFIG_MAP, TEXT_STYLE_MORE, [{
85
87
  id: STRIKETHROUGH,
86
88
  iconClass: 'sdocfont sdoc-strikethrough',
@@ -5,6 +5,7 @@ import Plugins from './plugins';
5
5
  import renderElement from './render/render-element';
6
6
  import renderLeaf from './render/render-leaf';
7
7
  import Toolbar from './toolbar';
8
+ import ContextToolbar from './toolbar/context-toolbar';
8
9
  var baseEditor = withHistory(withReact(createEditor()));
9
10
  var defaultEditor = Plugins.reduce(function (editor, pluginItem) {
10
11
  var withPlugin = pluginItem.editorPlugin;
@@ -14,4 +15,4 @@ var defaultEditor = Plugins.reduce(function (editor, pluginItem) {
14
15
  return editor;
15
16
  }, baseEditor);
16
17
  export default defaultEditor;
17
- export { renderLeaf, renderElement, Toolbar };
18
+ export { renderLeaf, renderElement, Toolbar, ContextToolbar };
@@ -4,10 +4,10 @@ import classnames from 'classnames';
4
4
  var ColorItem = function ColorItem(_ref) {
5
5
  var t = _ref.t,
6
6
  color = _ref.color,
7
- recentUsedColor = _ref.recentUsedColor;
7
+ lastUsedColor = _ref.lastUsedColor;
8
8
  return /*#__PURE__*/React.createElement("div", {
9
9
  className: classnames('sdoc-color-item', {
10
- 'selected': recentUsedColor === color.value
10
+ 'selected': lastUsedColor === color.value
11
11
  }),
12
12
  style: {
13
13
  backgroundColor: color.value
@@ -1,31 +1,45 @@
1
- .menu-group .sdoc-color-menu {
2
- width: 48px;
1
+ .menu-group .sdoc-color-menu.menu-show {
2
+ background: #e5e5e5;
3
+ border-radius: 2px;
4
+ }
5
+
6
+ .menu-group .sdoc-color-menu .last-used-color-container {
7
+ height: 100%;
3
8
  display: flex;
4
- align-items: center;
9
+ flex-direction: column;
5
10
  justify-content: center;
11
+ align-items: center;
6
12
  }
7
13
 
8
- .menu-group .sdoc-color-menu.disabled {
9
- width: 30px;
14
+ .menu-group .sdoc-color-menu .last-used-color-container.disabled {
15
+ padding-right: 0;
10
16
  }
11
17
 
12
- .menu-group .sdoc-color-menu.disabled .sdoc-color-toggle-icon {
13
- display: none;
18
+ .menu-group .sdoc-color-menu .sdoc-color-toggle {
19
+ height: 100%;
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+ }
24
+
25
+ .menu-group .sdoc-color-menu .sdoc-color-toggle:hover,
26
+ .menu-group .sdoc-color-menu .last-used-color-container:not(.disabled):hover {
27
+ background-color: rgba(0, 0, 0, 0.08);
14
28
  }
15
29
 
16
- .sdoc-color-menu .sdoc-color-toggle-icon {
17
- font-size: 14px;
18
- transform: scale(.8);
30
+ .menu-group .sdoc-color-menu.disabled .sdoc-color-toggle {
31
+ display: none;
19
32
  }
20
33
 
21
34
  .sdoc-color-menu .sdoc-color-icon {
22
35
  font-size: 12px !important;
23
36
  height: 12px;
37
+ width: 12px;
24
38
  line-height: 12px;
25
39
  }
26
40
 
27
- .sdoc-color-menu .recent-used-color {
28
- width: 12px;
41
+ .sdoc-color-menu .last-used-color {
42
+ width: 14px;
29
43
  height: 3px;
30
44
  border-radius: 1px;
31
45
  margin-top: 2px;
@@ -33,7 +47,7 @@
33
47
  }
34
48
 
35
49
  .sdoc-color-menu-popover .popover {
36
- left: -26px !important;
50
+ left: -30px !important;
37
51
  }
38
52
 
39
53
  .sdoc-color-menu-popover .sdoc-color-dropdown-menu {
@@ -64,6 +78,7 @@
64
78
  }
65
79
 
66
80
  .sdoc-color-menu-popover .sdoc-color-item {
81
+ position: relative;
67
82
  height: 20px;
68
83
  width: 20px;
69
84
  margin-right: 3px;
@@ -71,17 +86,24 @@
71
86
  border: 0.5px solid rgba(0, 0, 0, .08);
72
87
  }
73
88
 
74
- .sdoc-color-menu-popover .sdoc-color-item.selected {
75
- position: relative;
89
+ .sdoc-color-menu-popover .sdoc-color-item:not(.selected):hover::before {
90
+ content: '';
91
+ position: absolute;
92
+ width: calc(100% + 5px);
93
+ height: calc((100% + 5px));
94
+ top: -2.5px;
95
+ left: -2.5px;
96
+ pointer-events: none;
97
+ border: 1px solid rgba(0, 0, 0, .24);
76
98
  }
77
99
 
78
100
  .sdoc-color-menu-popover .sdoc-color-item.selected::after {
79
101
  content: '';
80
102
  position: absolute;
81
- width: calc(100% + 4px);
82
- height: calc((100% + 4px));
83
- top: -2px;
84
- left: -2px;
103
+ width: calc(100% + 5px);
104
+ height: calc((100% + 5px));
105
+ top: -2.5px;
106
+ left: -2.5px;
85
107
  pointer-events: none;
86
108
  border: 1px solid rgba(0, 0, 0, .88);
87
109
  }
@@ -131,3 +153,9 @@
131
153
  .sdoc-more-colors-popover .popover {
132
154
  left: 10px !important;
133
155
  }
156
+
157
+ /* commission */
158
+ .menu-group #button-sdoc-highlight-color .sdoc-color-icon {
159
+ position: relative;
160
+ left: 1px;
161
+ }
@@ -4,7 +4,7 @@ import { withTranslation } from 'react-i18next';
4
4
  import classnames from 'classnames';
5
5
  import { UncontrolledPopover, UncontrolledTooltip } from 'reactstrap';
6
6
  import { ChromePicker } from 'react-color';
7
- import { DEFAULT_COLORS, STANDARD_COLORS, DEFAULT_RECENT_USED_COLORS, TRANSPARENT } from '../../constants';
7
+ import { DEFAULT_COLORS, STANDARD_COLORS, DEFAULT_RECENT_USED_COLORS } from '../../constants';
8
8
  import { LocalStorage } from '../../../../utils';
9
9
  import { eventStopPropagation } from '../../../utils/mouse-event';
10
10
  import ColorItem from './color-item';
@@ -14,44 +14,52 @@ var ColorMenu = function ColorMenu(_ref) {
14
14
  id = _ref.id,
15
15
  isRichEditor = _ref.isRichEditor,
16
16
  className = _ref.className,
17
+ popoverClassName = _ref.popoverClassName,
17
18
  disabled = _ref.disabled,
18
19
  t = _ref.t,
19
20
  setColor = _ref.setColor,
20
- localStorageKey = _ref.localStorageKey,
21
+ recentUsedColorsKey = _ref.recentUsedColorsKey,
22
+ lastUsedColorKey = _ref.lastUsedColorKey,
21
23
  text = _ref.text,
22
24
  defaultColorTip = _ref.defaultColorTip,
23
25
  defaultColor = _ref.defaultColor;
24
26
  var popoverRef = useRef(null);
25
27
  var moreColorsPopoverRef = useRef(null);
26
- var _useState = useState(LocalStorage.getItem(localStorageKey, DEFAULT_RECENT_USED_COLORS)),
28
+ var _useState = useState(LocalStorage.getItem(lastUsedColorKey, '')),
27
29
  _useState2 = _slicedToArray(_useState, 2),
28
- recentUsedColors = _useState2[0],
29
- setRecentUsedColors = _useState2[1];
30
- var _useState3 = useState(false),
30
+ lastUsedColor = _useState2[0],
31
+ setLastUseColor = _useState2[1];
32
+ var _useState3 = useState(LocalStorage.getItem(recentUsedColorsKey, DEFAULT_RECENT_USED_COLORS)),
31
33
  _useState4 = _slicedToArray(_useState3, 2),
32
- isShowMenu = _useState4[0],
33
- setMenuShow = _useState4[1];
34
+ recentUsedColors = _useState4[0],
35
+ setRecentUsedColors = _useState4[1];
34
36
  var _useState5 = useState(false),
35
37
  _useState6 = _slicedToArray(_useState5, 2),
36
- isPickerShow = _useState6[0],
37
- setPickerShow = _useState6[1];
38
+ isShowMenu = _useState6[0],
39
+ setMenuShow = _useState6[1];
40
+ var _useState7 = useState(false),
41
+ _useState8 = _slicedToArray(_useState7, 2),
42
+ isPickerShow = _useState8[0],
43
+ setPickerShow = _useState8[1];
38
44
  var onSetColor = useCallback(function (color) {
39
45
  var shouldClose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
40
- var validColor = color || TRANSPARENT;
46
+ var validColor = color || '';
41
47
  setColor(validColor);
42
- if (validColor !== TRANSPARENT && recentUsedColors[0] !== validColor) {
48
+ if (validColor !== '' && recentUsedColors[0] !== validColor) {
43
49
  var newRecentUsedColors = recentUsedColors.slice(0, 9);
44
50
  newRecentUsedColors.unshift(validColor);
45
- LocalStorage.setItem(localStorageKey, newRecentUsedColors);
51
+ LocalStorage.setItem(recentUsedColorsKey, newRecentUsedColors);
46
52
  setRecentUsedColors(newRecentUsedColors);
47
53
  }
54
+ LocalStorage.setItem(lastUsedColorKey, validColor);
55
+ setLastUseColor(validColor);
48
56
  if (shouldClose) {
49
57
  popoverRef.current.toggle();
50
58
  setMenuShow(!isShowMenu);
51
59
  }
52
60
 
53
61
  // eslint-disable-next-line react-hooks/exhaustive-deps
54
- }, [recentUsedColors, localStorageKey, isShowMenu, isPickerShow]);
62
+ }, [recentUsedColors, recentUsedColorsKey, isShowMenu, isPickerShow]);
55
63
  var setColorProxy = useCallback(function (event) {
56
64
  if (event.target.className.includes('sdoc-color-item')) {
57
65
  var color = event.target.dataset.color;
@@ -59,7 +67,7 @@ var ColorMenu = function ColorMenu(_ref) {
59
67
  }
60
68
 
61
69
  // eslint-disable-next-line react-hooks/exhaustive-deps
62
- }, [recentUsedColors, localStorageKey, isShowMenu, isPickerShow]);
70
+ }, [recentUsedColors, recentUsedColorsKey, isShowMenu, isPickerShow]);
63
71
  var toggle = useCallback(function () {
64
72
  if (isPickerShow) return;
65
73
  popoverRef.current.toggle();
@@ -84,7 +92,8 @@ var ColorMenu = function ColorMenu(_ref) {
84
92
 
85
93
  // eslint-disable-next-line react-hooks/exhaustive-deps
86
94
  }, []);
87
- var validClassName = classnames(className, 'sdoc-color-menu', {
95
+ var validClassName = classnames(className, 'sdoc-color-menu sdoc-menu-with-dropdown', {
96
+ 'menu-show': isShowMenu,
88
97
  'disabled': disabled,
89
98
  'rich-icon-btn d-flex': isRichEditor,
90
99
  'rich-icon-btn-disabled': isRichEditor && disabled,
@@ -104,28 +113,30 @@ var ColorMenu = function ColorMenu(_ref) {
104
113
  id: buttonId,
105
114
  disabled: disabled
106
115
  }, /*#__PURE__*/React.createElement("div", {
107
- className: classnames('d-flex flex-column justify-content-center h-100 pt-1', {
108
- 'mr-1': !disabled
116
+ className: classnames('last-used-color-container sdoc-menu-with-dropdown-icon', {
117
+ 'disabled': disabled
109
118
  }),
110
119
  onClick: setRecentUsedColor
111
120
  }, /*#__PURE__*/React.createElement("i", {
112
121
  className: classnames(iconClass, 'sdoc-color-icon')
113
122
  }), /*#__PURE__*/React.createElement("div", {
114
- className: "recent-used-color",
123
+ className: "last-used-color",
115
124
  style: {
116
- backgroundColor: recentUsedColors[0] || TRANSPARENT
125
+ backgroundColor: lastUsedColor || 'unset'
117
126
  }
118
- })), /*#__PURE__*/React.createElement("i", {
127
+ })), /*#__PURE__*/React.createElement("div", {
119
128
  id: id,
120
- className: "sdoc-color-toggle-icon sdocfont sdoc-".concat(isShowMenu ? 'caret-up' : 'drop-down')
121
- })), text && /*#__PURE__*/React.createElement(UncontrolledTooltip, {
129
+ className: "sdoc-color-toggle sdoc-menu-with-dropdown-triangle"
130
+ }, /*#__PURE__*/React.createElement("i", {
131
+ className: "sdoc-menu-with-dropdown-triangle-icon sdocfont sdoc-".concat(isShowMenu ? 'caret-up' : 'drop-down')
132
+ }))), text && /*#__PURE__*/React.createElement(UncontrolledTooltip, {
122
133
  target: buttonId,
123
134
  fade: false,
124
135
  placement: "bottom",
125
136
  delay: 0
126
137
  }, t(text)), !disabled && /*#__PURE__*/React.createElement(UncontrolledPopover, {
127
138
  target: id,
128
- className: "sdoc-color-menu-popover",
139
+ className: classnames('sdoc-color-menu-popover', popoverClassName),
129
140
  trigger: "legacy",
130
141
  placement: "bottom-start",
131
142
  hideArrow: true,
@@ -150,7 +161,7 @@ var ColorMenu = function ColorMenu(_ref) {
150
161
  return /*#__PURE__*/React.createElement(ColorItem, {
151
162
  key: "default-color-".concat(index),
152
163
  color: color,
153
- recentUsedColor: recentUsedColors[0]
164
+ lastUsedColor: lastUsedColor
154
165
  });
155
166
  })), /*#__PURE__*/React.createElement("div", {
156
167
  className: "sdoc-color-standard-colors-container"
@@ -163,7 +174,7 @@ var ColorMenu = function ColorMenu(_ref) {
163
174
  return /*#__PURE__*/React.createElement(ColorItem, {
164
175
  key: "standard-color-".concat(index),
165
176
  color: color,
166
- recentUsedColor: recentUsedColors[0]
177
+ lastUsedColor: lastUsedColor
167
178
  });
168
179
  }))), /*#__PURE__*/React.createElement("div", {
169
180
  className: "sdoc-color-recent-used-colors-container"
@@ -202,7 +213,7 @@ var ColorMenu = function ColorMenu(_ref) {
202
213
  onClick: onClick
203
214
  }, /*#__PURE__*/React.createElement(ChromePicker, {
204
215
  disableAlpha: true,
205
- color: recentUsedColors[0] || '',
216
+ color: lastUsedColor || '',
206
217
  onChange: onChange
207
218
  }))))));
208
219
  };
@@ -4,6 +4,9 @@
4
4
  font-size: 0.75rem;
5
5
  border-right: 1px solid #e5e6e8;
6
6
  color: #555555;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
7
10
  }
8
11
 
9
12
  .menu-group .menu-group-item {
@@ -11,7 +14,7 @@
11
14
  height: 30px;
12
15
  line-height: 30px;
13
16
  margin-right: 10px;
14
- border: 1px solid transparent;
17
+ border: none !important;
15
18
  color: #555555;
16
19
  background-color: #fff;
17
20
  }
@@ -32,3 +35,51 @@
32
35
  .menu-group .menu-group-item .sdocfont {
33
36
  font-size: 14px;
34
37
  }
38
+
39
+ /* sdoc-menu-with-dropdown */
40
+ .menu-group .menu-group-item.sdoc-menu-with-dropdown {
41
+ width: 36px;
42
+ height: 30px;
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ border: 0 !important;
47
+ padding: 0 !important;
48
+ margin-right: 10px;
49
+ overflow: hidden;
50
+ }
51
+
52
+ .menu-group .menu-group-item.sdoc-menu-with-dropdown.disabled {
53
+ color: #999;
54
+ width: 24px !important;
55
+ }
56
+
57
+ .sdoc-menu-with-dropdown:not(.disabled):hover {
58
+ background: #e5e5e5;
59
+ border-radius: 2px;
60
+ }
61
+
62
+ .sdoc-menu-with-dropdown .sdoc-menu-with-dropdown-icon {
63
+ width: 24px;
64
+ height: 30px;
65
+ display: flex;
66
+ align-items: center;
67
+ justify-content: center;
68
+ }
69
+
70
+ .sdoc-menu-with-dropdown .sdoc-menu-with-dropdown-icon .sdocfont {
71
+ font-size: 14px;
72
+ }
73
+
74
+ .sdoc-menu-with-dropdown .sdoc-menu-with-dropdown-triangle {
75
+ width: 12px;
76
+ height: 30px;
77
+ display: flex;
78
+ align-items: center;
79
+ justify-content: center;
80
+ }
81
+
82
+ .sdoc-menu-with-dropdown .sdoc-menu-with-dropdown-triangle .sdoc-menu-with-dropdown-triangle-icon {
83
+ font-size: 14px;
84
+ transform: scale(.8);
85
+ }
@@ -1,7 +1,7 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
2
  import React, { useCallback, useEffect, useState } from 'react';
3
- import { createPortal } from 'react-dom';
4
3
  import { withTranslation } from 'react-i18next';
4
+ import ElementPopover from '../../../commons/element-popover';
5
5
  import { genCodeLangs } from '../prismjs';
6
6
  import './index.css';
7
7
  var CodeBlockHoverMenu = function CodeBlockHoverMenu(_ref) {
@@ -68,7 +68,7 @@ var CodeBlockHoverMenu = function CodeBlockHoverMenu(_ref) {
68
68
  }).text;
69
69
  setSelectedLanguageText(selectedLanguageText);
70
70
  }, [language]);
71
- return /*#__PURE__*/React.createElement(React.Fragment, null, createPortal( /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
71
+ return /*#__PURE__*/React.createElement(ElementPopover, null, /*#__PURE__*/React.createElement("div", {
72
72
  className: "sdoc-code-block-hover-menu-container",
73
73
  style: menuPosition
74
74
  }, /*#__PURE__*/React.createElement("div", {
@@ -110,6 +110,6 @@ var CodeBlockHoverMenu = function CodeBlockHoverMenu(_ref) {
110
110
  }, /*#__PURE__*/React.createElement("i", {
111
111
  className: "sdocfont sdoc-check-square icon-font"
112
112
  })), item.text);
113
- })))))), document.body));
113
+ }))))));
114
114
  };
115
115
  export default withTranslation('sdoc-editor')(CodeBlockHoverMenu);
@@ -3,6 +3,7 @@ import _createClass from "@babel/runtime/helpers/esm/createClass";
3
3
  import _inherits from "@babel/runtime/helpers/esm/inherits";
4
4
  import _createSuper from "@babel/runtime/helpers/esm/createSuper";
5
5
  import React from 'react';
6
+ import { Range } from '@seafile/slate';
6
7
  import { unWrapLinkNode } from './helpers';
7
8
  import AddLinkDialog from './menu/add-link-dialog';
8
9
  import LinkHoverComponent from './menu/hover-link-dialog';
@@ -96,7 +97,7 @@ var LinkHoverMenuComponent = /*#__PURE__*/function (_React$Component) {
96
97
  url: element.href,
97
98
  title: element.title,
98
99
  onLinkDialogToggle: this.onLinkDialogToggle
99
- }), isShowLinkMenu && /*#__PURE__*/React.createElement(LinkHoverComponent, {
100
+ }), isShowLinkMenu && Range.isCollapsed(editor.selection) && /*#__PURE__*/React.createElement(LinkHoverComponent, {
100
101
  menuPosition: menuPosition,
101
102
  editor: editor,
102
103
  href: element.href,
@@ -5,8 +5,8 @@ import _createSuper from "@babel/runtime/helpers/esm/createSuper";
5
5
  import React, { Component } from 'react';
6
6
  import { withTranslation } from 'react-i18next';
7
7
  import { Modal, ModalHeader, ModalBody, ModalFooter, Button, Label } from 'reactstrap';
8
- import NumberInput from '../../number-input';
9
8
  import { TABLE_MAX_ROWS, TABLE_MAX_COLUMNS } from '../../constants';
9
+ import NumberInput from './number-input';
10
10
  import './index.css';
11
11
  var CustomTableSizeDialog = /*#__PURE__*/function (_Component) {
12
12
  _inherits(CustomTableSizeDialog, _Component);
@@ -17,9 +17,9 @@ var CommonMenu = /*#__PURE__*/function (_Component) {
17
17
  className = _this$props.className,
18
18
  disabled = _this$props.disabled;
19
19
  var itemClass = 'btn btn-icon btn-secondary btn-active d-flex';
20
- if (!isRichEditor) return itemClass + ' ' + className;
20
+ if (!isRichEditor) return itemClass + ' ' + className + ' sdoc-menu-with-dropdown';
21
21
  itemClass = "rich-icon-btn d-flex ".concat(disabled ? 'rich-icon-btn-disabled' : 'rich-icon-btn-hover');
22
- return itemClass + ' ' + className;
22
+ return itemClass + ' ' + className + ' sdoc-menu-with-dropdown';
23
23
  };
24
24
  _this.hidePopover = function () {
25
25
  _this.ref && _this.ref.toggle && _this.ref.toggle();
@@ -53,11 +53,15 @@ var CommonMenu = /*#__PURE__*/function (_Component) {
53
53
  id: id,
54
54
  type: "button",
55
55
  className: className
56
+ }, /*#__PURE__*/React.createElement("div", {
57
+ className: "sdoc-menu-with-dropdown-icon"
56
58
  }, /*#__PURE__*/React.createElement("i", {
57
59
  className: iconClass
58
- }), /*#__PURE__*/React.createElement("span", {
59
- className: "sdocfont sdoc-".concat(isShowMenu ? 'caret-up' : 'drop-down')
60
- })), /*#__PURE__*/React.createElement(UncontrolledPopover, {
60
+ })), /*#__PURE__*/React.createElement("div", {
61
+ className: "sdoc-menu-with-dropdown-triangle"
62
+ }, /*#__PURE__*/React.createElement("i", {
63
+ className: "sdoc-menu-with-dropdown-triangle-icon sdocfont sdoc-".concat(isShowMenu ? 'caret-up' : 'drop-down')
64
+ }))), /*#__PURE__*/React.createElement(UncontrolledPopover, {
61
65
  target: id,
62
66
  className: "sdoc-common-menu-popover",
63
67
  trigger: "legacy",
@@ -1,11 +1,20 @@
1
1
  .sdoc-table-menu-group.menu-group .menu-group-item:not(.sdoc-remove-table) {
2
- width: 48px;
3
- display: flex;
4
- align-items: center;
5
- justify-content: center;
2
+ width: 36px;
6
3
  }
7
4
 
8
- .sdoc-table-menu-group .sdoc-drop-down,
9
- .sdoc-table-menu-group .sdoc-caret-up {
10
- transform: scale(.8);
5
+ .sdoc-table-menu-group .sdoc-menu-with-dropdown .sdoc-menu-with-dropdown-icon {
6
+ width: 24px;
7
+ }
8
+
9
+ .sdoc-table-menu-group .sdoc-menu-with-dropdown .sdoc-menu-with-dropdown-triangle {
10
+ width: 12px;
11
+ }
12
+
13
+ .sdoc-table-menu-group .sdoc-color-menu .last-used-color-container {
14
+ height: 100%;
15
+ padding-top: 2px;
16
+ }
17
+
18
+ .sdoc-color-menu-popover.sdoc-table-cell-bg-colors-popover .popover {
19
+ left: -24px !important;
11
20
  }
@@ -57,7 +57,7 @@ var ActiveTableMenu = /*#__PURE__*/function (_Component) {
57
57
  var t = _this.props.t;
58
58
  return /*#__PURE__*/React.createElement(CommonMenu, {
59
59
  id: "text-align",
60
- iconClass: "sdocfont sdoc-align-left mr-1",
60
+ iconClass: "sdocfont sdoc-align-left",
61
61
  ref: function ref(_ref) {
62
62
  return _this.textAlignRef = _ref;
63
63
  }
@@ -82,7 +82,7 @@ var ActiveTableMenu = /*#__PURE__*/function (_Component) {
82
82
  var t = _this.props.t;
83
83
  return /*#__PURE__*/React.createElement(CommonMenu, {
84
84
  id: "table-column",
85
- iconClass: "sdocfont sdoc-column mr-1",
85
+ iconClass: "sdocfont sdoc-column",
86
86
  ref: function ref(_ref2) {
87
87
  return _this.tableColumnRef = _ref2;
88
88
  }
@@ -98,7 +98,7 @@ var ActiveTableMenu = /*#__PURE__*/function (_Component) {
98
98
  var t = _this.props.t;
99
99
  return /*#__PURE__*/React.createElement(CommonMenu, {
100
100
  id: "table-row",
101
- iconClass: "sdocfont sdoc-row mr-1",
101
+ iconClass: "sdocfont sdoc-row",
102
102
  ref: function ref(_ref3) {
103
103
  return _this.tableRowRef = _ref3;
104
104
  }
@@ -144,7 +144,9 @@ var ActiveTableMenu = /*#__PURE__*/function (_Component) {
144
144
  }, menuConfig), {}, {
145
145
  onMouseDown: function onMouseDown() {},
146
146
  setColor: _this.setColor,
147
- localStorageKey: 'sdoc-recent-used-bg-colors'
147
+ recentUsedColorsKey: 'sdoc-recent-used-bg-colors',
148
+ lastUsedColorKey: 'sdoc-last-used-bg-colors',
149
+ popoverClassName: 'sdoc-table-cell-bg-colors-popover'
148
150
  });
149
151
  return /*#__PURE__*/React.createElement(ColorMenu, props);
150
152
  };
@@ -6,12 +6,12 @@ import _createSuper from "@babel/runtime/helpers/esm/createSuper";
6
6
  import React from 'react';
7
7
  import { withTranslation } from 'react-i18next';
8
8
  import ObjectUtils from '../../../../../utils/object-utils';
9
+ import ElementPopover from '../../../../commons/element-popover';
9
10
  import { ELEMENT_TYPE } from '../../../../constants';
10
- import InsertTableElement from './insert-table-element';
11
11
  import { getSelectedNodeByType } from '../../../../core';
12
12
  import { TABLE_MAX_COLUMNS, TABLE_MAX_ROWS, TABLE_ELEMENT, TABLE_ELEMENT_POSITION } from '../../constants';
13
13
  import { insertTableElement, removeTableElement } from '../../helpers';
14
- import ModalPortal from '../../../../commons/modal-portal';
14
+ import InsertTableElement from './insert-table-element';
15
15
  import './index.css';
16
16
  var TableContextMenu = /*#__PURE__*/function (_React$Component) {
17
17
  _inherits(TableContextMenu, _React$Component);
@@ -98,7 +98,7 @@ var TableContextMenu = /*#__PURE__*/function (_React$Component) {
98
98
  var selectedCols = tableSelectedRange.maxColIndex - tableSelectedRange.minColIndex + 1;
99
99
  var canAddRowsCount = currentRowsCount + selectedRows > TABLE_MAX_ROWS ? TABLE_MAX_ROWS - currentRowsCount : selectedRows;
100
100
  var canAddColsCount = currentColumnsCount + selectedCols > TABLE_MAX_COLUMNS ? TABLE_MAX_COLUMNS - currentColumnsCount : selectedCols;
101
- return /*#__PURE__*/React.createElement(ModalPortal, {
101
+ return /*#__PURE__*/React.createElement(ElementPopover, {
102
102
  className: "sdoc-context-menu"
103
103
  }, /*#__PURE__*/React.createElement("div", {
104
104
  style: contextStyle,
@@ -48,7 +48,7 @@ var TableCell = function TableCell(_ref) {
48
48
  }
49
49
  if (ObjectUtils.hasProperty(element.style, STYLE_KEY.BG_COLOR)) {
50
50
  var color = element.style[STYLE_KEY.BG_COLOR];
51
- if (color && (color !== 'transparent' || color !== 'unset')) {
51
+ if (color && color !== 'transparent' && color !== 'unset') {
52
52
  style['backgroundColor'] = isSelected ? colorBlend(SELECTED_TABLE_CELL_BG_COLOR, color, 0.9) : color;
53
53
  }
54
54
  }
@@ -88,7 +88,7 @@ function renderTableCell(props) {
88
88
  if (ObjectUtils.hasProperty(element, STYLE_KEY.TEXT_ALIGN)) {
89
89
  style[STYLE_KEY.TEXT_ALIGN] = element[STYLE_KEY.TEXT_ALIGN];
90
90
  }
91
- if (ObjectUtils.hasProperty(element.style, STYLE_KEY.BG_COLOR)) {
91
+ if (ObjectUtils.hasProperty(element.style, STYLE_KEY.BG_COLOR) && element.style[STYLE_KEY.BG_COLOR]) {
92
92
  style['backgroundColor'] = element.style[STYLE_KEY.BG_COLOR];
93
93
  }
94
94
  var column = getCellColumn(editor, element);
@@ -1,116 +1,87 @@
1
- import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
2
- import _createClass from "@babel/runtime/helpers/esm/createClass";
3
- import _inherits from "@babel/runtime/helpers/esm/inherits";
4
- import _createSuper from "@babel/runtime/helpers/esm/createSuper";
5
- import React from 'react';
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import React, { useRef, useState, useCallback } from 'react';
3
+ import { UncontrolledPopover } from 'reactstrap';
6
4
  import { withTranslation } from 'react-i18next';
7
5
  import classnames from 'classnames';
8
6
  import { getAlignType, isMenuDisabled, setAlignType } from '../helpers';
9
7
  import { TEXT_ALIGN, MENUS_CONFIG_MAP } from '../../../constants';
10
- import './style.css';
11
- var TextAlignMenu = /*#__PURE__*/function (_React$Component) {
12
- _inherits(TextAlignMenu, _React$Component);
13
- var _super = _createSuper(TextAlignMenu);
14
- function TextAlignMenu(props) {
15
- var _this;
16
- _classCallCheck(this, TextAlignMenu);
17
- _this = _super.call(this, props);
18
- _this.registerEventHandler = function () {
19
- document.addEventListener('click', _this.onHideTextAlignMenu, true);
20
- };
21
- _this.unregisterEventHandler = function () {
22
- document.removeEventListener('click', _this.onHideTextAlignMenu, true);
23
- };
24
- _this.onHideTextAlignMenu = function (e) {
25
- var menu = _this.menu;
26
- var clickIsInMenu = menu && menu.contains(e.target) && menu !== e.target;
27
- if (clickIsInMenu) return;
28
- _this.setState({
29
- isDropdownMenuOpen: false
30
- }, function () {
31
- _this.unregisterEventHandler();
32
- });
33
- };
34
- _this.getCurrentType = function () {
35
- var editor = _this.props.editor;
36
- return getAlignType(editor);
37
- };
38
- _this.isActive = function (type) {
39
- return _this.getCurrentType() === type;
40
- };
41
- _this.isDisabled = function () {
42
- var editor = _this.props.editor;
43
- return isMenuDisabled(editor);
44
- };
45
- _this.onToggleClick = function (event) {
46
- event.stopPropagation();
47
- event.nativeEvent.stopImmediatePropagation();
48
- var isDropdownMenuOpen = !_this.state.isDropdownMenuOpen;
49
- if (isDropdownMenuOpen) {
50
- _this.setState({
51
- isDropdownMenuOpen: isDropdownMenuOpen
52
- }, function () {
53
- _this.registerEventHandler();
54
- });
55
- } else {
56
- _this.setState({
57
- isDropdownMenuOpen: isDropdownMenuOpen
58
- }, function () {
59
- _this.unregisterEventHandler();
60
- });
8
+ var TextAlignMenu = function TextAlignMenu(_ref) {
9
+ var isRichEditor = _ref.isRichEditor,
10
+ className = _ref.className,
11
+ editor = _ref.editor;
12
+ var _useState = useState(false),
13
+ _useState2 = _slicedToArray(_useState, 2),
14
+ isShowMenu = _useState2[0],
15
+ setMenuShow = _useState2[1];
16
+ var popoverRef = useRef(null);
17
+ var disabled = isMenuDisabled(editor);
18
+ var buttonId = 'sdoc-button-text-align';
19
+ var toggle = useCallback(function (event) {
20
+ popoverRef.current.toggle();
21
+ setMenuShow(!isShowMenu);
22
+
23
+ // eslint-disable-next-line react-hooks/exhaustive-deps
24
+ }, [isShowMenu]);
25
+ var getCurrentType = useCallback(function () {
26
+ return getAlignType(editor);
27
+ }, [editor]);
28
+ var setType = useCallback(function (type) {
29
+ setAlignType(editor, type);
30
+ toggle();
31
+
32
+ // eslint-disable-next-line react-hooks/exhaustive-deps
33
+ }, [editor, isShowMenu]);
34
+ var validClassName = classnames(className, 'sdoc-menu-with-dropdown', {
35
+ 'menu-show': isShowMenu,
36
+ 'disabled': disabled,
37
+ 'rich-icon-btn d-flex': isRichEditor,
38
+ 'rich-icon-btn-disabled': isRichEditor && disabled,
39
+ 'rich-icon-btn-hover': isRichEditor && !disabled,
40
+ 'btn btn-icon btn-secondary btn-active d-flex': !isRichEditor
41
+ });
42
+ var curType = getCurrentType();
43
+ var curIcon = MENUS_CONFIG_MAP[TEXT_ALIGN].filter(function (item) {
44
+ return item.type === curType;
45
+ })[0].iconClass;
46
+ var caretIconClass = "sdoc-menu-with-dropdown-triangle-icon sdocfont sdoc-".concat(isShowMenu ? 'caret-up' : 'drop-down');
47
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("button", {
48
+ type: "button",
49
+ className: validClassName,
50
+ id: buttonId,
51
+ disabled: disabled
52
+ }, /*#__PURE__*/React.createElement("div", {
53
+ className: "sdoc-menu-with-dropdown-icon"
54
+ }, /*#__PURE__*/React.createElement("span", {
55
+ className: curIcon
56
+ })), !disabled && /*#__PURE__*/React.createElement("div", {
57
+ className: "sdoc-menu-with-dropdown-triangle"
58
+ }, /*#__PURE__*/React.createElement("span", {
59
+ className: caretIconClass
60
+ }))), !disabled && /*#__PURE__*/React.createElement(UncontrolledPopover, {
61
+ target: buttonId,
62
+ className: "sdoc-menu-popover sdoc-dropdown-menu",
63
+ trigger: "legacy",
64
+ placement: "bottom-start",
65
+ hideArrow: true,
66
+ toggle: toggle,
67
+ fade: false,
68
+ ref: popoverRef
69
+ }, /*#__PURE__*/React.createElement("div", {
70
+ className: "pt-2 pb-2"
71
+ }, MENUS_CONFIG_MAP[TEXT_ALIGN].map(function (item, index) {
72
+ return /*#__PURE__*/React.createElement("div", {
73
+ key: index,
74
+ className: "sdoc-dropdown-menu-item",
75
+ onClick: function onClick() {
76
+ return setType(item.type);
61
77
  }
62
- };
63
- _this.setType = function (type) {
64
- var editor = _this.props.editor;
65
- setAlignType(editor, type);
66
- _this.setState({
67
- isDropdownMenuOpen: false
68
- }, function () {
69
- _this.unregisterEventHandler();
70
- });
71
- };
72
- _this.setMenuRef = function (ref) {
73
- _this.menu = ref;
74
- };
75
- _this.state = {
76
- isDropdownMenuOpen: false
77
- };
78
- return _this;
79
- }
80
- _createClass(TextAlignMenu, [{
81
- key: "render",
82
- value: function render() {
83
- var _this2 = this;
84
- var isDropdownMenuOpen = this.state.isDropdownMenuOpen;
85
- var caretIconClass = "caret-icon sdocfont sdoc-".concat(isDropdownMenuOpen ? 'caret-up' : 'drop-down');
86
- var curType = this.getCurrentType();
87
- var curIcon = MENUS_CONFIG_MAP[TEXT_ALIGN].filter(function (item) {
88
- return item.type == curType;
89
- })[0].iconClass;
90
- var disabled = this.isDisabled();
91
- return /*#__PURE__*/React.createElement("div", {
92
- className: "align-menu"
93
- }, /*#__PURE__*/React.createElement("div", {
94
- className: classnames('align-toggle px-2', {
95
- 'align-toggle-disabled': disabled
96
- }),
97
- onClick: disabled ? function () {} : this.onToggleClick
98
- }, /*#__PURE__*/React.createElement("span", {
99
- className: "mr-1 ".concat(curIcon)
100
- }), !disabled && /*#__PURE__*/React.createElement("span", {
101
- className: caretIconClass
102
- })), isDropdownMenuOpen && /*#__PURE__*/React.createElement("div", {
103
- ref: this.setMenuRef,
104
- className: "align-popover sdoc-dropdown-menu"
105
- }, MENUS_CONFIG_MAP[TEXT_ALIGN].map(function (item, index) {
106
- return /*#__PURE__*/React.createElement("span", {
107
- key: index,
108
- className: "sdoc-dropdown-menu-item ".concat(item.iconClass),
109
- onClick: _this2.setType.bind(_this2, item.type)
110
- });
111
- })));
112
- }
113
- }]);
114
- return TextAlignMenu;
115
- }(React.Component);
78
+ }, /*#__PURE__*/React.createElement("i", {
79
+ className: item.iconClass
80
+ }));
81
+ }))));
82
+ };
83
+ TextAlignMenu.defaultProps = {
84
+ isRichEditor: true,
85
+ className: 'menu-group-item'
86
+ };
116
87
  export default withTranslation('sdoc-editor')(TextAlignMenu);
@@ -12,7 +12,8 @@ var TextStyleMenuList = function TextStyleMenuList(_ref) {
12
12
  var editor = _ref.editor,
13
13
  t = _ref.t,
14
14
  isRichEditor = _ref.isRichEditor,
15
- className = _ref.className;
15
+ className = _ref.className,
16
+ idPrefix = _ref.idPrefix;
16
17
  var isActive = useCallback(function (type) {
17
18
  var isMark = getValue(editor, type);
18
19
  return !!isMark;
@@ -59,7 +60,9 @@ var TextStyleMenuList = function TextStyleMenuList(_ref) {
59
60
  };
60
61
  itemProps['defaultColorTip'] = item.type === ELEMENT_TYPE.COLOR ? t('Default') : '';
61
62
  }
62
- return _objectSpread(_objectSpread({}, itemProps), item);
63
+ return _objectSpread(_objectSpread(_objectSpread({}, itemProps), item), {}, {
64
+ id: idPrefix ? "".concat(idPrefix, "_").concat(item.id) : item.id
65
+ });
63
66
  });
64
67
 
65
68
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -0,0 +1,10 @@
1
+ .sdoc-context-toolbar {
2
+ position: absolute;
3
+ width: auto;
4
+ height: 42px;
5
+ z-index: 101;
6
+ background-color: #fff;
7
+ border: 1px solid #e8e8e8;
8
+ border-radius: 3px;
9
+ box-shadow: 0 2px 5px #0000001f;
10
+ }
@@ -0,0 +1,55 @@
1
+ import React, { useRef, useEffect, useCallback } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import { useFocused, useSlateStatic, useReadOnly } from '@seafile/slate-react';
4
+ import { Editor, Range } from '@seafile/slate';
5
+ import { MenuGroup } from '../../menu';
6
+ import TextStyleMenuList from '../../plugins/text-style/menu';
7
+ import { useScrollContext } from '../../../hooks/use-scroll-context';
8
+ import { getSelectedNodeByType } from '../../core';
9
+ import { CODE_BLOCK } from '../../constants';
10
+ import './index.css';
11
+ var ContextToolbar = function ContextToolbar() {
12
+ var ref = useRef(null);
13
+ var editor = useSlateStatic();
14
+ var scrollRef = useScrollContext();
15
+ var inFocus = useFocused();
16
+ var readOnly = useReadOnly();
17
+ var setContextToolbarPosition = useCallback(function () {
18
+ var el = ref.current;
19
+ var domSelection = window.getSelection();
20
+ var domRange = domSelection.getRangeAt(0);
21
+ var rect = domRange.getBoundingClientRect();
22
+ el.style.top = "".concat(rect.top - el.offsetHeight, "px");
23
+ el.style.left = "".concat(rect.left, "px");
24
+ // eslint-disable-next-line react-hooks/exhaustive-deps
25
+ }, []);
26
+ var onScroll = useCallback(function (e) {
27
+ setContextToolbarPosition();
28
+ // eslint-disable-next-line react-hooks/exhaustive-deps
29
+ }, []);
30
+ useEffect(function () {
31
+ var el = ref.current;
32
+ var selection = editor.selection;
33
+ if (!el) {
34
+ return;
35
+ }
36
+ if (readOnly || !selection || !inFocus || Range.isCollapsed(selection) || Editor.string(editor, selection) === '' || getSelectedNodeByType(editor, CODE_BLOCK)) {
37
+ scrollRef.current && scrollRef.current.removeEventListener('scroll', onScroll);
38
+ el.removeAttribute('style');
39
+ return;
40
+ }
41
+ scrollRef.current && scrollRef.current.addEventListener('scroll', onScroll);
42
+ setContextToolbarPosition();
43
+ });
44
+ return createPortal( /*#__PURE__*/React.createElement("div", {
45
+ ref: ref,
46
+ className: "sdoc-context-toolbar",
47
+ onMouseDown: function onMouseDown(e) {
48
+ e.preventDefault(); // prevent toolbar from taking focus away from editor
49
+ }
50
+ }, /*#__PURE__*/React.createElement(MenuGroup, null, /*#__PURE__*/React.createElement(TextStyleMenuList, {
51
+ editor: editor,
52
+ idPrefix: 'sdoc_context_toolar'
53
+ }))), document.body);
54
+ };
55
+ export default ContextToolbar;
@@ -17,9 +17,17 @@ export var useSelectionPosition = function useSelectionPosition() {
17
17
  x: 0,
18
18
  y: 0
19
19
  };
20
- var domNode = ReactEditor.toDOMNode(editor, node[0]);
21
- var rect = domNode.getBoundingClientRect();
22
- return rect;
20
+ try {
21
+ var domNode = ReactEditor.toDOMNode(editor, node[0]);
22
+ var rect = domNode.getBoundingClientRect();
23
+ return rect;
24
+ } catch (error) {
25
+ // A new node has not yet been indexed, it cannot be retrieved, and the new node has no comment information, just do not display it
26
+ return {
27
+ x: 0,
28
+ y: 0
29
+ };
30
+ }
23
31
  };
24
32
  export var useCommentListPosition = function useCommentListPosition() {
25
33
  var selectionPosition = useSelectionPosition();
@@ -1,75 +1,38 @@
1
- import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
2
- import _createClass from "@babel/runtime/helpers/esm/createClass";
3
- import _inherits from "@babel/runtime/helpers/esm/inherits";
4
- import _createSuper from "@babel/runtime/helpers/esm/createSuper";
5
1
  import React from 'react';
6
- import './style.css';
7
- var MoreDropdownMenu = /*#__PURE__*/function (_React$Component) {
8
- _inherits(MoreDropdownMenu, _React$Component);
9
- var _super = _createSuper(MoreDropdownMenu);
10
- function MoreDropdownMenu(props) {
11
- var _this;
12
- _classCallCheck(this, MoreDropdownMenu);
13
- _this = _super.call(this, props);
14
- _this.registerEventHandler = function () {
15
- document.addEventListener('click', _this.onHideMoreDropdownMenu, true);
16
- };
17
- _this.unregisterEventHandler = function () {
18
- document.removeEventListener('click', _this.onHideMoreDropdownMenu, true);
19
- };
20
- _this.onHideMoreDropdownMenu = function (e) {
21
- var menu = _this.menu;
22
- var clickIsInMenu = menu && menu.contains(e.target) && menu !== e.target;
23
- if (clickIsInMenu) return;
24
- _this.setState({
25
- isDropdownMenuOpen: false
26
- }, function () {
27
- _this.unregisterEventHandler();
28
- });
29
- };
30
- _this.onToggleClick = function (event) {
31
- event.stopPropagation();
32
- event.nativeEvent.stopImmediatePropagation();
33
- var isDropdownMenuOpen = !_this.state.isDropdownMenuOpen;
34
- if (isDropdownMenuOpen) {
35
- _this.setState({
36
- isDropdownMenuOpen: isDropdownMenuOpen
37
- }, function () {
38
- _this.registerEventHandler();
39
- });
40
- } else {
41
- _this.setState({
42
- isDropdownMenuOpen: isDropdownMenuOpen
43
- }, function () {
44
- _this.unregisterEventHandler();
45
- });
46
- }
47
- };
48
- _this.setMenuRef = function (ref) {
49
- _this.menu = ref;
50
- };
51
- _this.state = {
52
- isDropdownMenuOpen: false
53
- };
54
- return _this;
55
- }
56
- _createClass(MoreDropdownMenu, [{
57
- key: "render",
58
- value: function render() {
59
- var isDropdownMenuOpen = this.state.isDropdownMenuOpen;
60
- return /*#__PURE__*/React.createElement("div", {
61
- className: "sdoc-more-menu"
62
- }, /*#__PURE__*/React.createElement("div", {
63
- className: "more-toggle px-2",
64
- onClick: this.onToggleClick
65
- }, /*#__PURE__*/React.createElement("span", {
66
- className: "sdocfont sdoc-more"
67
- })), isDropdownMenuOpen && /*#__PURE__*/React.createElement("div", {
68
- ref: this.setMenuRef,
69
- className: "more-popover"
70
- }, this.props.children));
71
- }
72
- }]);
73
- return MoreDropdownMenu;
74
- }(React.Component);
2
+ import classnames from 'classnames';
3
+ import { UncontrolledPopover } from 'reactstrap';
4
+ var MoreDropdownMenu = function MoreDropdownMenu(_ref) {
5
+ var className = _ref.className,
6
+ disabled = _ref.disabled,
7
+ isRichEditor = _ref.isRichEditor,
8
+ children = _ref.children;
9
+ var validClassName = classnames(className, 'sdoc-more-text-button', {
10
+ 'disabled': disabled,
11
+ 'rich-icon-btn': isRichEditor,
12
+ 'rich-icon-btn-disabled': isRichEditor && disabled,
13
+ 'rich-icon-btn-hover': isRichEditor && !disabled,
14
+ 'btn btn-icon btn-secondary btn-active': !isRichEditor
15
+ });
16
+ var buttonId = 'sdoc-more-text-operations';
17
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("button", {
18
+ className: validClassName,
19
+ type: "button",
20
+ id: buttonId
21
+ }, /*#__PURE__*/React.createElement("i", {
22
+ className: "sdocfont sdoc-more"
23
+ })), /*#__PURE__*/React.createElement(UncontrolledPopover, {
24
+ target: buttonId,
25
+ className: "sdoc-menu-popover sdoc-dropdown-menu",
26
+ trigger: "legacy",
27
+ placement: "bottom-end",
28
+ hideArrow: true,
29
+ fade: false
30
+ }, /*#__PURE__*/React.createElement("div", {
31
+ className: "menu-group"
32
+ }, children)));
33
+ };
34
+ MoreDropdownMenu.defaultProps = {
35
+ isRichEditor: true,
36
+ className: 'menu-group-item'
37
+ };
75
38
  export default MoreDropdownMenu;
@@ -20,6 +20,9 @@ html, body {
20
20
  border-bottom: 1px solid #e5e6e8;
21
21
  flex-shrink: 0;
22
22
  height: 56px;
23
+ position: relative;
24
+ z-index: 102;
25
+ background-color: #fff;
23
26
  }
24
27
 
25
28
  .sdoc-editor-page-wrapper .sdoc-editor-page-content {
@@ -7,12 +7,26 @@ var LocalStorage = /*#__PURE__*/function () {
7
7
  _createClass(LocalStorage, null, [{
8
8
  key: "setItem",
9
9
  value: function setItem(key, value) {
10
- return window.localStorage.setItem(key, JSON.stringify(value));
10
+ var savedValue;
11
+ var valueType = typeof value;
12
+ if (valueType === 'string') {
13
+ savedValue = value;
14
+ } else if (valueType === 'number') {
15
+ savedValue = value + '';
16
+ } else {
17
+ savedValue = JSON.stringify(value);
18
+ }
19
+ return window.localStorage.setItem(key, savedValue);
11
20
  }
12
21
  }, {
13
22
  key: "getItem",
14
23
  value: function getItem(key, defaultValue) {
15
- return JSON.parse(window.localStorage.getItem(key)) || defaultValue;
24
+ var value = window.localStorage.getItem(key);
25
+ try {
26
+ return JSON.parse(value) || defaultValue;
27
+ } catch (_unused) {
28
+ return value || defaultValue;
29
+ }
16
30
  }
17
31
  }, {
18
32
  key: "removeItem",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.1.88",
3
+ "version": "0.1.89",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -1,53 +0,0 @@
1
- .align-menu {
2
- display: flex;
3
- position: relative;
4
- margin-right: 10px;
5
- border: 1px solid transparent;
6
- padding: 1px 0px;
7
- }
8
-
9
- .align-menu .align-toggle {
10
- flex: 1;
11
- display: flex;
12
- justify-content: space-between;
13
- align-items: center;
14
- height: 30px;
15
- line-height: 30px;
16
- }
17
-
18
- .align-menu .align-toggle-disabled {
19
- color: #999;
20
- }
21
-
22
- .align-menu .align-toggle:not(.align-toggle-disabled):hover {
23
- background: #e5e5e5;
24
- border-radius: 2px;
25
- }
26
-
27
- .align-menu .align-toggle .sdocfont {
28
- display: inline-flex;
29
- justify-content: center;
30
- align-items: center;
31
- font-size: 14px;
32
- cursor: pointer;
33
- line-height: 1;
34
- }
35
-
36
- .align-menu .align-toggle .caret-icon {
37
- transform: scale(.8);
38
- }
39
-
40
- .align-menu .align-popover {
41
- position: absolute;
42
- top: 37px;
43
- left: 0;
44
- padding: 8px 0;
45
- background-color: #fff;
46
- border: 1px solid #e5e6e8;
47
- border-radius: 2px;
48
- box-shadow: 0 0 10px #ccc;
49
- display: flex;
50
- flex-direction: column;
51
- align-items: flex-start;
52
- z-index: 101;
53
- }
@@ -1,64 +0,0 @@
1
- .sdoc-more-menu {
2
- display: flex;
3
- position: relative;
4
- margin-right: 10px;
5
- border: 1px solid transparent;
6
- padding: 1px 0px;
7
- }
8
-
9
- .sdoc-more-menu .more-toggle {
10
- flex: 1;
11
- display: flex;
12
- justify-content: space-between;
13
- align-items: center;
14
- height: 30px;
15
- line-height: 30px;
16
- }
17
-
18
- .sdoc-more-menu .more-toggle-disabled {
19
- color: #999;
20
- }
21
-
22
- .sdoc-more-menu .more-toggle:not(.more-toggle-disabled):hover {
23
- background: #e5e5e5;
24
- border-radius: 2px;
25
- }
26
-
27
- .sdoc-more-menu .more-toggle .sdocfont {
28
- display: inline-flex;
29
- justify-content: center;
30
- align-items: center;
31
- font-size: 14px;
32
- cursor: pointer;
33
- line-height: 1;
34
- }
35
-
36
- .sdoc-more-menu .more-toggle .caret-icon {
37
- transform: scale(.8);
38
- }
39
-
40
- .sdoc-more-menu .more-popover {
41
- position: absolute;
42
- top: 37px;
43
- right: 0;
44
- height: 48px;
45
- padding: 8px 0 8px 10px;
46
- background-color: #fff;
47
- border: 1px solid #e5e6e8;
48
- border-radius: 2px;
49
- box-shadow: 0 0 10px #ccc;
50
- display: flex;
51
- z-index: 101;
52
- }
53
-
54
- .sdoc-more-menu .more-popover .more-menu-item {
55
- cursor: pointer;
56
- height: 30px;
57
- width: 100%;
58
- padding: 4px 24px;
59
- user-select: none;
60
- }
61
-
62
- .sdoc-more-menu .more-popover .more-menu-item:hover {
63
- background-color: rgb(245, 245, 245);
64
- }