@seafile/sdoc-editor 0.3.14 → 0.3.15

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.
@@ -13,7 +13,7 @@ export const INTERNAL_EVENT = {
13
13
  UPDATE_TAG_VIEW: 'update_tag_view',
14
14
  COMMENT_LIST_CLICK: 'comment_list_click',
15
15
  UNSEEN_NOTIFICATIONS_COUNT: 'unseen_notifications_count',
16
- DISPLAY_CALLOUT_COLOR_PICKER: 'display_callout_color_picker'
16
+ CLOSE_CALLOUT_COLOR_PICKER: 'close_callout_color_picker'
17
17
  };
18
18
  export const REVISION_DIFF_KEY = 'diff';
19
19
  export const REVISION_DIFF_VALUE = '1';
@@ -52,9 +52,14 @@ const withCallout = editor => {
52
52
  return insertFragment(data);
53
53
  };
54
54
  newEditor.onHotKeyDown = event => {
55
- if (isHotkey('mod+enter', event)) {
56
- insertElement(newEditor, PARAGRAPH, INSERT_POSITION.AFTER);
57
- return true;
55
+ if (getCalloutEntry(editor)) {
56
+ // Close color picker
57
+ const eventBus = EventBus.getInstance();
58
+ eventBus.dispatch(INTERNAL_EVENT.CLOSE_CALLOUT_COLOR_PICKER);
59
+ if (isHotkey('mod+enter', event)) {
60
+ insertElement(newEditor, PARAGRAPH, INSERT_POSITION.AFTER);
61
+ return true;
62
+ }
58
63
  }
59
64
  return onHotKeyDown && onHotKeyDown(event);
60
65
  };
@@ -3,11 +3,13 @@ import { Transforms } from '@seafile/slate';
3
3
  import { CALLOUT_COLOR_MAP } from '../constant';
4
4
  import { findPath } from '../../../core';
5
5
  import { changeFillBackgroundColor } from '../helper';
6
+ import { ElementPopover } from '../../../commons';
6
7
  import './index.css';
7
8
  const ColorSelector = (_ref, ref) => {
8
9
  let {
9
10
  editor,
10
- element
11
+ element,
12
+ popoverPosition
11
13
  } = _ref;
12
14
  const selectorRef = useRef(null);
13
15
  const handleClickColor = useCallback((editor, element, background_color) => {
@@ -24,12 +26,14 @@ const ColorSelector = (_ref, ref) => {
24
26
  } = element.style;
25
27
  return background_color && background_color === currentBackgroundColor;
26
28
  }, []);
27
- return /*#__PURE__*/React.createElement("div", {
29
+ return /*#__PURE__*/React.createElement(ElementPopover, null, /*#__PURE__*/React.createElement("div", {
30
+ className: "sdoc-callout-color-selector-container",
28
31
  ref: selectorRef,
29
- className: "sdoc-selector-gap-filler",
30
- contentEditable: false
31
- }, /*#__PURE__*/React.createElement("div", {
32
- className: "sdoc-callout-color-selector-container"
32
+ contentEditable: false,
33
+ style: {
34
+ top: popoverPosition.top,
35
+ left: popoverPosition.left
36
+ }
33
37
  }, /*#__PURE__*/React.createElement("ul", {
34
38
  className: "sdoc-color-selector-list"
35
39
  }, Object.values(CALLOUT_COLOR_MAP).map((_ref2, index) => {
@@ -18,23 +18,13 @@
18
18
  pointer-events: none;
19
19
  }
20
20
 
21
- .sdoc-selector-gap-filler {
22
- position: absolute;
23
- left: 0;
24
- top: -40px;
25
- width: 300px;
26
- height: 100%;
27
- z-index: 100;
28
- }
29
-
30
- .sdoc-selector-gap-filler .sdoc-callout-color-selector-container {
21
+ .sdoc-callout-color-selector-container {
31
22
  position: absolute;
32
23
  padding: 10px;
33
- top: -5px;
34
- left: 5px;
35
24
  background-color: #fff;
36
25
  border: 1px solid #eee;
37
26
  border-radius: 3px;
27
+ z-index: 100;
38
28
  }
39
29
 
40
30
  .sdoc-callout-color-selector-container .sdoc-color-selector-list {
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
2
  import React, { useCallback, useEffect, useRef, useState } from 'react';
3
+ import { useReadOnly } from '@seafile/slate-react';
3
4
  import { useTranslation } from 'react-i18next';
4
5
  import ColorSelector from './color-selector';
5
6
  import { CALLOUT_COLOR_MAP } from '../constant';
@@ -8,6 +9,7 @@ import { Editor } from '@seafile/slate';
8
9
  import { findPath } from '../../../core';
9
10
  import { INTERNAL_EVENT } from '../../../../constants';
10
11
  import EventBus from '../../../../utils/event-bus';
12
+ import { useScrollContext } from '../../../../hooks/use-scroll-context';
11
13
  import './index.css';
12
14
  const renderCallout = (_ref, editor) => {
13
15
  let {
@@ -16,8 +18,13 @@ const renderCallout = (_ref, editor) => {
16
18
  element
17
19
  } = _ref;
18
20
  const [isShowColorSelector, setIsShowColorSelector] = useState(false);
19
- const [isSelecting, setIsSelecting] = useState(false);
20
- const calloutRef = useRef(null);
21
+ const [popoverPosition, setPopoverPosition] = useState({
22
+ top: '',
23
+ left: ''
24
+ });
25
+ const readOnly = useReadOnly();
26
+ const scrollRef = useScrollContext();
27
+ const calloutRef = useRef();
21
28
  const colorSelectorRef = useRef({
22
29
  colorSelectorContainer: null
23
30
  });
@@ -28,25 +35,60 @@ const renderCallout = (_ref, editor) => {
28
35
  background_color
29
36
  } = element.style;
30
37
  const isFocusOnCallout = isFocusOnElement(editor, element);
31
- const handleMouseEnter = useCallback(id => {
32
- const isMoveInCurrentCallout = id === element.id;
33
- isMoveInCurrentCallout && !isSelecting && setIsShowColorSelector(true);
34
- }, [element.id, isSelecting]);
38
+ const handleCloseColorSelector = useCallback(() => {
39
+ setIsShowColorSelector(false);
40
+ }, []);
41
+ const handleScroll = useCallback(e => {
42
+ if (readOnly) return;
43
+ if (!isShowColorSelector) return;
44
+ if (e.currentTarget.scrollTop) {
45
+ const {
46
+ top,
47
+ left
48
+ } = calloutRef.current.getBoundingClientRect();
49
+ const menuTop = top - 42; // top = top distance - menu height
50
+ const newMenuPosition = {
51
+ top: menuTop,
52
+ left: left // left = code-block left distance
53
+ };
54
+
55
+ setPopoverPosition(newMenuPosition);
56
+ }
57
+ }, [isShowColorSelector, readOnly]);
35
58
  useEffect(() => {
36
59
  const eventBus = EventBus.getInstance();
37
- const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.DISPLAY_CALLOUT_COLOR_PICKER, handleMouseEnter);
60
+ const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.CLOSE_CALLOUT_COLOR_PICKER, handleCloseColorSelector);
38
61
  return unsubscribe;
39
- }, [handleMouseEnter]);
40
- const handleMouseLeave = useCallback(e => {
41
- setIsShowColorSelector(false);
42
- setIsSelecting(false);
43
- }, []);
62
+ }, [handleCloseColorSelector]);
63
+ useEffect(() => {
64
+ if (readOnly) return;
65
+ let observerRefValue = null;
66
+ if (scrollRef.current) {
67
+ scrollRef.current.addEventListener('scroll', handleScroll);
68
+ observerRefValue = scrollRef.current;
69
+ }
70
+ return () => {
71
+ observerRefValue.removeEventListener('scroll', handleScroll);
72
+ };
73
+ }, [handleScroll, readOnly, scrollRef]);
74
+ const handleDisplayColorSelector = useCallback(() => {
75
+ if (readOnly) return;
76
+ const {
77
+ top,
78
+ left
79
+ } = calloutRef.current.getBoundingClientRect();
80
+ const menuTop = top - 42; // top = top distance - menu height
81
+ const newMenuPosition = {
82
+ top: menuTop,
83
+ left: left // left = callout left distance
84
+ };
85
+
86
+ setPopoverPosition(newMenuPosition);
87
+ setIsShowColorSelector(true);
88
+ }, [readOnly]);
44
89
  const handleClick = useCallback(e => {
45
- var _colorSelectorRef$cur, _colorSelectorRef$cur2;
46
- setIsSelecting(true);
47
- const isClickInColorSelector = (_colorSelectorRef$cur = colorSelectorRef.current) === null || _colorSelectorRef$cur === void 0 ? void 0 : (_colorSelectorRef$cur2 = _colorSelectorRef$cur.colorSelectorContainer) === null || _colorSelectorRef$cur2 === void 0 ? void 0 : _colorSelectorRef$cur2.contains(e.target);
48
- !isClickInColorSelector && setIsShowColorSelector(false);
49
- }, []);
90
+ handleDisplayColorSelector();
91
+ }, [handleDisplayColorSelector]);
50
92
  const isShowPlaceholder = useCallback(() => {
51
93
  if (isFocusOnCallout) return false;
52
94
  // If element contains more than one element or element is not paragraph, show placeholder
@@ -56,27 +98,27 @@ const renderCallout = (_ref, editor) => {
56
98
  const elementContent = Editor.string(editor, elementPath);
57
99
  return !elementContent.length;
58
100
  }, [editor, element, isFocusOnCallout]);
59
- return /*#__PURE__*/React.createElement("div", {
60
- className: "sdoc-callout-white-wrapper"
61
- }, /*#__PURE__*/React.createElement("div", Object.assign({
101
+ return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
62
102
  "data-id": element.id,
63
103
  "data-root": "true",
64
- onMouseLeave: handleMouseLeave,
104
+ className: "sdoc-callout-white-wrapper",
105
+ onMouseLeave: handleCloseColorSelector
106
+ }), /*#__PURE__*/React.createElement("div", {
65
107
  onClick: handleClick,
66
108
  ref: calloutRef,
109
+ className: "".concat(attributes.className, " sdoc-callout-container"),
67
110
  style: {
68
111
  backgroundColor: background_color ? CALLOUT_COLOR_MAP[background_color].background_color : 'transparent',
69
112
  borderColor: isFocusOnCallout ? CALLOUT_COLOR_MAP[background_color].border_color : 'transparent'
70
113
  }
71
- }, attributes, {
72
- className: "".concat(attributes.className, " sdoc-callout-container")
73
- }), children, isShowPlaceholder() && /*#__PURE__*/React.createElement("div", {
114
+ }, children, isShowPlaceholder() && /*#__PURE__*/React.createElement("div", {
74
115
  contentEditable: false,
75
116
  className: "sdoc-callout-placeholder"
76
117
  }, t('Please_enter...')), isShowColorSelector && /*#__PURE__*/React.createElement(ColorSelector, {
77
118
  ref: colorSelectorRef,
78
119
  editor: editor,
79
- element: element
120
+ element: element,
121
+ popoverPosition: popoverPosition
80
122
  })));
81
123
  };
82
124
  export default renderCallout;
@@ -18,9 +18,6 @@ const TableSizePopover = _ref => {
18
18
  const [displaySize, setDisplaySize] = useState([5, 10]);
19
19
  const [selectedSize, setSelectedSize] = useState([1, 1]);
20
20
  const ref = useRef(null);
21
- const {
22
- t
23
- } = useTranslation();
24
21
  const onMouseEnter = useCallback(function (event) {
25
22
  let cellPosition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [1, 1];
26
23
  let newDisplaySize = displaySize.slice(0);
@@ -1,8 +1,6 @@
1
1
  import { Editor } from '@seafile/slate';
2
2
  import { findPath } from '../core';
3
- import { CALL_OUT, MOUSE_ENTER_EVENT_DISABLED_MAP } from '../constants';
4
- import { INTERNAL_EVENT } from '../../constants';
5
- import EventBus from '../../utils/event-bus';
3
+ import { MOUSE_ENTER_EVENT_DISABLED_MAP } from '../constants';
6
4
  import { onMouseEnter } from '../toolbar/side-toolbar/event';
7
5
  const isNeedAddMouseEnterEvent = (editor, element) => {
8
6
  const elementPath = findPath(editor, element);
@@ -20,18 +18,4 @@ const isNeedAddMouseEnterEvent = (editor, element) => {
20
18
  export const setMouseEnter = (editor, element, attributes) => {
21
19
  if (!isNeedAddMouseEnterEvent(editor, element)) return;
22
20
  attributes['onMouseEnter'] = e => onMouseEnter(e, element);
23
- };
24
-
25
- // Element extra event
26
- export const handleElementMouseEnterEvent = element => {
27
- const {
28
- id,
29
- type
30
- } = element;
31
- const eventBus = EventBus.getInstance();
32
- const elementEventMap = {
33
- [CALL_OUT]: eventBus.dispatch(INTERNAL_EVENT.DISPLAY_CALLOUT_COLOR_PICKER, id)
34
- };
35
- const event = elementEventMap[type];
36
- event && event();
37
21
  };
@@ -1,13 +1,9 @@
1
1
  import EventBus from '../../../utils/event-bus';
2
2
  import { INTERNAL_EVENT } from '../../../constants';
3
- import { CALL_OUT } from '../../constants';
4
- import { handleElementMouseEnterEvent } from '../../render/helper';
5
3
  export const onMouseEnter = (event, element) => {
6
4
  event.stopPropagation();
7
5
  const eventBus = EventBus.getInstance();
8
6
  eventBus.dispatch(INTERNAL_EVENT.ON_MOUSE_ENTER_BLOCK, event);
9
- element.type === CALL_OUT && eventBus.dispatch(INTERNAL_EVENT.DISPLAY_CALLOUT_COLOR_PICKER);
10
- handleElementMouseEnterEvent(element);
11
7
  };
12
8
  export const onDragOver = event => {
13
9
  event.stopPropagation();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "0.3.14",
3
+ "version": "0.3.15",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",